25 KiB
U3 r0.4 Reliable First Checkpoint Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: 上传材料后先产生一条真实、有来源的阶段事实;材料检索、模型工具流和失败通知均按可复核边界工作,使慢通道能够逐步帮助普通用户而不展示内部过程。
Architecture: Agent-Native 在流终态阻断不完整工具调用并保留已返回 Usage;Backend 从本任务附件快照提供受限检索兜底,收敛材料任务的首批发布顺序,并以实际终态和可用建议决定是否发交付物选择卡。沿用 r0.3 的 TaskSnapshot、来源与语义守卫、同一张卡和现有 UI 原语。
Tech Stack: Go 1.27、SQLite/PostgreSQL、Agent-Native SSE/runtime、Backend runmgr/runtime、React/Vite/Playwright、Dev make test/make build 与 Gitea CI。
Spec: 已批准的 r0.4 书面设计,Documents 7b21e6d495e99e15c458d608db47c517b2fdc599;r0.3 A01 失败记录。本计划版本仍待阶段 5 人工批准;设计批准不授权代码或新付费模型请求。
Global Constraints
- 保留 r0.3 的来源原文连续短引、owner/project、artifact hash/解析版本、数字/分期/决定状态守卫和 CAS;旧结果不追溯改写。Core 候选契约、TaskSnapshot 持久字段、数据库表和生产模型路由不变。
- 只沿现有三栏、同一张任务卡和“材料记载/待核对的判断/待确认”分层呈现;默认不展示模型调用、命令或原始 SSE。UI 变更先读 Dev
DESIGN.md,只用@ui令牌与原语,事件按 seq 丢弃过期项。 - 不增加独立摘要、审核或自动修复模型;自然工具回合仍受每 run 的轮数、工具数、300 秒及返回 Usage 边界约束。工具拒绝、缺 Usage 或额度耗尽后不得追加 provider 请求。新付费 A01 必须单独审批,不沿用 r0.3 的额度或标签。
- 旧 r0.2 语义 FAIL 与 r0.3 执行 FAIL 保留。新 A01 仍须两个真正有用、终态前可感知的不同阶段成果和完整准确正文;来源字面匹配、单测、假流或绿色 CI 均不能代替这项真实模型质量出口。
- Agent-Native、Backend、Documents、Dev 各在自己的任务分支提交;不要直接编辑 Backend 内嵌的 detached Agent-Native 后把本地文件当已交付。新 Agent-Native PR 是现有六个草稿 PR 的依赖,固定指针和合入顺序为 Agent-Native → Backend → Dev。
- 启动/恢复、
make evidence、task-sync、Review、当前 HEAD CI、阶段 6/7 人工结论和安全回收遵循 DevAGENTS.md与policy/delivery.md。本计划只申请零付费实施与验证;不得从计划批准推导新模型资源或部署授权。
Review Focus
- 看似正常的
tool_calls结束原因但没有[DONE]: 不得执行任何工具,返回不可自动重试的失败,已返回 Usage 仍计入预算。Task 1 的TestParseSSEToolFinishWithoutDone和TestRunTerminalToolFailureKeepsUsage钉住。 - 同名附件或其他 owner/project 的知识命中: 文件名兜底必须拒绝歧义和越界,不将其他人的材料带入当前任务。Task 2 的
TestMaterialAttachmentFallbackScope钉住。 - 本次附件注册后原件被替换: 同 artifactId 的旧解析快照和索引不得继续供模型读取。Task 2 的
TestMaterialAttachmentFallbackVersionDrift钉住。 - 后台失败但旧阶段发现已保存: 卡保留已验证发现并明确未完成,不出现“全部完成”或交付物选择卡。Task 4 的
TestFailedMaterialNoticeKeepsPartialFindingsWithoutChoice钉住。 - 后台成功但没有实际建议项: 不生成默认四选项,也不触发弱模型选择卡兜底;让用户自由说明下一步。Task 4 的
TestMaterialNoticeWithoutSuggestionsDoesNotNudge钉住。
文件与交付顺序
| 单元 | 主要文件(均相对于对应组件仓根目录) | 单一职责与可独立验证的产物 |
|---|---|---|
| Agent-Native 流终态 | runtime/llm/{types,sse,sse_test}.go、runtime/{loop,loop_test}.go |
完整工具调用才可执行;错误保留 Usage、不可自动重试。单独 Agent-Native PR。 |
| Backend 材料检索 | internal/runmgr/{runmgr,material_retrieve,material_retrieve_test}.go |
仅本次材料子任务从唯一附件快照兜底,拒绝歧义、越权和版本漂移。 |
| Backend 首条发布 | internal/runmgr/{material,material_test}.go、internal/runtime/{work_checkpoint,work_checkpoint_test}.go |
v11 配方和一条短事实优先;不伪造发现、不增加独立模型回合。 |
| Backend 失败交互 | internal/runmgr/{runmgr,material_test}.go、internal/runtime/{verify,llm_direct,material_flow_test}.go |
成功且有实际建议才发选择卡;失败和无建议不强制选择。 |
| Backend 评测与组合 | internal/server/{work_checkpoint_eval_test,work_checkpoint_eval_budget_test}.go、eval/live/work_checkpoints_test.go、modules/frontend/e2e/work-checkpoints.playwright.ts(从 Dev 根目录) |
诊断元数据、预算停止、实际 HTTP/浏览器和固定组合证据。 |
以上单元紧扣同一材料整理链路,接口按表格顺序依赖;暂不拆成互不关联的新项目。UI 仅在实际浏览器证明现有失败文案不足时修改 Frontend/UI,届时在同一任务卡记录影响并重跑各自设计守护;不预设新增组件。
Task 1: Agent-Native 完整工具终态与 Usage
Files: Agent-Native runtime/llm/types.go、runtime/llm/sse.go:53-180、runtime/llm/sse_test.go:65-155、runtime/loop.go:320-360、runtime/loop_test.go。
Interfaces: 扩展内部 llm.Event 的 StreamComplete bool;对不完整工具调用发一个含 Usage、StopReason=StopError、非空 Err 且无 ToolCalls 的 KindMessageEnd。runtime.Run 计入该终态已返回 Usage 后以不可重试错误结束;Backend 既有逐调用 wrapper 仍能从 KindMessageEnd 计量。普通文本和合法完整工具调用保持原行为。
- Step 1: 建 Agent-Native 隔离分支并写 RED。 从其权威
origin/main建feature/fast-slow-u3-r04-stream-guard(不要在 Backend 的 detached gitlink 上写);在sse_test.go增加两例:tool_calls结束但无[DONE],及有[DONE]但参数停在"findings":。使用与既有TestParseSSEToolCallIncrements相同的 SSE 输入写法,断言:
if end.Kind != KindMessageEnd || end.Message.StopReason != StopError ||
len(end.Message.ToolCalls) != 0 || end.Err == nil || end.Retryable ||
end.Usage.TotalTokens != 17 {
t.Fatalf("unsafe incomplete terminal: %#v", end)
}
同时在 loop_test.go 用假 stream 发上述错误终态(Usage 17),工具处理器计数必须为 0,res.Err != nil、res.Usage.TotalTokens == 17、没有第二次 provider 调用。
-
Step 2: 重放 RED。 在 Agent-Native 根运行
GOWORK=off go test ./runtime/llm ./runtime -run 'TestParseSSEToolFinishWithoutDone|TestParseSSEInvalidToolArguments|TestRunTerminalToolFailureKeepsUsage' -count=1;记录预期失败的原始 SELF 收据,不能把旧TestParseSSEUncleanEndDropsToolCall当作已覆盖finish_reason=tool_calls的情况。 -
Step 3: 最小 GREEN。 在
emitParsed拼完工具片段后要求sawDone、受支持结束原因、每个非空 ID/名称及可解为 JSON 对象的参数;不完整时构造错误终态,不修补参数。实现形状:
func terminalToolFailure(content string, usage Usage, reason string, complete bool, why string) Event {
err := &StreamError{Message: why, Retryable: false}
return Event{Kind: KindMessageEnd, Message: Message{Role: RoleAssistant,
Content: content, StopReason: StopError}, Usage: usage,
FinishReason: reason, StreamComplete: complete, Err: err,
ErrorMessage: why, Retryable: false}
}
runtime.Run 在现有 Usage 累加之后、工具执行与 stop-hook 之前,遇 end.Err != nil 即返回 Result{StopReason: llm.StopError, Usage: usage, Err: end.Err, Retryable: false};更新与新语义相冲突的旧 length/断流测试预期。KindToolCallDelta 可以作为过程事件,但不得据此执行工具。
-
Step 4: 跑 GREEN 与正常回归。 运行定向测试、
GOWORK=off go vet ./...、GOWORK=off go test -count=1 ./...,另断言合法多片工具调用和无工具正常文本仍 PASS。用make evidence保存完整 SELF 输出;审阅返回 Usage 的终态错误不会被上层误报为成功,也不会触发 LLM 自动重试。 -
Step 5: 提交并开草稿 PR。 仅提交本任务 Agent-Native 文件;英文祈使句主题、
Why/Evidence/Impact/Refsbody。推送该组件分支并记录准确 SHA 和草稿 PR,不修改其main或发布版本。
Task 2: Backend 只读、限域的附件检索兜底
Files: Backend internal/runmgr/runmgr.go:966-1018;新建 internal/runmgr/material_retrieve.go、internal/runmgr/material_retrieve_test.go;必要时复用 task_projection.go:358-370 的原件 hash 检查。
Interfaces: func (c *runCtx) materialAttachmentFallback(q core.RetrievalQuery) ([]core.RetrievalHit, error) 仅在 c.subAgent == materialSubagentID、正常检索成功但零命中时调用;消耗 c.attachments(startBackgroundSlot 已从受信 bgSpawnOpts.documents 固定),不得从客户端 query 中取 artifactId 作权限。返回的每条 hit 的 Doc.Ref 必须等于当前任务唯一附件 artifactId。
- Step 1: 写 RED 与版本负例。 用
newCardSpawnEnv、materialDocs()及真实 SQLite knowledge/artifact fixture,让本次 A01 的需求.txt 上线 预算 验收 接口在当前常规路径零命中,而兜底应找到当前任务的需求.txt;重复文件名、另一 owner/project、同 ID 原件内容修改和Task.Inputs中 hash/解析版本不匹配时,兜底必须零命中或返回不含旧正文的明确错误。核心断言:
if len(got) != 1 || got[0].Doc.Ref != string(docs[0].Meta.Origin.ArtifactID) ||
got[0].Doc.ProjectID != rc.run.ProjectID ||
got[0].Doc.Owner != rc.run.Owner {
t.Fatal("material fallback crossed the task boundary")
}
-
Step 2: 重放 RED。
go test ./internal/runmgr -run 'TestMaterialAttachmentFallbackScope|TestMaterialAttachmentFallbackVersionDrift|TestMaterialAttachmentFallbackQuery' -count=1,记录每例失败原因,不用未授权共享知识充当正例。 -
Step 3: 实现受限兜底。 从
q.Text识别恰好一个当前附件文件名;核对该 origin artifactId/hash/解析版本与card.Task.Inputs;经GetArtifact(owner,id)、ArtifactContent(owner,id)和项目 ID/sha256 再读确认后,从本次ParsedDocument快照构造有限RetrievalHit(Source=upload、Ref=artifactId)。若查询有其余词,优先返回包含这些词的有界原文片段;仅文件名时返回尚未内联的部分或当前文档的有限原文,最多遵守现有MaxToolResultChars。在runCtx.Retrieve的正常结果为零、错误为 nil 时调用:
if err == nil && len(hits) == 0 && c.subAgent == materialSubagentID {
return c.materialAttachmentFallback(q)
}
return hits, err
不得改变通用检索的 FTS/LIKE、共享授权或其他子代理结果;重名和版本证明失败时 fail closed,不猜测最相近文件。
-
Step 4: 跑 GREEN、权限与存储回归。 运行上述三例、
go test ./internal/runmgr ./internal/store -count=1,再在任务自有 PostgreSQL 上重放材料兜底与权限负例;相同文档多段、中文关键词和超长结果必须保持有限输出。记录被测 Backend SHA、数据库实例及 SELF 收据。 -
Step 5: 提交 Backend 检索单元。 只提交本任务文件并核对
git diff --check;此时仍未改变阶段提示或失败交互,单元测试可独立审阅。
Task 3: 首条有来源事实优先,配方 v11
Files: Backend internal/runmgr/material.go:88-132,286-303、internal/runmgr/material_sources.go:144、internal/runmgr/material_test.go、internal/runtime/work_checkpoint_test.go。
Interfaces: 不改 WorkCheckpointCandidate 或 publish_work_checkpoint JSON 契约。buildMaterialTaskFor 在已有实质内联片段时要求首个 reading 工具调用只含一条 material_record、当前 sourceId/blockIndex/quote;第二阶段沿 r0.3 evidence 守卫产生新的差异/待确认。材料输入修订从 material-recipe.v10 改为 material-recipe.v11,旧完成卡只读保留。
- Step 1: 写 RED。
material_test.go用三份完整内联 A01 和一份空/不可读材料分别断言:前者任务指令明确“首条一项短事实、先于检索”;后者不要求凑发现。work_checkpoint_test.go的假流先发布原文事实、再可选检索、后发布不同的 crosscheck 条目,核对运行中卡片 seq、两批不同 findingKey/来源及最终正文;再用无效 sourceId 断言整批零提交。关键检查形状:
if first.Task.CheckpointSeq != 1 || second.Task.CheckpointSeq != 2 ||
first.Task.Findings[0].Kind != "material_record" ||
second.Task.Findings[1].Kind != "needs_user" {
t.Fatal("reading and crosscheck did not remain distinct")
}
-
Step 2: 重放 RED。
go test ./internal/runmgr ./internal/runtime -run 'TestMaterialFirstFindingBeforeOptionalSearch|TestMaterialNoForcedFindingWithoutSource|TestWorkCheckpointTwoUsefulPhases' -count=1。如果假流只证明宿主接受顺序、无法证明真实模型会遵循,明确在任务卡标“机制 PASS / 模型 NOT_RUN”。 -
Step 3: 最小 GREEN。 把材料任务的首条指令放在长篇最终正文要求之前,避免模型先写完整计划或做已提供材料的冗余检索;提示只要求一条已提供原文短引,不复制全部来源索引或增加新工具。实现形状:
task = "先从已提供的实质原文发布一条 reading 材料记载:只写一项,附当前 sourceId、blockIndex 和连续短引;发布成功后再按需检索、核对差异和形成完整正文。\n\n" + task
空文本或只有处理警告时不追加强制首条要求;将配方常量更新到 v11。Host 不凭规则自行合成内容,模型未按顺序调用时如实失败或继续原有受控流程。
-
Step 4: 跑 GREEN 与预算体积检查。 运行前述定向测试和 Backend
go test ./... -count=1;离线比对 v10/v11 任务提示及工具 schema UTF-8 字节和粗估 token 增量,不能将粗估当真实 Usage。补测旧 r0.3 数字、决定、来源及 CAS 回归。 -
Step 5: 提交 Backend 首条发布单元。 仅提交提示、配方与相关测试,记录“优先顺序不等于模型质量保证”的限制。
Task 4: 失败通知按终态与建议可用性分流
Files: Backend internal/runmgr/runmgr.go:2254-2400、internal/runmgr/material_test.go:198-230、internal/runtime/verify.go:34-44、internal/runtime/llm_direct.go:148-161,634-648、internal/runtime/material_flow_test.go:146-225。
Interfaces: materialChoiceReady(bgNotice, core.ActivityCard) bool 仅在 material && Status==completed、任务卡确有可用最终正文且正文“建议后续处理”包含 3–4 条带依据的真实选项时为真。只有该路径加入新的内部 materialChoiceReadyMarker 并开启 stop 兜底;失败、取消、零成果及成功但无建议时只投递状态/恢复说明,保留已经持久化的旧发现,不出现默认四选项。
-
Step 1: 写 RED。 扩展
TestMaterialNoticeContract:失败零成果、失败但卡已有一条合法 finding、取消、完成但无建议、完成且有 3 条建议。前四种系统提醒均不得含confirm_choice/ready marker;第五种仍含两者。material_flow_test.go加失败及无建议通知回合,断言不会产生 HITL 或materialNoticeBackstopReason,成功有建议仍生成选择卡。 -
Step 2: 重放 RED。
go test ./internal/runmgr ./internal/runtime -run 'TestMaterialNoticeContract|TestFailedMaterialNoticeKeepsPartialFindingsWithoutChoice|TestMaterialNoticeWithoutSuggestionsDoesNotNudge|TestMaterialNoticeChoiceChain' -count=1;保存失败原件。 -
Step 3: 最小 GREEN。 从
bgNotice.payload.Status、任务卡Task.OutcomeCompleteness/结果和正文里的实际建议列表判断选择资格;只接受“建议后续处理”标题下 3–4 个非空选项,每项有材料依据文本。保守解析失败时提示用户自行说明目标,不生成虚构选项。verify.go用与“已结束”不同的内部 ready marker;llm_direct.go只按该 marker 设置st.materialNotice。实现门槛示意:
func materialChoiceReady(n bgNotice, card core.ActivityCard) bool {
return n.material && n.payload.Status == core.RunCompleted &&
card.Task != nil && card.Task.OutcomeCompleteness == "complete" &&
len(parseMaterialSuggestions(n.payload.Text)) >= 3
}
若当前 Task 的实际完成枚举或结果落点不同,以 core.TaskSnapshot 的现有定义修正该判断并在同一测试证明;不要硬编码“状态:completed”字符串。通知正文和终轮兜底保持一致,失败时不再要求 delegate_task 基于不存在的建议启动工作。
-
Step 4: 跑 GREEN。 重跑定向测试、
go test ./internal/runmgr ./internal/runtime ./internal/cardsvc -count=1和正常完成链;检查旧阶段发现/失败终态的持久事件没有被新通知写成成功。所有结果由make evidence写入任务卡。 -
Step 5: 提交 Backend 失败交互单元。 只提交相关文件和测试,通知文字使用普通用户能理解的状态,不输出 tool/JSON/Usage 细节。
Task 5: 评测诊断与停止规则零付费重放
Files: Backend internal/server/work_checkpoint_eval_test.go:347-455、internal/server/work_checkpoint_eval_budget_test.go:201-300、eval/live/work_checkpoints_test.go:146-295;Agent-Native runtime/llm/types.go 提供 Task 1 的 StreamComplete。
Interfaces: 评测逐调用记录增加 finishReason、streamComplete、toolArgumentBytes、toolArgumentsValid 和 usagePresent;原有 run ID、调用数、reported Usage、输出上限保留。诊断字段不含 API key 或原始 SSE;KindMessageEnd 的错误终态仍计入 Usage,任一检查点拒绝或缺 Usage 后零后继 provider 请求。
-
Step 1: 写 RED。 用本地
httptestSSE 服务分别发送“合法工具调用”“有tool_calls、已返回 Usage、缺[DONE]”“有[DONE]但参数半截”“无 Usage”四种结果;每次从全新隔离 SQLite 和 0 个既有 run 开始。断言坏结果后第二次请求没有到达服务端、记录 Usage 如实、toolArgumentsValid=false、结果卡为失败。不得调用外部模型。 -
Step 2: 重放 RED。 在 Backend 根运行
go test -tags live ./internal/server -run 'TestEvaluationStopsAfterMalformedToolTerminal|TestEvaluationKeepsUsageOnTerminalFailure' -count=1;在eval/live用go test -tags live ./eval/live -run 'TestFollowupA01KeepsItsOwnOneShotResult|TestPersistedRunningCheckpointMaxDoesNotMissShortWindow' -count=1保留既有零付费结果名与窗口回归。TestWorkCheckpoints必须保持NOT_RUN,此步不提供模型实例或路由。 -
Step 3: 最小 GREEN。 从 Task 1 的终态字段和每个
ToolCall.Arguments的json.Valid生成诊断布尔值;错误终态的Usage必须先进入reportedTokens与 provider record,再向 runner 发出非重试失败。评测 wrapper 增加批次级terminalFault,遇此错误后与checkpointRejected/usageUnknown一样拒绝所有后继 provider 请求;即使直接再次调用 stream,也只返回本地错误。不要把失败伪装成正常message_end或用下一轮模型修补参数。 -
Step 4: 跑 GREEN 与上限。 运行上述 live-tag 假 provider 集及
go test ./internal/server -count=1;eval/live只用上述-tags live -run选择零付费用例,避免无 manifest 时误执行TestWorkCheckpoints。核对每 run 30,000 配置、8轮/12工具/300秒、单次输出4,000、整批返回 Usage 停止目标的既有逻辑未变。对失败和正常路径分别保存 SELF 收据。 -
Step 5: 提交 Backend 评测单元。 记录新诊断只证明机制,不能把旧 r0.3 A01 或未运行的 r0.4 模型质量改判。
Task 6: 固定组合、真实浏览器、复审与资源出口
Files: Dev modules/backend、modules/documents gitlink、.task/feature-fast-slow-u2-u3-plan.md、PROJECT.md;Backend deps/agent-native gitlink;视需要 Frontend e2e/work-checkpoints.playwright.ts(若 UI 确需文字调整,再列明 Frontend/UI 文件和设计守护)。
Interfaces: 对外的 TaskSnapshot、卡片事件 seq 和来源跳转保持现有契约。各组件分支自己的 commit/PR 是唯一交付对象;Dev 组合 pin 明确 Core、Backend、Frontend、UI、Documents、嵌套 Agent-Native 的 SHA。
-
Step 1: 固定依赖与 RED/GREEN 组合。 先把 Agent-Native 草稿 PR 的准确 SHA 固定进 Backend gitlink,在 Backend 跑
GOWORK=off go test ./...;提交/推送 Backend。Dev 再固定 Backend 与已批准计划 Documents SHA,跑RECEIPT=/tmp/fast-slow-u3-r04-20261014-combo-implementation.json CMD='make test && make build' make evidence(该路径必须尚不存在;若已占用,选新的带序号绝对路径,绝不覆盖),导入原始收据并提交/推送 Dev gitlink。任何 pin 漂移、活动 Git 锁或其他工作区未保存内容均停止,不强删锁或覆盖。 -
Step 2: PG 与 HTTP/浏览器。 启动本任务独有 PostgreSQL 和 HTTP 假流实例;manifest 记录 PID、二进制 SHA、Dev/Backend/Agent-Native SHA 与数据目录,测试前验证绑定。PG 重放 runmgr/cardsvc/store;
PLAYWRIGHT_BASE_URL指向受验 manifest 的本地地址后运行e2e/work-checkpoints.playwright.ts,覆盖两次 running 阶段、零成果失败、部分成果失败、成功建议选择、刷新和来源版本变化、后台不抢文件/焦点。只停止任务自有进程并保留 trace。 -
Step 3: 独立 Review 与正式固定。 在请求审核前、验收前及合入前分别按 Dev
AGENTS.md用CMD='make task-sync' make evidence同步最新权威 main;同步改变 base/head 或组件时按影响重跑组合、PG、浏览器和代码复审。独立审阅者对 Agent-Native 流边界、检索权限/版本、成功/失败通知、预算停止、UI 状态投影和计划范围作最小重放;不能把作者 SELF 升格为 REPLAY。Dev 当前 HEAD 的test、test-pg、svc-realcombo与 Agent-Native/Backend/适用 UI 的必需 CI 必须核对实际 SHA、runner 和所有步骤。 -
Step 4: 阶段 6 与模型资源分开审阅。 将零付费候选、独立 Review、精确 HEAD CI 和实际浏览器结果交用户确认阶段 6;只有候选固定且用户另行批准一次性资源提案后,才能用原 A01 材料、受保护路由、全新 0-run 数据目录和独立输出名运行真实模型。提案必须列明最多付费 run、单 run token/轮/工具/时间、批次返回 Usage 目标、输出 cap、在途超额风险、停止规则及不自动重试;本计划不预填或授权新的用量数字。
-
Step 5: 依据真实结果决策。 只读重放 SQLite、逐调用 Usage、运行中卡片窗口、每条短引及逻辑归属、完整正文;任何 FAIL 保留所有相关 PR 草稿,不自动重跑或合入。质量 PASS 后仍须阶段 7 人工验收,随后按 Dev 策略完成 Agent-Native → Backend → 其他组件 → Dev 的独立 Review、准确 HEAD CI、串行 PR 合入、合入后内容核验、任务卡闭合和安全回收;未获阶段结论时写 NOT_RUN,不能提前标完成。
计划自检与停止条件
每个实现单元的 RED、GREEN、独立审阅、失败原件和版本都进入同一 Dev 任务主记录;Documents 设计/计划仅作引用,不复制第二份状态。局部代码修复若只改变等价实现,在已批准阶段内按影响补测;若改变工具公开契约、权限、模型调用数/预算、阶段验收条件或组件职责,回到设计/计划人工评审。真实模型样本一旦缺 Usage、检查点拒绝、预算停、输出不完整或语义错误,停止后续请求,保留原件并报告,不通过“再试一次”抹平失败。计划获批后才开始 Task 1;目前 Task 1–6 均 NOT_RUN。