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,各命令再按实际
资源作用域声明 required 或 preferred 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 trace 和 doctor 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 和展示 |
| 基础设施型 | store、mem、net |
按需贡献目标身份、连接配置或默认选择,不实现通用基础设施诊断 | 执行标准探测与分析,控制风险、资源生命周期和证据交付 |
| 混合型 | trace、log、config、model、mcp |
处理业务入口、私有 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 的结果不是成功/失败二态,而是命令终止、诊断覆盖度与产物交付三个正交维度。只要流程正常
结束、形成可解释的部分证据并成功交付报告,partial 也是成功完成;报告必须醒目标明缺失证据、原因
及不能支持的结论。Finding 严重度只描述 Target 健康,不改变命令完成语义。
Collect 仍遵循 Config → Facts → Observations → Evidence → Findings/Coverage → Render 的单向数据流。
单项 Probe 失败只降低相应 Coverage,不阻断其它独立 Probe;未声明可降级处理的异常继续向上抛,避免
把 Doctor 自身错误伪装成部分完成。完整状态、调度、Evidence、退出码与授权契约见
collect-protocol.md。
两者都可能执行非只读动作,边界取决于主要结果:Provision 以外部能力准备完成为结果;Collect 以 可审计 Evidence 为结果。Collect 不会为了绕过前置条件隐藏式发布 image、创建 debug environment 或 安装工具;能力不足时说明缺口,由用户独立运行对应准备命令。
Provision 不使用统一 engine。image、debug、install 的结果和生命周期不同,因此各自拥有检查、授权、
执行和验证流程,只共享 CommandContext、terminal 交互和 infra 原语。
Perf 的主要动作是主动产生业务请求,结果是负载曲线与其对应的可观测证据。它既不是为后续诊断准备
环境的 Provision,也不是只观察既有现场的 Collect。doctor perf 因而与 doctor chat 一样保留顶层
入口:Core 负责共享负载契约、安全边界、窗口和报告;Plugin 的 Case capability 负责具体 Service 的
单次请求协议与协议判定,Perf capability 只声明 Case 组合和关联范围。Metric、Trace、Log 的采集仍调用
现有 Collect 实现,不在 Perf 下复制第四套采集器。
app 可以组装 Plugin、provision、collect、perf、chat 和 infra。Provision、Collect 与 Chat
保持互不依赖;Perf 是编排层,会有意调用 Collect 稳定的 Metric、Trace、Log 入口,但不能复制其采集
实现。共同启动上下文、Kubernetes 目标解析和审批模型归 command,交互归 terminal,执行原语归 infra。
packages/agent 与 packages/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/plugin 与 plugins/<plugin>;Registry、container engine、
package manager、文件传输和外部 client 属于 infra。Service Catalog 声明“可能提供什么”,具体部署
是否启用由运行时 Facts 判断。
Service 定义只由身份字段和 capabilities 容器组成。Catalog 只提供 find、findWith、servicesWith
三种通用发现操作,不为每种能力增加专用方法;Store 选择等领域语义由对应 capability 模块提供 helper。
Plugin 原始配置 schema、解析规则和请求模板留在 plugins/<plugin>,必要时投影成中性 capability 接口供
collect 消费,不能让 collect 反向知道某个 Plugin 的配置 key 或内部对象。
Command 同时服务交互用户和自动化调用:domain 只提供候选与选择语义,共用 prompt 和输出机制归
terminal。chat-tui 只依赖 Controller 提供的 view state 与 intent;Session 只接收 AgentUE patch,
不直接解释 pi 或 server wire 字段。doctor-server wire schema 由 ServerAgent 收口。
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/host、infra/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 为事实源, 不在设计文档复制。
每个 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,更新本文或代码即可,无需创建横切专题文档。