欢迎光临
我们一直在努力

Zagens agent 的组合式 Harness 工程实践

Agent 长程任务的完成度信任问题,以及 Zagens 如何用组合式 Harness 解决它

  • 模型自建的 checklist 有欠分解上限——open_items: 0 不等于真完成。
  • Zagens 用三层可组合门禁:L1 防早停 → L2 退出码 Oracle → L3 交付物对账,均在 graph_complete 候选时由 Harness 主动裁决。
  • 裁决信号必须是机器可回放的(退出码、路径命中、事件日志),禁止 LLM 当法官。
  • 对抗审计只做缺口枚举,最终绿灯仍由机器门决定;超大任务叠加 Cycle / Macro Loop。
  • 术语速查

    术语含义
    LHT Long-Horizon Task,长程代码任务模式;Layer 1 的强制继续机制
    CRAFT 多代理 QA 段(Implementer + Reviewer + Verifier),与 LHT 实现段交替
    Machine Oracle 机器裁决:退出码、路径/glob 命中等可回放信号
    graph_complete 模型自产 plan + checklist 均无可办项时的完成候选状态
    audit_unmet 有界轮次耗尽后门仍未全绿时的诚实停机,不产生假绿灯
    MicroStack02 Go 微服务框架压测用例:24 类交付物 + 四门验收,暴露欠分解假绿
    DEMO3–6 Monkey 解释器等长程实证压测序列,逐轮修补早停泄漏与假绿路径

    1. 引言:Agent 的「声称完成」陷阱

    2025–2026 年,LLM Agent 的编码能力已经很强——能写数千行代码、做多文件重构、跑测试。但实践中暴露出一类深层问题:模型经常过早「声称完成」,而大量交付物实际上并未落地。

    这不是模型在说谎。根因在于:

    • 模型自建的 checklist 存在欠分解(under-decomposition)——某些必要交付物从未进入它自己的任务图;
    • 模型检查自己的 checklist 全部打勾 → 任务图显示 open_items: 0 → 模型合法地宣布完成;
    • 但检视才发现:gzip 中间件没写,router trie 重构没做,e2e 脚本没跑过。

    用 Zagens 团队的内部术语说:完成度的天花板 = 模型自分解 checklist 的完整性。模型自己画的作战地图画漏了,按图索骥也找不到漏掉的目标。

    #mermaid-svg-jJupXfvS0VBaXKfz{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-jJupXfvS0VBaXKfz .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-jJupXfvS0VBaXKfz .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-jJupXfvS0VBaXKfz .error-icon{fill:#552222;}#mermaid-svg-jJupXfvS0VBaXKfz .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-jJupXfvS0VBaXKfz .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-jJupXfvS0VBaXKfz .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-jJupXfvS0VBaXKfz .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-jJupXfvS0VBaXKfz .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-jJupXfvS0VBaXKfz .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-jJupXfvS0VBaXKfz .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-jJupXfvS0VBaXKfz .marker{fill:#333333;stroke:#333333;}#mermaid-svg-jJupXfvS0VBaXKfz .marker.cross{stroke:#333333;}#mermaid-svg-jJupXfvS0VBaXKfz svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-jJupXfvS0VBaXKfz p{margin:0;}#mermaid-svg-jJupXfvS0VBaXKfz .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-jJupXfvS0VBaXKfz .cluster-label text{fill:#333;}#mermaid-svg-jJupXfvS0VBaXKfz .cluster-label span{color:#333;}#mermaid-svg-jJupXfvS0VBaXKfz .cluster-label span p{background-color:transparent;}#mermaid-svg-jJupXfvS0VBaXKfz .label text,#mermaid-svg-jJupXfvS0VBaXKfz span{fill:#333;color:#333;}#mermaid-svg-jJupXfvS0VBaXKfz .node rect,#mermaid-svg-jJupXfvS0VBaXKfz .node circle,#mermaid-svg-jJupXfvS0VBaXKfz .node ellipse,#mermaid-svg-jJupXfvS0VBaXKfz .node polygon,#mermaid-svg-jJupXfvS0VBaXKfz .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-jJupXfvS0VBaXKfz .rough-node .label text,#mermaid-svg-jJupXfvS0VBaXKfz .node .label text,#mermaid-svg-jJupXfvS0VBaXKfz .image-shape .label,#mermaid-svg-jJupXfvS0VBaXKfz .icon-shape .label{text-anchor:middle;}#mermaid-svg-jJupXfvS0VBaXKfz .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-jJupXfvS0VBaXKfz .rough-node .label,#mermaid-svg-jJupXfvS0VBaXKfz .node .label,#mermaid-svg-jJupXfvS0VBaXKfz .image-shape .label,#mermaid-svg-jJupXfvS0VBaXKfz .icon-shape .label{text-align:center;}#mermaid-svg-jJupXfvS0VBaXKfz .node.clickable{cursor:pointer;}#mermaid-svg-jJupXfvS0VBaXKfz .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-jJupXfvS0VBaXKfz .arrowheadPath{fill:#333333;}#mermaid-svg-jJupXfvS0VBaXKfz .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-jJupXfvS0VBaXKfz .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-jJupXfvS0VBaXKfz .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-jJupXfvS0VBaXKfz .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-jJupXfvS0VBaXKfz .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-jJupXfvS0VBaXKfz .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-jJupXfvS0VBaXKfz .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-jJupXfvS0VBaXKfz .cluster text{fill:#333;}#mermaid-svg-jJupXfvS0VBaXKfz .cluster span{color:#333;}#mermaid-svg-jJupXfvS0VBaXKfz div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-jJupXfvS0VBaXKfz .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-jJupXfvS0VBaXKfz rect.text{fill:none;stroke-width:0;}#mermaid-svg-jJupXfvS0VBaXKfz .icon-shape,#mermaid-svg-jJupXfvS0VBaXKfz .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-jJupXfvS0VBaXKfz .icon-shape p,#mermaid-svg-jJupXfvS0VBaXKfz .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-jJupXfvS0VBaXKfz .icon-shape .label rect,#mermaid-svg-jJupXfvS0VBaXKfz .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-jJupXfvS0VBaXKfz .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-jJupXfvS0VBaXKfz .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-jJupXfvS0VBaXKfz :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    模型自建 checklist(欠分解)

    必要交付物从未进入任务图

    open_items: 0

    模型合法宣布完成

    检视发现遗漏gzip / trie 重构 / e2e

    Zagens 作为面向 DeepSeek V4 的开源 Agent Harness,核心工程命题是:如何构建一套不依赖模型自我声明的、可审计的、可回放的完成度信任机制。

    本文从工程架构角度,拆解 Zagens Harness 系统的设计与实现。


    2. 核心理念:Harness,不是聊天壳

    Zagens 的判断很明确:不能信任模型自己说「做完了」。需要一套独立于模型的完成度判定系统。

    这套系统的三条设计原则(源自 Zagens Harness 设计文档,经 DeepSeek Agent + Harness 负责人 Deli Chen 的持续学习研究印证):

  • 信号质量 = 机器裁决(Machine Oracle)—— 最终判断依据是退出码(exit code)、路径命中(path/glob hit)等可精确回放的信号,不是 LLM 的散文判断;
  • 信号独立性 —— 需要两层独立:规则独立(不靠模型推理,靠正则/文件扫描)和 Agent 独立(不是同一个 Agent 的自我确认);
  • 独立性不能退化为「换一个 LLM 盖章」 —— 用 LLM 审计 LLM 的输出,只会把「建设者自我确认」变成「审计者-建设者共谋确认」,独立性名存实亡。
  • 这些原则落实到工程上,就是 Zagens 的组合式 Harness(Composable Harness)—— 三层可插拔门禁系统。

    #mermaid-svg-D64cqMM7gYfjiQ1H{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-D64cqMM7gYfjiQ1H .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-D64cqMM7gYfjiQ1H .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-D64cqMM7gYfjiQ1H .error-icon{fill:#552222;}#mermaid-svg-D64cqMM7gYfjiQ1H .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-D64cqMM7gYfjiQ1H .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-D64cqMM7gYfjiQ1H .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-D64cqMM7gYfjiQ1H .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-D64cqMM7gYfjiQ1H .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-D64cqMM7gYfjiQ1H .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-D64cqMM7gYfjiQ1H .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-D64cqMM7gYfjiQ1H .marker{fill:#333333;stroke:#333333;}#mermaid-svg-D64cqMM7gYfjiQ1H .marker.cross{stroke:#333333;}#mermaid-svg-D64cqMM7gYfjiQ1H svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-D64cqMM7gYfjiQ1H p{margin:0;}#mermaid-svg-D64cqMM7gYfjiQ1H .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-D64cqMM7gYfjiQ1H .cluster-label text{fill:#333;}#mermaid-svg-D64cqMM7gYfjiQ1H .cluster-label span{color:#333;}#mermaid-svg-D64cqMM7gYfjiQ1H .cluster-label span p{background-color:transparent;}#mermaid-svg-D64cqMM7gYfjiQ1H .label text,#mermaid-svg-D64cqMM7gYfjiQ1H span{fill:#333;color:#333;}#mermaid-svg-D64cqMM7gYfjiQ1H .node rect,#mermaid-svg-D64cqMM7gYfjiQ1H .node circle,#mermaid-svg-D64cqMM7gYfjiQ1H .node ellipse,#mermaid-svg-D64cqMM7gYfjiQ1H .node polygon,#mermaid-svg-D64cqMM7gYfjiQ1H .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-D64cqMM7gYfjiQ1H .rough-node .label text,#mermaid-svg-D64cqMM7gYfjiQ1H .node .label text,#mermaid-svg-D64cqMM7gYfjiQ1H .image-shape .label,#mermaid-svg-D64cqMM7gYfjiQ1H .icon-shape .label{text-anchor:middle;}#mermaid-svg-D64cqMM7gYfjiQ1H .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-D64cqMM7gYfjiQ1H .rough-node .label,#mermaid-svg-D64cqMM7gYfjiQ1H .node .label,#mermaid-svg-D64cqMM7gYfjiQ1H .image-shape .label,#mermaid-svg-D64cqMM7gYfjiQ1H .icon-shape .label{text-align:center;}#mermaid-svg-D64cqMM7gYfjiQ1H .node.clickable{cursor:pointer;}#mermaid-svg-D64cqMM7gYfjiQ1H .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-D64cqMM7gYfjiQ1H .arrowheadPath{fill:#333333;}#mermaid-svg-D64cqMM7gYfjiQ1H .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-D64cqMM7gYfjiQ1H .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-D64cqMM7gYfjiQ1H .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-D64cqMM7gYfjiQ1H .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-D64cqMM7gYfjiQ1H .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-D64cqMM7gYfjiQ1H .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-D64cqMM7gYfjiQ1H .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-D64cqMM7gYfjiQ1H .cluster text{fill:#333;}#mermaid-svg-D64cqMM7gYfjiQ1H .cluster span{color:#333;}#mermaid-svg-D64cqMM7gYfjiQ1H div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-D64cqMM7gYfjiQ1H .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-D64cqMM7gYfjiQ1H rect.text{fill:none;stroke-width:0;}#mermaid-svg-D64cqMM7gYfjiQ1H .icon-shape,#mermaid-svg-D64cqMM7gYfjiQ1H .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-D64cqMM7gYfjiQ1H .icon-shape p,#mermaid-svg-D64cqMM7gYfjiQ1H .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-D64cqMM7gYfjiQ1H .icon-shape .label rect,#mermaid-svg-D64cqMM7gYfjiQ1H .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-D64cqMM7gYfjiQ1H .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-D64cqMM7gYfjiQ1H .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-D64cqMM7gYfjiQ1H :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    Harness 设计原则

    信号质量 = 机器裁决退出码 · 路径命中 · 可回放

    信号独立性规则独立 + Agent 独立

    禁止 LLM 盖章审计者不能当法官

    组合式 Harness三层可插拔门禁


    3. 引擎基础:Kernel V3 —— 事件溯源的 Turn 引擎

    Harness 门禁要可审计、可回放,离不开底层引擎的事件持久化。Zagens v0.8.2 的 Kernel V3 是事件溯源 turn 循环——下文只保留与 Harness 相关的要点;完整 turn 机状态机见源码 LiveTurnMachine / ReplayTurnMachine。

    #mermaid-svg-Jecs9Qt4r0mcXizn{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Jecs9Qt4r0mcXizn .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Jecs9Qt4r0mcXizn .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Jecs9Qt4r0mcXizn .error-icon{fill:#552222;}#mermaid-svg-Jecs9Qt4r0mcXizn .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Jecs9Qt4r0mcXizn .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Jecs9Qt4r0mcXizn .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Jecs9Qt4r0mcXizn .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Jecs9Qt4r0mcXizn .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Jecs9Qt4r0mcXizn .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Jecs9Qt4r0mcXizn .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Jecs9Qt4r0mcXizn .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Jecs9Qt4r0mcXizn .marker.cross{stroke:#333333;}#mermaid-svg-Jecs9Qt4r0mcXizn svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Jecs9Qt4r0mcXizn p{margin:0;}#mermaid-svg-Jecs9Qt4r0mcXizn .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-Jecs9Qt4r0mcXizn .cluster-label text{fill:#333;}#mermaid-svg-Jecs9Qt4r0mcXizn .cluster-label span{color:#333;}#mermaid-svg-Jecs9Qt4r0mcXizn .cluster-label span p{background-color:transparent;}#mermaid-svg-Jecs9Qt4r0mcXizn .label text,#mermaid-svg-Jecs9Qt4r0mcXizn span{fill:#333;color:#333;}#mermaid-svg-Jecs9Qt4r0mcXizn .node rect,#mermaid-svg-Jecs9Qt4r0mcXizn .node circle,#mermaid-svg-Jecs9Qt4r0mcXizn .node ellipse,#mermaid-svg-Jecs9Qt4r0mcXizn .node polygon,#mermaid-svg-Jecs9Qt4r0mcXizn .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Jecs9Qt4r0mcXizn .rough-node .label text,#mermaid-svg-Jecs9Qt4r0mcXizn .node .label text,#mermaid-svg-Jecs9Qt4r0mcXizn .image-shape .label,#mermaid-svg-Jecs9Qt4r0mcXizn .icon-shape .label{text-anchor:middle;}#mermaid-svg-Jecs9Qt4r0mcXizn .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Jecs9Qt4r0mcXizn .rough-node .label,#mermaid-svg-Jecs9Qt4r0mcXizn .node .label,#mermaid-svg-Jecs9Qt4r0mcXizn .image-shape .label,#mermaid-svg-Jecs9Qt4r0mcXizn .icon-shape .label{text-align:center;}#mermaid-svg-Jecs9Qt4r0mcXizn .node.clickable{cursor:pointer;}#mermaid-svg-Jecs9Qt4r0mcXizn .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Jecs9Qt4r0mcXizn .arrowheadPath{fill:#333333;}#mermaid-svg-Jecs9Qt4r0mcXizn .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Jecs9Qt4r0mcXizn .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Jecs9Qt4r0mcXizn .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Jecs9Qt4r0mcXizn .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Jecs9Qt4r0mcXizn .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Jecs9Qt4r0mcXizn .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Jecs9Qt4r0mcXizn .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Jecs9Qt4r0mcXizn .cluster text{fill:#333;}#mermaid-svg-Jecs9Qt4r0mcXizn .cluster span{color:#333;}#mermaid-svg-Jecs9Qt4r0mcXizn div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Jecs9Qt4r0mcXizn .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Jecs9Qt4r0mcXizn rect.text{fill:none;stroke-width:0;}#mermaid-svg-Jecs9Qt4r0mcXizn .icon-shape,#mermaid-svg-Jecs9Qt4r0mcXizn .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Jecs9Qt4r0mcXizn .icon-shape p,#mermaid-svg-Jecs9Qt4r0mcXizn .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Jecs9Qt4r0mcXizn .icon-shape .label rect,#mermaid-svg-Jecs9Qt4r0mcXizn .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Jecs9Qt4r0mcXizn .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Jecs9Qt4r0mcXizn .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Jecs9Qt4r0mcXizn :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    事件溯源持久化

    KernelEvent

    LiveTurnMachine

    outer 循环step-frame → pre-inner → inner→ post-inner → boundary grants

    inner 循环inner_step_live_plan→ EffectInterpreter

    InnerStepHost IOstreaming · tool execution · LSP notify

    handle_deepseek_turn

    Turn endruntime-server host_impl

    finish_kernel_turn

    kernel_turn_replay_verify+ projection compare

    kernel_eventsSQLite

    每次 turn 的完整生命周期被记录为 KernelEvent,存储在 SQLite 的 kernel_events 表:

    CREATE TABLE kernel_events (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    seq INTEGER NOT NULL,
    ts_ms INTEGER NOT NULL,
    kind TEXT NOT NULL,
    turn_id TEXT,
    payload TEXT NOT NULL — JSON KernelEvent
    );

    事件溯源对 Harness 的价值:

    • 可回放(Replayable):ReplayTurnMachine 能从事件日志重建状态,Harness 的金色夹具(golden fixtures)可在 CI 中精确验证门禁行为;
    • 可审计:所有 turn 生命周期事件(模型请求、工具调用结果、门禁判定)都有结构化持久化记录;
    • 可恢复:log-first 会话恢复优先从事件日志重建消息,不依赖 session JSON。

    基于这个引擎,Zagens 的 Harness 各层门禁得以可靠地挂载在 turn 循环的各个退出点上。


    4. 三层组合式 Harness 架构

    Zagens 的完成度门禁系统是三层可组合的:

    #mermaid-svg-Mx7ct2rBjbEpmPyJ{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Mx7ct2rBjbEpmPyJ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .error-icon{fill:#552222;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .marker.cross{stroke:#333333;}#mermaid-svg-Mx7ct2rBjbEpmPyJ svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Mx7ct2rBjbEpmPyJ p{margin:0;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .cluster-label text{fill:#333;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .cluster-label span{color:#333;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .cluster-label span p{background-color:transparent;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .label text,#mermaid-svg-Mx7ct2rBjbEpmPyJ span{fill:#333;color:#333;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .node rect,#mermaid-svg-Mx7ct2rBjbEpmPyJ .node circle,#mermaid-svg-Mx7ct2rBjbEpmPyJ .node ellipse,#mermaid-svg-Mx7ct2rBjbEpmPyJ .node polygon,#mermaid-svg-Mx7ct2rBjbEpmPyJ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .rough-node .label text,#mermaid-svg-Mx7ct2rBjbEpmPyJ .node .label text,#mermaid-svg-Mx7ct2rBjbEpmPyJ .image-shape .label,#mermaid-svg-Mx7ct2rBjbEpmPyJ .icon-shape .label{text-anchor:middle;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .rough-node .label,#mermaid-svg-Mx7ct2rBjbEpmPyJ .node .label,#mermaid-svg-Mx7ct2rBjbEpmPyJ .image-shape .label,#mermaid-svg-Mx7ct2rBjbEpmPyJ .icon-shape .label{text-align:center;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .node.clickable{cursor:pointer;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .arrowheadPath{fill:#333333;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Mx7ct2rBjbEpmPyJ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Mx7ct2rBjbEpmPyJ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Mx7ct2rBjbEpmPyJ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .cluster text{fill:#333;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .cluster span{color:#333;}#mermaid-svg-Mx7ct2rBjbEpmPyJ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Mx7ct2rBjbEpmPyJ rect.text{fill:none;stroke-width:0;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .icon-shape,#mermaid-svg-Mx7ct2rBjbEpmPyJ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .icon-shape p,#mermaid-svg-Mx7ct2rBjbEpmPyJ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .icon-shape .label rect,#mermaid-svg-Mx7ct2rBjbEpmPyJ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Mx7ct2rBjbEpmPyJ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Mx7ct2rBjbEpmPyJ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Mx7ct2rBjbEpmPyJ :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    graph_complete 候选时(原子执行)

    运行中(全程)

    checklist 全绿

    Layer 1: 模型自驱plan + checklist + nudge 继续

    Stub 门 · 文件扫描

    Layer 2: 硬验收门 · 退出码 Oracle

    Layer 3: 交付物对账 · path/glob

    ✅ 真实完成

    组合方式(可独立开关):

    • Layer 1 仅 = 原始效果(模型自驱 + 防早停);
    • Layer 1+2 = 纯粹的退出码门禁(最确定、最便宜);
    • Layer 1+2+3 = 完整组合,能捕获欠分解场景。

    4.1 门禁在何时触发

    §4 的流程图容易误读为「L1 跑完再跑 L2」。实际时序如下:

    Layer 3

    Layer 2

    Stub 门

    graph_complete 候选

    Layer 1 (LHT)

    模型

    Layer 3

    Layer 2

    Stub 门

    graph_complete 候选

    Layer 1 (LHT)

    模型

    #mermaid-svg-JUCBsLgmAwKFcCMV{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-JUCBsLgmAwKFcCMV .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-JUCBsLgmAwKFcCMV .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-JUCBsLgmAwKFcCMV .error-icon{fill:#552222;}#mermaid-svg-JUCBsLgmAwKFcCMV .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-JUCBsLgmAwKFcCMV .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-JUCBsLgmAwKFcCMV .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-JUCBsLgmAwKFcCMV .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-JUCBsLgmAwKFcCMV .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-JUCBsLgmAwKFcCMV .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-JUCBsLgmAwKFcCMV .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-JUCBsLgmAwKFcCMV .marker{fill:#333333;stroke:#333333;}#mermaid-svg-JUCBsLgmAwKFcCMV .marker.cross{stroke:#333333;}#mermaid-svg-JUCBsLgmAwKFcCMV svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-JUCBsLgmAwKFcCMV p{margin:0;}#mermaid-svg-JUCBsLgmAwKFcCMV .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-JUCBsLgmAwKFcCMV text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-JUCBsLgmAwKFcCMV .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-JUCBsLgmAwKFcCMV .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-JUCBsLgmAwKFcCMV .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-JUCBsLgmAwKFcCMV .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-JUCBsLgmAwKFcCMV #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-JUCBsLgmAwKFcCMV .sequenceNumber{fill:white;}#mermaid-svg-JUCBsLgmAwKFcCMV #sequencenumber{fill:#333;}#mermaid-svg-JUCBsLgmAwKFcCMV #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-JUCBsLgmAwKFcCMV .messageText{fill:#333;stroke:none;}#mermaid-svg-JUCBsLgmAwKFcCMV .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-JUCBsLgmAwKFcCMV .labelText,#mermaid-svg-JUCBsLgmAwKFcCMV .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-JUCBsLgmAwKFcCMV .loopText,#mermaid-svg-JUCBsLgmAwKFcCMV .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-JUCBsLgmAwKFcCMV .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-JUCBsLgmAwKFcCMV .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-JUCBsLgmAwKFcCMV .noteText,#mermaid-svg-JUCBsLgmAwKFcCMV .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-JUCBsLgmAwKFcCMV .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-JUCBsLgmAwKFcCMV .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-JUCBsLgmAwKFcCMV .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-JUCBsLgmAwKFcCMV .actorPopupMenu{position:absolute;}#mermaid-svg-JUCBsLgmAwKFcCMV .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-JUCBsLgmAwKFcCMV .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-JUCBsLgmAwKFcCMV .actor-man circle,#mermaid-svg-JUCBsLgmAwKFcCMV line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-JUCBsLgmAwKFcCMV :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    alt

    [graph.incomplete]

    loop

    [整个任务周期]

    alt

    [缺交付物]

    [全绿]

    alt

    [退出码 ≠ 0]

    [全绿]

    alt

    [发现 todo!/unimplemented!]

    [通过]

    无工具调用 / step 耗尽 / loop_guard 等

    注入 nudge,继续

    plan + checklist 均无可办项

    纯文件扫描(先于 L2/L3)

    阻断,强制返工

    Harness 主动执行 verify

    强制返工

    路径/glob 对账

    missing_deliverables + 返工

    ✅ 真实完成

    要点: Layer 1 贯穿全程;Layer 2/3(及 Stub 门)仅在 graph_complete 候选时原子执行,同轮内 L2 全绿后才进入 L3。

    4.2 案例:MicroStack02 欠分解假绿

    MicroStack 框架压测(代号 MICROSTACK)规定 24 类交付物、四门验收 + [verify:] 纪律。一次典型失败跑(MicroStack02):

    观测模型侧实际产物
    UI / 节点 checklist 100%、incomplete_stop=0、gate_skip graph_complete ×3
    规模 声称完成 仅 ~7045 行(目标 15–40K)
    覆盖率 checklist 项已勾 app 16.3%、orm 4.7%
    欠分解 任务图全绿 gzip 中间件、cmd/microstack/main.go、Router trie 重构从未进 checklist

    各层分别拦住了什么?

    层级仅 Layer 1 时加上 Layer 2+3 后
    Layer 1 ✅ 无早停;但 checklist 全绿 → 放行候选 同左
    Layer 2 ✅ 覆盖率门、gofmt 真门可拦「测试红/未格式化」
    Layer 3 ✅ middleware/gzip.go、**/*trie*.go 等 manifest 项抓到「从未分解进清单」的交付物

    根因代码定位:maybe_continue_incomplete_code_task 只看模型自产 plan + checklist——完成度上界 = 模型自拆清单完整度。Layer 3 把「模型欠分解」平移为「操作者预写 manifest」,但 manifest 可离线审查、可回归,远比每次现场分解稳定。

    下面逐层深入。


    5. Layer 1:强制继续(LHT)—— 不让模型用散文结束

    Layer 1 解决的核心问题:模型在多步骤任务中途以文字总结结束,不再调用任何工具。

    5.1 问题根因

    源码定位在 crates/runtime-server/src/long_horizon/mod.rs 的 maybe_continue_incomplete_code_task:

    graph = CodeTaskGraph::from_snapshots(plan, checklist)
    if graph.is_empty() -> Skip("graph_empty")
    if !graph.incomplete() -> Skip("graph_complete")

    完成判定完全依赖模型自产的 plan + checklist 快照。如果模型在初始分解时就遗漏了关键交付物,「open_items == 0」就是一个虚假的完成信号。

    5.2 强制继续机制

    maybe_continue_incomplete_code_task 被挂载在 no_tool_uses.rs 的分支链中(audit 之后、Break 之前):

    #mermaid-svg-VVwsRXdLLQIgrGvO{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-VVwsRXdLLQIgrGvO .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-VVwsRXdLLQIgrGvO .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-VVwsRXdLLQIgrGvO .error-icon{fill:#552222;}#mermaid-svg-VVwsRXdLLQIgrGvO .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-VVwsRXdLLQIgrGvO .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-VVwsRXdLLQIgrGvO .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-VVwsRXdLLQIgrGvO .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-VVwsRXdLLQIgrGvO .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-VVwsRXdLLQIgrGvO .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-VVwsRXdLLQIgrGvO .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-VVwsRXdLLQIgrGvO .marker{fill:#333333;stroke:#333333;}#mermaid-svg-VVwsRXdLLQIgrGvO .marker.cross{stroke:#333333;}#mermaid-svg-VVwsRXdLLQIgrGvO svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-VVwsRXdLLQIgrGvO p{margin:0;}#mermaid-svg-VVwsRXdLLQIgrGvO .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-VVwsRXdLLQIgrGvO .cluster-label text{fill:#333;}#mermaid-svg-VVwsRXdLLQIgrGvO .cluster-label span{color:#333;}#mermaid-svg-VVwsRXdLLQIgrGvO .cluster-label span p{background-color:transparent;}#mermaid-svg-VVwsRXdLLQIgrGvO .label text,#mermaid-svg-VVwsRXdLLQIgrGvO span{fill:#333;color:#333;}#mermaid-svg-VVwsRXdLLQIgrGvO .node rect,#mermaid-svg-VVwsRXdLLQIgrGvO .node circle,#mermaid-svg-VVwsRXdLLQIgrGvO .node ellipse,#mermaid-svg-VVwsRXdLLQIgrGvO .node polygon,#mermaid-svg-VVwsRXdLLQIgrGvO .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-VVwsRXdLLQIgrGvO .rough-node .label text,#mermaid-svg-VVwsRXdLLQIgrGvO .node .label text,#mermaid-svg-VVwsRXdLLQIgrGvO .image-shape .label,#mermaid-svg-VVwsRXdLLQIgrGvO .icon-shape .label{text-anchor:middle;}#mermaid-svg-VVwsRXdLLQIgrGvO .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-VVwsRXdLLQIgrGvO .rough-node .label,#mermaid-svg-VVwsRXdLLQIgrGvO .node .label,#mermaid-svg-VVwsRXdLLQIgrGvO .image-shape .label,#mermaid-svg-VVwsRXdLLQIgrGvO .icon-shape .label{text-align:center;}#mermaid-svg-VVwsRXdLLQIgrGvO .node.clickable{cursor:pointer;}#mermaid-svg-VVwsRXdLLQIgrGvO .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-VVwsRXdLLQIgrGvO .arrowheadPath{fill:#333333;}#mermaid-svg-VVwsRXdLLQIgrGvO .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-VVwsRXdLLQIgrGvO .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-VVwsRXdLLQIgrGvO .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-VVwsRXdLLQIgrGvO .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-VVwsRXdLLQIgrGvO .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-VVwsRXdLLQIgrGvO .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-VVwsRXdLLQIgrGvO .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-VVwsRXdLLQIgrGvO .cluster text{fill:#333;}#mermaid-svg-VVwsRXdLLQIgrGvO .cluster span{color:#333;}#mermaid-svg-VVwsRXdLLQIgrGvO div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-VVwsRXdLLQIgrGvO .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-VVwsRXdLLQIgrGvO rect.text{fill:none;stroke-width:0;}#mermaid-svg-VVwsRXdLLQIgrGvO .icon-shape,#mermaid-svg-VVwsRXdLLQIgrGvO .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-VVwsRXdLLQIgrGvO .icon-shape p,#mermaid-svg-VVwsRXdLLQIgrGvO .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-VVwsRXdLLQIgrGvO .icon-shape .label rect,#mermaid-svg-VVwsRXdLLQIgrGvO .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-VVwsRXdLLQIgrGvO .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-VVwsRXdLLQIgrGvO .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-VVwsRXdLLQIgrGvO :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    模型无工具调用no_tool_uses 路径

    1. scratchpad_summary+ pending steers?

    Continue

    2. pending steers?

    Continue

    3. sub-agentcompletions?

    Continue

    4. REPL blocks?

    Continue / Break

    5. incompleteaudit continue?

    Continue(audit 独占)

    6. ★ LHTgraph.incomplete?

    Continue(注入 nudge)

    Break

    当模型在工具调用后只输出文字总结,引擎走 no_tool_uses 路径 → 第 6 分支触发 → 注入一条强制继续的 nudge 消息:

    长程代码任务尚未完成 — 请勿仅用文字总结结束本轮。

    目标:将 auth 模块重构为基于 trait 的后端
    进度:████░░░░░░ 42%(plan 1/3 阶段;checklist 2/5 项未完成)

    仍待完成:
    – [plan ◎] 引入 AuthBackend trait
    – [todo ○] 更新集成测试

    请继续用工具完成当前 in_progress 项,验证(如 cargo check/test),再 checklist_update / update_plan。

    5.3 NudgeTracker:防死循环

    为防止模型在同一个 item 上无限循环,Zagens 实现了 NudgeTracker:

    #mermaid-svg-TKmBecJsMiLk8491{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-TKmBecJsMiLk8491 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-TKmBecJsMiLk8491 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-TKmBecJsMiLk8491 .error-icon{fill:#552222;}#mermaid-svg-TKmBecJsMiLk8491 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-TKmBecJsMiLk8491 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-TKmBecJsMiLk8491 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-TKmBecJsMiLk8491 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-TKmBecJsMiLk8491 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-TKmBecJsMiLk8491 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-TKmBecJsMiLk8491 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-TKmBecJsMiLk8491 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-TKmBecJsMiLk8491 .marker.cross{stroke:#333333;}#mermaid-svg-TKmBecJsMiLk8491 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-TKmBecJsMiLk8491 p{margin:0;}#mermaid-svg-TKmBecJsMiLk8491 defs #statediagram-barbEnd{fill:#333333;stroke:#333333;}#mermaid-svg-TKmBecJsMiLk8491 g.stateGroup text{fill:#9370DB;stroke:none;font-size:10px;}#mermaid-svg-TKmBecJsMiLk8491 g.stateGroup text{fill:#333;stroke:none;font-size:10px;}#mermaid-svg-TKmBecJsMiLk8491 g.stateGroup .state-title{font-weight:bolder;fill:#131300;}#mermaid-svg-TKmBecJsMiLk8491 g.stateGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-TKmBecJsMiLk8491 g.stateGroup line{stroke:#333333;stroke-width:1;}#mermaid-svg-TKmBecJsMiLk8491 .transition{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-TKmBecJsMiLk8491 .stateGroup .composit{fill:white;border-bottom:1px;}#mermaid-svg-TKmBecJsMiLk8491 .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}#mermaid-svg-TKmBecJsMiLk8491 .state-note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-TKmBecJsMiLk8491 .state-note text{fill:black;stroke:none;font-size:10px;}#mermaid-svg-TKmBecJsMiLk8491 .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-TKmBecJsMiLk8491 .edgeLabel .label rect{fill:#ECECFF;opacity:0.5;}#mermaid-svg-TKmBecJsMiLk8491 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-TKmBecJsMiLk8491 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-TKmBecJsMiLk8491 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-TKmBecJsMiLk8491 .edgeLabel .label text{fill:#333;}#mermaid-svg-TKmBecJsMiLk8491 .label div .edgeLabel{color:#333;}#mermaid-svg-TKmBecJsMiLk8491 .stateLabel text{fill:#131300;font-size:10px;font-weight:bold;}#mermaid-svg-TKmBecJsMiLk8491 .node circle.state-start{fill:#333333;stroke:#333333;}#mermaid-svg-TKmBecJsMiLk8491 .node .fork-join{fill:#333333;stroke:#333333;}#mermaid-svg-TKmBecJsMiLk8491 .node circle.state-end{fill:#9370DB;stroke:white;stroke-width:1.5;}#mermaid-svg-TKmBecJsMiLk8491 .end-state-inner{fill:white;stroke-width:1.5;}#mermaid-svg-TKmBecJsMiLk8491 .node rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-TKmBecJsMiLk8491 .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-TKmBecJsMiLk8491 #statediagram-barbEnd{fill:#333333;}#mermaid-svg-TKmBecJsMiLk8491 .statediagram-cluster rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-TKmBecJsMiLk8491 .cluster-label,#mermaid-svg-TKmBecJsMiLk8491 .nodeLabel{color:#131300;}#mermaid-svg-TKmBecJsMiLk8491 .statediagram-cluster rect.outer{rx:5px;ry:5px;}#mermaid-svg-TKmBecJsMiLk8491 .statediagram-state .divider{stroke:#9370DB;}#mermaid-svg-TKmBecJsMiLk8491 .statediagram-state .title-state{rx:5px;ry:5px;}#mermaid-svg-TKmBecJsMiLk8491 .statediagram-cluster.statediagram-cluster .inner{fill:white;}#mermaid-svg-TKmBecJsMiLk8491 .statediagram-cluster.statediagram-cluster-alt .inner{fill:#f0f0f0;}#mermaid-svg-TKmBecJsMiLk8491 .statediagram-cluster .inner{rx:0;ry:0;}#mermaid-svg-TKmBecJsMiLk8491 .statediagram-state rect.basic{rx:5px;ry:5px;}#mermaid-svg-TKmBecJsMiLk8491 .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#f0f0f0;}#mermaid-svg-TKmBecJsMiLk8491 .note-edge{stroke-dasharray:5;}#mermaid-svg-TKmBecJsMiLk8491 .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-TKmBecJsMiLk8491 .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-TKmBecJsMiLk8491 .statediagram-note text{fill:black;}#mermaid-svg-TKmBecJsMiLk8491 .statediagram-note .nodeLabel{color:black;}#mermaid-svg-TKmBecJsMiLk8491 .statediagram .edgeLabel{color:red;}#mermaid-svg-TKmBecJsMiLk8491 #dependencyStart,#mermaid-svg-TKmBecJsMiLk8491 #dependencyEnd{fill:#333333;stroke:#333333;stroke-width:1;}#mermaid-svg-TKmBecJsMiLk8491 .statediagramTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-TKmBecJsMiLk8491 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    in_progress_id 被 nudge

    有实质进展 → 重置计数

    同一 item nudge 3 次无进展

    同一 item nudge 5 次(硬上限)

    连续 8 turn 无工具调用

    long_horizon_blocked

    用户消息恢复

    请用户引导

    Nudging

    Blocked

    WaitUser

    AskUser

    上图为状态机概览;阈值如下:

    规则行为
    同一 in_progress_id 被 nudge 3 次而无实质进展 long_horizon_blocked
    同一 item 被 nudge 5 次(硬上限) 停止 nudge,等待用户消息恢复
    in_progress_id 变化 重置计数
    连续 8 个助手 turn 无工具调用 nudge 变为「请用户引导」,不再机械继续

    5.4 进展判定

    「有进展吗?」需要客观信号,而非正则的玄学判断:

    信号判断方式性质
    edit_file / write_file / apply_patch 成功 工具返回 success 客观
    exec_shell + 退出码 0 + 匹配验证正则 success + 匹配 启发式
    checklist_update / update_plan 成功 状态机迁移 客观
    git working-tree 变化 git status –porcelain 签名变化 客观,语言无关

    其中 git working-tree 信号(Phase 2.x 引入)解决了非主流语言项目中验证正则列表不全的问题——只要工作区文件发生了实际变化,就算进展。

    5.5 演进中的关键修补

    LHT 并非一次性设计完成。经过 DEMO3–DEMO6 四次实证压力测试,团队修复了多个隐蔽的早停泄漏路径:

    泄漏路径症状修复
    Step budget 耗尽 模型在 100 step 后 break,无任何 nudge maybe_continue_at_step_limit 给予新的预算窗口(最多 3 次续命)
    loop_guard 截停 同一工具连续失败 8 次,直接 Break maybe_continue_after_loop_guard_halt 清除失败计数 + 建议切换方案
    上下文溢出 上下文超出模型窗口,强制 Failed maybe_cycle_handoff_on_context_overflow 强制一次 cycle 交接
    欠分解导致的虚假完成 checklist 全绿但关键交付物未写 交给 Layer 2+3 解决(见 §4.2)

    每个泄漏路径都对应一个 run.rs 中的 break 出口。团队做了系统性审计:每个 turn 退出点都必须经过 LHT 门禁,否则就是一个新的早停泄漏。

    #mermaid-svg-agHLwLPuuqODKMDX{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-agHLwLPuuqODKMDX .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-agHLwLPuuqODKMDX .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-agHLwLPuuqODKMDX .error-icon{fill:#552222;}#mermaid-svg-agHLwLPuuqODKMDX .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-agHLwLPuuqODKMDX .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-agHLwLPuuqODKMDX .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-agHLwLPuuqODKMDX .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-agHLwLPuuqODKMDX .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-agHLwLPuuqODKMDX .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-agHLwLPuuqODKMDX .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-agHLwLPuuqODKMDX .marker{fill:#333333;stroke:#333333;}#mermaid-svg-agHLwLPuuqODKMDX .marker.cross{stroke:#333333;}#mermaid-svg-agHLwLPuuqODKMDX svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-agHLwLPuuqODKMDX p{margin:0;}#mermaid-svg-agHLwLPuuqODKMDX .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-agHLwLPuuqODKMDX .cluster-label text{fill:#333;}#mermaid-svg-agHLwLPuuqODKMDX .cluster-label span{color:#333;}#mermaid-svg-agHLwLPuuqODKMDX .cluster-label span p{background-color:transparent;}#mermaid-svg-agHLwLPuuqODKMDX .label text,#mermaid-svg-agHLwLPuuqODKMDX span{fill:#333;color:#333;}#mermaid-svg-agHLwLPuuqODKMDX .node rect,#mermaid-svg-agHLwLPuuqODKMDX .node circle,#mermaid-svg-agHLwLPuuqODKMDX .node ellipse,#mermaid-svg-agHLwLPuuqODKMDX .node polygon,#mermaid-svg-agHLwLPuuqODKMDX .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-agHLwLPuuqODKMDX .rough-node .label text,#mermaid-svg-agHLwLPuuqODKMDX .node .label text,#mermaid-svg-agHLwLPuuqODKMDX .image-shape .label,#mermaid-svg-agHLwLPuuqODKMDX .icon-shape .label{text-anchor:middle;}#mermaid-svg-agHLwLPuuqODKMDX .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-agHLwLPuuqODKMDX .rough-node .label,#mermaid-svg-agHLwLPuuqODKMDX .node .label,#mermaid-svg-agHLwLPuuqODKMDX .image-shape .label,#mermaid-svg-agHLwLPuuqODKMDX .icon-shape .label{text-align:center;}#mermaid-svg-agHLwLPuuqODKMDX .node.clickable{cursor:pointer;}#mermaid-svg-agHLwLPuuqODKMDX .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-agHLwLPuuqODKMDX .arrowheadPath{fill:#333333;}#mermaid-svg-agHLwLPuuqODKMDX .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-agHLwLPuuqODKMDX .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-agHLwLPuuqODKMDX .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-agHLwLPuuqODKMDX .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-agHLwLPuuqODKMDX .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-agHLwLPuuqODKMDX .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-agHLwLPuuqODKMDX .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-agHLwLPuuqODKMDX .cluster text{fill:#333;}#mermaid-svg-agHLwLPuuqODKMDX .cluster span{color:#333;}#mermaid-svg-agHLwLPuuqODKMDX div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-agHLwLPuuqODKMDX .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-agHLwLPuuqODKMDX rect.text{fill:none;stroke-width:0;}#mermaid-svg-agHLwLPuuqODKMDX .icon-shape,#mermaid-svg-agHLwLPuuqODKMDX .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-agHLwLPuuqODKMDX .icon-shape p,#mermaid-svg-agHLwLPuuqODKMDX .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-agHLwLPuuqODKMDX .icon-shape .label rect,#mermaid-svg-agHLwLPuuqODKMDX .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-agHLwLPuuqODKMDX .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-agHLwLPuuqODKMDX .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-agHLwLPuuqODKMDX :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    早停泄漏路径(DEMO3–6 修补)

    Step budget 耗尽

    maybe_continue_at_step_limit最多 3 次续命

    loop_guard 截停

    maybe_continue_after_loop_guard_halt清除失败计数

    上下文溢出

    maybe_cycle_handoff_on_context_overflow强制 cycle 交接

    欠分解虚假完成

    Layer 2+3 机器门禁

    每个 break 出口必须经过 LHT 门禁


    6. Layer 2:硬验收门 —— Harness 主动执行,退出码当法官

    Layer 1 只能保证「模型没提前停」,但不能保证「做对了」。Layer 2 扭转了判决权力:不再相信模型说「我跑过了,通过了」,Harness 重新跑一遍,看退出码。

    6.1 设计铁律

    不能用 LLM 当法官。 用 LLM 审计者「读一遍然后说 LGTM」是一个软的、非确定性的、可说服的、不能离线回放的裁决。

    正确的分工(下图);硬验收门与交付物覆盖均由机器 Oracle 裁决,不由 LLM 散文判断:

    #mermaid-svg-DCYfhpD42b0MN23r{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-DCYfhpD42b0MN23r .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-DCYfhpD42b0MN23r .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-DCYfhpD42b0MN23r .error-icon{fill:#552222;}#mermaid-svg-DCYfhpD42b0MN23r .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-DCYfhpD42b0MN23r .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-DCYfhpD42b0MN23r .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-DCYfhpD42b0MN23r .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-DCYfhpD42b0MN23r .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-DCYfhpD42b0MN23r .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-DCYfhpD42b0MN23r .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-DCYfhpD42b0MN23r .marker{fill:#333333;stroke:#333333;}#mermaid-svg-DCYfhpD42b0MN23r .marker.cross{stroke:#333333;}#mermaid-svg-DCYfhpD42b0MN23r svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-DCYfhpD42b0MN23r p{margin:0;}#mermaid-svg-DCYfhpD42b0MN23r .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-DCYfhpD42b0MN23r .cluster-label text{fill:#333;}#mermaid-svg-DCYfhpD42b0MN23r .cluster-label span{color:#333;}#mermaid-svg-DCYfhpD42b0MN23r .cluster-label span p{background-color:transparent;}#mermaid-svg-DCYfhpD42b0MN23r .label text,#mermaid-svg-DCYfhpD42b0MN23r span{fill:#333;color:#333;}#mermaid-svg-DCYfhpD42b0MN23r .node rect,#mermaid-svg-DCYfhpD42b0MN23r .node circle,#mermaid-svg-DCYfhpD42b0MN23r .node ellipse,#mermaid-svg-DCYfhpD42b0MN23r .node polygon,#mermaid-svg-DCYfhpD42b0MN23r .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-DCYfhpD42b0MN23r .rough-node .label text,#mermaid-svg-DCYfhpD42b0MN23r .node .label text,#mermaid-svg-DCYfhpD42b0MN23r .image-shape .label,#mermaid-svg-DCYfhpD42b0MN23r .icon-shape .label{text-anchor:middle;}#mermaid-svg-DCYfhpD42b0MN23r .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-DCYfhpD42b0MN23r .rough-node .label,#mermaid-svg-DCYfhpD42b0MN23r .node .label,#mermaid-svg-DCYfhpD42b0MN23r .image-shape .label,#mermaid-svg-DCYfhpD42b0MN23r .icon-shape .label{text-align:center;}#mermaid-svg-DCYfhpD42b0MN23r .node.clickable{cursor:pointer;}#mermaid-svg-DCYfhpD42b0MN23r .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-DCYfhpD42b0MN23r .arrowheadPath{fill:#333333;}#mermaid-svg-DCYfhpD42b0MN23r .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-DCYfhpD42b0MN23r .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-DCYfhpD42b0MN23r .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-DCYfhpD42b0MN23r .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-DCYfhpD42b0MN23r .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-DCYfhpD42b0MN23r .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-DCYfhpD42b0MN23r .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-DCYfhpD42b0MN23r .cluster text{fill:#333;}#mermaid-svg-DCYfhpD42b0MN23r .cluster span{color:#333;}#mermaid-svg-DCYfhpD42b0MN23r div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-DCYfhpD42b0MN23r .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-DCYfhpD42b0MN23r rect.text{fill:none;stroke-width:0;}#mermaid-svg-DCYfhpD42b0MN23r .icon-shape,#mermaid-svg-DCYfhpD42b0MN23r .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-DCYfhpD42b0MN23r .icon-shape p,#mermaid-svg-DCYfhpD42b0MN23r .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-DCYfhpD42b0MN23r .icon-shape .label rect,#mermaid-svg-DCYfhpD42b0MN23r .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-DCYfhpD42b0MN23r .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-DCYfhpD42b0MN23r .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-DCYfhpD42b0MN23r :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    ✅ 机器 Oracle

    ❌ 禁止

    软 · 不可回放

    LLM 审计者读一遍说 LGTM

    退出码法官Harness 主动执行 manifest

    路径对账法官预声明交付物扫描

    不放行

    通过 / 不通过

    6.2 验收 Manifest

    操作者在 ~/.zagens/config.toml 中声明验收门列表:

    [long_horizon.completion_gate]
    mode = "enforce"
    max_manifest_rounds = 5

    [[long_horizon.completion_gate.verify]]
    id = "build"
    cmd = "go build ./…"

    [[long_horizon.completion_gate.verify]]
    id = "contracts_stable"
    cmd = "git diff –exit-code contracts/"

    [[long_horizon.completion_gate.verify]]
    id = "coverage_app"
    shell = "none"
    argv = ["zagens", "coverage-gate", "–pkg", "app", "–min", "75"]

    关键约束:

    • shell = "none" + argv:跨平台(Windows 无 bash),避免引用语义漂移;
    • 退出码不是 0 就判不通过,强制模型返工;
    • 区分断言失败与基础设施错误:exit_class 分 assertion(测试红)和 infra(命令找不到、超时),连续 N 次 infra 则诚实宣布 audit_unmet;
    • 只信任用户全局配置/内置测试夹具中的可执行命令,工作区配置/模型生成文件只能走 observe 模式(记录但不阻塞)。

    6.3 任务无关的通用验收门

    Layer 2 有三类 verify 来源;其中 操作者 manifest(§6.2)适合回归夹具与强约束任务,另有两类零 per-task 配置、全局开关即覆盖所有代码任务的通用来源:

    来源配置开关命令从哪里来信任层级
    操作者 manifest completion_gate.mode 手写的 [[verify]] 列表 受信任全局配置
    模型 [verify:] 回放 auto_verify_replay 扫描已完成 checklist 项,Harness 主动重跑 无需额外信任
    工具链探测门 toolchain_gate 探测 go.mod/Cargo.toml/package.json 等 内置固定命令

    三类来源按归一化命令合并去重(优先级 operator > toolchain > model),一次跑完。日常任务可在 ~/.zagens/config.toml 中只开全局开关,无需 per-task manifest:

    [long_horizon.completion_gate]
    auto_verify_replay = "enforce" # 主动复跑模型声明的 [verify:]
    toolchain_gate = "observe" # 工具链探测 build/test

    如此设计后,Layer 2 的价值核心不再是「每个任务写一份 manifest」,而是**「Harness 主动执行、退出码当法官」**——大多数日常任务打开上述开关即可。

    #mermaid-svg-iHEI6X0tNxnJXqEV{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-iHEI6X0tNxnJXqEV .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-iHEI6X0tNxnJXqEV .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-iHEI6X0tNxnJXqEV .error-icon{fill:#552222;}#mermaid-svg-iHEI6X0tNxnJXqEV .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-iHEI6X0tNxnJXqEV .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-iHEI6X0tNxnJXqEV .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-iHEI6X0tNxnJXqEV .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-iHEI6X0tNxnJXqEV .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-iHEI6X0tNxnJXqEV .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-iHEI6X0tNxnJXqEV .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-iHEI6X0tNxnJXqEV .marker{fill:#333333;stroke:#333333;}#mermaid-svg-iHEI6X0tNxnJXqEV .marker.cross{stroke:#333333;}#mermaid-svg-iHEI6X0tNxnJXqEV svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-iHEI6X0tNxnJXqEV p{margin:0;}#mermaid-svg-iHEI6X0tNxnJXqEV .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-iHEI6X0tNxnJXqEV .cluster-label text{fill:#333;}#mermaid-svg-iHEI6X0tNxnJXqEV .cluster-label span{color:#333;}#mermaid-svg-iHEI6X0tNxnJXqEV .cluster-label span p{background-color:transparent;}#mermaid-svg-iHEI6X0tNxnJXqEV .label text,#mermaid-svg-iHEI6X0tNxnJXqEV span{fill:#333;color:#333;}#mermaid-svg-iHEI6X0tNxnJXqEV .node rect,#mermaid-svg-iHEI6X0tNxnJXqEV .node circle,#mermaid-svg-iHEI6X0tNxnJXqEV .node ellipse,#mermaid-svg-iHEI6X0tNxnJXqEV .node polygon,#mermaid-svg-iHEI6X0tNxnJXqEV .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-iHEI6X0tNxnJXqEV .rough-node .label text,#mermaid-svg-iHEI6X0tNxnJXqEV .node .label text,#mermaid-svg-iHEI6X0tNxnJXqEV .image-shape .label,#mermaid-svg-iHEI6X0tNxnJXqEV .icon-shape .label{text-anchor:middle;}#mermaid-svg-iHEI6X0tNxnJXqEV .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-iHEI6X0tNxnJXqEV .rough-node .label,#mermaid-svg-iHEI6X0tNxnJXqEV .node .label,#mermaid-svg-iHEI6X0tNxnJXqEV .image-shape .label,#mermaid-svg-iHEI6X0tNxnJXqEV .icon-shape .label{text-align:center;}#mermaid-svg-iHEI6X0tNxnJXqEV .node.clickable{cursor:pointer;}#mermaid-svg-iHEI6X0tNxnJXqEV .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-iHEI6X0tNxnJXqEV .arrowheadPath{fill:#333333;}#mermaid-svg-iHEI6X0tNxnJXqEV .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-iHEI6X0tNxnJXqEV .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-iHEI6X0tNxnJXqEV .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-iHEI6X0tNxnJXqEV .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-iHEI6X0tNxnJXqEV .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-iHEI6X0tNxnJXqEV .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-iHEI6X0tNxnJXqEV .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-iHEI6X0tNxnJXqEV .cluster text{fill:#333;}#mermaid-svg-iHEI6X0tNxnJXqEV .cluster span{color:#333;}#mermaid-svg-iHEI6X0tNxnJXqEV div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-iHEI6X0tNxnJXqEV .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-iHEI6X0tNxnJXqEV rect.text{fill:none;stroke-width:0;}#mermaid-svg-iHEI6X0tNxnJXqEV .icon-shape,#mermaid-svg-iHEI6X0tNxnJXqEV .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-iHEI6X0tNxnJXqEV .icon-shape p,#mermaid-svg-iHEI6X0tNxnJXqEV .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-iHEI6X0tNxnJXqEV .icon-shape .label rect,#mermaid-svg-iHEI6X0tNxnJXqEV .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-iHEI6X0tNxnJXqEV .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-iHEI6X0tNxnJXqEV .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-iHEI6X0tNxnJXqEV :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    发现 todo!/unimplemented!

    通过

    graph_complete 候选

    Stub 门纯文件扫描

    立即阻止

    Layer 2 硬验收门

    操作者 manifest

    [verify:] 回放

    工具链探测门go.mod / Cargo.toml / package.json

    退出码 = 0?

    Layer 3 交付物对账

    强制返工

    6.4 Stub 门(规则独立的接地信号)

    Green build 可能掩盖缺失的功能实现——todo!() 编译能通过,但运行就崩。Zagens 在 Layer 2 之前插入一个纯文件扫描的 stub 门:

    • 阻塞级(enforce):todo!()、unimplemented!()、NotImplementedError、throw/panic!/raise + “not implemented” 句式 → 立即阻止完成;
    • 记录级:纯 TODO/FIXME 注释 → 从不阻塞,仅计 telemetry。

    这层门在 graph_complete 候选时先于 Layer 2/3 执行——纯文件扫描几乎零开销,如果发现 stub 就没必要花几分钟跑构建了。


    7. Layer 3:交付物对账 —— 抓到模型从未分解进 checklist 的项

    Layer 2 能阻止「测试没过但模型声称过了」,但它不能捕获「模型从未写在 checklist 里的交付物」——这才是 MicroStack02 的核心失败模式。

    Layer 3 在 Layer 2 全绿后,用纯 Rust 同步扫描(非 agent_spawn、非 LLM)对工作区做 path/glob/tracked 对账,可选每项跑 optional_verify_cmd:

    #mermaid-svg-WuGhqxA1bnb0hMVa{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-WuGhqxA1bnb0hMVa .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-WuGhqxA1bnb0hMVa .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-WuGhqxA1bnb0hMVa .error-icon{fill:#552222;}#mermaid-svg-WuGhqxA1bnb0hMVa .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-WuGhqxA1bnb0hMVa .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-WuGhqxA1bnb0hMVa .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-WuGhqxA1bnb0hMVa .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-WuGhqxA1bnb0hMVa .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-WuGhqxA1bnb0hMVa .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-WuGhqxA1bnb0hMVa .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-WuGhqxA1bnb0hMVa .marker{fill:#333333;stroke:#333333;}#mermaid-svg-WuGhqxA1bnb0hMVa .marker.cross{stroke:#333333;}#mermaid-svg-WuGhqxA1bnb0hMVa svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-WuGhqxA1bnb0hMVa p{margin:0;}#mermaid-svg-WuGhqxA1bnb0hMVa .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-WuGhqxA1bnb0hMVa .cluster-label text{fill:#333;}#mermaid-svg-WuGhqxA1bnb0hMVa .cluster-label span{color:#333;}#mermaid-svg-WuGhqxA1bnb0hMVa .cluster-label span p{background-color:transparent;}#mermaid-svg-WuGhqxA1bnb0hMVa .label text,#mermaid-svg-WuGhqxA1bnb0hMVa span{fill:#333;color:#333;}#mermaid-svg-WuGhqxA1bnb0hMVa .node rect,#mermaid-svg-WuGhqxA1bnb0hMVa .node circle,#mermaid-svg-WuGhqxA1bnb0hMVa .node ellipse,#mermaid-svg-WuGhqxA1bnb0hMVa .node polygon,#mermaid-svg-WuGhqxA1bnb0hMVa .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-WuGhqxA1bnb0hMVa .rough-node .label text,#mermaid-svg-WuGhqxA1bnb0hMVa .node .label text,#mermaid-svg-WuGhqxA1bnb0hMVa .image-shape .label,#mermaid-svg-WuGhqxA1bnb0hMVa .icon-shape .label{text-anchor:middle;}#mermaid-svg-WuGhqxA1bnb0hMVa .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-WuGhqxA1bnb0hMVa .rough-node .label,#mermaid-svg-WuGhqxA1bnb0hMVa .node .label,#mermaid-svg-WuGhqxA1bnb0hMVa .image-shape .label,#mermaid-svg-WuGhqxA1bnb0hMVa .icon-shape .label{text-align:center;}#mermaid-svg-WuGhqxA1bnb0hMVa .node.clickable{cursor:pointer;}#mermaid-svg-WuGhqxA1bnb0hMVa .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-WuGhqxA1bnb0hMVa .arrowheadPath{fill:#333333;}#mermaid-svg-WuGhqxA1bnb0hMVa .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-WuGhqxA1bnb0hMVa .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-WuGhqxA1bnb0hMVa .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-WuGhqxA1bnb0hMVa .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-WuGhqxA1bnb0hMVa .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-WuGhqxA1bnb0hMVa .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-WuGhqxA1bnb0hMVa .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-WuGhqxA1bnb0hMVa .cluster text{fill:#333;}#mermaid-svg-WuGhqxA1bnb0hMVa .cluster span{color:#333;}#mermaid-svg-WuGhqxA1bnb0hMVa div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-WuGhqxA1bnb0hMVa .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-WuGhqxA1bnb0hMVa rect.text{fill:none;stroke-width:0;}#mermaid-svg-WuGhqxA1bnb0hMVa .icon-shape,#mermaid-svg-WuGhqxA1bnb0hMVa .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-WuGhqxA1bnb0hMVa .icon-shape p,#mermaid-svg-WuGhqxA1bnb0hMVa .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-WuGhqxA1bnb0hMVa .icon-shape .label rect,#mermaid-svg-WuGhqxA1bnb0hMVa .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-WuGhqxA1bnb0hMVa .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-WuGhqxA1bnb0hMVa .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-WuGhqxA1bnb0hMVa :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    退出码 ≠ 0

    通过

    操作者预声明交付物 manifest

    纯 Rust 同步扫描非 agent_spawn · 非 LLM

    路径/glob存在?

    missing_deliverables

    可选 verify命令

    不通过

    pass: true

    结构化 JSON 输出离线可回放

    操作者在 ~/.zagens/config.toml 中声明 [[long_horizon.completion_gate.deliverable]](完整回归夹具见 fixtures/harness/microstack-completion-gate.toml):

    [[long_horizon.completion_gate.deliverable]]
    id = "gzip_middleware"
    path = "middleware/gzip.go"

    [[long_horizon.completion_gate.deliverable]]
    id = "deliverable_24_refactor"
    glob = "**/*trie*.go"
    optional_verify_cmd = "go test ./… -run Refactor"

    [[long_horizon.completion_gate.deliverable]]
    id = "contracts_frozen"
    path = "contracts/server.go"
    tracked = true # 须 git 仓库且已 commit,否则无基线

    扫描完成后输出结构化 JSON,例如:

    {
    "pass": false,
    "missing_deliverables": [
    {"id": "gzip_middleware", "what": "middleware/gzip.go does not exist", "evidence": "workspace path missing"},
    {"id": "deliverable_24_refactor", "what": "Router trie refactor not executed", "evidence": "glob router/*trie* zero hits"}
    ],
    "manifest_round": 2
    }

    pass 只取决于退出码和路径命中——不依赖任何 LLM 的「感觉」,纯函数输出,离线可回放,可做快照回归。

    诚实上限

    三层门禁各自有界计数器:max_manifest_rounds、max_audit_rounds。如果耗尽而门仍未全绿,不会无限循环,而是记录 audit_unmet + 未达标门列表,不产生虚假绿灯。


    8. Cycle & Handoff:可信的回合间交接

    长程任务往往单次会话的上下文窗口不够。Zagens 通过 **Cycle(循环)**机制实现上下文无缝交接。

    8.1 触发条件

    条件默认
    活动输入 token ≥ 阈值 768K(约 1M 窗口的 75%)
    无飞行中的工具/流/审批 in_flight: false
    LHT 增强 在 75–85% 警告带内,优先在 checklist item 完成时触发,避开编辑中途

    8.2 交接内容

    每次 cycle 交接有两层:

    #mermaid-svg-LHX50Y1WgE3w1f6F{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-LHX50Y1WgE3w1f6F .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-LHX50Y1WgE3w1f6F .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-LHX50Y1WgE3w1f6F .error-icon{fill:#552222;}#mermaid-svg-LHX50Y1WgE3w1f6F .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-LHX50Y1WgE3w1f6F .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-LHX50Y1WgE3w1f6F .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-LHX50Y1WgE3w1f6F .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-LHX50Y1WgE3w1f6F .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-LHX50Y1WgE3w1f6F .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-LHX50Y1WgE3w1f6F .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-LHX50Y1WgE3w1f6F .marker{fill:#333333;stroke:#333333;}#mermaid-svg-LHX50Y1WgE3w1f6F .marker.cross{stroke:#333333;}#mermaid-svg-LHX50Y1WgE3w1f6F svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-LHX50Y1WgE3w1f6F p{margin:0;}#mermaid-svg-LHX50Y1WgE3w1f6F .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-LHX50Y1WgE3w1f6F .cluster-label text{fill:#333;}#mermaid-svg-LHX50Y1WgE3w1f6F .cluster-label span{color:#333;}#mermaid-svg-LHX50Y1WgE3w1f6F .cluster-label span p{background-color:transparent;}#mermaid-svg-LHX50Y1WgE3w1f6F .label text,#mermaid-svg-LHX50Y1WgE3w1f6F span{fill:#333;color:#333;}#mermaid-svg-LHX50Y1WgE3w1f6F .node rect,#mermaid-svg-LHX50Y1WgE3w1f6F .node circle,#mermaid-svg-LHX50Y1WgE3w1f6F .node ellipse,#mermaid-svg-LHX50Y1WgE3w1f6F .node polygon,#mermaid-svg-LHX50Y1WgE3w1f6F .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-LHX50Y1WgE3w1f6F .rough-node .label text,#mermaid-svg-LHX50Y1WgE3w1f6F .node .label text,#mermaid-svg-LHX50Y1WgE3w1f6F .image-shape .label,#mermaid-svg-LHX50Y1WgE3w1f6F .icon-shape .label{text-anchor:middle;}#mermaid-svg-LHX50Y1WgE3w1f6F .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-LHX50Y1WgE3w1f6F .rough-node .label,#mermaid-svg-LHX50Y1WgE3w1f6F .node .label,#mermaid-svg-LHX50Y1WgE3w1f6F .image-shape .label,#mermaid-svg-LHX50Y1WgE3w1f6F .icon-shape .label{text-align:center;}#mermaid-svg-LHX50Y1WgE3w1f6F .node.clickable{cursor:pointer;}#mermaid-svg-LHX50Y1WgE3w1f6F .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-LHX50Y1WgE3w1f6F .arrowheadPath{fill:#333333;}#mermaid-svg-LHX50Y1WgE3w1f6F .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-LHX50Y1WgE3w1f6F .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-LHX50Y1WgE3w1f6F .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-LHX50Y1WgE3w1f6F .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-LHX50Y1WgE3w1f6F .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-LHX50Y1WgE3w1f6F .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-LHX50Y1WgE3w1f6F .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-LHX50Y1WgE3w1f6F .cluster text{fill:#333;}#mermaid-svg-LHX50Y1WgE3w1f6F .cluster span{color:#333;}#mermaid-svg-LHX50Y1WgE3w1f6F div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-LHX50Y1WgE3w1f6F .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-LHX50Y1WgE3w1f6F rect.text{fill:none;stroke-width:0;}#mermaid-svg-LHX50Y1WgE3w1f6F .icon-shape,#mermaid-svg-LHX50Y1WgE3w1f6F .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-LHX50Y1WgE3w1f6F .icon-shape p,#mermaid-svg-LHX50Y1WgE3w1f6F .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-LHX50Y1WgE3w1f6F .icon-shape .label rect,#mermaid-svg-LHX50Y1WgE3w1f6F .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-LHX50Y1WgE3w1f6F .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-LHX50Y1WgE3w1f6F .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-LHX50Y1WgE3w1f6F :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    层 2: Carry Forward(模型手写)

    长程目标(一行)

    待办 item ids

    上次验证命令与结果

    正在编辑的文件路径

    失败方案 / 约束

    层 1: StructuredState(自动保留)

    模式 / 工作区 / cwd

    plan → 阶段列表 + 状态标记

    checklist → 进度 + 未完成项

    working set → 最近读写文件

    sub-agent → id + role + objective

    audit scratchpad → run_id

    Cycle 触发条件

    活动 token ≥ 768K

    in_flight: false

    LHT: 优先在 checklist item 完成时

    Cycle 交接

    新 Cycle 会话

    层 1(StructuredState)由引擎确定性保留;层 2(carry_forward)由模型在 cycle 边界手写。Carry forward 模板示例:

    Also include in <carry_forward>:
    – Long-horizon objective (one line)
    – Open checklist/plan item ids or labels still pending
    – Last verification command and outcome (pass/fail/not run)
    – Files currently being edited (paths only)
    – Failed approaches / constraints

    8.3 可视化的 Cycle 时间线

    下图仅为示意,不代表真实耗时。

    #mermaid-svg-dsCYwX4WAwpnZlzZ{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-dsCYwX4WAwpnZlzZ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-dsCYwX4WAwpnZlzZ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-dsCYwX4WAwpnZlzZ .error-icon{fill:#552222;}#mermaid-svg-dsCYwX4WAwpnZlzZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-dsCYwX4WAwpnZlzZ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-dsCYwX4WAwpnZlzZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-dsCYwX4WAwpnZlzZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-dsCYwX4WAwpnZlzZ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-dsCYwX4WAwpnZlzZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-dsCYwX4WAwpnZlzZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-dsCYwX4WAwpnZlzZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-dsCYwX4WAwpnZlzZ .marker.cross{stroke:#333333;}#mermaid-svg-dsCYwX4WAwpnZlzZ svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-dsCYwX4WAwpnZlzZ p{margin:0;}#mermaid-svg-dsCYwX4WAwpnZlzZ .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-dsCYwX4WAwpnZlzZ .cluster-label text{fill:#333;}#mermaid-svg-dsCYwX4WAwpnZlzZ .cluster-label span{color:#333;}#mermaid-svg-dsCYwX4WAwpnZlzZ .cluster-label span p{background-color:transparent;}#mermaid-svg-dsCYwX4WAwpnZlzZ .label text,#mermaid-svg-dsCYwX4WAwpnZlzZ span{fill:#333;color:#333;}#mermaid-svg-dsCYwX4WAwpnZlzZ .node rect,#mermaid-svg-dsCYwX4WAwpnZlzZ .node circle,#mermaid-svg-dsCYwX4WAwpnZlzZ .node ellipse,#mermaid-svg-dsCYwX4WAwpnZlzZ .node polygon,#mermaid-svg-dsCYwX4WAwpnZlzZ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-dsCYwX4WAwpnZlzZ .rough-node .label text,#mermaid-svg-dsCYwX4WAwpnZlzZ .node .label text,#mermaid-svg-dsCYwX4WAwpnZlzZ .image-shape .label,#mermaid-svg-dsCYwX4WAwpnZlzZ .icon-shape .label{text-anchor:middle;}#mermaid-svg-dsCYwX4WAwpnZlzZ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-dsCYwX4WAwpnZlzZ .rough-node .label,#mermaid-svg-dsCYwX4WAwpnZlzZ .node .label,#mermaid-svg-dsCYwX4WAwpnZlzZ .image-shape .label,#mermaid-svg-dsCYwX4WAwpnZlzZ .icon-shape .label{text-align:center;}#mermaid-svg-dsCYwX4WAwpnZlzZ .node.clickable{cursor:pointer;}#mermaid-svg-dsCYwX4WAwpnZlzZ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-dsCYwX4WAwpnZlzZ .arrowheadPath{fill:#333333;}#mermaid-svg-dsCYwX4WAwpnZlzZ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-dsCYwX4WAwpnZlzZ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-dsCYwX4WAwpnZlzZ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-dsCYwX4WAwpnZlzZ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-dsCYwX4WAwpnZlzZ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-dsCYwX4WAwpnZlzZ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-dsCYwX4WAwpnZlzZ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-dsCYwX4WAwpnZlzZ .cluster text{fill:#333;}#mermaid-svg-dsCYwX4WAwpnZlzZ .cluster span{color:#333;}#mermaid-svg-dsCYwX4WAwpnZlzZ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-dsCYwX4WAwpnZlzZ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-dsCYwX4WAwpnZlzZ rect.text{fill:none;stroke-width:0;}#mermaid-svg-dsCYwX4WAwpnZlzZ .icon-shape,#mermaid-svg-dsCYwX4WAwpnZlzZ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-dsCYwX4WAwpnZlzZ .icon-shape p,#mermaid-svg-dsCYwX4WAwpnZlzZ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-dsCYwX4WAwpnZlzZ .icon-shape .label rect,#mermaid-svg-dsCYwX4WAwpnZlzZ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-dsCYwX4WAwpnZlzZ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-dsCYwX4WAwpnZlzZ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-dsCYwX4WAwpnZlzZ :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    token ≥ 768K

    再次触线

    Cycle 1实现 + 工具调用

    交接StructuredState + carry_forward

    Cycle 2继续实现

    交接

    Cycle 3收尾验证

    用户在 LongHorizonPanel 的 Cycle 标签页中可以看到:

    • 当前 cycle 编号 + 时间线;
    • 每轮 carry_forward 摘要(可展开预览);
    • 768K 警告线与当前上下文使用量的对比。

    9. 宏观循环(Phase 4):LHT ↔ CRAFT 交替

    何时启用: 默认长程任务 Layer 1–3 + Cycle 即可。Macro Loop 面向 15K–20K 行级超大重构,在实现与 QA 之间交替多轮;回归基线见 fixtures/harness/lht-eval-arms/lht_long_refactor.toml。

    CRAFT(Implementer + Reviewer + Verifier 多代理段)负责质量闭环与缺口识别,没有 graph_complete 放行权——最终仍由 Layer 2/3 机器门裁决。

    Zagens 实现了 Phase 4 Macro Loop——在 LHT 实现段和 CRAFT QA 段之间交替:

    #mermaid-svg-nCOAot3bcCPdEJm2{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-nCOAot3bcCPdEJm2 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-nCOAot3bcCPdEJm2 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-nCOAot3bcCPdEJm2 .error-icon{fill:#552222;}#mermaid-svg-nCOAot3bcCPdEJm2 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-nCOAot3bcCPdEJm2 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-nCOAot3bcCPdEJm2 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-nCOAot3bcCPdEJm2 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-nCOAot3bcCPdEJm2 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-nCOAot3bcCPdEJm2 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-nCOAot3bcCPdEJm2 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-nCOAot3bcCPdEJm2 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-nCOAot3bcCPdEJm2 .marker.cross{stroke:#333333;}#mermaid-svg-nCOAot3bcCPdEJm2 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-nCOAot3bcCPdEJm2 p{margin:0;}#mermaid-svg-nCOAot3bcCPdEJm2 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-nCOAot3bcCPdEJm2 .cluster-label text{fill:#333;}#mermaid-svg-nCOAot3bcCPdEJm2 .cluster-label span{color:#333;}#mermaid-svg-nCOAot3bcCPdEJm2 .cluster-label span p{background-color:transparent;}#mermaid-svg-nCOAot3bcCPdEJm2 .label text,#mermaid-svg-nCOAot3bcCPdEJm2 span{fill:#333;color:#333;}#mermaid-svg-nCOAot3bcCPdEJm2 .node rect,#mermaid-svg-nCOAot3bcCPdEJm2 .node circle,#mermaid-svg-nCOAot3bcCPdEJm2 .node ellipse,#mermaid-svg-nCOAot3bcCPdEJm2 .node polygon,#mermaid-svg-nCOAot3bcCPdEJm2 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-nCOAot3bcCPdEJm2 .rough-node .label text,#mermaid-svg-nCOAot3bcCPdEJm2 .node .label text,#mermaid-svg-nCOAot3bcCPdEJm2 .image-shape .label,#mermaid-svg-nCOAot3bcCPdEJm2 .icon-shape .label{text-anchor:middle;}#mermaid-svg-nCOAot3bcCPdEJm2 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-nCOAot3bcCPdEJm2 .rough-node .label,#mermaid-svg-nCOAot3bcCPdEJm2 .node .label,#mermaid-svg-nCOAot3bcCPdEJm2 .image-shape .label,#mermaid-svg-nCOAot3bcCPdEJm2 .icon-shape .label{text-align:center;}#mermaid-svg-nCOAot3bcCPdEJm2 .node.clickable{cursor:pointer;}#mermaid-svg-nCOAot3bcCPdEJm2 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-nCOAot3bcCPdEJm2 .arrowheadPath{fill:#333333;}#mermaid-svg-nCOAot3bcCPdEJm2 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-nCOAot3bcCPdEJm2 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-nCOAot3bcCPdEJm2 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-nCOAot3bcCPdEJm2 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-nCOAot3bcCPdEJm2 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-nCOAot3bcCPdEJm2 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-nCOAot3bcCPdEJm2 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-nCOAot3bcCPdEJm2 .cluster text{fill:#333;}#mermaid-svg-nCOAot3bcCPdEJm2 .cluster span{color:#333;}#mermaid-svg-nCOAot3bcCPdEJm2 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-nCOAot3bcCPdEJm2 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-nCOAot3bcCPdEJm2 rect.text{fill:none;stroke-width:0;}#mermaid-svg-nCOAot3bcCPdEJm2 .icon-shape,#mermaid-svg-nCOAot3bcCPdEJm2 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-nCOAot3bcCPdEJm2 .icon-shape p,#mermaid-svg-nCOAot3bcCPdEJm2 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-nCOAot3bcCPdEJm2 .icon-shape .label rect,#mermaid-svg-nCOAot3bcCPdEJm2 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-nCOAot3bcCPdEJm2 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-nCOAot3bcCPdEJm2 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-nCOAot3bcCPdEJm2 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    代码实现

    识别缺口

    Layer 1–3

    验证通过

    auto_continue

    CRAFT QA 段

    Implementer

    Reviewer

    Verifier

    LHT 实现段

    Layer 1 防早停

    Layer 2 退出码门

    Layer 3 交付物对账

    LHT 修复段

    完成 / 下一轮

    每轮 LHT 段使用 Layer 1–3 门禁推进代码实现;CRAFT 段使用多代理(Implementer + Reviewer + Verifier)做质量闭环。Macro Loop 的 auto_continue 机制让这个过程可以无人值守地跑多个回合。

    这个宏循环的回归基线固定在 fixtures/harness/lht-eval-arms/lht_long_refactor.toml 中,作为 CI 的定期验证夹具。


    10. 对抗审计器:Agent 独立的缺口枚举器

    可选扩展: 默认 Stub 门 + Layer 2/3 已覆盖大多数场景。对抗审计在 config.toml 中 opt-in 启用,用于 Stub 扫不到的「无标记占位实现」或「规格有、清单无」的缺口枚举。

    Layer 2 的 stub 门(正则扫描)只能捕获标记明确的残缺实现。对「函数体返回 return Ok(()) 占位但没有标记」或「整个模块从未进入 checklist」这类情况,需要另一个 Agent 来发现。

    但这里有一个微妙的设计边界:「法官」vs「缺口枚举器」。

    法官型(禁止)缺口枚举器型(允许)
    权力 直接判 pass/fail,放行或阻塞 没有放行/否决权;只输出「疑似缺口」候选
    输出 “LGTM/不通过” 散文 机器可测试的断言:{file:line, 缺什么, 建议的 [verify: cmd]}
    谁最终裁决 自身(软的、可说服的、不可回放) 仍然是机器 Oracle——候选注入后,stub 门/退出码/路径对账来裁决
    失败模式 审计者-建设者共谋盖章 最坏情况「报几个假缺口」,机器门一跑就驳回了

    对抗审计器的输出永远不直接进入 graph_complete 的放行/阻塞判断;它只能扩展机器的门禁检查面。最终绿灯仍然由退出码和路径命中决定。

    #mermaid-svg-u0dNAROFnExZFVEG{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-u0dNAROFnExZFVEG .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-u0dNAROFnExZFVEG .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-u0dNAROFnExZFVEG .error-icon{fill:#552222;}#mermaid-svg-u0dNAROFnExZFVEG .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-u0dNAROFnExZFVEG .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-u0dNAROFnExZFVEG .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-u0dNAROFnExZFVEG .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-u0dNAROFnExZFVEG .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-u0dNAROFnExZFVEG .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-u0dNAROFnExZFVEG .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-u0dNAROFnExZFVEG .marker{fill:#333333;stroke:#333333;}#mermaid-svg-u0dNAROFnExZFVEG .marker.cross{stroke:#333333;}#mermaid-svg-u0dNAROFnExZFVEG svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-u0dNAROFnExZFVEG p{margin:0;}#mermaid-svg-u0dNAROFnExZFVEG .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-u0dNAROFnExZFVEG .cluster-label text{fill:#333;}#mermaid-svg-u0dNAROFnExZFVEG .cluster-label span{color:#333;}#mermaid-svg-u0dNAROFnExZFVEG .cluster-label span p{background-color:transparent;}#mermaid-svg-u0dNAROFnExZFVEG .label text,#mermaid-svg-u0dNAROFnExZFVEG span{fill:#333;color:#333;}#mermaid-svg-u0dNAROFnExZFVEG .node rect,#mermaid-svg-u0dNAROFnExZFVEG .node circle,#mermaid-svg-u0dNAROFnExZFVEG .node ellipse,#mermaid-svg-u0dNAROFnExZFVEG .node polygon,#mermaid-svg-u0dNAROFnExZFVEG .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-u0dNAROFnExZFVEG .rough-node .label text,#mermaid-svg-u0dNAROFnExZFVEG .node .label text,#mermaid-svg-u0dNAROFnExZFVEG .image-shape .label,#mermaid-svg-u0dNAROFnExZFVEG .icon-shape .label{text-anchor:middle;}#mermaid-svg-u0dNAROFnExZFVEG .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-u0dNAROFnExZFVEG .rough-node .label,#mermaid-svg-u0dNAROFnExZFVEG .node .label,#mermaid-svg-u0dNAROFnExZFVEG .image-shape .label,#mermaid-svg-u0dNAROFnExZFVEG .icon-shape .label{text-align:center;}#mermaid-svg-u0dNAROFnExZFVEG .node.clickable{cursor:pointer;}#mermaid-svg-u0dNAROFnExZFVEG .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-u0dNAROFnExZFVEG .arrowheadPath{fill:#333333;}#mermaid-svg-u0dNAROFnExZFVEG .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-u0dNAROFnExZFVEG .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-u0dNAROFnExZFVEG .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-u0dNAROFnExZFVEG .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-u0dNAROFnExZFVEG .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-u0dNAROFnExZFVEG .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-u0dNAROFnExZFVEG .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-u0dNAROFnExZFVEG .cluster text{fill:#333;}#mermaid-svg-u0dNAROFnExZFVEG .cluster span{color:#333;}#mermaid-svg-u0dNAROFnExZFVEG div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-u0dNAROFnExZFVEG .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-u0dNAROFnExZFVEG rect.text{fill:none;stroke-width:0;}#mermaid-svg-u0dNAROFnExZFVEG .icon-shape,#mermaid-svg-u0dNAROFnExZFVEG .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-u0dNAROFnExZFVEG .icon-shape p,#mermaid-svg-u0dNAROFnExZFVEG .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-u0dNAROFnExZFVEG .icon-shape .label rect,#mermaid-svg-u0dNAROFnExZFVEG .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-u0dNAROFnExZFVEG .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-u0dNAROFnExZFVEG .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-u0dNAROFnExZFVEG :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    全绿

    未通过

    禁止直连

    对抗审计 Agent缺口枚举器

    输出候选file:line · 缺什么 · verify 建议

    注入门禁检查面

    Stub 门扫描

    退出码 Oracle

    路径/glob 对账

    机器裁决

    ✅ graph_complete

    返工 / audit_unmet

    ❌ 直接放行/阻塞


    11. 可视化:让完成度可见

    Harness 产生事实,可视化让事实可见。

    Zagens 的桌面 UI 中有一个 2×2 的 Harness Grid:

    #mermaid-svg-4Y3urxoutt3zmRWs{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-4Y3urxoutt3zmRWs .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-4Y3urxoutt3zmRWs .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-4Y3urxoutt3zmRWs .error-icon{fill:#552222;}#mermaid-svg-4Y3urxoutt3zmRWs .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-4Y3urxoutt3zmRWs .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-4Y3urxoutt3zmRWs .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-4Y3urxoutt3zmRWs .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-4Y3urxoutt3zmRWs .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-4Y3urxoutt3zmRWs .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-4Y3urxoutt3zmRWs .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-4Y3urxoutt3zmRWs .marker{fill:#333333;stroke:#333333;}#mermaid-svg-4Y3urxoutt3zmRWs .marker.cross{stroke:#333333;}#mermaid-svg-4Y3urxoutt3zmRWs svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-4Y3urxoutt3zmRWs p{margin:0;}#mermaid-svg-4Y3urxoutt3zmRWs .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-4Y3urxoutt3zmRWs .cluster-label text{fill:#333;}#mermaid-svg-4Y3urxoutt3zmRWs .cluster-label span{color:#333;}#mermaid-svg-4Y3urxoutt3zmRWs .cluster-label span p{background-color:transparent;}#mermaid-svg-4Y3urxoutt3zmRWs .label text,#mermaid-svg-4Y3urxoutt3zmRWs span{fill:#333;color:#333;}#mermaid-svg-4Y3urxoutt3zmRWs .node rect,#mermaid-svg-4Y3urxoutt3zmRWs .node circle,#mermaid-svg-4Y3urxoutt3zmRWs .node ellipse,#mermaid-svg-4Y3urxoutt3zmRWs .node polygon,#mermaid-svg-4Y3urxoutt3zmRWs .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-4Y3urxoutt3zmRWs .rough-node .label text,#mermaid-svg-4Y3urxoutt3zmRWs .node .label text,#mermaid-svg-4Y3urxoutt3zmRWs .image-shape .label,#mermaid-svg-4Y3urxoutt3zmRWs .icon-shape .label{text-anchor:middle;}#mermaid-svg-4Y3urxoutt3zmRWs .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-4Y3urxoutt3zmRWs .rough-node .label,#mermaid-svg-4Y3urxoutt3zmRWs .node .label,#mermaid-svg-4Y3urxoutt3zmRWs .image-shape .label,#mermaid-svg-4Y3urxoutt3zmRWs .icon-shape .label{text-align:center;}#mermaid-svg-4Y3urxoutt3zmRWs .node.clickable{cursor:pointer;}#mermaid-svg-4Y3urxoutt3zmRWs .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-4Y3urxoutt3zmRWs .arrowheadPath{fill:#333333;}#mermaid-svg-4Y3urxoutt3zmRWs .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-4Y3urxoutt3zmRWs .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-4Y3urxoutt3zmRWs .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-4Y3urxoutt3zmRWs .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-4Y3urxoutt3zmRWs .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-4Y3urxoutt3zmRWs .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-4Y3urxoutt3zmRWs .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-4Y3urxoutt3zmRWs .cluster text{fill:#333;}#mermaid-svg-4Y3urxoutt3zmRWs .cluster span{color:#333;}#mermaid-svg-4Y3urxoutt3zmRWs div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-4Y3urxoutt3zmRWs .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-4Y3urxoutt3zmRWs rect.text{fill:none;stroke-width:0;}#mermaid-svg-4Y3urxoutt3zmRWs .icon-shape,#mermaid-svg-4Y3urxoutt3zmRWs .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-4Y3urxoutt3zmRWs .icon-shape p,#mermaid-svg-4Y3urxoutt3zmRWs .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-4Y3urxoutt3zmRWs .icon-shape .label rect,#mermaid-svg-4Y3urxoutt3zmRWs .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-4Y3urxoutt3zmRWs .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-4Y3urxoutt3zmRWs .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-4Y3urxoutt3zmRWs :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    下排

    LongHorizonPanelTask Graph · Cycles · Context门禁状态 · 768K 阈值

    AgentPanelSub-agents / CRAFT

    上排

    ChecklistPanel计划与 checklist 进度

    AuditScratchpadPanel审计草稿与恢复区

    LongHorizonPanel 有三个子标签页:Task Graph(计划/checklist/门禁摘要)、Cycle(时间线与 carry_forward)、Context(768K 阈值 vs 上限)。

    读屏场景:如何判断「真完成」?

    你看到的含义建议
    Task Graph 100% + 门禁全绿 Layer 2/3 已通过 ✅ 可信任完成
    Checklist 100% + 门禁琥珀色「有条件完成」 checklist 全勾但 manifest 未绿或 observe 缺口 继续让模型返工或检查 config
    Nodes 有 gate_skip graph_complete 但无 manifest_gate_result 未启用 completion_gate 考虑打开 Layer 2/3
    Nodes 有 audit_unmet 有界轮次耗尽 人工介入,不假绿

    Nodes 标签页记录 Harness 决策流:

    #mermaid-svg-X6WFUvcdg3NGGIfn{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-X6WFUvcdg3NGGIfn .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-X6WFUvcdg3NGGIfn .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-X6WFUvcdg3NGGIfn .error-icon{fill:#552222;}#mermaid-svg-X6WFUvcdg3NGGIfn .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-X6WFUvcdg3NGGIfn .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-X6WFUvcdg3NGGIfn .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-X6WFUvcdg3NGGIfn .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-X6WFUvcdg3NGGIfn .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-X6WFUvcdg3NGGIfn .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-X6WFUvcdg3NGGIfn .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-X6WFUvcdg3NGGIfn .marker{fill:#333333;stroke:#333333;}#mermaid-svg-X6WFUvcdg3NGGIfn .marker.cross{stroke:#333333;}#mermaid-svg-X6WFUvcdg3NGGIfn svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-X6WFUvcdg3NGGIfn p{margin:0;}#mermaid-svg-X6WFUvcdg3NGGIfn .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-X6WFUvcdg3NGGIfn .cluster-label text{fill:#333;}#mermaid-svg-X6WFUvcdg3NGGIfn .cluster-label span{color:#333;}#mermaid-svg-X6WFUvcdg3NGGIfn .cluster-label span p{background-color:transparent;}#mermaid-svg-X6WFUvcdg3NGGIfn .label text,#mermaid-svg-X6WFUvcdg3NGGIfn span{fill:#333;color:#333;}#mermaid-svg-X6WFUvcdg3NGGIfn .node rect,#mermaid-svg-X6WFUvcdg3NGGIfn .node circle,#mermaid-svg-X6WFUvcdg3NGGIfn .node ellipse,#mermaid-svg-X6WFUvcdg3NGGIfn .node polygon,#mermaid-svg-X6WFUvcdg3NGGIfn .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-X6WFUvcdg3NGGIfn .rough-node .label text,#mermaid-svg-X6WFUvcdg3NGGIfn .node .label text,#mermaid-svg-X6WFUvcdg3NGGIfn .image-shape .label,#mermaid-svg-X6WFUvcdg3NGGIfn .icon-shape .label{text-anchor:middle;}#mermaid-svg-X6WFUvcdg3NGGIfn .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-X6WFUvcdg3NGGIfn .rough-node .label,#mermaid-svg-X6WFUvcdg3NGGIfn .node .label,#mermaid-svg-X6WFUvcdg3NGGIfn .image-shape .label,#mermaid-svg-X6WFUvcdg3NGGIfn .icon-shape .label{text-align:center;}#mermaid-svg-X6WFUvcdg3NGGIfn .node.clickable{cursor:pointer;}#mermaid-svg-X6WFUvcdg3NGGIfn .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-X6WFUvcdg3NGGIfn .arrowheadPath{fill:#333333;}#mermaid-svg-X6WFUvcdg3NGGIfn .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-X6WFUvcdg3NGGIfn .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-X6WFUvcdg3NGGIfn .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-X6WFUvcdg3NGGIfn .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-X6WFUvcdg3NGGIfn .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-X6WFUvcdg3NGGIfn .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-X6WFUvcdg3NGGIfn .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-X6WFUvcdg3NGGIfn .cluster text{fill:#333;}#mermaid-svg-X6WFUvcdg3NGGIfn .cluster span{color:#333;}#mermaid-svg-X6WFUvcdg3NGGIfn div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-X6WFUvcdg3NGGIfn .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-X6WFUvcdg3NGGIfn rect.text{fill:none;stroke-width:0;}#mermaid-svg-X6WFUvcdg3NGGIfn .icon-shape,#mermaid-svg-X6WFUvcdg3NGGIfn .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-X6WFUvcdg3NGGIfn .icon-shape p,#mermaid-svg-X6WFUvcdg3NGGIfn .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-X6WFUvcdg3NGGIfn .icon-shape .label rect,#mermaid-svg-X6WFUvcdg3NGGIfn .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-X6WFUvcdg3NGGIfn .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-X6WFUvcdg3NGGIfn .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-X6WFUvcdg3NGGIfn :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}#mermaid-svg-X6WFUvcdg3NGGIfn .green>*{fill:#dfd!important;stroke:#3a3!important;}#mermaid-svg-X6WFUvcdg3NGGIfn .green span{fill:#dfd!important;stroke:#3a3!important;}#mermaid-svg-X6WFUvcdg3NGGIfn .yellow>*{fill:#ffd!important;stroke:#fa0!important;}#mermaid-svg-X6WFUvcdg3NGGIfn .yellow span{fill:#ffd!important;stroke:#fa0!important;}#mermaid-svg-X6WFUvcdg3NGGIfn .red>*{fill:#fee!important;stroke:#c33!important;}#mermaid-svg-X6WFUvcdg3NGGIfn .red span{fill:#fee!important;stroke:#c33!important;}#mermaid-svg-X6WFUvcdg3NGGIfn .neutral>*{fill:#eef!important;stroke:#36c!important;}#mermaid-svg-X6WFUvcdg3NGGIfn .neutral span{fill:#eef!important;stroke:#36c!important;}

    Nodes 决策流(颜色编码)

    continue_injected

    step_limit_continue

    gate_skip

    blocked

    incomplete_stop

    audit_unmet

    verify_gate 裁决


    背景:DEMO3–6 压测序列

    代号载体主要发现
    DEMO3 ~2W 行 Go Monkey 解释器 unverified_acceptance 软提示→软门禁;[verify:] 纪律
    DEMO4 同上 step budget 耗尽无声早停 → maybe_continue_at_step_limit
    DEMO5 20K 行解释器 plan/checklist 双计数、verify_gate 文本匹配误报、cycle 阈值 mid-turn 不评估
    DEMO6 Monkey 双后端 checklist_write 批量更新绕过 verify_gate

    12. 经验教训与演化

    Zagens Harness 不是纸面设计——它在 DEMO3–DEMO6 四次实证压力测试中暴露出许多隐蔽问题,并逐一修补。以下是几个有普适性的教训:

    12.1 所有 turn 退出点都必须是 LHT 门禁

    最初 LHT 只挂载在 no-tool-uses 路径上。但 step budget 耗尽、loop_guard 截停、上下文溢出——每个外循环 break 路径都可能产生虚假的 Completed,必须系统性审计每个退出点。

    12.2 进展判定不能依赖文本匹配

    最初用 result_contains_success 检查 "exit code: 0" 子串来判定验证命令是否成功,但 exec_shell 成功路径返回的是裸 stdout(ok monkey/lexer 0.078s),根本不包含退出码信息。修复很简单:删除多余的文本检查,success 布尔值就是退出码 0 的权威信号。

    12.3 checklist 和 plan 不能算两份工作量

    DEMO5 中,模型创建了 12 个 plan 项但全部放弃(pending),同时用 checklist 推进了 19 项全部完成。原来的进度算法将两方面相加,结果 12 + 19 = 31 总项、12 项 pending,进度卡在 61%。修复:当 checklist 非空时,以 checklist 为完成度的权威来源。

    12.4 [verify:] 纪律是基础

    模型的 checklist 项经常把「可运行的验收」退化为「创建文件」项——“create example scripts” 在 checklist 中标记完成只是创建了文件,但从未真正跑过。Zagens 在 base.md 中强化了 checklist 写作纪律:任何需要运行的验收项必须写作 [verify: <command>] <label>,并在引擎层做了判断强化。

    12.5 门禁系统的天花板 = manifest 的完整性

    这是一个诚实的边界声明。Layer 3 保证「manifest 中的交付物不会漏掉」,但不能保证「规范中写了但 manifest 中没写的」。这本质上是把「模型欠分解」变成了「操作者欠写 manifest」。但 manifest 可以离线审查、可回归、可复用——比模型每次现场分解稳定得多。


    13. 测试与回归架

    Zagens Harness 的验证体系包括:

    #mermaid-svg-DYkYfzMaD8OdcdIW{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-DYkYfzMaD8OdcdIW .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-DYkYfzMaD8OdcdIW .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-DYkYfzMaD8OdcdIW .error-icon{fill:#552222;}#mermaid-svg-DYkYfzMaD8OdcdIW .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-DYkYfzMaD8OdcdIW .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-DYkYfzMaD8OdcdIW .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-DYkYfzMaD8OdcdIW .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-DYkYfzMaD8OdcdIW .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-DYkYfzMaD8OdcdIW .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-DYkYfzMaD8OdcdIW .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-DYkYfzMaD8OdcdIW .marker{fill:#333333;stroke:#333333;}#mermaid-svg-DYkYfzMaD8OdcdIW .marker.cross{stroke:#333333;}#mermaid-svg-DYkYfzMaD8OdcdIW svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-DYkYfzMaD8OdcdIW p{margin:0;}#mermaid-svg-DYkYfzMaD8OdcdIW .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-DYkYfzMaD8OdcdIW .cluster-label text{fill:#333;}#mermaid-svg-DYkYfzMaD8OdcdIW .cluster-label span{color:#333;}#mermaid-svg-DYkYfzMaD8OdcdIW .cluster-label span p{background-color:transparent;}#mermaid-svg-DYkYfzMaD8OdcdIW .label text,#mermaid-svg-DYkYfzMaD8OdcdIW span{fill:#333;color:#333;}#mermaid-svg-DYkYfzMaD8OdcdIW .node rect,#mermaid-svg-DYkYfzMaD8OdcdIW .node circle,#mermaid-svg-DYkYfzMaD8OdcdIW .node ellipse,#mermaid-svg-DYkYfzMaD8OdcdIW .node polygon,#mermaid-svg-DYkYfzMaD8OdcdIW .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-DYkYfzMaD8OdcdIW .rough-node .label text,#mermaid-svg-DYkYfzMaD8OdcdIW .node .label text,#mermaid-svg-DYkYfzMaD8OdcdIW .image-shape .label,#mermaid-svg-DYkYfzMaD8OdcdIW .icon-shape .label{text-anchor:middle;}#mermaid-svg-DYkYfzMaD8OdcdIW .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-DYkYfzMaD8OdcdIW .rough-node .label,#mermaid-svg-DYkYfzMaD8OdcdIW .node .label,#mermaid-svg-DYkYfzMaD8OdcdIW .image-shape .label,#mermaid-svg-DYkYfzMaD8OdcdIW .icon-shape .label{text-align:center;}#mermaid-svg-DYkYfzMaD8OdcdIW .node.clickable{cursor:pointer;}#mermaid-svg-DYkYfzMaD8OdcdIW .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-DYkYfzMaD8OdcdIW .arrowheadPath{fill:#333333;}#mermaid-svg-DYkYfzMaD8OdcdIW .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-DYkYfzMaD8OdcdIW .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-DYkYfzMaD8OdcdIW .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-DYkYfzMaD8OdcdIW .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-DYkYfzMaD8OdcdIW .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-DYkYfzMaD8OdcdIW .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-DYkYfzMaD8OdcdIW .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-DYkYfzMaD8OdcdIW .cluster text{fill:#333;}#mermaid-svg-DYkYfzMaD8OdcdIW .cluster span{color:#333;}#mermaid-svg-DYkYfzMaD8OdcdIW div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-DYkYfzMaD8OdcdIW .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-DYkYfzMaD8OdcdIW rect.text{fill:none;stroke-width:0;}#mermaid-svg-DYkYfzMaD8OdcdIW .icon-shape,#mermaid-svg-DYkYfzMaD8OdcdIW .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-DYkYfzMaD8OdcdIW .icon-shape p,#mermaid-svg-DYkYfzMaD8OdcdIW .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-DYkYfzMaD8OdcdIW .icon-shape .label rect,#mermaid-svg-DYkYfzMaD8OdcdIW .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-DYkYfzMaD8OdcdIW .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-DYkYfzMaD8OdcdIW .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-DYkYfzMaD8OdcdIW :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    CI: verify-workspace.sh+ verify-lint.sh

    kernel-v3-replay/

    microstack-completion-gate.toml

    lht-harness-baseline.json

    strict-task-seed/

    lht_long_refactor.toml

    夹具路径均在 fixtures/harness/ 下;设计规格见 docs/harness/COMPOSABLE_HARNESS.md。


    14. 结语

    Zagens 的 Harness 工程回答了一个核心问题:当 AI Agent 说「我做完了」时,你怎么知道它是真的做完了?

    答案不是信任模型,而是构建一整套独立于模型的机器门禁系统:

    #mermaid-svg-ZmDB5QhshjFC06El{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ZmDB5QhshjFC06El .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ZmDB5QhshjFC06El .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ZmDB5QhshjFC06El .error-icon{fill:#552222;}#mermaid-svg-ZmDB5QhshjFC06El .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ZmDB5QhshjFC06El .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ZmDB5QhshjFC06El .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ZmDB5QhshjFC06El .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ZmDB5QhshjFC06El .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ZmDB5QhshjFC06El .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ZmDB5QhshjFC06El .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ZmDB5QhshjFC06El .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ZmDB5QhshjFC06El .marker.cross{stroke:#333333;}#mermaid-svg-ZmDB5QhshjFC06El svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ZmDB5QhshjFC06El p{margin:0;}#mermaid-svg-ZmDB5QhshjFC06El .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-ZmDB5QhshjFC06El .cluster-label text{fill:#333;}#mermaid-svg-ZmDB5QhshjFC06El .cluster-label span{color:#333;}#mermaid-svg-ZmDB5QhshjFC06El .cluster-label span p{background-color:transparent;}#mermaid-svg-ZmDB5QhshjFC06El .label text,#mermaid-svg-ZmDB5QhshjFC06El span{fill:#333;color:#333;}#mermaid-svg-ZmDB5QhshjFC06El .node rect,#mermaid-svg-ZmDB5QhshjFC06El .node circle,#mermaid-svg-ZmDB5QhshjFC06El .node ellipse,#mermaid-svg-ZmDB5QhshjFC06El .node polygon,#mermaid-svg-ZmDB5QhshjFC06El .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ZmDB5QhshjFC06El .rough-node .label text,#mermaid-svg-ZmDB5QhshjFC06El .node .label text,#mermaid-svg-ZmDB5QhshjFC06El .image-shape .label,#mermaid-svg-ZmDB5QhshjFC06El .icon-shape .label{text-anchor:middle;}#mermaid-svg-ZmDB5QhshjFC06El .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ZmDB5QhshjFC06El .rough-node .label,#mermaid-svg-ZmDB5QhshjFC06El .node .label,#mermaid-svg-ZmDB5QhshjFC06El .image-shape .label,#mermaid-svg-ZmDB5QhshjFC06El .icon-shape .label{text-align:center;}#mermaid-svg-ZmDB5QhshjFC06El .node.clickable{cursor:pointer;}#mermaid-svg-ZmDB5QhshjFC06El .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ZmDB5QhshjFC06El .arrowheadPath{fill:#333333;}#mermaid-svg-ZmDB5QhshjFC06El .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ZmDB5QhshjFC06El .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ZmDB5QhshjFC06El .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ZmDB5QhshjFC06El .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ZmDB5QhshjFC06El .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ZmDB5QhshjFC06El .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ZmDB5QhshjFC06El .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ZmDB5QhshjFC06El .cluster text{fill:#333;}#mermaid-svg-ZmDB5QhshjFC06El .cluster span{color:#333;}#mermaid-svg-ZmDB5QhshjFC06El div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ZmDB5QhshjFC06El .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ZmDB5QhshjFC06El rect.text{fill:none;stroke-width:0;}#mermaid-svg-ZmDB5QhshjFC06El .icon-shape,#mermaid-svg-ZmDB5QhshjFC06El .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ZmDB5QhshjFC06El .icon-shape p,#mermaid-svg-ZmDB5QhshjFC06El .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ZmDB5QhshjFC06El .icon-shape .label rect,#mermaid-svg-ZmDB5QhshjFC06El .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ZmDB5QhshjFC06El .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ZmDB5QhshjFC06El .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ZmDB5QhshjFC06El :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    Zagens Harness 全景

    上下文续命

    超大型重构

    扩展检查面

    Layer 1 · LHT防早停 · nudge 继续

    Layer 2 · 硬验收门退出码 Oracle

    Layer 3 · 交付物对账路径/glob 扫描

    Cycle 交接StructuredState + Carry Forward

    Macro LoopLHT ↔ CRAFT 交替

    对抗审计缺口枚举 → 机器门裁决

    可审计 · 可回放 · 真实完成

    这套系统的设计哲学可以浓缩为一句话:Harness 不替模型做事,它只负责检查模型有没有把事做完。检查的手段是机器可回放的、可审计的、不依赖模型自身表达的。

    本文基于 Zagens v0.8.2 的公开设计文档与源码。作品名称:Zagens(MIT 协议),开源地址:github.com/didclawapp-ai/zagens

    赞(0)
    未经允许不得转载:171主机测评 » Zagens agent 的组合式 Harness 工程实践
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址