Skip to content

Latest commit

 

History

History
280 lines (224 loc) · 19 KB

File metadata and controls

280 lines (224 loc) · 19 KB

CLI Kernel

理念 / 概念

CLI kernel 定义 Provision、Collect、Perf 和 Chat 四条并列主路径的稳定边界。它们共用底层能力, 但不共享业务流程:

  • app 是 composition root,解析用户输入并注入 Plugin 与基础设施能力;
  • command 持有四条主路径共用的启动事实、目标解析和 access/审批契约;
  • provision 承载 image 发布、debug environment 创建和目标工具安装等显式状态变更;
  • collect/<domain> 拥有一次确定性诊断的配置、Facts、Probes、Detectors 和交付;
  • perf 使用共享 Perf Harness 产生受控业务负载,并以时间窗口和 Plugin 声明的关联 ID 复用 Collect 证据面;
  • packages/agent → chat/Session → chat/Controller → chat-tui 是独立问答链路,不依赖 provision 或 collect;
  • model 准备模型发现与 inference 访问,由 Chat 和 Model Collect 共用,不归属任一主路径;
  • packages/plugin 定义 Plugin、Service 与 capability 公共协议,plugins/<plugin> 持有访问实现与固定业务查询; infra 只提供 Doctor 的外部资源访问能力。

确定性诊断的核心不是“执行一组命令”,而是生成可复查的 Evidence:

Config → target confirmation → preparation → Inspect → Facts ─┬→ Probe → Observations ─┐
                                                               └─────────────────────────→ Evidence
                                                                                            ├→ Detector → Findings
                                                                                            ├→ Coverage
                                                                                            └→ Render
概念 稳定语义
Config flags/profile/交互输入形成的用户意图,不进入 Facts
Inspect / Facts 行动前的只读现场快照;每个子 Fact 显式标记取得状态
Probe / Observation 一次受限采集行动,以及它产生的结构化数据
Evidence 交给 detector 的 Observations 与领域显式挑选的 Facts
Finding / Coverage 基于证据的确定性判断,以及诊断目标的证据充分度
Operation 需要授权的副作用描述,本身不执行动作
Evidence Bundle manifest、原始输出和摘要组成的可审计产物

所有命令在进入上述领域流程前,都经过同一条准备链路:

validated Profile snapshot + command options
  → required Plugin capability + Plugin config
  → declared Host / Kubernetes environment
  → selected Target + staged access plan
  → permission check
  → PreparedCommand
  → Provision / Inspect+Probe / Chat

Profile 在单次命令内只解析和校验一次,后续 target、infra 与 Plugin context 均消费这份不可变快照。 CommandContext 是单次顶层命令的运行作用域:Decision 复用用户或命令意图作出的决策,Discovery 复用 执行期间的只读发现,ExecutionRecord 追加保存步骤已经产生、且会影响后续 action 的中间结果。三者都按 类型和语义作用域隔离;ExecutionRecord 不持久化,也不等同于 Collect Facts、Observations 或 Evidence。 Command 声明需要的 Host/Kubernetes 环境和最窄 Plugin capability;目标选择完成后,再把 Core 自身需求与 本次实际选中的 capability access 合成阶段性 access plan。配置、capability、通道或 required access 任一不满足时,命令不得进入实际采集、变更或 Agent loop。

环境准备不拥有隐式访问权。若 Service/Pod discovery 本身需要读 Kubernetes,它必须作为独立 access need 声明;preferred discovery 被拒绝时可进入已声明的手工输入路径,required operation 被拒绝时才 终止对应阶段。这样既能在干活前暴露真实权限缺口,也不会按命令的最大可能权限过度预检。

代码地图

cli/src/
├── app/                 命令入口、profile、会话流程与能力组装
├── chat/                AgentUE model、Session/Controller 与 Server wire protocol adapter
├── model/               Chat 与 Model Collect 共用的模型发现、选择与 inference 访问
├── plugin/              Plugin 宿主侧的选择、上下文与加载边界
├── command/             启动检查、Kubernetes 目标解析、执行上下文与 access/审批契约
├── provision/           image、debug environment 与目标工具准备
├── perf/                主动负载、Perf Harness 适配和可观测证据编排
├── protocol/            CLI ↔ doctor-server 协议与 SSE client
├── terminal/            命令共用的选择、输入、确认与输出边界
├── collect/
│   ├── protocol.ts      Facts、Observation、Finding、Coverage 等共享协议
│   ├── engine.ts        Facts → Probe → Evidence → Detector/Coverage
│   ├── *-engine.ts      Inspect、Probe 与 Strategy 调度
│   ├── evidence.ts      Worksheet 与 Evidence Bundle
│   ├── operation.ts     副作用授权和审计
│   ├── output/          Bundle、Markdown、HTML 等交付
│   └── <domain>/        领域 config/fact/probe/detector/render
└── infra/               Host、Target、K8s 与各类外部资源 adapter
    └── dump/            Target heap dumper backend 与 Toolkit bundle 适配

packages/agent/          CLI 与 server 宿主共用的 Agent、Skill 输入与 AgentUE 输出
packages/plugin/         Plugin、Service Catalog 与 capability 公共协议
plugins/<plugin>/        具体 Plugin 的 Catalog、领域模型与固定业务查询

目录按真实职责生长,不为概念对称提前创建空层。跨领域 Fact、Probe 或 infra 只有出现稳定、同语义的 重复时才上提;表面相似但诊断口径不同的逻辑继续留在各自 domain。

运行形态与执行位置

profile 决定 CLI 能呈现的能力,而不是让不同执行模型互相渗透:

条件 能力形态
零配置 使用本地 kubeconfig 的确定性诊断
配置 llm doctor chat 默认运行本地 Agent
配置 server 且显式 --server / --resume 连接 doctor-server 的远端 Agent

direct collect 不创建 connection、conversation 或 SSE,也不承担开放式 agent 推理;server mode 不把 server 内的工具执行细节搬回 CLI。本地模式由 CLI interface 驱动 packages/agent;远端模式由 ServerAgent 把 server wire protocol 投影为 AgentUE。server 只声明 endpoint,不隐式改变运行位置; server 宿主通过自己的 interface、凭据、执行环境和持久化 adapter 使用同一 Agent 实现。

执行位置属于能力身份:

  • Doctor Host 是运行 CLI 的工作站或部署机,拥有本地文件、网络入口、container engine 和离线 analyzer;
  • Target 是本轮被诊断的 Pod、container、进程、远端服务或数据对象;
  • Host 与 Target 的文件传输由 infra/file-transfer 表达,路径和方向必须显式命名;
  • 某侧缺少能力时,错误必须指出缺的是 Host 还是 Target,不能用全局 available 混合表达。

Kubernetes 是 Doctor Host 到 Target 的一种访问通道。app 完成通用准备并形成 CommandContext,各命令再按实际 资源作用域声明 requiredpreferred access contract:required 被明确拒绝时停止当前阶段; preferred 被拒绝时进入手动输入或低能力降级;kubectl auth can-i 无法判断时保留 unknown,由实际 操作给出最终结论。权限上下文按 executor 缓存,但不进入诊断 Facts/Evidence。

命令的前置条件沿两条正交能力轴表达:Core access 描述如何接近和安全操作 Target,Plugin capability 描述目标是什么、业务数据在哪里以及数据语义。Core command 不依赖 Plugin;Plugin command 始终注册, 但在创建 CommandContext 和访问 Kubernetes 前先验证 Doctor Host 已加载 Plugin 且具备 required capability,缺失时直接说明具体 capability。preferred capability 缺失只触发声明过的降级路径。 命令应声明自己真正消费的最窄业务契约:例如 doctor tracedoctor log 消费规范 trace_id,因此 依赖 service.traceId,而不是借用宽泛的 service.data 或在 OpenSearch 中猜测业务 ID 语义。

Command requirements
├── Plugin capability      业务目标、数据来源与语义
├── Core access contract   Host/Target/Kubernetes 访问条件
└── Operation              副作用上限与用户授权

Core 与 Plugin 的稳定协议面只有 access、data、infra、config:access 是 capability 的声明,data 是调用 输入输出,infra 是 Core 为选中 Target 提供的运行便利,config 是 profile 对 Plugin-owned schema 的不透明 透传。四者分开后,Core 不必理解业务配置,Plugin 也不能把获得 infra handle 等同于获得任意权限。

Command orchestration
├── Access plan = Core command needs + selected Service capability needs
├── Core infra ──Target-scoped helpers──> PluginContext
└── Plugin capability ──typed data/handle──> Evidence pipeline

Plugin (versioned distribution unit)
├── Service Catalog
│   ├── Service A ── capabilities + access declarations
│   └── Service B ── capabilities + access declarations
└── Skills

访问检查在实际工作之前、按当前阶段惰性发生,不能以命令可能使用的最大权限提前阻断低能力路径。例如 doctor debug 已有 可复用 debug container 时不需要 update pods/ephemeralcontainers;只有确实需要注入时才检查该权限。

业务型、基础设施型与混合型命令

Collect command 按诊断算法和数据语义的所有者分为三类。这个分类用于判断 Core 与 Plugin 的职责, 不是目录拆分规则;同一个命令可以先消费业务 capability,再进入标准基础设施诊断。

类型 典型命令 Plugin 负责 CLI Core 负责
业务型 data 定位业务 Service,经 Core access 取得运行态事实,执行固定 HTTP/DB 查询并返回约定结果 提供 Target-scoped access,触发 capability,编排 Evidence、Detector/Coverage 和展示
基础设施型 storememnet 按需贡献目标身份、连接配置或默认选择,不实现通用基础设施诊断 执行标准探测与分析,控制风险、资源生命周期和证据交付
混合型 tracelogconfigmodelmcp 处理业务入口、私有 schema 和目标投影 消费规范目标后执行通用采集、协议分析和报告

Kubernetes 的分工遵循同一所有权:Core 解析当前 profile 的 kubeconfig/context,但只向 Plugin 注入 namespace、Service 身份和 Target-scoped Kubernetes access,并统一托管超时、输出上限、取消与 port-forward 回收;Plugin 用该 access 自行解释 selector、定位 Pod、读取运行时配置。Core 不预先读取 selector、Pod、container 或 env 再回传给 Plugin,Plugin 也不持有 kubeconfig 或自行启动 kubectl。 只有 Kubernetes 操作本身属于 Core command 时,例如 log 读取 Pod 日志、mem 操作目标进程,Core 才 负责定位和操作对应 Target,并声明实际需要的 access contract。

混合型命令按阶段保持边界。例如 trace 先由 Plugin 把业务 ID 解析为规范 trace_id 并贡献 OpenSearch 目标,再由 Core 按 OTel/Jaeger 语义下载和分析 span;config 的 Deployment env 由 Core 采集,租户配置等业务数据由 Plugin 取得。collect 不因上述分类拆成 biz/infra 两套框架。

Collect 共享协议

Collect 的结果不是成功/失败二态,而是命令终止、诊断覆盖度与产物交付三个正交维度。只要流程正常 结束、形成可解释的部分证据并成功交付报告,partial 也是成功完成;报告必须醒目标明缺失证据、原因 及不能支持的结论。Finding 严重度只描述 Target 健康,不改变命令完成语义。

Collect 仍遵循 Config → Facts → Observations → Evidence → Findings/Coverage → Render 的单向数据流。 单项 Probe 失败只降低相应 Coverage,不阻断其它独立 Probe;未声明可降级处理的异常继续向上抛,避免 把 Doctor 自身错误伪装成部分完成。完整状态、调度、Evidence、退出码与授权契约见 collect-protocol.md

关键边界

Provision 与 Collect

两者都可能执行非只读动作,边界取决于主要结果:Provision 以外部能力准备完成为结果;Collect 以 可审计 Evidence 为结果。Collect 不会为了绕过前置条件隐藏式发布 image、创建 debug environment 或 安装工具;能力不足时说明缺口,由用户独立运行对应准备命令。

Provision 不使用统一 engine。image、debug、install 的结果和生命周期不同,因此各自拥有检查、授权、 执行和验证流程,只共享 CommandContext、terminal 交互和 infra 原语。

Perf 为什么单列

Perf 的主要动作是主动产生业务请求,结果是负载曲线与其对应的可观测证据。它既不是为后续诊断准备 环境的 Provision,也不是只观察既有现场的 Collect。doctor perf 因而与 doctor chat 一样保留顶层 入口:Core 负责共享负载契约、安全边界、窗口和报告;Plugin 的 Case capability 负责具体 Service 的 单次请求协议与协议判定,Perf capability 只声明 Case 组合和关联范围。Metric、Trace、Log 的采集仍调用 现有 Collect 实现,不在 Perf 下复制第四套采集器。

依赖方向与领域所有权

app 可以组装 Plugin、provisioncollectperfchatinfra。Provision、Collect 与 Chat 保持互不依赖;Perf 是编排层,会有意调用 Collect 稳定的 Metric、Trace、Log 入口,但不能复制其采集 实现。共同启动上下文、Kubernetes 目标解析和审批模型归 command,交互归 terminal,执行原语归 infrapackages/agentpackages/plugin 不依赖 CLI,具体 Plugin 只依赖 Plugin 公共包;CLI infra 实现 Plugin 公共包定义的 access port,但不知道业务 Service、表关系和诊断结论。Plugin loader 把当前精确 Plugin 版本的 Skills 解析后交给本地 Agent,Agent 不扫描独立的 Skill 目录。

Plugin 是多个 Service 与 Skill 的版本化分发单元;Service capability 才是业务能力与 access 的运行时 选择单位。命令只把实际参与本次调用的 Service capability 合入 access plan,不能因为同一 Plugin 还打包了 其它 Service 就预检整包最大权限。

运行时配置、Probe 生命周期、Evidence 适配和采集编排属于 collect/<domain>;Service 协议、固定查询 和 Plugin capability 分别属于 packages/pluginplugins/<plugin>;Registry、container engine、 package manager、文件传输和外部 client 属于 infra。Service Catalog 声明“可能提供什么”,具体部署 是否启用由运行时 Facts 判断。

Service 定义只由身份字段和 capabilities 容器组成。Catalog 只提供 findfindWithservicesWith 三种通用发现操作,不为每种能力增加专用方法;Store 选择等领域语义由对应 capability 模块提供 helper。 Plugin 原始配置 schema、解析规则和请求模板留在 plugins/<plugin>,必要时投影成中性 capability 接口供 collect 消费,不能让 collect 反向知道某个 Plugin 的配置 key 或内部对象。

入口、TUI 与终端输出

Command 同时服务交互用户和自动化调用:domain 只提供候选与选择语义,共用 prompt 和输出机制归 terminal。chat-tui 只依赖 Controller 提供的 view state 与 intent;Session 只接收 AgentUE patch, 不直接解释 pi 或 server wire 字段。doctor-server wire schema 由 ServerAgent 收口。

CLI 与 Toolkit 分发

CLI core 只依赖 Node-compatible API,从同一个入口构建各平台单文件。诊断 executable、debug image 与 离线系统包归独立版本的 Doctor Toolkit,不进入 CLI 单文件。infra/toolkit 先根据 Host process、Host container 或 Kubernetes container 的实际 OS/arch 选择并校验资源;需要共同演进的组件还必须按协议与 runtime compatibility 从同一个 archive 解析成完整 bundle,再交给对应 infra/hostinfra/dump、 container engine 或 Kubernetes adapter 执行。Doctor Host 平台不能替代 Target 平台。

Host 上同一能力同时具有 container 和 process backend 时,由 infra/host 自动探测:优先复用已经可用的 本地 container engine 与工具 image,不能满足能力要求时再回退本机进程。这里只观察已有能力,不会为了 命中优先通道而隐式 load image;需要准备 image 时仍由 Provision 明确完成。

Linux x64 CLI 同时提供 modern Bun 与 glibc 2.17-compatible Node SEA;无法证明 Host 满足 modern 基线时 保守选择兼容产物。具体版本、文件名、校验和与发布矩阵以各自 Makefile、manifest 和 CI gate 为事实源, 不在设计文档复制。

Command 文档约定

每个 doctor <command> 只在 docs/commands/ 维护一篇文档,描述领域理念、主流程和不能从单文件代码 看出的关键设计;共享执行协议只在本文定义,字段、阈值、参数和实现形状留在代码。命令文档如下:

Command 文档
Config commands/config-diagnosis.md
CPU commands/cpu-diagnosis.md
Data commands/data-diagnosis.md
Debug commands/debug-container.md
HTTP commands/http-diagnosis.md
Image commands/image.md
Install commands/install.md
Log commands/log-diagnosis.md
MCP commands/mcp-diagnosis.md
Memory commands/memory-diagnosis.md
Metric commands/metric-diagnosis.md
Perf commands/perf.md
Model commands/model-diagnosis.md
Network commands/network-diagnosis.md
Store(DB/VDB/S3/Redis) commands/store-diagnosis.md
Trace commands/trace-diagnosis.md

新增 command 时先定义 Facts、Observations、Evidence/Findings/Coverage 和纯 detector,再实现 Inspect/Probe 与 renderer;契约测试至少覆盖依赖调度、能力降级、授权拒绝、敏感信息边界和交付结果。若新增内容只是 共享协议的一个 case,更新本文或代码即可,无需创建横切专题文档。