Status: active Scope: six-step execution model, evidence states, Steps 4-6 / fail2pivot boundary Owner:
nexrur.enginesRelated:DESIGN_五桶证据.md,DESIGN_DIAGNOSIS.md,DESIGN_ENGINES_CAMPAIGN.md,DESIGN_AISKILLS.mdTracking:dakoolfrank/nexrur#95
1. 定位
本文冻结 nexrur 的六步执行模型,以及 Steps 4-6、fail2pivot、AI-skills trace、 active promotion、campaign execution 之间的顺序边界。
它不是新的 engine,也不是替代 diagnosis / campaign / evidence / projection 设计文档。它只回答一个问题:
一个 app/subagent/module 从 evidence 到 production,再到失败治理,底座按什么顺序调度?
2. 六步模型
六步模型固定为:
1. Evidence
2. Product
3. Schema
4. Re-evidence
5. Diagnosis
6. Campaign
含义:
- Step 1 Evidence 收集、压缩并组装 Product 输入;facts / digest / obligations 是 Evidence 内部组成,不是三个顶层 Step。
- Step 2 Product 生成业务结果,并拥有本轮 Product status/reason/reason_code。
- Step 3 Schema 机械验证 Product,不做 root-cause / route。
- Step 4 Re-evidence 在 Product + Schema 落盘后重新组装 Diagnosis 输入。
- Step 5 Diagnosis 解释事实并生成
diagnosis_result。 - Step 6 Campaign 消费 Diagnosis 并生成
campaign_control。 fail2pivot = Step 5 Diagnosis + Step 6 Campaign;它消费 Step 4 Re-evidence,但 Re-evidence 本身不属于 fail2pivot。
程序只负责证据、合同、落盘和调度;业务解释交给 diagnosis,执行控制交给 campaign。
2.1 Product 返回即封存
Step 2 Production 一旦返回 Product,本 cycle 的 Product 事实即封存。这里的 “封存”是字段所有权约束,不是新增 envelope、receipt、hash、文件或第二条 Product 总线。
Production 拥有并封存的字段包括:
status / reason / reason_code / failure_kind
artifact_refs / evidence_refs / warnings / errors
以及 producer 明确返回的其他业务字段
后续步骤必须遵守:
- Step 3 Schema 只追加机械校验 finding。
- Step 4 Re-evidence 只追加诊断证据。
- Step 5 Diagnosis 只写自己的
diagnosis_result/result_code。 - Step 6 Campaign 只写自己的
campaign_control/result_code。 - Orchestrator 和 Parent 只追加执行坐标、运行事实及控制回执,并原样传递 Product。
Product 已经存在后,如果 evidence handoff、projection、active promotion、identity check 或其他 runtime/infrastructure 动作失败,该失败可以停止当前执行图,但只能 进入独立的 execution/runtime incident channel;不得用执行失败的 status、reason 或 code 覆盖 Product。只有 Campaign 在新 cycle 中重跑拥有该 Product 的 Production,且 producer 返回新结果,Product 才可能改变。
3. Evidence State
底座 evidence state 固定为三种:
evidence
step6_evidence
restart_evidence
对应 envelope:
envelopes/evidence.json
envelopes/step6_evidence.json
envelopes/restart_evidence.json
对应 digest lane:
digest/evidence/
digest/step6_evidence/
digest/restart_evidence/
规则:
evidence是 Step 1 输出,也是正常首轮 / 顺跑 Product 输入。step6_evidence是 Step 4 Re-evidence 在 Step 2 Product / Step 3 Schema 已落盘后生成、供 Step 5 Diagnosis 消费的现有物理 envelope 名。restart_evidence是 campaign 接受 repair/restart 后下一次 attempt 的输入。 它进入下一 cycle 的 Step 1 Evidence,不构成第七步。- 如果 restart target 是当前 campaign-owned trace 的任意 orchestrator 阶段,
下一次 attempt 必须是同一
trace_id下的新cycle_no/cycle_segment。 - 新
trace_id只来自新的 CLI campaign 或 campaign 内新的 asset attempt。 restart_evidence不得追加到已经完成的旧 cycle;它必须写入新 cycle 的 独立 lane。
4. Steps 4-6 / fail2pivot 顺序
Steps 4-6 的底座执行顺序固定为:
Step 4 Re-evidence -> step6_evidence
-> Step 5 Diagnosis -> diagnosis_result
-> Step 6 Campaign -> campaign_control
-> trace.py 写 step6.json
-> campaign execution
解释:
- Step 4 Re-evidence 产出
step6_evidence,作为 Diagnosis 输入。 - Step 5 Diagnosis 产出
diagnosis_result。 - Step 6 Campaign control builder 消费
diagnosis_result和 app campaign assets, 产出campaign_control。 trace.py把 Steps 5-6 结果写入当前 trace/cycle 的envelopes/step6.json。- campaign execution 根据
campaign_control执行 restart / halt / route。 - 只有整个 subagent product graph 成功关闭时,orchestrator 才调用
nexrur_projection_active,把完整 cycle 投影到 active。
fail2pivot.py 只组合并执行 Step 5 Diagnosis 与 Step 6 Campaign control
生成;它不重新执行 Step 4 Re-evidence,也不把 Evidence 内部子阶段提升为顶层 Step。
Steps 5-6 的 code 命名空间固定分离:
production_result.reason_code
-> producer-owned Product 事实,后续层只读并原样保留
diagnosis_result.result_code
-> Diagnosis 对事实的独立分类,不是 Product reason
campaign_control.result_code
-> Campaign 消费并携带的 Diagnosis route key
step6.execution_result_code
-> Steps 5-6 自身执行结果,例如 diagnosis unavailable;不是 Product reason,
也不是 Diagnosis 分类或 Campaign route key
diagnosis_result 和 campaign_control 中禁止出现 Diagnosis
reason_code 兼容字段。Campaign 不得用 production_result.reason_code 作为
result_code 的 fallback;fail2pivot、Steps 5-6、child graph 和 parent graph 也不得
把 result_code 提升或改写成 Product reason_code。
Steps 5-6 自身失败时仍然遵守同一边界:diagnosis_unavailable、
prompt_a_failed、golden_no_eligible_cards、campaign_handoff_failed、projection
failure 等只能进入 step6.execution_result_code、对应组件的
execution_status 或 errors。它们不得写入、覆盖或替换
production_result.reason_code。如果 step6.json 为兼容投影保留顶层
reason_code,该字段只能是原 Product reason_code 的原样副本或空值,不能承载
Step6 执行码。Parent handoff 同样必须传播原 Product code,而不是选择 Step6
执行码作为新的 Product 原因。
关键边界:
campaign_control已生成,不等于 campaign execution 已完成。step6.json是本次失败/restart 的 Steps 5-6 诊断与控制真相;失败 cycle 不更新 active。- restart evidence 同时读取本次 Step6 trace 和 last-known-good active,不能把失败 cycle 冒充业务成功快照。
graph_role=module的嵌套模块只落本模块 Steps 4-6 现场,不发布共享的父级 active;父级 active 只由完整 subagent graph 成功收口后统一晋升。- 当前 cycle 没有真实业务文件,或完整 product graph 未成功关闭时,不得发布, 也不得覆盖上一版 active。
- 如果
campaign_control.status是restart_requested、halt或escalation_requested,fail2pivot 必须在 trace + active 完成后返回一个 非 completed 图状态,让 orchestrator 停止继续普通 downstream 并把控制权交给 campaign。 - 如果
campaign_control.status=continue_with_repair,fail2pivot 必须返回partial,而不是伪装成success。partial是 orchestrator 的 completed dependency status:当前 graph 继续执行 downstream,但 Steps 5-6、checkpoint、 active 和 Admin 仍保留问题与待修复目标。 - 如果
campaign_control.status是continue、no_failure或同类无需修复的 状态,fail2pivot 才返回 success,让 orchestrator 正常继续 / 完成。
4.1 Production-wide non-blocking partial
partial 不是 Mirror 特例。任何 Step 2 Product leaf、nested module 或
subagent 都必须能用同一份结果合同报告“已有可用业务产物,但仍有质量问题”:
status: partial
reason_code: <producer-owned factual reason or empty>
failure_kind: <factual class or empty>
errors: []
warnings: []
artifact_refs: [<real usable business artifacts>]
evidence_refs: []
该合同的固定语义是:
partial+ 真实可用artifact_refs是非阻断质量事实,不是 success,也不是 restart 指令。- Production 只报告自身事实和 refs;不得决定
continue_with_repair、target、 restart 或 halt。 - Orchestrator 把
partial视为已完成依赖,继续执行剩余 Product 工作、Step 3 Schema、Step 4 Re-evidence、Step 5 Diagnosis 和 Step 6 Campaign;不得因为 上游不是success就制造*_upstream_result_failed二次误诊。 - Step 4 Re-evidence 必须把该问题收入
phase_issue_facts并设置requires_diagnosis=true。Step 5 Diagnosis 必须解释,Step 6 Campaign 必须 给出正式控制结果。 - Diagnosis 判断为可延后修复且
campaign.yml存在合法continue_with_repair路由时,当前 graph 继续,repair target 留在当前campaign_control/ checkpoint 中供后台处理。 failed/blocked,或声明的业务产物不存在、不可读、不可作为本轮交付时, 仍是阻断事实,必须进入 restart / halt / escalation,不得借partial放行。
因此,非阻断不是 Python 对某个 reason code 的硬编码,也不是绕过 Diagnosis:
Production partial
-> Step 4 Re-evidence phase_issue_facts
-> Step 5 Diagnosis result_code + non_blocking_repairable intent
-> Step 6 Campaign continue_with_repair
-> fail2pivot partial
-> downstream continues; repair remains visible
4.2 Nested / outer Re-evidence 的物化复用边界
nested module 和 outer subagent 都必须完整执行自己的 Step 4 Re-evidence。两层的
production、schema、runtime、phase facts 和 diagnosis scope 不同,因此禁止跨层复用
完整 facts bundle、digest、obligations、handoff 或
diagnosis_evidence_packet。
但 Step 4 重新运行不等于相同 upstream 文件必须重复物化。对于相同的 upstream source group,底座只允许复用其物理 raw copy / inventory refs:
Mirror Step 4
-> 独立组装 Mirror Re-evidence
-> raw_evidence source receipt miss
-> 一次 batch projection,写入 raw_evidence inventory
Outline Step 4
-> 独立组装 Outline Re-evidence
-> 相同 raw_evidence source receipt hit
-> 复用 inventory refs
-> Outline production/schema/runtime facts 仍重新收集与组装
复用判断必须按:
state + source_id + target subtree + source fingerprint
不同 source id 必须分别判断;不能对整个 upstream lane 共用一个大 fingerprint。
source fingerprint 不得包含 run_id / step_run_id,完整 Evidence cache 则继续保留
这些 scope identity。两套机制不能合并。
物化必须通过 projection 的 write_aiskills_bundle 一次提交 batch;运行 receipt 写入
docs/ai-runs/.engines/.projection-materialization/,不得进入业务 aiskills、
envelope、artifact/evidence refs 或 active。详细 fingerprint、临时目录、逐项
os.replace、completed receipt 与 hash 校验协议,以 DESIGN_五桶证据.md 和
DESIGN_AISKILLS.md 为准。
该优化只改变底座物理写入与复用方式,不改变六步顺序、Step 4 输入范围、Step 5 Diagnosis 或 Step 6 Campaign 语义,也不得通过增加 ToolLoop timeout 代替修复。
同一 trace/cycle 内 nested Step 4 首次提交 source group 时,receipt 必须记录目标文件 hash、size 与 mtime。outer Step 4 对未变化目标只做边界、数量和 size/mtime 快速校验; 元数据变化才回退到 SHA-256。source inventory 已取得的 stat 事实必须复用,禁止 reader 为了 fingerprint 再做一轮逐文件 resolve/stat。该快速路径只减少重复 I/O,不复用两层 各自的 facts bundle、diagnosis scope 或完整 Evidence cache。
如果 upstream source 有 canonical manifest,首次 Step 4 还必须写 source-inventory receipt;同一 trace/cycle 的后续 Step 4 只验证该 manifest marker 并复用逐文件 inventory facts。这样 nested 与 outer Step6 都仍独立执行,但不会在每层再次递归扫描相同原始资料。
5. step6.json 的含义
step6.json 是 Step 5 Diagnosis + Step 6 Campaign 的组合结果落档,可以包含:
diagnosis_result:
execution_status: success | failed
result_code: <diagnosis-owned classification>
explanation: <diagnosis explanation>
campaign_control:
result_code: <exact diagnosis route key>
execution_result_code: <step6 execution outcome; empty when execution completed>
reason_code: <exact producer-owned Product reason_code copy or empty>
step6_evidence: {}
diagnosis_evidence_packet: {}
artifact_refs: {}
warnings: []
errors: []
step6.json 的存在只说明:
Step 5 diagnosis result + Step 6 campaign control contract 已经生成并落 trace。
它不说明:
campaign execution 已经完成。
因此,step6.json 可以包含 campaign_control,但 campaign 的 route /
restart / halt 执行必须发生在 active promotion 之后。
6. active promotion 的位置
active promotion 是 projection 能力,由 orchestrator 的 product-completion boundary 触发,不是 fail2pivot 内联逻辑。
固定职责:
| 组件 | 职责 |
|---|---|
trace.py | 只写 trace/cycle 文件,包括 step6.json |
active.py | 只把明确 cycle promote / project 到 active |
fail2pivot.py | 执行 Steps 5-6,写 step6.json 并交付 diagnosis/campaign control,不碰 active |
orchestrator.py | 完整 subagent product graph 成功后调用 active projection |
campaign.py | 根据 Step6 control 执行 restart / halt / route |
正确顺序:
fail2pivot.py
-> projection trace writes step6.json
-> returns success for clean continue, partial for continue_with_repair,
or blocked for restart / halt / escalation
-> campaign execution consumes campaign_control when graph is interrupted
completed subagent product graph
-> orchestrator calls nexrur_projection_active
-> active becomes the complete last-known-good snapshot
orchestrator 必须把最近一次 Schema result 的 validation_passed=true|false|null
原样交给 active projection。该字段只描述验证观察;false 或 null 不得阻断已经
完成的 Product graph 晋升,也不得被伪造成 true。
禁止:
trace.py直接写 active。fail2pivot.py复制 active promotion 实现。active.py解释 Diagnosisresult_code或 campaign route。campaign.py回头改写 trace/cycle 的step6.json。
7. restart evidence 与 business 关系
restart 时 business evidence 必须能读到本次失败 Steps 5-6 和此前成功 active。
固定口径:
step6.json 落 trace
-> campaign 执行 restart
-> 同 trace / 新 cycle 跑 restart_evidence
-> business reader 读取 last-known-good active + current Steps 5-6 diagnosis/reference
restart_evidence 的 business 结构以 DESIGN_五桶证据.md 为准:
business/
upstream/
diagnosis/
step6.json
reference.json
business/diagnosis/step6.json 是 restart-only,用于突出转入 restart 的
Step 5 Diagnosis + Step 6 Campaign result。
8. 反模式
禁止以下模式:
- Steps 5-6 或中间 module 成功就提前更新整个 product active。
- failed / blocked / restart_requested cycle 覆盖 last-known-good active。
- 把
campaign_control从step6.json拆走后又没有其它可追溯落档。 - 把 active promotion 代码复制进
fail2pivot.py。 - 用 app owner 手工拼 Steps 4-6、active 或 restart evidence。
- 在 Step 2 Product / Step 3 Schema / active 阶段解释 root cause 或决定 campaign route。
- 在 fail2pivot / orchestrator Python 中按 Product
reason_code或 Diagnosisresult_code硬编码“partial 放行”。 - 在
diagnosis_result/campaign_control中保留 Diagnosisreason_code别名, 或用 Productreason_code兜底缺失的 Diagnosisresult_code。 - 把 Diagnosis/Campaign
result_code提升成 Steps 5-6、child graph 或 parent graph 的 Productreason_code。 - 把
diagnosis_unavailable、prompt_a_failed、golden_no_eligible_cards或其他 Step6 执行码写入 Productreason_code,导致 parent 丢失 producer-owned 原因。 - 把 Production
partial改写成 success,导致 Diagnosis 和后台看不到问题。 - 把
continue_with_repair当成立即 restart,重复执行已经可用的当前 graph。 - 因 nested/outer scope 不同而重复逐文件物化同一个 upstream source,形成 N+1 projection/schema 调用。
- 为消除重复写入而跨 scope 复用完整 Step6 Evidence,导致 module facts 冒充 parent facts。
- 用提高 ToolLoop hard timeout 掩盖 materialization N+1 或重复物化。
9. 验收口径
任何 Steps 4-6 / fail2pivot / projection active / campaign 调整,都必须能回答:
-
step6_evidence从哪里来?- Step 2 Product / Step 3 Schema 落盘后,由 Step 4 Re-evidence 生成。
-
step6.json写在什么时候?- Step 5
diagnosis_result和 Step 6campaign_control生成后,由 trace 写入 当前 cycle。
- Step 5
-
active 什么时候更新?
- 完整 subagent product graph 成功关闭后,由 orchestrator 统一提升。
-
campaign_control在step6.json里是否代表 campaign 已执行?- 不代表。它只是控制合同落档。
-
restart production 读的 business 是什么?
- last-known-good active,加当前失败 cycle 的 Steps 5-6 diagnosis/reference。
-
restart 后是新 trace 还是新 cycle?
- 同一 campaign-owned trace 内的 restart 都是同 trace 的新 cycle;新的 CLI campaign 或新的 asset attempt 才是新 trace。
-
Production 已有可用产物但存在质量问题时怎么办?
- Step 2 Product 返回
partial和原始 refs;Step 4 Re-evidence 收集问题, Step 5 Diagnosis 诊断,Step 6 Campaign 只能通过声明式continue_with_repair让当前 graph 继续并登记修复目标。
- Step 2 Product 返回
-
continue_with_repair是 success 吗?- 不是。fail2pivot 返回
partial;它允许依赖图继续,但问题仍进入 Admin、 checkpoint、active 和后续修复治理。
- 不是。fail2pivot 返回
-
三层 code 如何传递?
- Product
reason_code原样保留;Diagnosis 只输出result_code;Campaign 只按该result_code路由。三者不得别名、fallback、双写或相互覆盖。
- Product
-
Product 返回后又发生 runtime/infrastructure failure 怎么办?
- 原 Product 继续原样保留;运行故障进入独立 execution/runtime incident channel,必要时停止执行图。不得就地改写 Product;只有新 cycle 重跑 Production 才能产生不同 Product。
-
Prompt A 过滤后没有 Golden 候选怎么办?
eligible_card_count=0、run_prompt_a=false,不调用 LLM;Required Golden 报告独立的 Step6/Diagnosis asset-contract failure,同时原 Productreason_code继续原样传递。
-
nested module 与 outer subagent 是否都要跑 Step 4?
- 都要。两层 Re-evidence scope 不同,facts、digest、obligations 和 diagnosis packet 必须分别生成。
-
两层共享相同 raw evidence 时是否必须重复写 inventory?
- 不需要。只按 source id 命中 substrate materialization receipt 并复用物理 refs; 其它 source 和两层各自的 Step6 Evidence 仍独立处理。
-
materialization receipt 是 Step 4 业务产物吗?
- 不是。它只属于
.engines/.projection-materialization/运行事实,不能进入 aiskills、envelope、artifact/evidence refs 或 active。
- 不是。它只属于
10. 一句话总结
Step 1 Evidence -> Step 2 Product -> Step 3 Schema -> Step 4 Re-evidence
-> Step 5 Diagnosis -> Step 6 Campaign。
fail2pivot = Step 5 + Step 6;它消费 Step 4 的 step6_evidence,生成
diagnosis_result 和 campaign_control,再写 step6.json,
再 active,最后 campaign execution;active 是 campaign restart 前的真实状态快照。
campaign 内 restart 是 same trace new cycle;新 CLI campaign / 新 asset 才是 new trace。
Production partial 必须被 Diagnosis 看见,并由 Campaign 以
continue_with_repair 显式放行;不得跳过诊断或伪装 success。
Product `reason_code` 始终属于 Production;Diagnosis 与 Campaign 只使用独立
`result_code`,不得回写或提升为 Product code。
Production 返回即封存;后置运行故障单独记录并可以停图,但只有新 cycle 重跑
Production 才能改变 Product。
11. Step5/6 截止时间合同
nexrur_fail2pivot 是 Step 5 Diagnosis 与 Step 6 Campaign 的组合父级,其 execution
watchdog floor 必须不短于本轮已接纳的 Diagnosis child、Campaign 确定性路由、结果组装与
Projection 收尾。通用 120 秒不能作为固定父壳,因为 Diagnosis 的单个 admission-aware
LLM child 只要仍有进展就可以合法超过 120 秒。
Diagnosis 若存在 Prompt A 重试/候选筛选、Prompt B 解释等串行调用,可声明保守的 watchdog floor 防止父级短于 child;并发调用按 wave 暴露同类安全下限。该计算不构成 完成时限。Step6 graph floor 由 Orchestrator 单调发布,只能延长 Worker 的 operator watchdog,不能缩短它。
Step6 自身超时属于 Step6 runtime incident,不拥有 Production Product。即使 Diagnosis
未返回、Campaign 未收口或外层进程终止,也必须原样保留已经封存的 Product
status/reason/reason_code/artifact_refs;不得以 diagnosis_unavailable、
TOOLLOOP_BATCH_ERROR 或任何 Step6 code 替换。只有新 cycle 重跑 Production 才可能
改变 Product。
验收至少覆盖:单个 Diagnosis child 长于旧 120 秒仍可成功、Prompt A 重试、Prompt B、 合法排队、Campaign 收尾、Step6 局部失败,以及 nested/outer Step6 的 watchdog 均不会 误杀仍有进展的 child。