Files
linuxcncWebWASM/docs/linuxcnc-web-wasm-context-governance.md

248 lines
18 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# LinuxCNC Web/WASM 上下文治理与最小任务目录
**状态**:执行规范 v1.0
**适用基线**:LinuxCNC `2.10.0~pre0`;实际版本由 context lock 冻结
**生成器**:[`scripts/context_packet.py`](../scripts/context_packet.py)
**测试**:[`scripts/test_context_packet.py`](../scripts/test_context_packet.py)
本文件只解决两个问题:任务如何拆到可以持续接续的大小,以及一次任务交接究竟允许携带什么上下文。架构、功能范围、源文件关联和发布门禁分别以[技术路线](linuxcnc-web-wasm-technical-roadmap.md)、[完整仿真机床实施蓝图](linuxcnc-web-wasm-full-port-implementation.md)、[运动学完整移植计划](linuxcnc-web-wasm-kinematics-migration-plan.md)、[源程序关联目录](linuxcnc-web-wasm-source-map.md)、[覆盖矩阵](linuxcnc-web-wasm-simulation-coverage.md)和[执行与交付策略](linuxcnc-web-wasm-execution-strategy.md)为准。本文件不复制这些文档的内容。
## 1. 不变量
1. 一个任务只有一个主工作流、一个里程碑、一个可验证结果和一个回滚点。跨三个以上工作流必须拆分。
2. 一个上下文包只有固定八段:`header`、`baseline`、`scope`、`contracts`、`evidence`、`risks`、`next`、`forbidden`。禁止追加 `history`、聊天记录或完整日志段。`nextTask.md` 只是 8 KiB 以内的启动指针,历史和证据摘要必须移到按需读取的索引。
3. 默认 profile 为 `feature`(4,096 tokens/16 KiB);里程碑任务才使用 `milestone`(8,192 tokens/32 KiB)。`doc` 和 `contract` 只在确有需要时使用。
4. `total_bytes` 同时限制序列化包和选中证据负载:`context_bytes = packet_bytes + selected_evidence_bytes`。`evidence_bytes` 是独立的证据总量上限,不能用文件数量替代。
5. 证据在生成阶段筛选。可选证据被排除时必须记录稳定 `reason_code`;必需证据无法容纳时生成失败,不输出部分成功包。
6. 交接只携带最新包、context lock 摘要、受影响 manifest ID 和可重跑命令。完整日志、golden 和差异报告只通过路径、大小和哈希引用。
7. 模型请求必须为输出预留独立预算。`context` 输入预算、请求外固定开销(system/developer、工具 schema 和必要的当前状态摘要)、`max_output_tokens` 和模型上下文窗口分别记录;不能把完整日志追加到输入后再把输出预算设为最大值。连续执行从最新包重建请求,旧对话只保留路径/哈希,不能累加。请求失败时先缩减输入证据或拆分任务,不自动重试同一超大请求。
8. 流式响应必须经过 [`scripts/model_stream.py`](../scripts/model_stream.py) 的有界 SSE 消费器。只有收到 `response.completed` 且 provider `usage` 通过校验时结果才可复用;断流、残缺 UTF-8、`response.failed`、`context_length_exceeded`、usage 缺失/不一致或 `max_output_tokens` 截断都必须写入 metadata-only checkpoint。checkpoint 只能保存 `context_id`、`packet_id`、事件/字节计数、输出哈希和恢复建议,不得保存半截模型文本;恢复必须生成新的、更小的 packet。
9. `context_packet.py` 的 `token_limit`、`total_bytes`、`evidence_bytes` 和 `max_files` 覆盖值只能小于或等于 profile 默认值;扩大值必须改用新的、经过审查的 profile。没有 provider tokenizer 时,生成器和校验器按 UTF-8 字节作硬上界;调用方拿到精确令牌数后可通过 `--input-tokens` 替换保守估算,但不得放宽 profile 上限。
### 1.1 包的分层读取
任务执行者按以下顺序读取,读到足够完成任务即停止:
| 层 | 内容 | 何时读取 | 预算归属 |
|---|---|---|---:|
| L0 | `context_id`、源码/工具链/schema 摘要、任务账本状态 | 每次开始和恢复 | `baseline` |
| L1 | 本任务目标、非目标、直接契约、受影响 manifest | 每次执行 | `header`/`scope`/`contracts` |
| L2 | 通过/失败测试摘要、差异首点、回滚点、下一步 | 执行中或交接 | `evidence`/`risks`/`next` |
| L3 | 完整日志、源码全文、golden 原件 | 只有需要定位时按路径读取 | 不进入包 |
L3 证据候选必须先给出 `path`、`bytes`、`sha256`、`kind`、`priority`、`required`;生成器按照必需、优先级、路径排序。读取清单不能包含未经过预算选择的路径。
## 2. 最小任务契约
任务描述必须能在一屏内完成审查,并使用以下字段。字段值是摘要或引用,不复制大段背景:
```yaml
id: INV-06a
title: 生成上下文包骨架
owner: WS-0
milestone: M0
profile: feature
objective: 固定八段包和稳定 packet_id
non_goals: [证据内容读取, manifest 扫描]
inputs: [context-lock.json, task-summary.json]
contracts: [context_packet.v1]
outputs: [packet.json]
tests: [test_context_packet.test_skeleton]
rollback: 删除生成物,保留输入锁
next: INV-06b
```
`objective` 必须是可观察结果;`non_goals` 防止任务吸收邻近工作;`inputs/contracts` 只列直接依赖;`outputs/tests` 必须能由 CI 重跑;`next` 最多三项。任务完成还需更新 manifest 状态和证据索引,但不把这些历史复制回包内。
## 3. 最小任务目录
下面的任务是执行单元,不是新的功能范围。原有大任务保留为父任务;实现时使用子任务 ID。每个子任务只拥有一条主要产物和一组直接测试。
### 3.1 M0:基线、清单和参考格式
| ID | 单一结果 | 直接输入 | 依赖 | Profile |
|---|---|---|---|---|
| INV-01a | 文档能力来源索引 | docs、source map | 无 | doc |
| INV-01b | 源码导出符号索引 | `src/emc/**`、`src/hal/**` | INV-01a | feature |
| INV-01c | 配置资源索引 | `configs/sim/**` | INV-01a | feature |
| INV-01d | 测试用例索引 | `tests/**`、`unit_tests/**` | INV-01a | feature |
| INV-02a | 规范化 source ID 和哈希 | INV-01a..d | contract |
| INV-02b | 依赖闭包和孤儿报告 | 规范化来源 | INV-02a | feature |
| INV-03a | context lock 文件 | 版本、工具链、schema | INV-02a | contract |
| INV-03b | context lock 校验器 | context lock | INV-03a | doc |
| INV-04a | native runner 输入接口 | sim 配置、测试索引 | INV-01c,d | contract |
| INV-04b | golden JSONL schema | runner 输入接口 | INV-04a | contract |
| INV-04c | 首个 divergent tick 报告 | native 输出 | INV-04b | feature |
| INV-05a | source→feature→task 图 | manifest、协议 | INV-02b | feature |
| INV-05b | 差异报告字段校验 | golden、manifest | INV-04b、INV-05a | doc |
| INV-06a | 固定八段包骨架 | context lock、任务摘要 | INV-03a | feature |
| INV-06b | 证据预算选择 | 候选证据清单 | INV-06a | feature |
| INV-06c | 排除原因和必需项失败 | 预算选择器 | INV-06b | doc |
### 3.2 M1:WASM 核心和最小运行闭环
| ID | 单一结果 | 直接输入 | 依赖 | Profile |
|---|---|---|---|---|
| CORE-01a | 独立构建目录和入口 | 编译锁 | INV-03a | contract |
| CORE-01b | 最小 posemath 编译 | posemath 源文件 | CORE-01a | feature |
| CORE-01c | TP/解释器最小链接 | TP、rs274 依赖 | CORE-01b | feature |
| CORE-02a | `sim_create/destroy` ABI | ABI 草案 | CORE-01a | contract |
| CORE-02b | `sim_load` 工作区入口 | INI/G-code 路径 | CORE-02a、FS-01a | feature |
| CORE-02c | `sim_step` 固定 tick | 状态结构 | CORE-02a | feature |
| CORE-02d | snapshot 导出/导入 | snapshot schema | CORE-02c | contract |
| CORE-02e | 错误码和行号映射 | rs274 错误 | CORE-01c | doc |
| RT-01a | 单会话 tick 队列 | `sim_step` | CORE-02c | feature |
| RT-01b | pause/abort/单步状态机 | tick 队列 | RT-01a | feature |
| FS-01a | 虚拟 POSIX 路径规则 | workspace 约束 | INV-02b | contract |
| FS-01b | open/read/write/stat | POSIX 规则 | FS-01a | feature |
| COM-01a | message envelope/schema | ABI 和错误码 | CORE-02a | contract |
| COM-01b | 命令 ack/result 路由 | envelope | COM-01a、RT-01a | feature |
| FE-01a | AppShell 和只读状态页 | protocol mock | COM-01a | doc |
| FE-01b | WorkerClient 超时/取消 | ack/result | COM-01b | feature |
### 3.3 M2-M3:核心行为、设备和恢复
| ID | 单一结果 | 直接输入 | 依赖 | Profile |
|---|---|---|---|---|
| CORE-03a | 基础 G/M 解释 golden | rs274 源和样例 | CORE-01c、INV-04b | feature |
| CORE-03b | O-word/参数/循环 | 解释器状态 | CORE-03a | feature |
| CORE-03c | remap 调用边界 | remap API | CORE-03b、PY-01a | contract |
| CORE-04a | 直线/圆弧 canonical | TP 源 | CORE-01c | feature |
| CORE-04b | 速度/加速度/拐角 | TP 配置 | CORE-04a | feature |
| CORE-05a | NML 命令/状态最小映射 | NML 消息清单 | CORE-02a、COM-01a | contract |
| CORE-05b | Task 状态快照 | NML 映射 | CORE-05a、CORE-02d | feature |
| CORE-06a | homing/软限位 | motion 状态 | CORE-02c | feature |
| CORE-06b | following error/急停 | motion 状态 | CORE-06a | feature |
| CORE-07a | trivkins 姿态 | kinematics ABI | CORE-02d | feature |
| CORE-07b | 非 trivkins 能力注册 | kinematics 清单 | CORE-07a | feature |
| CORE-08a | 工具表解析和快照 | tooldata 源和样例 | CORE-02b、FS-01b | feature |
| CORE-08b | 主轴/换刀/IO 状态 | iotask 消息 | CORE-05a、CORE-08a | feature |
| RT-02a | HAL pin/signal 图 | HAL 语法 | CORE-02c | feature |
| RT-02b | thread/function/addf 顺序 | HAL 图 | RT-02a | feature |
| RT-03a | 主轴/编码器/探针模型 | 虚拟设备 schema | RT-02b | feature |
| RT-03b | 限位/换刀故障注入 | 设备模型 | RT-03a | feature |
| RT-04a | ClassicLadder 解析 | ladder 输入 | RT-02a | feature |
| RT-04b | scan/寄存器/IO 顺序 | ladder 模型 | RT-04a、RT-02b | feature |
| FS-02a | journal prepare/commit | POSIX 工作区 | FS-01b | contract |
| FS-02b | 损坏记录和配额错误 | journal | FS-02a | feature |
| FS-03a | checkpoint 基线 | snapshot ABI | CORE-02d、FS-02a | feature |
| FS-03b | 增量重放和迁移 | checkpoint/journal | FS-03a | feature |
| PY-01a | Pyodide `linuxcnc/hal` 模块 | Python API 清单 | CORE-03a、FS-01b | feature |
| PY-01b | 资源/权限错误 | 虚拟模块 | PY-01a | doc |
| PY-02a | remap/filter 生命周期 | Python 回调契约 | CORE-03c、PY-01a | feature |
| PY-02b | VCP pin 回调和隔离 | VCP descriptor | PY-02a、RT-02a | feature |
| COM-02a | TaskLedger prepare/commit | operation schema | COM-01b、FS-02a | contract |
| COM-02b | 确认丢失对账 | TaskLedger | COM-02a | feature |
| COM-03a | 完整快照发布 | snapshot schema | CORE-02d、COM-01b | contract |
| COM-03b | 轨迹/HAL 流背压 | stream schema | COM-03a、RT-02b | feature |
| COM-04a | NML→Worker 命令映射 | NML 映射 | CORE-05a、COM-01a | contract |
| COM-04b | 状态/错误顺序 golden | message bus | COM-04a、INV-04b | feature |
| COM-05a | 能力/限制注册表 | 全量 manifest | INV-02b、CORE-07b | contract |
| COM-05b | 未支持能力解释 | 能力注册表 | COM-05a | doc |
#### 3.3.1 K0-K8:运动学主线
运动学任务按实现族和验收闭环拆分,完整契约、来源文件和测试矩阵见[运动学完整移植计划](linuxcnc-web-wasm-kinematics-migration-plan.md)。下列 ID 是最小任务目录的入口,不得把 CORE-07 作为一个不可拆分的大任务:
| ID | 单一结果 | 依赖 | Profile |
|---|---|---|---|
| K0-INV-01 | 运动学源文件、符号、缺失测试输入审计 | INV-01..02 | milestone |
| K0-INV-02 | `configs/sim` 运动学入口图和参数样本 | K0-INV-01 | feature |
| K0-ORACLE-01 | native FK/IK JSONL golden schema 和样本 | K0-INV-01 | contract |
| K1-CONTRACT-01 | pose/joint、flags、home、错误码 C ABI | K0-ORACLE-01、CORE-02 | contract |
| K1-CONTRACT-02 | 坐标映射、extra joints、数值/迭代政策 | K1-CONTRACT-01 | feature |
| K2-TRIV-01 | trivkins 四种类型、重复轴和 home | K1-CONTRACT-02 | feature |
| K2-COUPLED-01 | corexy/rose/max/rotate 及 HAL 等价链 | K2-TRIV-01、RT-02a | feature |
| K3-5AXIS-01 | 5axiskins、xyzac/xyzbc TRT | K2-COUPLED-01 | feature |
| K3-ROBOT-01 | GenSer、SCARA、PUMA、Scorbot | K1-CONTRACT-02 | feature |
| K4-PARALLEL-01 | Delta、RotaryDelta、Tripod | K1-CONTRACT-02 | feature |
| K4-PARALLEL-02 | Hexapod、Pentapod 迭代正解和分支 | K4-PARALLEL-01 | feature |
| K5-SWITCH-01 | switchkins 静态切换和 lastpose | K3、K4 | contract |
| K5-USER-01 | userk/ugenser 构建期静态能力 | K5-SWITCH-01 | feature |
| K6-MOTION-01 | TP→IK→motion→FK feedback | K2..K5、CORE-04/06 | milestone |
| K7-REG-01 | 全配置、UI 姿态和浏览器故障回归 | K6、FE/COM | milestone |
| K8-REL-01 | 运动学兼容、来源和发布闭合 | K7、REL-01 | milestone |
### 3.4 M4-M5:前端、回归和发布
| ID | 单一结果 | 直接输入 | 依赖 | Profile |
|---|---|---|---|---|
| FE-03a | 工程选择/租约 | workspace API | FS-03b、COM-02a | feature |
| FE-03b | 刷新/Worker 重启恢复向导 | recovery events | FE-03a、COM-02b | feature |
| FE-04a | 编辑器诊断和当前行 | interpreter events | CORE-03a、COM-01b | feature |
| FE-04b | 轨迹预览与 golden 差异 | trajectory stream | FE-04a、COM-03b | feature |
| FE-05a | MDI/run/pause/abort | command schema | RT-01b、FE-01b | feature |
| FE-05b | jog/home/override 释放保护 | motion commands | FE-05a、CORE-06a | feature |
| FE-06a | 工具/IO/报警面板 | device events | RT-03b | feature |
| FE-06b | 主轴/换刀/探针恢复 | IO panel | FE-06a、CORE-08b | feature |
| FE-07a | HAL pin 图和命令控制台 | HAL snapshot | RT-02a、COM-03a | feature |
| FE-07b | scope/Ladder/日志回放 | sampled streams | FE-07a、RT-04b | feature |
| FE-08a | 轨迹和姿态非空渲染 | snapshot/trajectory | CORE-04a、CORE-07a | feature |
| FE-08b | 毛坯、坐标和最终姿态 | render state | FE-08a、COM-03b | feature |
| FE-09a | VCP descriptor 权限 | Python/VCP schema | PY-01a、COM-01a | contract |
| FE-09b | VCP 生命周期和异常隔离 | VCP runtime | FE-09a、PY-02b | feature |
| FE-10a | 虚拟列表和消息统计 | UI streams | FE-04b、FE-07b | feature |
| FE-10b | 帧预算和录制回放 | performance events | FE-10a、FE-08b | doc |
| COM-06a | 通讯/离线/租约 E2E | protocol + workspace | COM-02b、FE-03b | feature |
| COM-06b | 背压/未知消息/重启矩阵 | protocol streams | COM-03b、COM-06a | feature |
| REG-01a | 单入口 configs/sim 回归 | manifest、native runner | INV-02b、INV-04a | milestone |
| REG-01b | 全入口差异汇总 | 单入口报告 | REG-01a | feature |
| REG-02a | 失败样本保留和分类 | tests/unit_tests | INV-04a | feature |
| REG-03a | 断网/崩溃/配额矩阵 | FS-02b、FS-03b | feature |
| REG-03b | 回放终点一致性 | 连续/恢复 golden | REG-03a | feature |
| REG-04a | 浏览器通讯和离线 | Playwright | FE-03b、COM-02b | feature |
| REG-04b | 性能 P95/P99 报告 | 浏览器矩阵 | REG-04a | doc |
| REL-01a | 许可证和兼容报告 | 全量 manifest | REG-01b、REG-02a | doc |
| REL-01b | 迁移/回滚/离线包 | 发布候选产物 | REL-01a、REG-03b | milestone |
父任务只有在所有直接子任务完成且证据链闭合后才能更新状态。子任务之间不得共享未版本化的临时结构;需要共享时先建立 contract 子任务。
## 4. 交接和恢复
### 4.1 正常交接
1. 从 context lock 和父任务摘要生成新的 `packet_id`;只填本子任务的八段。
2. 用候选证据的实际字节数调用生成器。生成前就排除 `E1`-`E6`,输出后只接受 `budget.packet_bytes <= byte_limit`、`packet_bytes + selected_evidence_bytes <= byte_limit` 且估算输入令牌不超过 profile 上限。
3. 完成一步就更新 `evidence`、`risks`、`next`;不追加旧包全文。
4. 提交正文只写 `Context-ID`、`Context-Packet`、子任务 ID、测试命令和证据路径。
### 4.2 工具失败或确认丢失
以 `operation_id` 查询任务账本:`verified` 步骤只引用原证据,`unfinished` 从最近 checkpoint 继续,`unknown` 先对账。无法对账时标记 `blocked`,保留包和产物,不重放可能产生副作用的操作。
### 4.3 拆分停止线
出现任一条件立即拆分,而不是扩大 profile:上下文包超过 profile 80%、候选证据超过证据预算 80%、任务同时修改两个独立契约、测试需要读取三个以上大日志、或 `next` 不能写成三项以内的动作。拆分后的父任务只保留依赖图和摘要。
## 5. CI 检查
CI 在生成阶段执行以下检查,校验器只做复核:
```text
packet JSON 可解析
固定八段存在且无额外段
packet_id/context_id 与任务账本一致
budget.packet_bytes == UTF-8 序列化字节数
budget.packet_bytes <= byte_limit
budget.packet_bytes + budget.selected_evidence_bytes <= byte_limit
selected_evidence_bytes <= evidence_byte_limit
selected_evidence_files <= evidence_file_limit
所有排除项都有 E1-E6 reason_code
required 证据无法容纳时命令失败且不写输出
```
最小回归命令:
```bash
python3 -m unittest discover -s scripts -p 'test_*.py' -v
python3 scripts/validate_task_pointer.py
python3 scripts/validate_model_budget.py <packet.json> --context-window <model-window> --overhead-tokens <current-request-overhead>
```
流式请求还必须通过 `scripts/test_model_stream.py`:覆盖跨 chunk UTF-8、无终态断流、provider failure/context overflow、usage 校验、输出截断和 checkpoint 不包含部分文本。网络传输异常只能记录为 `stream_disconnected`,不能重试原 packet。
本规范的目标不是把所有信息压进一个更大的包,而是让每个任务只携带完成当前结果所需的最小、可重建、可审计上下文。