564 lines
70 KiB
Markdown
564 lines
70 KiB
Markdown
# 自主 CAD 生成协议:可靠性与 Token 效率目标
|
||
|
||
## 1. 目标与结论
|
||
|
||
本目标直接替换当前自主 CAD 协议,不保留旧任务兼容、迁移或恢复路径。目标是在不降低建模判断能力的前提下,消除当前“先生成大型 Markdown 建模计划,再按计划生成 CDSL”的硬门,并把每一轮 LLM 的输出缩小为可验证的单个建模动作。
|
||
|
||
必须达成:
|
||
|
||
- **LLM 决定下一步建模意图和操作。** 服务端不生成 CAD 步骤、不替 LLM 选 operation、不把需求编译成几何模板。
|
||
- **服务端只负责事实、约束和状态转换。** 它提供不可变需求、当前模型、拓扑、Runtime 合同、已接受动作及复核证据;校验 LLM 的选择,执行 CDSL,持久化真实结果。
|
||
- 不再要求新任务生成或复核 `modeling-plan.md`,不再出现计划版本、计划解析、计划动作 ID、计划 revision limit 或计划跳步门。
|
||
- 保留 `source-requirements.md`、`requirements.md`、`completion.md`、单 feature CDSL、候选构建、独立候选复核、检查点和最终独立复核。
|
||
- LLM 产生的每一项会改变状态、影响执行或作为验收依据的数据,必须通过固定 Pydantic schema 或 Runtime 动态 JSON Schema 校验。Markdown 和解释文本只由服务端从已验证数据渲染,绝不被解析为状态机输入。
|
||
- 可靠性的含义不是假定任何 LLM 永不产生错误格式,而是错误格式、过期引用和不符合 operation 合同的输出在**任何副作用之前**被确定性拒绝;它们不能创建候选、污染状态、消耗构建预算或触发无限重试。
|
||
- 文档和动作的格式问题必须是**无副作用的可诊断拒绝**;内部服务错误必须一次失败并保留检查点,不能被伪装成 LLM/CDSL 错误后循环重试。
|
||
- **v3 必须完成架构解耦。** “LLM 决策、Runtime contract、任务状态机、候选构建、持久化、渲染/复核”必须是职责明确、依赖方向受控的独立模块;不能继续集中在一个巨型 runner/service 中,或通过模块全局对象互相访问。
|
||
- 使用真实 API usage(可用时)和服务端上下文字节数度量 token 消耗,验收时以基线任务集比较,不以主观感觉判断。
|
||
|
||
这不是“取消计划后让服务端推断下一步”。计划能力仍存在,但由 LLM 在每个检查点结合当前事实重新判断;服务端保存的是实际发生过的动作账本,而不是预先要求 LLM 写完整未来路径。
|
||
|
||
## 2. 当前基线与已确认问题
|
||
|
||
当前路径由 `backend/app/services/autonomous_cdsl_generation.py` 实现:
|
||
|
||
1. 服务端创建不可变 `source-requirements.md`。
|
||
2. 作者 LLM 写入并立即冻结 `requirements.md`。
|
||
3. 作者 LLM 写入并立即冻结 `completion.md`。
|
||
4. 作者 LLM 必须写大型 `modeling-plan.md`,独立模型审查它,失败后重写版本。
|
||
5. 作者 LLM 按计划动作读 Runtime contract,提交一条 CDSL feature。
|
||
6. 服务端构建候选,独立模型审查,接受后提交 checkpoint。
|
||
7. 完成清单覆盖后执行最终重建和视觉复核。
|
||
|
||
`cad_30933fe2fc6b` 已在 `rev_003` 生成正确的法兰:圆盘、中心贯穿孔、四个均布孔均已构建并接受。该任务随后失败的根因包括:
|
||
|
||
- `_final_review` 使用了未赋值的 `global_violations`,导致每次 `complete_task` 都触发 `NameError`。这是确定性的后端缺陷,不是 CDSL 或 LLM 错误。
|
||
- 调度器把上述内部异常归类为 authoring/fragment 错误,并允许重复 `complete_task`;因此无检查点进展的重试最终命中 `NO_PROGRESS_LIMIT`。
|
||
- 建模计划审查要求精确 operation、selector、盲孔深度和 action 粒度,但计划又允许自然语言。这种“自然语言写入,严格执行含义”的双重合同使法兰计划在 `hole_blind | hole_wizard`、多孔单 action 和 through-equivalent 深度等问题上反复返工。
|
||
- `CDSL_MODELING_PLAN_MAX_REVISIONS=2` 的检查在计划已写入及审查后执行,并且后续循环仍可能继续,形成“已到上限却继续调用”的矛盾控制流。
|
||
|
||
已直接修复第一项:最终重建得到 `health` 后,现在会先调用 `_global_geometry_violations(...)`,再使用该变量。这一改动必须保留,并以最终复核回归测试覆盖。
|
||
|
||
### 2.1 真实 LLM 连通性测试
|
||
|
||
2026-08-31 在隔离临时任务根目录中,直接使用当前后端的 `AgentService._complete_once` 和完整 runner 调用配置的真实作者模型,依次发送了三个请求:矩形底板、简单法兰、带肋和四个安装孔的底板。第一个请求尚未产生工具调用或 CAD 工件时,OpenAI 作者请求已连续三次连接失败;runner 随后切换到 DeepSeek,同样连续三次失败。
|
||
|
||
测试发现 `_is_author_transport_error` 分支在所有作者 provider 失败后仍以约 4.5 秒间隔无限重试,使任务永久处于 `running`。测试已手动终止,以避免无意义 API/CPU 消耗;没有生成模型,因此不能把这次测试伪称为模型生成质量结果。该证据证明当前 transport 恢复策略存在流程缺陷,必须在 P0 修复:记录有限的 provider/总调用预算和指数退避,超限后将任务转为 `WAITING_RETRY`,保留 checkpoint 和调用诊断;只能由显式恢复操作或受控调度重新启动,而不能在同一个 run 中无限循环。
|
||
|
||
## 3. 不采用的方案
|
||
|
||
以下方案不满足本目标:
|
||
|
||
- **不保留现有 Markdown 计划,只改提示词。** 它仍把未来的操作、selector 和精确 Runtime 语义要求压到一次大输出中,根因未消失。
|
||
- **改成 LLM 一次输出大型 JSON/DAG 执行计划。** JSON 更容易解析,但不能消除大输出遗漏、过期 selector、前后依赖和重试 token 消耗;问题从 Markdown 转移到 JSON。
|
||
- **服务端依据未覆盖需求决定下一步。** 这会把建模策略藏在程序规则中,违反“LLM 决定下一步”的边界,也会让复杂零件的 CAD 判断不可审计。
|
||
- **取消独立候选/最终复核。** 能减少 token,但会显著降低最终几何可信度;优化应先删除重复的计划复核与冗余上下文,而不是删除实际结果复核。
|
||
- **用盲孔深度大于厚度作为所有通孔的唯一证明。** 这只是候选输入条件;最终仍须从拓扑/几何证明孔连接了预期两侧面、孔数和直径满足要求。
|
||
|
||
## 4. 新协议中的工件、结构化输出与验证
|
||
|
||
### 4.1 统一的结构化输出边界
|
||
|
||
不得让 LangChain、任何 provider 或 Pydantic 自身成为可信边界。它们只负责请求和解析;服务端必须对原始 tool arguments 再做一次 canonical validation,验证通过后才允许写库、构建候选或改变 revision。
|
||
|
||
```text
|
||
LLM provider
|
||
-> LangChain structured-output adapter
|
||
-> 原始 tool arguments / JSON
|
||
-> Pydantic 或 JSON Schema canonical validator
|
||
-> 当前 task、revision、权限和幂等校验
|
||
-> Runtime / CDSL / 几何验证
|
||
-> SQLite 事务提交
|
||
```
|
||
|
||
固定业务对象使用 Pydantic v2 模型生成 JSON Schema;例如需求草稿、审查 verdict、动作提案、修复决定都必须是 `extra="forbid"` 的模型。不同 operation 的 CDSL fragment 由 Runtime contract 生成动态 JSON Schema,不能伪装成一个“所有参数都可选”的静态 Pydantic 模型。需求草稿的外层是固定 Pydantic schema,但每个 `acceptance_claim.expected` 是 verifier registry 在当前任务启动时生成的 closed `oneOf`;这同样是动态 schema,不能用 `dict[str, Any]` 放过未知 claim 数据。
|
||
|
||
LangChain 仅封装在 `cad_agent/adapters/structured_llm.py` 或等价 adapter 内:
|
||
|
||
- 固定对象使用 `with_structured_output(PydanticModel)`。
|
||
- 动态 operation contract 使用 `bind_tools()` 或 provider 的等价 tool schema 接口,传入服务端生成的 JSON Schema。
|
||
- 无论 provider 宣称支持 strict JSON、function calling 或 JSON mode,服务端都使用相同的 Pydantic/`jsonschema` validator 二次验证。
|
||
- 禁止使用 LangChain Agent、Memory、文本 JSON 提取、自动无限 re-ask 或自动 tool 执行。CAD runner 仍是唯一状态机。
|
||
- 不具备成功通过 provider conformance test 的 structured-output / tool-call 能力的模型,不可作为生产作者或审查模型。不能为了“支持任意模型”退回纯文本解析。
|
||
|
||
每次 LLM tool call 都经过同一条严格管线:限制一个允许的 tool name 和一个 call、限制原始 arguments 的字节数/JSON 深度、解析 JSON、schema canonical validation、当前状态与版本绑定、跨字段/几何 preflight,最后才进入事务或候选构建。provider 的 parser、LangChain 的 parser 和 Pydantic 的第一次反序列化都不是最终结论。服务端保留经脱敏的原始 arguments 与字段级错误用于诊断,但不会以“尽量修复”方式补全、重命名或猜测 LLM 字段。
|
||
|
||
工具的 `schema_name`、`schema_version`、当前 `working_head`、`contract_hash` 和 selector snapshot 由服务端 route/state 绑定,而不是信任 LLM 声称的版本。固定对象可以在工具 schema 中携带这些字段并做 canonical equality 校验;空参数命令(例如完成请求)则只以服务端暴露它的状态作为版本绑定。任何 schema 或 contract 变更都会使旧 pending action 失效,必须重新读取当前事实和合同。
|
||
|
||
### 4.2 需求和完成工件
|
||
|
||
`source-requirements.md` 是服务端保存的用户原文,不要求格式。服务端把它按原始段落或附件块生成稳定 `source_id`,只作为可引用证据,不尝试用规则理解自然语言。
|
||
|
||
LLM 不直接写 `requirements.md` 或 `completion.md`。它提交受严格 schema 约束的、分批且有上限的 `RequirementsDraftBatch`;服务端校验并保存 JSON,再渲染人类可读 Markdown。草稿阶段还必须使用结构化 `RequirementsPatchBatch` 修订 reviewer 指出的条目,并以零参数 `finalize_requirements_draft()` 明确请求进入独立复核。服务端在 source coverage 不完整时拒绝该最后一步,不自行猜测“需求已经写完”:
|
||
|
||
```text
|
||
source-requirements.md # 服务端创建,不可变
|
||
documents/source-index.json # 服务端生成:source_id -> 原始文本
|
||
documents/requirements-draft-v1.json # 仅已验证 RequirementsDraftBatch 合并结果
|
||
documents/requirements-review-v1.json # 严格结构化的独立审查结果
|
||
requirements-contract.json # 冻结的机器可验证需求与验收合同
|
||
requirements.md # 服务端从 contract 渲染,不作为程序输入
|
||
completion.md # 服务端从 contract 渲染,不作为程序输入
|
||
requirements-index.json # 服务端生成的 req/claim 索引
|
||
```
|
||
|
||
每次 `submit_requirements_draft_batch` 最多提交 8 条 requirement,避免大型一次性文档输出。外层固定 schema 至少包含:
|
||
|
||
```json
|
||
{
|
||
"items": [
|
||
{
|
||
"source_ids": ["src_001"],
|
||
"statement": "法兰为外径 120 mm、厚度 12 mm 的单一连通实体",
|
||
"assumptions": ["未指定标准时采用普通平面法兰"],
|
||
"acceptance_claims": [
|
||
{
|
||
"claim_kind": "solid_count_equals",
|
||
"expected": {"value": 1}
|
||
},
|
||
{
|
||
"claim_kind": "bbox_dimension_mm",
|
||
"expected": {"axis": "z", "value": 12, "tolerance_mm": 0.01}
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
`source_ids` 必须来自服务端 enum;`claim_kind` 必须来自已注册 verifier enum;每一种 `claim_kind` 的 `expected` 都按该 verifier 专属 JSON Schema 校验。服务端分配不可变的 draft item ID、`req_###` 与 `claim_###`,不会接受 LLM 自定义 ID。
|
||
|
||
`RequirementsPatchBatch` 的每一项只能是 `replace` 或 `remove`,并且 `target_draft_id` 必须是当前 draft revision 的 enum。`replace` 必须携带完整、重新验证过的 requirement 对象,不能提交局部自然语言 patch;`remove` 必须给出长度受限的原因。这样 reviewer 修改的是可审计的单项,而不是要求模型重写整份文档。删除后若使 source 无覆盖,`finalize_requirements_draft()` 必须被拒绝。
|
||
|
||
冻结前,独立 reviewer 必须返回 `RequirementsReview`。它对**每一个** `source_id` 给出恰好一行 coverage(该行可引用一个或多个 requirement ID),并对每一个 draft item 给出 `pass`、`revise` 或 `waiting_for_user`。`pass` 只有在全部 source 已被映射、全部 claim 的 verifier 可用且不存在冲突时有效。一个 source 可以支撑多条 requirement;因此不要求 source 只被一条 requirement 引用,只要求 reviewer coverage 行唯一且完整。`waiting_for_user` 必须具有 machine-readable reason code 和受限的提问文本,不能用模糊 prose 隐藏关键尺寸或基准缺失。
|
||
|
||
`requirements.md` 和 `completion.md` 可以是自然、自由的 Markdown,因为它们是 JSON contract 的只读渲染。例如:
|
||
|
||
```markdown
|
||
- [ ] 单一连通实体,外径 120 mm、厚度 12 mm
|
||
- [ ] 同轴直径 40 mm 的中心贯穿孔
|
||
- [ ] 节圆直径 90 mm 上四个直径 10 mm 的均布贯穿螺栓孔
|
||
```
|
||
|
||
程序永远不从上述 Markdown 重新提取 ID、验收项、步骤或状态。任何可测几何需求若没有注册 verifier,必须在需求阶段报 `VERIFIER_UNAVAILABLE`,不得偷偷降级为“让视觉模型看一看”。确实只能依赖外观判断的要求可显式声明为 `visual` claim,但其风险必须在任务界面标记。
|
||
|
||
需求草稿、修订和 review 的 canonical schema 还必须有以下共同约束:所有数组有上下限,所有可见文本有长度上限,所有枚举/ID 来自当前服务端快照,嵌套对象 `additionalProperties=false`;禁止任意 JSON object、任意键值 metadata 和未注册 claim。若需求是文件命名、材料、单位或展示约束,也必须绑定相应的确定性 verifier;没有 verifier 就不能被冻结为可发布合同。
|
||
|
||
### 4.3 LLM 的单动作意图
|
||
|
||
LLM 不再写模型级执行计划。没有待处理动作时,作者只可调用 `propose_next_action`。该 tool 的 JSON Schema 由服务端传给模型并在服务端再次校验;不得接受 Markdown、自由 JSON 字符串或未知字段。
|
||
|
||
```json
|
||
{
|
||
"working_head": "head_5f2e...",
|
||
"intent": "在当前法兰顶面加工四个均布螺栓孔",
|
||
"requirement_ids": ["req_003"],
|
||
"atomic_id": "hole_blind",
|
||
"expected_change": "新增四个直径 10 mm、在节圆直径 90 mm 上等角分布并贯穿 12 mm 本体的孔"
|
||
}
|
||
```
|
||
|
||
约束:
|
||
|
||
- `intent`、`expected_change` 为短文本(建议分别最多 360 字符),只说明当前动作,不复述全任务。
|
||
- `requirement_ids` 必须来自 `requirements-index.json` 的 enum,最多引用五项。
|
||
- `atomic_id` 必须来自当前 Runtime `SUPPORTED_ATOMIC_IDS` enum。
|
||
- `working_head` 必须与服务端发出的 opaque current-head token 完全相等;Pydantic 检查其形状,canonical state validator 检查其相等性。
|
||
- 提案不包含 selector、草图、参数、深度、工作平面或 CDSL;这些属于后续读取精确 contract 后的 canonical fragment。
|
||
- 提案必须绑定当前 `working_head`。检查点变化后旧提案不可提交,需由 LLM 基于新事实重新提出。
|
||
|
||
因此格式错误无法“完全不发生”,但影响面被限制为一个极小、严格 schema 的无副作用调用:服务端返回字段级错误并保留模型/检查点,不会再生成计划版本、消耗候选构建次数或污染账本。
|
||
|
||
### 4.4 服务端动作账本
|
||
|
||
账本不是 LLM 输出,也不是执行计划。服务端在动作提案、拒绝、候选构建、复核和 checkpoint 后,以 append-only JSON Lines 写入 `actions/action-ledger.jsonl`。每一行是一个状态事件,便于审计、恢复和增量读取:
|
||
|
||
```json
|
||
{"schema_version":"cad.action-ledger.v1","sequence":7,"event":"proposed","action_id":"act_003","working_head":"main:rev_002","intent":"在当前法兰顶面加工四个均布螺栓孔","requirement_ids":["req_003"],"proposed_atomic_id":"hole_blind","expected_change":"新增四个直径10 mm贯穿孔","at":"2026-08-31T...Z"}
|
||
{"schema_version":"cad.action-ledger.v1","sequence":8,"event":"accepted","action_id":"act_003","working_head_before":"main:rev_002","revision_id":"rev_003","actual_atomic_id":"hole_blind","fragment_sha256":"...","selector_snapshot_id":"...","candidate_id":"candidate_...","review_path":"revisions/rev_003/reviews/candidate-review/candidate-review.json","coverage":[{"requirement_id":"req_003","status":"complete"}],"at":"2026-08-31T...Z"}
|
||
```
|
||
|
||
运行中的 pending action 是事务状态,不从 JSONL 反推。它只保存 `action_id`、`working_head`、提案内容、contract hash 和幂等 key。给作者的上下文只包含 pending action 与压缩后的最近动作摘要,完整账本仅用于审计/UI 查询,避免随模型复杂度线性膨胀 prompt。
|
||
|
||
### 4.5 CDSL 与完成调用
|
||
|
||
提交 CDSL 的动态 tool schema 不存在“统一的 feature JSON 模板”。它只暴露当前 pending action 已选择的一个 operation 的 author-owned 字段;下面只是一个形状示意,实际是否有 `sketch`、是否有 `params`、是否有 selector/reference token 由 operation contract 决定:
|
||
|
||
```json
|
||
{"fragment": {"sketch": {"...": "仅 contract 要求时存在"}, "feature": {"atomic_id": "与 pending action 相同", "params": {"...": "contract 精确字段"}}}}
|
||
```
|
||
|
||
移除 `batch_goal`、`plan_step_id`、`plan_action_id`。候选复核的目标、需求映射和 operation 均从 pending action 与真实 fragment 取得,不能由 LLM 在提交时再次声称。
|
||
|
||
动态 schema 必须由当前 Runtime 的**完整、版本化** `feature_atomic_contract` 唯一生成,并与 `contract_hash`、`working_head`、engine/profile schema revision 和 selector snapshot ID 绑定。当前 `feature_atomic_contract` 仅列出 required/optional 参数,而 `cdsl_authoring_schema.py` 仍按 operation 名称硬编码很多 JSON 类型、hole 特例和 pattern 注入;这会产生 contract drift,不能作为 v3 的终态。P2 必须把这些信息收拢到 Runtime contract registry,删除 authoring schema 中按 operation 前缀补规则的兜底分支。
|
||
|
||
每个 operation contract 至少声明以下数据,且 contract 自身先经 JSON Schema / registry integrity validator 验证:
|
||
|
||
```json
|
||
{
|
||
"atomic_id": "hole_blind",
|
||
"contract_version": "3.0",
|
||
"fragment_shape": {
|
||
"sketch": "forbidden",
|
||
"params": "required_object",
|
||
"selector_tokens": "required"
|
||
},
|
||
"author_params_schema": {"type": "object", "additionalProperties": false},
|
||
"selector_policy": {
|
||
"slot": "params.host_face",
|
||
"token_kind": "face",
|
||
"min_items": 1,
|
||
"max_items": 1,
|
||
"snapshot_bound": true
|
||
},
|
||
"server_injected_paths": ["params.host_face"],
|
||
"reference_policy": {"mode": "none"},
|
||
"semantic_preflight": ["host_face_exists", "hole_positions_on_host_plane"],
|
||
"candidate_verifiers": ["cylindrical_bore", "through_cylindrical_bore"]
|
||
}
|
||
```
|
||
|
||
其中 `author_params_schema` 是 closed JSON Schema,必须递归关闭其嵌套对象。禁止用 `{}`、`type: object` 未限制 properties、任意 `dict` 或“其它 operation 以后再解释”的 fallback 暴露给作者。`hole_wizard` 的 `hole_type`、`thread`、`countersink`、`counterbore` 等嵌套对象必须各有枚举/closed 子 schema;当前的开放对象定义不满足此要求,必须在该 operation 可暴露前补齐。
|
||
|
||
动态 schema 必须精确表达以下 operation 差异,而不能靠 prompt 约定:
|
||
|
||
- `fragment_shape.sketch=required` 时 `sketch.workplane` 和 `sketch.profile` 必填;`forbidden` 时 `sketch` 出现即拒绝。profile 类型和每层字段同样由 closed schema 限制。
|
||
- `fragment_shape.params=required_object` 时 `params` 必须存在并匹配该 operation 的专属 schema;若 operation 没有 author-owned 参数,contract 明确指定 `params` 是必填的空 object 还是 forbidden,不能假设所有 feature 均需或均不需参数。
|
||
- `selector_policy` 只能为 `forbidden`、`required` 或明确的 `optional`。required selector 的 token schema 是当前 snapshot 中匹配 kind 的 opaque token **enum**,并有精确数量上限;没有有效 snapshot 时根本不暴露 fragment tool。`host_face`、mirror plane 等 server-owned selector 只由 resolver 注入,LLM 提供原始 selector object 或注入字段即拒绝。
|
||
- `reference_policy` 处理 feature-source、reference plane/axis 等关系。禁止当前实现中“默认把最后一个 committed feature 当 pattern source”的通用猜测;若关系不是 contract 可唯一推导,schema 必须要求来自当前 feature-reference snapshot 的 opaque token,并由服务端解析为 Runtime ID。
|
||
- 每个 operation 只允许自身的 required/optional params,`additionalProperties=false`;例如 `extrude_cut_blind.distance_mm` 不能替换为 hole 的 `depth_mm`,hole 的 `positions` 也不能出现在 extrude。所有数字必须是有限值,并满足 Runtime 安全范围、单位和 operation 专属的跨字段限制。
|
||
- `atomic_id` 必须同时等于 pending action、active contract 和动态 schema 的 `const`;三者任一不一致均在构建前拒绝。
|
||
- 新增 Runtime operation 时,必须同时新增完整 operation contract、contract integrity fixture、动态 schema fixture、canonical validator 测试、semantic-preflight 测试、引擎执行测试和对应 verifier;缺任一项不得进入作者可选 `atomic_id` enum。
|
||
|
||
动态 schema 校验成功后仍必须依次通过:当前 revision/head 校验、contract hash 与 registry revision 校验、selector/reference snapshot 校验、operation semantic preflight、静态 CDSL schema、完整 materialized CDSL validation 和隔离 CDSL-only rebuild。前六项均不产生候选目录;只有通过后才消耗候选构建预算。schema 不能表达的关系必须由 preflight/geometry validator 检查,例如工作平面正交且法向非零、profile 不自交、hole position 位于宿主面、revolve axis 位于草图平面,以及为了满足“贯穿” claim 的 `hole_blind` 或 `extrude_cut_blind` 的切削方向、有效行程和出口面连通性。
|
||
|
||
`complete_task` 改为无参数 tool。删除 `self_review`,因为作者的自我声明不能作为完成证据。服务端仅在当前 revision 的独立 coverage 全部完成且没有 pending/rejected repair 时暴露该 tool。
|
||
|
||
### 4.6 每类 LLM 输出的可信边界
|
||
|
||
| LLM 输出 | 输出方式 | 必须由程序验证 | 不由它控制的内容 |
|
||
| --- | --- | --- | --- |
|
||
| 需求草稿/修订/提交复核 | `RequirementsDraftBatch`、`RequirementsPatchBatch`、`finalize_requirements_draft()` | 字段、source/draft-ID enum、批量上限、claim kind 的动态 `oneOf`、重复项、累计 source coverage | Markdown 文档、req/claim ID、draft/review 状态、冻结状态 |
|
||
| 需求独立审查 | `RequirementsReview` Pydantic schema | 每个 source_id 的唯一 coverage 行、每个 draft item verdict、引用的 req/claim 存在、`WAITING_FOR_USER` reason code | 是否冻结由服务端 coverage gate 决定 |
|
||
| 下一动作 | `NextAction` Pydantic schema | requirement ID enum、Runtime operation enum、working head、无 pending action、幂等键 | action_id、pending 状态、实际 CDSL ID |
|
||
| 观察/测量/contract 请求 | 固定 Pydantic tool schema,动态 enum 绑定当前 head/snapshot | 参数范围、当前 revision、selector kind/limit、operation enum;每回合只接受允许的一个 tool call | 观察结果、contract、selector/reference token 均由服务端生成 |
|
||
| CDSL feature | 当前 operation 的动态 JSON Schema | contract hash、`const atomic_id`、fragment shape、递归 closed params、selector/reference enum、静态 CDSL、语义 preflight、引擎 preflight | feature/sketch ID、dependency、host face、selector/reference 解析 |
|
||
| 诊断、回滚与完成请求 | `GeometryConclusion`、`RollbackCheckpoint`、`complete_task()` | decision enum、当前 evidence ref enum、rollback token、head、文本/数组上限;完成 gate 由服务端先验证 | 几何诊断证据、回滚可达性、发布判断 |
|
||
| 候选审查 | `CandidateReview` Pydantic schema | candidate/revision enum、claim coverage 的精确集合、verdict enum、证据上限;确定性 verifier 必须先通过 | checkpoint 提交、coverage 更新 |
|
||
| 最终审查 | `FinalReview` Pydantic schema | current revision、所有 final claim 的精确集合、verdict enum、证据上限;所有 deterministic claim 必须通过 | 发布、published revision |
|
||
| 可见解释/意图文字 | 普通文本字段,长度限制 | 仅编码、安全和长度检查 | 不参与任何状态转移或 CAD 参数计算 |
|
||
|
||
“结构化输出通过”只证明对象格式和引用有效,不证明 CAD 语义必然正确。语义正确性必须由 source coverage、requirement acceptance contract、Runtime、几何 verifier 和独立 review 共同证明;其中 deterministic verifier 失败时,任何 LLM 的 accept verdict 都不能覆盖失败。
|
||
|
||
### 4.7 Canonical schema 目录与二次校验
|
||
|
||
以下目录是 v3 必须实现的**唯一** LLM 输入合同。每个固定模型均使用 Pydantic v2 的 strict model(`extra="forbid"`、显式长度/数量限制),由服务端导出 JSON Schema;动态 enum 和 dynamic `oneOf` 在每次 tool 暴露时由服务端收窄。任何新的 state-changing LLM tool 必须先加入本表、fixture、conformance test 和错误映射,不能临时添加自由 object 参数。
|
||
|
||
| Tool / 输出模型 | 必填结构化字段 | schema 类型 | 格式后仍必须程序校验 |
|
||
| --- | --- | --- | --- |
|
||
| `submit_requirements_draft_batch` / `RequirementsDraftBatch` | `items[1..8]`;每项有 `source_ids`、`statement`、`assumptions`、`acceptance_claims` | Pydantic outer + verifier registry 的 closed claim `oneOf` | source enum、去重、claim 语义/单位、可用 verifier、draft transaction |
|
||
| `patch_requirements_draft` / `RequirementsPatchBatch` | `patches[1..8]`;`target_draft_id`、`op=replace|remove`;replace 携带完整 item | Pydantic + current draft-ID enum | 目标存在且属于当前 draft revision、替换后的 coverage/去重 |
|
||
| `finalize_requirements_draft` | 空 object | fixed empty schema | 至少一个 draft item、无缺 source、无不可用 claim 后才可进入 review |
|
||
| `review_requirements` / `RequirementsReview` | `verdict`、每个 source 的唯一 coverage row、每个 draft item verdict、`issues[]` | Pydantic + source/draft/claim ID enum | coverage 精确集合、issue code、approve gate;服务端而非 reviewer 冻结 contract |
|
||
| `propose_next_action` / `NextAction` | `working_head`、`intent`、`requirement_ids`、`atomic_id`、`expected_change` | Pydantic + Runtime operation/requirement ID enum | head equality、无 pending action、operation available、idempotency |
|
||
| 事实读取工具 | 例如 `inspect_topology(kind, limit)`、`get_cdsl_operation_contract(atomic_id)`、`render_section(origin_mm, normal)` | Pydantic,动态 operation/head/snapshot enum | 参数范围、访问当前 revision、预算/缓存;结果只能由服务端生成 |
|
||
| `submit_cdsl_fragment` | 只有当前 operation contract 定义的 fragment | Runtime-generated Draft 2020-12 JSON Schema | contract/schema/snapshot hash、引用解析、cross-field semantic preflight、materialized CDSL schema、engine preflight |
|
||
| `record_geometry_conclusion` / `GeometryConclusion` | `working_head`、`evidence_refs`、`root_cause`、`decision`、受限 `corrective_intent` | Pydantic + current evidence enum | evidence 属于同一 head、decision 可达;`corrective_intent` 不直接成为 CDSL |
|
||
| `rollback_checkpoint` / `RollbackCheckpoint` | `working_head`、`checkpoint_token`、受限 reason | Pydantic + active lineage enum | token 是祖先、没有 candidate/transaction 冲突、原子 branch transition |
|
||
| `review_candidate` / `CandidateReview` | `candidate_id`、`revision/head`、`verdict`、精确 claim coverage、受限 evidence/issues | Pydantic + candidate/claim enum | candidate identity、确定性 claim gate、reviewer 不能覆盖 deterministic result |
|
||
| `complete_task` | 空 object | fixed empty schema | 没有 pending action/repair,所有 deterministic claim pass;为 final review 创建幂等工作项 |
|
||
| `review_final` / `FinalReview` | `revision/head`、`verdict`、精确 final claim coverage、受限 evidence/issues | Pydantic + final claim enum | final rebuild identity、全局 invariant、deterministic/visual gate、一次发布事务 |
|
||
|
||
`GeometryConclusion.decision` 只能是 `return_to_action_selection`、`rollback` 或 `waiting_for_user`;它不包含 feature ID、参数、selector 或下一段 CDSL。选择修复仍由下一次 `NextAction` 明确作出,避免诊断对象暗中变成第二套执行计划。`CandidateReview` 与 `FinalReview` 允许模型提出 reject/repair;对确定性 claim,服务端只把 reviewer 的 accept 当作额外条件,而不是证明。
|
||
|
||
## 5. 完整执行流程及 LLM 边界
|
||
|
||
| 阶段 | 输入/产物 | LLM 生成内容 | 服务端职责 | 失败后的唯一去向 |
|
||
| --- | --- | --- | --- | --- |
|
||
| 0. 创建 | 用户请求 | 无 | 创建 `source-requirements.md`、任务与 run | 请求错误,拒绝创建 |
|
||
| 1. 需求草稿 | source index + 用户上下文 | `submit_requirements_draft_batch(RequirementsDraftBatch)`,每次最多 8 项;按需 `patch_requirements_draft(RequirementsPatchBatch)`,最后 `finalize_requirements_draft()` | outer Pydantic、source/draft-ID enum、verifier dynamic schema、去重和批量事务;只保存 JSON | `AUTHOR_FORMAT_INVALID` 或 `REQUIREMENTS_COVERAGE_INCOMPLETE`,不写 Markdown、不进入建模 |
|
||
| 2. 需求独立复核 | source index + draft contract | `review_requirements(RequirementsReview)` | coverage 行、假设/冲突/验收可行性;通过后冻结 JSON 并渲染 `requirements.md` / `completion.md` | `revise` 回到阶段 1;歧义为 `WAITING_FOR_USER`;缺 verifier 为 `VERIFIER_UNAVAILABLE` |
|
||
| 3. 选择下一动作 | frozen contract、claim coverage、当前模型摘要、账本摘要、Runtime operation enum | `propose_next_action(NextAction)` | Pydantic、ID enum、head、operation、幂等和 pending-action 校验 | 无副作用 `AUTHOR_DECISION_REJECTED` 或 Runtime 前置条件错误 |
|
||
| 4. 收集事实 | 当前 checkpoint | LLM 自主调用结构化 inspect/measure/render/topology/contract tools | 返回真实、版本绑定数据;为动态 fragment 生成 selector/reference enum、限额和缓存 | snapshot 过期或 selector/reference 不匹配,保留 checkpoint,重新观察 |
|
||
| 5. 生成 CDSL | pending action + 精确 operation contract + 相关 snapshot | `submit_cdsl_fragment(DynamicOperationSchema)` | contract/head/snapshot-bound dynamic JSON Schema、静态 CDSL、语义/引擎零副作用 preflight | `CDSL_SCHEMA_INVALID` 或 `RUNTIME_PRECONDITION_FAILED`,只允许修正当前动作;不消耗候选尝试 |
|
||
| 6. 构建候选 | materialized CDSL | 无 | 隔离 rebuild、健康检查、拓扑、deterministic claim verifier、渲染 | `CANDIDATE_BUILD_FAILED` 或 `CLAIM_VERIFICATION_FAILED`,保留基线并进入诊断/修复或回滚 |
|
||
| 7. 独立候选复核 | 渲染、真实 CDSL、拓扑、pending action、只读 claim 结果 | `review_candidate(CandidateReview)` | 验证结构化 verdict/claim coverage;deterministic claim 失败时强制 reject | reject 形成明确 repair card;review 服务故障为 typed service failure,不让作者重做几何 |
|
||
| 8. 写账本/检查点 | accepted candidate | 无 | 原子提交 revision,追加 accepted ledger,更新 claim coverage,清除 pending action | 存储失败必须原子回滚,不出现半提交 |
|
||
| 9. 下一轮 | 新 checkpoint | 回到阶段 3,由 LLM 决定下一动作 | 仅提供最新事实 | 同上 |
|
||
| 10. 最终完成 | 当前 revision、claim coverage、最终渲染 | `complete_task()`,无参数;`review_final(FinalReview)` 由独立 reviewer 输出 | CDSL-only rebuild、全部 deterministic claim、全局几何不变量、结构化最终独立复核、发布 | repair 回阶段 3;内部故障一次标为 `FAILED_INTERNAL` |
|
||
|
||
阶段 3 的“下一步”必须由 LLM 做决定。服务端不可根据未覆盖的 `req_003` 自动构造“加工螺栓孔”;它只能在 LLM 提出 `hole_blind` 后检查该选择是否是当前 Runtime 支持的原子操作、是否与 checkpoint/contract 相容,以及是否可安全进入下一阶段。
|
||
|
||
## 6. 可靠性规则
|
||
|
||
### 6.1 明确错误分类
|
||
|
||
定义可序列化的错误码和类别,禁止将 Python 异常文本当作 authoring error:
|
||
|
||
- `AUTHOR_FORMAT_INVALID`:tool 参数或 canonical CDSL schema 无效;无 CAD 副作用,可限次数修正。
|
||
- `AUTHOR_DECISION_REJECTED`:动作与当前 pending/head/contract 不一致;无 CAD 副作用,要求重新选择或修订。
|
||
- `STALE_WORKING_HEAD`:command 的 head、state version、contract 或 selector/reference snapshot 已过期;无 CAD 副作用,返回最新事实,禁止自动合并或覆盖新的 checkpoint。
|
||
- `FAILED_AUTHOR_FORMAT`:同一 schema 的字段级修正次数达到上限,或 provider 持续不能交付该 schema;终止本 run 并保留 checkpoint,不能改记为 `NO_PROGRESS_LIMIT` 或降级到自由文本。
|
||
- `RUNTIME_PRECONDITION_FAILED`:selector 不存在/歧义、body/host 缺失、操作不支持;保留 checkpoint,要求新的观察或动作决策。
|
||
- `RUNTIME_CONTRACT_INVALID`:operation registry 缺少 closed field schema、注入/selector/reference policy、semantic preflight 或与 engine schema 不一致;这是部署/代码缺陷,feature 不得暴露给作者,也不能归因于 LLM。
|
||
- `CANDIDATE_BUILD_FAILED`:BRep/STEP 构建失败;消耗候选预算,进入诊断、修复或回滚。
|
||
- `CANDIDATE_REVIEW_REJECTED`:几何已构建但不符合动作或需求;保留证据,LLM 决定修复/回滚。
|
||
- `VERIFIER_UNAVAILABLE`:冻结的 requirement claim 没有已注册且可运行的 verifier;不得创建 task contract 或发布。
|
||
- `CLAIM_VERIFICATION_FAILED`:候选/最终 deterministic verifier 得到 fail;LLM reviewer 不能覆盖该结果。
|
||
- `MODEL_STRUCTURED_OUTPUT_UNSUPPORTED`:provider/model 未通过当前 schema 的 conformance suite;任务开始前拒绝,不进入 author loop。
|
||
- `AUTHOR_TRANSPORT_UNAVAILABLE`、`REVIEW_SERVICE_UNAVAILABLE`、`RENDER_SERVICE_UNAVAILABLE`、`STORAGE_FAILURE`:基础设施失败;不归入 no-progress、不允许 author 重复 CDSL。使用相同幂等键和有限指数退避重试服务操作,超限后进入 `WAITING_RETRY`,由显式恢复操作或受控调度重新开始。
|
||
- `FAILED_INTERNAL`:未预期异常(例如 `NameError`);记录 traceback/版本/调用幂等键,立即终止该 run,保留最后 checkpoint。
|
||
- `WAITING_FOR_USER`:源需求冲突、关键尺寸/基准不可合理假设、或多轮文档复核无法消除的语义歧义;不是 `failed`。
|
||
|
||
`NO_PROGRESS_LIMIT` 只统计作者在允许的观察/决策阶段反复作出没有状态推进的合法但无效选择;同一无副作用格式错误超过上限应归为 `FAILED_AUTHOR_FORMAT`。它绝不能统计 `FAILED_INTERNAL`、`RUNTIME_CONTRACT_INVALID`、verifier/review/render/network/storage 故障,也不能把重复 `complete_task` 视为可继续作者修正的机会。`WAITING_RETRY` 只用于可恢复的基础设施失败,`WAITING_FOR_USER` 只用于用户决定缺失,二者都不能掩盖 author format failure。
|
||
|
||
### 6.2 幂等与事务
|
||
|
||
- 每个状态改变 tool call 有 `invocation_id`;每个候选/最终复核有基于 `task_id + working_head + action_id + fragment_hash` 的幂等键。
|
||
- 同一 `complete_task` 对同一 revision 最多执行一次最终重建/复核;调用中断后恢复相同结果或明确失败,不能重新进入作者循环。
|
||
- candidate commit、task revision 更新、pending-action 清除和 ledger append 必须在同一事务内完成。
|
||
- 新协议的权威可变状态采用 SQLite(任务、run、pending action、ledger index、invocation、coverage),STEP/GLB/CDSL/Markdown/渲染仍保留在任务目录作为不可变工件。`WorkspaceStore` 重构为“数据库状态 + 文件工件”,不允许 JSON 与数据库双写且各自成为事实来源。
|
||
- `task.json` 可以作为 API/人工查看的派生快照,不能再是并发状态机的权威来源。
|
||
- 外部 build/render/review 不能与 SQLite 假装存在同一事务。候选工件先写入不可见的 staging 目录,并带有输入 head、fragment hash、engine version 和每个文件 sha256 的 manifest;只有所有 preflight/build/verifier 都成功,才原子 rename 到不可变 revision artifact 位置。随后 SQLite 条件事务写入 revision、coverage、ledger index 和已存在 artifact manifest 引用;API 只通过 SQLite 引用读取工件,因此在数据库提交前已发布的文件仍不可见。进程崩溃时恢复器验证 manifest/hash,清理未引用工件或复用已发布的同 hash 工件;不会让 active revision 指向尚未发布的文件。
|
||
- 状态事件写入 transactional outbox,与状态迁移同一 SQLite 事务提交;stream/UI 通知由 outbox dispatcher 幂等发布,不能由 command handler 直接 emit。这样断连、重放或前端失败不会回滚已确认的 CAD checkpoint,也不会导致重复 build。
|
||
|
||
### 6.3 几何验证
|
||
|
||
- selector 必须来自当前 topology snapshot;零个候选报 `selector_not_found`,并列候选报 `selector_ambiguous`,不可默认取第一个。
|
||
- 对“贯穿孔”建立 topology 断言:孔轴对应的圆柱面必须连通目标进/出平面;验证孔数、直径、位置/节圆和穿透方向。`depth_mm >= body_thickness` 只可作为 preflight 辅助证据。
|
||
- 对需要“等效贯穿”的 `hole_blind` 和 `extrude_cut_blind`,preflight 必须从实际宿主面/工作平面、切削方向和目标实体计算最小出口距离;不足则拒绝为 `RUNTIME_PRECONDITION_FAILED`。候选与最终阶段仍以拓扑连通性为最终结论,不能以参数名称或深度文字代替。
|
||
- 多位置 `hole_blind` 在同一 host face、孔径和深度一致时必须允许为一个 action/一个 feature;不得被 review 层拆成四条虚假要求。
|
||
- 全局不变量(单实体、显式尺寸等)在候选和最终重建两处都执行,二者使用同一函数;最终复核不得引用未初始化的局部变量。
|
||
|
||
### 6.4 验收 verifier registry
|
||
|
||
`requirements-contract.json` 中的每一个 `acceptance_claim` 必须引用一个注册 verifier。每个 verifier 是服务端代码,不是 LLM prompt,至少定义:
|
||
|
||
```text
|
||
claim_kind
|
||
expected_json_schema
|
||
required_artifacts # CDSL / rebuild report / topology / render
|
||
evaluate(current_revision) -> pass | pending | fail | unavailable
|
||
evidence() -> 结构化测量和工件引用
|
||
```
|
||
|
||
首批必须覆盖当前项目已能可靠观测的内容:
|
||
|
||
| claim_kind | 程序化证据 |
|
||
| --- | --- |
|
||
| `solid_count_equals` | CDSL-only rebuild 的 `solid_count` |
|
||
| `bbox_dimension_mm` | rebuild bbox 指定轴和容差 |
|
||
| `cylindrical_bore` | topology 的圆柱面、直径、轴线和位置 |
|
||
| `through_cylindrical_bore` | bore verifier 加上入口/出口平面连通性 |
|
||
| `circular_hole_pattern` | 孔数、直径、节圆半径、角间距、宿主面与穿透状态 |
|
||
| `coaxial` / `coplanar` | topology 几何轴线、法向和容差 |
|
||
| `single_connected_body` | rebuild solid count 与连通性 |
|
||
| `visual` | 固定 render + 独立 reviewer;必须明确标为非确定性 |
|
||
|
||
每个 checkpoint 都计算所有 claims:尚未由前序几何满足的 claim 为 `pending`,已经被错误几何破坏的 claim 为 `fail`。候选不得因未来工作仍是 `pending` 而被拒绝;但如果动作引用的 requirement 已经被 `fail`、或任何全局 invariant 为 `fail`,候选必须拒绝。最终发布要求所有 deterministic claim 为 `pass`,所有 visual claim 获独立 reviewer `pass`。LLM reviewer 只能拒绝或为 visual claim 提供证据,永远不能把 deterministic `fail` 改成 `pass`。
|
||
|
||
verifier registry 的注册也是可靠性边界:registry 启动时必须校验 `claim_kind` 唯一、`expected_json_schema` 为有效的 closed schema、required artifacts 可由当前 engine/rebuild 产生、`evaluate` 可序列化返回结构化 evidence。任何 verifier 在候选/最终运行时不可用都返回 `unavailable` 和 `VERIFIER_UNAVAILABLE`,不得把 claim 静默转成 visual。
|
||
|
||
### 6.5 Provider conformance 与模型切换
|
||
|
||
切换模型不得修改 CAD runner、Pydantic 模型、Runtime contract 或 verifier。新增 provider/model 时先运行真实 API conformance suite,成功后才写入 `model_capabilities`:
|
||
|
||
- 固定 Pydantic schema:必填字段、enum、嵌套对象、数组上限、`additionalProperties=false`。
|
||
- 强制指定 tool 与模型返回多个 tool call 时的行为。
|
||
- 每一个已注册 Runtime operation 的动态 fragment schema,至少验证 required params、forbidden params、`requires_sketch` 差异、selector token enum 和 `const atomic_id`。
|
||
- usage、timeout、429、断连、空 choices、无 tool call 和无效 JSON 的统一错误映射。
|
||
- provider 的 strict schema、普通 tool calling、JSON mode 分别记录;只能选择实测通过的模式。
|
||
|
||
能力档案不通过时拒绝启动任务,返回 `MODEL_STRUCTURED_OUTPUT_UNSUPPORTED`。格式失败时允许有限次数的同 schema re-ask,错误信息只含 validator 的字段级结果;每次失败均不创建候选、不消耗 build 预算、不改变 revision。达到格式上限必须显式进入 `FAILED_AUTHOR_FORMAT`;只有 transport/限流等基础设施重试超限才进入 `WAITING_RETRY`。两者都绝不降级为自由文本执行。
|
||
|
||
### 6.6 架构、依赖与状态机边界
|
||
|
||
v3 采用 Ports and Adapters(六边形)架构、显式 command handler 和有限状态机。目的不是增加抽象层数量,而是让“LLM 选择下一动作”和“程序证明、执行、持久化该动作”在代码上无法相互越界。`autonomous_cdsl_generation.py` 当前同时承担 prompt、tool schema、状态迁移、CDSL materialization、文件读写、候选构建、review 和重试;v3 不得保留这种万能 service。
|
||
|
||
依赖方向只能由外向内:API/UI 与 adapter 可依赖 application;application 可依赖 domain 与 port;domain 不得导入 FastAPI、LangChain、SQLite、文件路径、engine、renderer 或 settings。adapter 只能实现 port,不能直接改变 task state 或绕开 command handler。composition root 是唯一可以同时 import application、adapter 和 settings 的位置。
|
||
|
||
```text
|
||
API / worker / stream
|
||
-> application: command handlers + workflow coordinator
|
||
-> domain: immutable state, transitions, contracts, policies
|
||
<- ports: TaskRepository, ArtifactStore, ModelGateway, CadRuntime,
|
||
ReviewGateway, VerifierExecutor, EventPublisher, Clock
|
||
<- adapters: SQLite/files, LangChain/providers, CDSL engine,
|
||
renderer, reviewer, outbox dispatcher
|
||
```
|
||
|
||
模块职责固定如下:
|
||
|
||
| 层级 | 模块/对象 | 允许做什么 | 明确禁止 |
|
||
| --- | --- | --- | --- |
|
||
| domain | `TaskState`、`PendingAction`、`Revision`、`OperationContract`、claim/verifier policy、transition function | 不可变 value object、跨字段规则、合法状态迁移、typed error/result | I/O、网络、文件、SQL、prompt 拼接、选择下一 CAD action |
|
||
| application | `CommandHandler`、`WorkflowCoordinator`、`UnitOfWork` 使用方、context assembler | 接收已验证 command、读取 snapshot、调用 port、安排幂等 side effect、提交 transition/outbox | 直接解析原始 LLM JSON、直接访问 SQLite/路径、按 operation 名称写参数规则、从 requirement 推导下一动作 |
|
||
| ports | Python `Protocol`/interface | 声明 repository、artifact、LLM、runtime、review、event 等依赖的输入输出和 failure contract | 保存业务状态、提供默认实现、泄漏 provider/engine 私有对象 |
|
||
| adapters | `StructuredModelGateway`、SQLite repository、artifact store、CDSL runtime、renderer/reviewer、outbox dispatcher | 调用外部系统并翻译为 port 的 typed result/error | 决定 workflow transition、修改 domain object、吞掉/重新归类内部异常 |
|
||
| delivery | FastAPI、worker、stream、frontend mapper | 鉴权、请求/响应、启动 command、消费 outbox event | CAD 规则、状态迁移、直接读写 task 文件 |
|
||
|
||
固定采用以下模式和约束:
|
||
|
||
- **Command + Result。** 每个 state-changing tool 映射到一个 typed command;handler 只返回 `Accepted`、`Rejected(typed_error)`、`Waiting` 或 `FailedInternal` 这类结果。预期业务失败不以 Python exception 驱动控制流;adapter 未预期 exception 在边界转为 `FAILED_INTERNAL` 并携带 correlation ID。
|
||
- **有限状态机。** 持久化状态至少为 `DRAFTING_REQUIREMENTS`、`REVIEWING_REQUIREMENTS`、`AWAITING_ACTION`、`ACTION_PENDING`、`CANDIDATE_BUILDING`、`CANDIDATE_REVIEW`、`FINAL_VALIDATION`、`WAITING_RETRY`、`WAITING_FOR_USER`、`COMPLETED`、`FAILED`。观察/测量是只读 command,不新增持久化 phase;tool 可见性由 state、pending action 和 snapshot 派生,不能由 prompt 文本隐式决定。
|
||
- **Strategy + registry。** operation contract、semantic preflight 和 verifier 以已验证 registry entry 注册;不得以 `if atomic_id.startswith(...)` 在 runner 中散落规则。registry 选择由已验证 `atomic_id` 完成,不能演变为 service locator 或反射执行任意插件。
|
||
- **不可变快照与乐观并发。** command 带 `working_head`、schema/contract hash、必要的 selector/reference snapshot;repository 以 task state version/head 做 compare-and-swap。冲突返回 `STALE_WORKING_HEAD`,不会合并或覆盖较新的 checkpoint。
|
||
- **Unit of Work + transactional outbox。** SQLite 是唯一状态提交点;工件、LLM、engine、renderer 等非事务性副作用通过 invocation/candidate staging 和 outbox 与状态机衔接,不允许“先更新 task.json,再希望文件/stream 成功”。
|
||
- **依赖注入和 composition root。** handler 构造时显式传入 ports;测试替换为 in-memory/fake adapter。禁止 handler/validator 内部调用 `load_engine()`、读取全局 settings、创建 HTTP client 或直接 new `WorkspaceStore`。
|
||
|
||
状态迁移必须集中在纯函数/transition table 中,并作为架构测试覆盖。一个 handler 的标准过程是:读取 immutable snapshot -> canonical/schema/state validation -> 注册或复用 invocation idempotency record -> 调用必要 port -> 以 expected state version 计算 domain transition -> 单一 Unit of Work 提交 state、ledger index、outbox。build/review 这类长时操作先持久化 `processing` invocation/candidate 状态,重启后从该记录恢复;同一 idempotency key 只能得到一个最终 result,不允许重新生成第二个候选。每一次 command、adapter call、candidate、review 和 outbox event 都记录同一 `task_id`、`run_id`、`invocation_id`、head/state version 的结构化 correlation fields;日志不得保存密钥、完整用户附件或未脱敏 prompt。
|
||
|
||
LLM 的回合管理也服从这个边界:`WorkflowCoordinator` 只根据当前 workflow state 请求 `ModelGateway` 输出允许的一个 structured command,然后交给对应 handler;它不分析 requirement 文本、不了解某个 hole 的字段,也不自行选择 operation。prompt/context assembly 是 application service,输入只能是 domain projection 和 port 返回的事实快照;operation schema 由 runtime contract adapter 提供。
|
||
|
||
为防止架构随时间退化,测试必须检查 import dependency rules、每个 port 的 adapter conformance、domain transition table、crash recovery/outbox 重放和并发 CAS 冲突。`autonomous_cdsl_generation.py` 只能在过渡期作为迁移入口;v3 发布前必须删除其中的业务实现,替换为薄 composition/compatibility-free bootstrap,不能只是把原函数移动到新文件。
|
||
|
||
### 6.7 真实 LLM 端到端评测与 Codex 执行门
|
||
|
||
provider conformance 只证明某个模型在小型、受控 schema 提示下能返回合法 tool arguments;它不能证明该模型在完整 requirements、动态 operation contract、真实 CAD 结果和多轮状态机中能稳定完成零件。因此 v3 必须提供可由 Codex 非交互执行的真实评测入口,并将其作为完成该目标与发布的硬门。实现本目标的 Codex 必须实际运行它、读取失败工件与诊断、修复可修复的实现缺陷后重新运行;不得只运行 mock/unit tests 后声称目标完成。
|
||
|
||
必须新增命令:
|
||
|
||
```text
|
||
cd backend
|
||
python -m app.cad_agent.evals.live --suite release --require-live
|
||
```
|
||
|
||
该命令默认从当前 `Settings` 取得已选择的 author provider/model 和独立 reviewer provider/model;允许以显式、非秘密的 provider/model ID 覆盖,便于逐个验证已配置模型。凭据只从现有配置来源读取,CLI 参数、输出、工件和日志绝不回显密钥。它必须经由生产 `StructuredModelGateway`、生产 `CadRuntime`、生产 `ReviewGateway`、v3 `WorkflowCoordinator`、SQLite repository 与 ArtifactStore adapter 运行,测试代码不得替换 LLM、CAD engine、reviewer、状态机或动态 schema validator 为 mock/fake。唯一允许的隔离是每次评测创建临时 v3 SQLite 数据库和独立 artifact root,绝不读取、修改或发布普通用户 task。
|
||
|
||
命令开始时先以实际 provider 请求执行选定模式的 conformance preflight;author 与 reviewer 均需成功。配置缺失、凭据无效、网络不可达、provider 限流、模型未通过 structured-output capability 或引擎不可用时,命令写出结构化 `LIVE_EVAL_BLOCKED`/对应 typed error 并以非零退出。`--require-live` 禁止任何 skip、离线 fallback、mock fallback 或把 `WAITING_RETRY` 记为通过。只有用户显式选择不执行 live eval 的开发场景才允许 `--allow-skip`;该模式产生 `skipped`,永远不满足本目标的完成或发布验收。
|
||
|
||
评测分层以控制成本但保留真实覆盖:
|
||
|
||
- `smoke`:矩形底板和简单法兰各一次,用于 Codex 在完成高风险改动后快速验证真实 author/reviewer/engine 串联。
|
||
- `release`:矩形底板、法兰、带肋和安装孔的支架、含 face/edge selector 的修饰特征;每个场景至少连续运行三次,以独立 task/run 执行。任务需求、units、验收 claims、最大 author/reviewer turn 数、最长 wall time、总 token/调用预算和期望终态作为版本化 fixture 保存在仓库。
|
||
- 新增或修改 operation contract、selector/reference policy、verifier 或动态 schema 时,`release` 还必须包含该 operation 的最小真实生成场景;不能只补 unit fixture。
|
||
|
||
每个 live run 的成功只取决于当前 revision 的可验证结果,不取决于 LLM 是否恰好选择某个预期 feature sequence。它必须:完成到 `COMPLETED`、通过全部 deterministic claims 和必要 visual review、生成可读取的 immutable artifacts;无 `FAILED_INTERNAL`、`NO_PROGRESS_LIMIT`、未终止 `running`、重复 revision、重复 complete/build invocation 或未分类异常;所有 state-changing LLM 输出均有 raw-arguments hash、canonical validation、head/contract/snapshot binding 的审计记录;任何格式拒绝均在候选创建前发生。reference happy-path fixture 的 schema/decision rejection 计数必须为零;若出现,即使系统后来恢复,也视为 live quality failure,Codex 必须报告字段级原因并调整 schema/context/contract 或模型 capability,而不能隐藏为普通重试。
|
||
|
||
每次运行写入 `live-evals/<run_id>/report.json` 和链接到隔离工件的 manifest。报告至少包含:git revision、protocol/contract/verifier 版本、author/reviewer provider+model ID、实际 structured-output mode、每场景和每重复的最终 lifecycle、typed failure、所有 invocation/candidate/revision IDs、每个 claim 结果、schema rejection/重试/rollback 计数、token usage/上下文字节/耗时、预算是否超限,以及脱敏后的 correlation ID。保存 JSON summary、ledger、CDSL、拓扑、rebuild/verifier evidence 和 reviewer verdict;禁止保存密钥、完整未脱敏 prompt、附件原文或 provider 响应中的敏感 metadata。
|
||
|
||
Codex 的最终交付必须在结果中逐项说明实际执行的 live command、author/reviewer model、通过/失败场景、可定位的 report/artifact 路径、token 用量与任何失败的根因。发生网络/凭据等外部阻塞时,Codex 必须明确报告 `LIVE_EVAL_BLOCKED`,而不是宣称真实模型质量已验证;这会阻止把本目标标记为完成。运行有成本,因此开发中先跑相关 `smoke`,但实现完成前必须运行一次无 skip 的完整 `release` suite。
|
||
|
||
## 7. Token 优化目标与实现规则
|
||
|
||
优化优先级是减少无效轮次,其次再压缩每轮上下文;不能通过删除必要的运行时合同或独立复核来换 token。
|
||
|
||
1. 删除新任务的大型 `modeling-plan.md`、它的 parser、一次或多次计划 review 和重写循环。
|
||
2. requirements contract 由最多 8 项的结构化 batch 构成;`requirements.md` / `completion.md` 由服务端渲染,作者不再生成或重写 Markdown。复核通过后,建模循环不再重复发送 `source-requirements.md`,只发送冻结 contract 的紧凑摘要、requirement/claim ID 和未完成状态。最终复核仍发送 source,以防冻结 contract 遗漏源需求。
|
||
3. 每轮作者上下文固定为:冻结 requirements、ID/coverage 摘要、当前模型紧凑测量、pending action 或最近动作摘要、最近一次相关错误、Runtime operation 名称。只在 LLM 调用 `inspect_topology` 后附带当前 selector token bank,只在调用 contract 后附带该 operation 的精确 schema。
|
||
4. 一次 LLM 回合最多执行一个 tool call;每个候选只允许一个 feature。此约束已经存在,必须保留。
|
||
5. tool 结果按结构化摘要持久化,prompt 只保留最新且仍与当前 `working_head` 有关的内容;历史完整证据在工件/账本中按需读取。
|
||
6. `batch_goal`、plan step/action 文本和 author `self_review` 从反复 prompt/调用中删除,改为服务端引用 pending action。
|
||
7. 记录每次 author/reviewer 调用的 provider `usage.prompt_tokens`、`usage.completion_tokens`(支持时)、序列化 context 字符数、工具名、重试原因和缓存命中。没有 usage 的 provider 使用 context 字符数作为次级指标,不伪造 token 数据。
|
||
|
||
验收指标以一组固定代表任务为准:矩形底板、简单法兰、带肋和安装孔的支架、含 selector 的修饰特征。与当前协议对比,目标是:
|
||
|
||
- 计划相关作者/审查调用降为零;
|
||
- 无失败的常规零件中,每一检查点只发生一次作者 fragment 调用和一次独立 candidate review;
|
||
- 无副作用格式错误不进入候选构建、不创建 revision;
|
||
- 因内部异常产生的重复完成调用为零;
|
||
- 总 author+plan-review prompt tokens 的中位数下降至少 30%,同时完成率、最终复核通过率和几何断言通过率不低于基线。
|
||
|
||
30% 是初始验收线,不是凭空承诺。实现前须在现有协议上记录相同任务集的实际 usage,实施后以同一模型、温度、运行时版本和需求文本复测。
|
||
|
||
## 8. 实现范围与顺序
|
||
|
||
### P0:立即修复和回归(可直接实施)
|
||
|
||
- 保留已修复的 `_final_review` `global_violations` 初始化。
|
||
- 让未预期异常进入 `FAILED_INTERNAL`;不要走 `_fragment_diagnostic` 或增加 `no_progress`。
|
||
- 为 `complete_task` 加 revision-scoped idempotency,排除内部/基础设施错误对 `NO_PROGRESS_LIMIT` 的影响。
|
||
- 将 author transport fallback 改为有界状态机:每 provider 有限重试、最多一次 provider failover、全 run 总预算和指数退避;超限后进入 `WAITING_RETRY`,绝不保持 `running` 无限循环。
|
||
- 修复 modeling-plan revision-limit 的后检查控制流,直到 P2 完成前也不得出现“报上限后继续写计划”。
|
||
- 添加最小测试:最终审计全局不变量、内部错误只失败一次、同 revision 完成调用幂等、法兰四位置 `hole_blind` 单 feature 允许、贯穿孔拓扑断言。
|
||
|
||
### P1:文档先复核后冻结(可直接实施,独立于 P2)
|
||
|
||
- 建立 v3 `domain`、`application`、`ports`、`adapters` 包边界与 composition root;先迁移 requirements draft/review 这条窄路径作为样板。新增代码不得继续写入 `AutonomousCdslGenerationRunner`,也不得让 domain import 当前 services/engine/storage。
|
||
- 在 `backend/requirements.txt` 显式加入并锁定兼容的 Pydantic v2 与 LangChain core / 已配置 provider integration 依赖;adapter 需要保留 `raw_arguments_json`(固定 schema 可使用 `with_structured_output(..., include_raw=True)` 或等价 raw tool-call 模式),不能只接收 LangChain 已解析的对象。依赖升级必须通过现有 API、timeout 和 usage 回归测试。
|
||
- 新增 Pydantic `RequirementsDraftBatch`、`RequirementsPatchBatch`、`RequirementsReview` 和空参数 finalize tool,由 `cad_agent/adapters/structured_llm.py` 的 LangChain adapter 调用,并在服务端原始 arguments 上二次验证。每 batch 最多 8 项,禁止 Markdown 写入工具。
|
||
- 在 `TaskRepository` 与 `ArtifactStore` adapter 增加 source index、requirements JSON draft、requirements contract、review 和 render API;不得覆盖冻结 contract 或由 Markdown 反向读入状态。
|
||
- 实现 verifier registry、每种 claim 的 `expected` dynamic `oneOf` schema、registry integrity check 和 `requirements-contract.json` renderer;缺少 verifier 的可测需求必须明确失败。
|
||
- 在 runner 中替换“首次写入即 freeze”为结构化草稿状态机;复核失败有明确修改次数,达到上限时 `WAITING_FOR_USER`,不能无限重试或静默降级。
|
||
- 冻结 contract 后一次性生成 `requirements.md`、`completion.md` 和 `requirements-index.json`。
|
||
|
||
### P2:以单动作协议替换建模计划(主要改动)
|
||
|
||
- 实现第 6.6 节的 finite state machine、typed command/result、port interfaces、Unit of Work、invocation idempotency、candidate staging/immutable publish 和 transactional outbox;先通过 domain/handler 测试,再接入真实 LLM、runtime 与 UI adapter。
|
||
- 新增固定 Pydantic `NextAction`、`GeometryConclusion`、`RollbackCheckpoint`、`CandidateReview`、`FinalReview`;`autonomous_tools()` 仅暴露第 4.7 节列出的严格结构化工具,移除 `write_modeling_plan`、`skip_satisfied_plan_step`、自由 `self_review` 和 plan 专属字段。
|
||
- 将 `_author_tools()`、`_prompt_messages()`、`_execute_tool()` 拆为 context assembler、LLM turn coordinator 与独立 command handler;candidate metadata、coverage、repair 路径使用 pending action/ledger/claim result,不再读取或写入 modeling plan。handler 不得直接 import file/SQLite/provider/engine implementation。
|
||
- 将 `profile_schema.json` 中的 feature contract 升级为完整 versioned operation contract registry:author param JSON Schema、fragment shape、selector/reference policy、server injection、semantic-preflight 和 verifier binding 都由此处声明。删除 `cdsl_authoring_schema.py`、`cdsl_fragment.py`、`autonomous_cdsl_generation.py` 中按 operation 名称/前缀推断 params、selector 或默认 pattern source 的兜底规则。
|
||
- `submit_cdsl_fragment` 从完整 `feature_atomic_contract` 生成并绑定动态 schema;不得用一个宽松通用模型容纳不同 operation 的 params、sketch、selector、reference 或注入字段。schema 必须使用当前 snapshot 的 token enum,而不是任意 string 后补检。
|
||
- candidate/final 先执行 verifier registry,再调用结构化独立 review;`ReviewGateway` 接收 action card、claim IDs 和只读验证结果,而非 `plan_step`/`plan_action`。requirements review 是独立的 application command handler,不把它伪装成 completion Markdown review。
|
||
- `complete_task` 无参数;最终完成门检查所有 claim、pending action、repair 与最终复核。
|
||
- 增加 provider/model conformance suite 和 `model_capabilities` 持久化;不通过时禁止启动。
|
||
- 设计并实现 SQLite 状态层、账本 append 和幂等事务;文件工件由独立 `ArtifactStore` adapter 管理。
|
||
|
||
### P3:删除旧协议、API 和 UI
|
||
|
||
- 将任务 schema 直接升级为 `3.0`;不实现 `2.0` 迁移器、只读读取器或恢复逻辑。旧任务目录不由运行时扫描、打开或恢复,可在部署前由运维单独归档。
|
||
- 删除 `AutonomousCdslGenerationRunner` 的巨型实现及其 module-global helper 状态;入口仅负责 dependency composition 和发起 `WorkflowCoordinator`。旧 `WorkspaceStore` 不能继续同时是 repository、artifact store、task JSON writer 和状态机。
|
||
- 从 `WorkspaceStore`、runner、API、前端类型和测试中删除 `modeling_plan_*`、plan step/action、`write_modeling_plan`、`skip_satisfied_plan_step` 及其 Markdown parser/reviewer。新协议中不得保留隐藏 fallback、遗留 tool 参数或分支。
|
||
- `GET /v1/tasks/{id}` 和前端 `cad-types.ts` 替换 modeling-plan 字段为 requirements contract/review、claim summary、pending action、action ledger summary 和 protocol version;不再有 completion Markdown review 字段。
|
||
- `agent_service.py`、`cad-stream.ts` 删除“建模计划 / 计划独立复核 / 计划步骤已满足”事件,增加“需求合同独立复核 / 动作选择 / 候选独立复核 / 最终独立复核 / 动作账本”事件。
|
||
- 前端显示事实和状态,不能把 ledger 误显示为 LLM 的未来计划。
|
||
|
||
### P4:验证与发布门
|
||
|
||
- 单元:所有固定 Pydantic model 的 valid/invalid fixtures、每个 Runtime operation 的动态 schema fixture、operation mismatch、stale head、selector ambiguity、single multi-position hole、through topology、每个 verifier、ledger/transaction/idempotency、typed errors。
|
||
- 架构:domain transition table 的全部合法/非法状态边、每个 command handler 的纯 result、port adapter conformance、dependency-rule test、SQLite CAS 冲突、staged artifact crash recovery、outbox 至少一次投递与消费者幂等;不得依赖端到端 LLM run 才发现状态机错误。
|
||
- 集成:每个配置 provider/model 的真实 conformance suite;实现过程中按第 6.7 节调用真实 LLM `smoke`,并在完成前由 Codex 实际执行 `python -m app.cad_agent.evals.live --suite release --require-live`。release 报告必须保存匿名化调用指标与工件路径;分别覆盖成功、格式拒绝、候选拒绝、verifier fail、review service 失败、内部异常。任何 `LIVE_EVAL_BLOCKED`、skip、预算超限或场景失败均阻止发布,不能以 mock/integration test 替代。
|
||
- 回归:全量 `backend` 测试、前端类型/stream 测试,以及不识别旧任务 schema 的拒绝测试。
|
||
- 发布:一次性切换到 v3;部署前停止旧 worker 并归档旧任务目录。上线后删除 v2 plan 生成路径、parser/reviewer 和全部关联测试,不保留 feature flag 双轨或历史工件读取能力。
|
||
|
||
## 9. 主要代码触点
|
||
|
||
| 位置 | 必须修改 |
|
||
| --- | --- |
|
||
| `backend/app/services/autonomous_cdsl_generation.py` | 删除巨型 runner 的业务实现;迁移期间只可作为入口 shim,v3 发布前移除,不能继续承载状态、CAD、LLM、文件和复核逻辑 |
|
||
| `backend/app/cad_agent/domain/*.py`(新增) | 不可变 task/action/revision value objects、workflow state/transition table、operation/claim policy、typed domain result/error;无任何 I/O import |
|
||
| `backend/app/cad_agent/application/*.py`(新增) | command schemas 到 domain command 的转换、command handlers、workflow coordinator、context assembler、Unit of Work 使用;不直接依赖 adapter 实现 |
|
||
| `backend/app/cad_agent/application/llm_contracts.py`(新增) | Pydantic v2 固定 LLM input/output DTO;只负责 schema,不包含 persistence、Runtime 或 transition 规则 |
|
||
| `backend/app/cad_agent/ports.py`(新增) | `TaskRepository`、`ArtifactStore`、`ModelGateway`、`CadRuntime`、`ReviewGateway`、`VerifierExecutor`、`EventPublisher` 等 Protocol 与 typed failure contract |
|
||
| `backend/app/cad_agent/adapters/*.py`(新增) | SQLite/file、CDSL engine、render/review、provider、outbox 的 port 实现;所有外部异常在此映射为 typed adapter error |
|
||
| `backend/app/cad_agent/adapters/structured_llm.py`(新增) | 唯一 LangChain provider adapter;固定 Pydantic 和动态 JSON Schema 调用、原始 arguments 捕获、canonical 二次验证入口、provider capability mapping;不含 CAD 状态机 |
|
||
| `backend/app/cad_agent/evals/live.py`、`backend/app/cad_agent/evals/fixtures/*.json`(新增) | 非交互真实 provider/engine/reviewer release runner、版本化场景/预算/claim fixtures、隔离 SQLite/artifact root、脱敏 report/manifest;`--require-live` 时任何 skip 或 fake adapter 都必须失败 |
|
||
| `backend/requirements.txt`(及实际使用的 lock file) | 显式 Pydantic v2、LangChain core 和对应 provider integration 的兼容范围;不能依赖 FastAPI 间接安装的 Pydantic 版本 |
|
||
| `backend/app/cad_agent/application/requirements_review.py`(新增) | 结构化 requirements review command handler、coverage gate、draft patch feedback;不解析或写入 Markdown |
|
||
| `backend/app/cad_agent/domain/verifier_registry.py`(新增) | claim schema registry、contract integrity、针对 typed verification facts 的纯 deterministic evaluator;启动时拒绝不可用 verifier |
|
||
| `backend/app/services/cdsl_authoring_schema.py`、`backend/app/services/cdsl_fragment.py`、`backend/engine/cdsl_engine/profile_schema.json` | 迁移为 `CadRuntime` adapter 的完整 versioned operation contract、dynamic fragment schema、selector/reference resolver、semantic preflight;删除按 atomic ID 的重复/开放式 author schema 和默认 source 注入 |
|
||
| `backend/app/services/storage.py` | 拆分为 SQLite `TaskRepository`/`UnitOfWork` adapter 与不可变 `ArtifactStore` adapter;加入 invocation、state version、candidate staging manifest、ledger index、outbox;删除 task.json 权威状态和 v2 兼容 |
|
||
| `backend/app/services/visual_review.py` | 迁移为 `ReviewGateway` adapter;action-based candidate/final review,不再承担 requirement 或 completion Markdown review |
|
||
| `backend/app/services/agent_service.py` | delivery/worker adapter,只启动 `WorkflowCoordinator`、记录 usage 并消费 typed result;不得重试内部失败为 author turn |
|
||
| `backend/app/settings.py` | protocol version、文档修订上限、action/context/usage 配置;删除 plan 配置 |
|
||
| `backend/app/main.py` | API 输出 v3 文档审核和动作账本摘要 |
|
||
| `frontend/src/lib/cad-types.ts`、`frontend/src/lib/cad-stream.ts` | 新事件与字段,删除 plan 特有状态 |
|
||
| `backend/tests/*`、`frontend/src/lib/*.test.ts` | 删除 v2 plan 行为测试,新增 P0-P4 回归 |
|
||
|
||
## 10. 需要确认的架构决策
|
||
|
||
以下是本目标已作出的绑定选择,不留作实现期间临时决定:
|
||
|
||
1. **采用 SQLite 作为 v3 可变状态的唯一权威来源。** 当前 `task.json`/`agent-state.json` 的文件读写无法为 checkpoint、pending action、幂等调用和 ledger append 提供真正的原子事务。保留 JSONL 账本和文件工件,但它们不是可变状态源。代价是 `WorkspaceStore` 持久化层重构;这是达到可靠性目标的必要改动。
|
||
2. **不兼容旧任务。** 不应把已有 `modeling-plan.md` 任务转换为 pending action,因为无法无歧义地映射历史计划状态;v3 运行时只识别新协议工件。
|
||
3. **建议把无法可靠消除的需求歧义显式置为 `WAITING_FOR_USER`。** 对“简单法兰”一类可合理假设的请求,LLM 仍可写明假设并继续;只有冲突、关键基准/尺寸导致多种同等合理且会明显改变模型的情况才暂停。
|
||
4. **采用第 6.6 节的六边形边界和显式状态机。** 这不是可选重构或文件整理;不允许以“赶进度”为由把 Runtime/LLM/SQLite 直接重新接回 workflow handler。
|
||
|
||
## 11. 非功能验收
|
||
|
||
实现完成时必须能证明:
|
||
|
||
- 法兰任务不会因 `global_violations`、重复 `complete_task` 或 plan revision limit 失败;最终复核若故障,任务保留 `rev_003` 类的最后健康 checkpoint 和精确错误类别。
|
||
- LLM 看到 requirements、coverage、当前模型和账本摘要后,自己提出“下一动作”;服务端日志可证明它没有自动替 LLM 推导该动作。
|
||
- `hole_blind` 的四个同宿主位置作为一个 action/feature 通过,中心/螺栓通孔通过最终 topology 断言而非仅靠盲孔深度文字。
|
||
- 任意 action proposal 或 CDSL 格式错误均不产生 revision、不改变 active head、不消耗候选构建预算。
|
||
- 每个接受的 checkpoint 都能从 ledger 追到 author intent、真实 atomic/fragment hash、selector snapshot、独立复核和 coverage 证据。
|
||
- 静态 dependency-rule test 证明 domain 不导入 FastAPI、LangChain、SQLite、文件、engine、render 或 settings;application 不导入 adapter 实现。状态迁移只存在于 domain transition table/command handler,API、stream、adapter 和 reviewer 均不能直接写任务状态。
|
||
- 进程在 candidate build、artifact publish、SQLite commit、outbox dispatch 或 stream publish 的任一点终止后,恢复测试均证明:系统要么保留原 checkpoint,要么通过同一 invocation/manifest 完成一次提交;不会出现公开半工件、双 revision、重复 build 或丢失已提交 ledger event。
|
||
- 所有会改变状态、影响 CAD 执行或作为验收依据的 LLM 输出均对应第 4.7 节的一项 canonical schema,并在状态变更前通过 schema、state binding 和适用的 domain validator;不存在 Markdown/自由文本/开放 object 的旁路。
|
||
- 每个 Runtime operation 均通过完整 contract integrity、valid/invalid dynamic-schema fixture、selector/reference snapshot、semantic preflight 和 engine-execution 测试;缺少参数、无参数、草图、非草图、required/forbidden selector 和 nested option 的差异均由 schema 而非 prompt 表示。
|
||
- task 开始前,选定 provider/model 在全部固定 schema 与每个已注册 dynamic operation schema 的真实 API conformance suite 中通过;未通过只报 `MODEL_STRUCTURED_OUTPUT_UNSUPPORTED`,不允许回退为自由文本。
|
||
- 实现目标的 Codex 已实际运行第 6.7 节的无 skip `release` 命令,使用当前配置的真实 author/reviewer 模型、真实 CAD engine 和 v3 状态机完成固定任务集三次重复;结果报告和工件 manifest 可定位,且没有 `LIVE_EVAL_BLOCKED`、失败场景、预算超限或隐藏的 schema/decision rejection。
|
||
- 发布前全部 deterministic claim 必须以当前 revision 的程序化 evidence `pass`;LLM review 只作为 visual/语义的独立补充,永远不能覆盖 `fail` 或 `unavailable`。
|
||
- P4 固定任务集给出实施前后真实调用指标,满足第 7 节的可靠性及 token 目标。
|