Skip to content

Latest commit

 

History

History
299 lines (233 loc) · 19.3 KB

File metadata and controls

299 lines (233 loc) · 19.3 KB

CLI Kernel

理念 / 概念

Doctor CLI 的 Kernel 定义跨 Command 稳定的生命周期、数据流、扩展边界和信任边界。Provision、Collect、 Eval、Perf 与 Chat 共用启动上下文和基础设施,但各自拥有不同的领域结果:

主路径 主要结果 与 Collect 的关系
Provision 外部能力或环境准备完成 不隐藏在 Collect 中;由用户显式触发
Collect 可复查的 Evidence、Finding、Coverage 与诊断产物 确定性诊断主路径
Eval Case 执行记录及关联证据 复用已有 Collect 入口采集证据
Perf 受控负载结果及同窗口证据 复用已有 Collect 入口采集证据
Chat Agent 会话与 AgentUE 输出 面向无法预先固化路径的开放式问题

Collect Command 的最小模型是:Core 统一驱动 Prepare、Execute、Finalize;Execute 固定沿 Inspect → Probe → Detector 推进;Core 与 Plugin Service 在同一流程中贡献能力,不形成两套执行框架。

Collect Command Kernel

三阶段生命周期

Prepare
  → 解析 Config / Profile / Target / Service
  → 选择 Core 与 Plugin Service contributions
  → 形成 access plan 与 CommandContext
  ↓
Execute(Core 驱动)
  → Inspect [Core Inspect + Plugin Service Inspect]
  → 汇总并冻结 Facts
  → Probe(Facts) [Core Probe + Plugin Service Probe]
  → 汇总 Observations,构建 Evidence
  → Detector(Evidence) [Core Detector + Plugin Service Detector]
  → Findings / Coverage / Diagnosis
  → Render(领域输出投影,触发位置沿用现状)
  ↓
Finalize
  → Artifact / Bundle
  → Delivery / Cleanup / exit status

Inspect 与 Probe 之间存在阶段屏障:选中的 Inspect 全部收敛并冻结 Facts 后,Core 才生成 Probe 计划。 Detector 只能在 Observations 汇总成 Evidence 后运行。Plugin Service 只注册 contribution;阶段推进、 调度、失败隔离和收尾始终由 Core 控制。

Core 与 Plugin Service 分工

阶段 Core Plugin Service
Prepare 解析并校验用户意图;选择 Target、Service 与 contribution;合并 Core/Plugin access needs;创建本轮上下文和清理责任 声明 Service、Workload、capability、dependency、access 与 contribution;校验 Plugin-owned config;不自行创建命令生命周期
Inspect 形成 Query;决定 Inspect 的依赖、顺序、预算、遍历、去重和失败隔离;驱动 Core/Plugin Inspect;规范化并冻结 Facts 执行一次业务 Inspect,返回 Fact/Relation;拥有私有协议和业务数据语义,不拥有遍历或后续调度
Probe 根据冻结 Facts 生成计划;向 Probe 注入公共 Fact;控制依赖、策略、授权、风险和资源生命周期;驱动 Core/Plugin Probe 执行一次业务 Probe,消费 Input/Facts 并返回 Observation;不内建循环、并发或跨 Probe 调度
Detector 构建 Evidence;统一执行 Core/Plugin Detector;校验证据引用与 provenance;形成 Coverage 和 Diagnosis 提供纯业务 Detector,消费只读 Evidence,返回带显式证据引用的 Finding;不接收运行上下文或发起 I/O
Finalize 驱动领域 Renderer,组装 Artifact/Bundle,完成 Delivery、Cleanup 与最终退出语义 不拥有阶段或资源生命周期;业务语义已通过 Fact、Observation 与 Finding 进入 Diagnosis

Plugin 不必在每个阶段都有可执行逻辑。Prepare 中它主要提供声明,Execute 中贡献业务采集和判断, Finalize 则由 Core 收口。Renderer 的领域逻辑与当前触发位置仍归 collect/<domain>/render;Finalize 只消费已准备的产物。

Execute 数据模型

Inspect 与 Fact

Inspect 回答“本轮诊断中已经知道什么”。Core Command 根据诊断目标形成由 Identity + Constraints 组成的 Query,并选择 Core Inspect 或接受该 Identity 的 Service Inspect contribution:

Query(Identity + Constraints)
  → Inspect
  → InspectQueryResult
  → ValueFact / RecordFact / RelationFact
  • ValueFact 表达一个 kind 至多一个的领域值。
  • RecordFact 表达同 kind 可重复、带稳定 recordKey 的独立记录。
  • RelationFact 表达两个 Identity 之间已经由现场数据证明的关系。

Fact 在一次 Command 内足够稳定,可被后续 Probe 和 Detector 复用,但不是跨时间永远成立的真理。 InspectQueryResult 独立表达解析状态、缺失证据与截断,不能把采集状态伪装成领域 Fact。 Core 与适配后的 Plugin Fact 都携带 kind + schemaVersion + producerrunInspects 在阶段边界校验 每个叶子 Fact 的 schema identity,并要求 Core Fact 的 producer.id 等于实际执行的 Inspect.id;违反 契约属于实现错误,不能降级成 Coverage 缺口。Fact 不另设对象 ID,Detector 通过本轮 Evidence 中的 factPath 引用它。

RelationFact 可以形成后续 Query,但只有 Core Command 能决定是否继续,以及查询深度、容量、去重、 失败隔离和停止条件。Plugin 拥有 Identity、Fact、Relation 的业务语义与固定查询,不拥有自递归调度。

Probe 与 Observation

Probe 回答“针对已确认目标,本次主动观察到了什么”。Core 根据冻结 Facts 选择并驱动 Core Probe 与 Service Probe。领域先显式选择可公开的 Fact、Service scope、factPath 与 value shape,再由共享 Service Evidence adapter 保留原始 kind + schemaVersion + producer 并形成公共投影;adapter 不递归遍历 Evidence,也不把 Fact payload 的子对象派生成新的伪 Fact。当前选出的公共 Fact 不再按 Service、producer 或 kind 过滤;所有 Probe 共享同一份深冻结快照,只能消费,不能修改或追加 Fact。

Probe 是一次执行原语:可以使用 Core 提供的 Target-scoped infra 和授权入口,但不拥有 Command 的循环、 并发、预算、停止条件或 Evidence。Observation 只陈述某个探测时间点或时间窗口看到的状态,不能默认 代表之后的现场。Probe 之间的真实数据依赖显式声明;会产生负担或改变现场的动作必须经过 Operation 授权。

Plugin Workload Probe 的 Observation 契约由 Plugin 以 produces: ObservationDefinition 拥有;其 TypeBox object schema 同时驱动 TypeScript payload 推导和 Core 的 Draft 2020-12 运行时验证。Core 不信任 跨动态 ESM 边界的静态类型;未通过严格 JSON/schema 校验的 payload 不进入 Evidence,校验不会强转、 补默认值或删字段。

Evidence、Detector 与 Diagnosis

Evidence 是本次诊断明确选择的 Facts 与 Observations。Detector 回答“已有证据说明什么”:

  • Core Detector 提供跨业务通用判断。
  • Service Detector 提供业务判断,可以关联跨 producer、跨 Service 的 Evidence。
  • Detector 不接收 CommandContextPluginContext 或 infra handle,不执行 I/O。
  • Finding 必须显式引用 Evidence 中的 factPathobservationId
  • Core 通过同一个 Detector runner 执行 Core Detector 与适配后的 Service Detector,并校验 Finding 身份、 producer、Evidence 引用和本轮唯一 ID;违反契约属于实现错误,不能降级成 Coverage 缺口。
  • Coverage 表达诊断目标的证据充分度,不表达 Target 是否健康。

Fact、Observation 与 Finding 使用 kind + schemaVersion 标识 payload schema。Core kind 使用保留短名; Plugin 本地 kind 由 Core 规范化为 plugin/<plugin-id>/<service>/<local-kind>。两者都携带结构化 producer, 消费方不能通过解析 kind 字符串猜测来源。Plugin version 标识实现版本,schemaVersion 只标识数据契约。 cli/src/plugin/evidence.ts 是 Core/Plugin Service Evidence 的统一适配边界:Core Fact/Observation 原样继承 已持久化 identity,Plugin 本地 schema 在这里统一补 namespace 与 producer;领域 projector 只拥有披露和 Service 关联决策,不能再次手写或改写 identity。

共享生命周期边界

CommandSpec 与执行入口

每个常规命令提供 CommandSpec<Input, Output>,普通命令和组合命令共用 run(context, input): Promise<CommandResult<Output>>。CLI 将 flags 转为领域 Input;父命令直接调用 子命令的同一入口。defineCommand 包装校验、环境准备、取消与资源收尾,因此嵌套调用仍需满足自身 的 capability 和 access 前提。

根入口只解析一次 Profile,选定的 Plugin 及其配置校验在整轮内复用。每次调用按顺序执行:

validate domain input
  → required Plugin capability + validated Plugin config
  → declared Host / Kubernetes environment
  → selected Target + staged access plan + permission check
  → domain work or child CommandSpec.run calls
  → invocation result + resource cleanup

组合命令逐个调用已选择的子命令;一个子命令不可用时,其它独立子命令仍可执行。子命令的必要条件 不能简单合并成父命令的全局门槛,否则缺少一种证据能力就会阻断整个概览或采集。

Input 可以提供 idempotencyKey(): string,显式声明本次逻辑执行的身份。defineCommand 在输入校验后, 按 Command 定义身份和 key 在当前 CommandContext 中合并调用:正在执行时等待同一个 Promise,包括资源 清理;已完成时返回原状态、Output、Artifacts 和 reportName,不产生 skipped 状态。未提供方法时每次独立 执行。完成结果包括 partial 和 failed,本轮不隐式重试;取消始终优先于复用。key 必须包含会改变结果的 领域参数,Profile、Plugin 和宿主配置由当前 Context 隔离,记录不跨 Doctor 运行保留。

Inspect 和 Tenant 的 Input 构造函数按检查范围、租户及采集参数生成 key,Collect 使用这些 Input 调用 子命令。调用方仍显式纳入子产物,Artifacts 按路径去重,因此多个 Collect 可引用同一份环境/租户证据, 最终报告只交付一份。Overview 无需识别第一次或后续 Collect。

Context 与调用归属

CommandContext 属于整轮执行树,保存 Profile、当前 Plugin、按需准备并复用的环境信息、权限检查、 Decision、Discovery、ExecutionRecord 与取消信号。领域 Context 保存单次执行准备的 Target、client、 Bundle 和领域状态;PluginContext 只暴露本次 Service 调用所需的受限依赖与 infra。

同一 CommandContext 可以被并发子命令共享。Artifacts 使用异步调用作用域,每次调用返回自己的产物 引用和报告名称,父命令显式选择并纳入子产物;不能按全局列表位置或命令名猜测产物属于哪次调用。 领域输入与输出通过 Input / Output 传递,不放入共享 Context。

Host 创建的 PluginContext 继承当前调用的取消信号,并登记到本次调用的资源作用域。显式 dispose 和执行层兜底清理共用一次回收;子调用只关闭自己的资源,不关闭父调用的资源。用户取消会传播到整轮 执行树,停止后续工作,并保留已生成证据。

结果与 Finalize

CommandStatus 统一定义 ok / partial / failed / cancelled 四种最终执行状态。它描述命令完成度; 业务错误、Finding severity 和 Evidence Coverage 各自保留领域含义。父命令依据自己的目标汇总子结果: 部分采集失败但仍形成有效结果时为 partial;用户只看 Overview 并拒绝可选采集属于正常完成。

根 CLI 将结果映射为退出码:ok 和 partial 为 0,failed 为非零,cancelled 为 130。子命令不设置 进程退出码,也不调用根入口的最终交付。

Finalize 只执行一次,消费根结果纳入的 Artifacts,统一处理路径、格式、Bundle、Delivery 和临时产物 清理。报告名称由相应调用拥有,最外层决定最终交付名称。交付失败时保留源产物以便恢复。

默认格式、partial 报告、Evidence Bundle、失败兜底和退出码语义由 collect-protocol.md 统一定义。init/profile 等启动命令不要求已有 Profile。

Core / Plugin 边界

Core 与 Plugin 使用同一套 Inspect、Probe、Detector 词汇。Service 是业务 contribution、Workload 和运行时 依赖的归属单元;Plugin 是多个 Service 与 Skill 的版本化分发单元。具体 Plugin 只依赖公共 Plugin SDK, CLI Core 不依赖任何具体 Plugin 实现。

这里统一的是概念、执行阶段和 Evidence 语义,不要求 Core 与 Plugin 直接复用同一个代码 interface。 Core 实现可以直接消费进程内领域上下文;Plugin contribution 还必须携带 Service、版本、access 与分发 边界所需的信息。CLI composition root 负责把选中的 Plugin contribution 适配进同一 Execute 流程,不能 为了统一函数签名丢掉边界信息,也不让 packages/plugin 反向依赖 CLI Core。

双方边界分为两层:

边界 方向 所有权
Inspect / Probe / Detector contribution Plugin Service → Core Plugin 提供业务逻辑;Core 选择、驱动并验证结果
access Plugin capability → Core Plugin 声明最小需求;Core 合并、检查并授权
dependencies Service → Core Service 声明所需其它 Service capability;Core 解析并注入受限 handle
data Core ↔ Plugin capability 公共包定义类型化输入输出;私有 schema 留在 Plugin 内
infra Core → PluginContext Core 提供当前 Target 的受限访问、取消和资源生命周期
config Profile/Core → PluginContext Core 不透明保存和透传;schema、校验和解释归 Plugin

这些边界不能互相替代:取得 infra handle 不代表获得任意权限;config 不承载 kubeconfig 等 Core-owned 连接状态;业务返回值不能泄露整包私有配置;Plugin contribution 不能推进或绕过 Core 生命周期。

Kubernetes 只是 Doctor Host 到 Target 的一种访问通道。Core 解析 kubeconfig/context,托管查询、超时、 输出上限、取消和 port-forward 回收;Plugin 通过 Workload discovery 描述业务部署拓扑,通过 capability 持有专有 API 与业务语义。Plugin 不持有 kubeconfig,也不自行启动 kubectl。

Collect 完成语义与安全

Collect 的命令终止、证据覆盖度、Target 健康和产物交付是不同维度:

  • Finding severity 描述 Target 健康,不决定命令是否成功。
  • Coverage 描述证据是否充分;partial 可以是正常完成状态。
  • 单项 Probe 现场失败只降低对应 Coverage;Doctor 自身不变量错误不能伪装成 partial。
  • Delivery 失败会改变最终命令结果,但不能抹掉已经取得的 Evidence。

Collect 以可审计 Evidence 为结果,即使某个 Probe 需要受控副作用,也不能隐藏式发布 image、创建 debug environment 或安装工具。Operation 明确描述风险、目标、影响和步骤;授权只覆盖当前动作,不是 blanket approval。完整的调度、Coverage、Worksheet、授权、报告和退出码契约见 collect-protocol.md

与其它主路径的边界

主路径 与 Collect 的稳定边界
Provision 以外部状态变化或能力准备为结果,不使用 Collect engine;只共享 CommandContext、终端和 infra
Eval 顺序触发 canonical Case,并调用已有 Trace/Log/Data Collect 入口取得关联证据;不复制采集器,也不评价回答质量
Perf 负责并发、预算、熔断与性能窗口,并调用已有 Metric/Trace/Log Collect 入口;Plugin Case runner 每次只执行一个请求
Chat 使用共享 Agent runtime 处理开放式问题;不依赖 Collect 的确定性流程

Model discovery、Case、Trace、Store 等能力可以被多个主路径复用,但复用的是稳定 capability 或 Command 入口,不是复制内部编排。具体边界分别见 plugin.mdcommands/eval.mdcommands/perf.md../docs/chat.md

依赖方向与代码地图

cli/src/
├── app/                 Prepare / Execute / Finalize composition root
├── command/             CommandContext、Target、access 与审批契约
├── collect/
│   ├── protocol.ts      Fact、Observation、Finding、Coverage 共享协议
│   ├── evidence-identity.ts  Fact/Observation/Finding schema identity 运行时校验
│   ├── engine.ts        runCollect:Inspect → Probe → Evidence → Detector / Coverage
│   ├── inspect-engine.ts  Inspect 依赖调度与 Facts 冻结
│   ├── probe-engine.ts  Probe 依赖、安全顺序与失败隔离
│   ├── detector-engine.ts  Core/Plugin Detector 执行与 Finding 契约校验
│   ├── evidence.ts      Worksheet 与 Evidence Bundle
│   ├── operation.ts     副作用授权与审计
│   ├── output/          通用格式与交付原语
│   └── <domain>/        领域 Config、Inspect、Probe、Detector、Renderer
├── provision/           image、debug environment 与工具准备
├── eval/                Case 顺序执行与关联证据编排
├── perf/                受控负载与跨数据面证据编排
├── chat/                Session / Controller 与 AgentUE adapter
├── plugin/              Plugin 宿主选择、加载与公共协议适配
├── model/               Model Collect 与 Chat 共用的模型访问
├── terminal/            选择、确认与输出边界
└── infra/               Host、Target、Kubernetes 与外部资源 adapter

packages/plugin/         Plugin、Service、capability 与 Inspect/Probe/Detector contribution 公共协议
packages/agent/          CLI/server 共用的 Agent runtime
plugins/<plugin>/        具体 Service 实现、固定查询与 Skills
toolkit/                 独立版本的诊断工具和平台资源

依赖方向保持:

cli/collect → packages/plugin ← plugins/<plugin>
app → command / collect / provision / eval / perf / chat / infra
collect/<domain> → collect shared protocol + infra ports

公共协议和调度只有出现跨领域稳定、同语义的重复时才上提;领域数据语义、固定查询、Renderer 和具体 Failure/Coverage 解释继续留在 collect/<domain>packages/plugin 不依赖 CLI,具体 Plugin 不反向依赖 CLI 实现。

深入阅读

新增 Collect Command 时,先定义 Facts、Observations、Evidence、Findings/Coverage 和纯 Detector,再实现 Inspect、Probe 与 Renderer;契约测试至少覆盖依赖调度、能力降级、授权拒绝、敏感信息边界和交付结果。