@tea-agent/loop-agent 0.42.0-next.9 → 0.42.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +111 -45
- package/dist/application/dag/run-dag.js +8 -2
- package/dist/application/evaluation/budget.js +19 -1
- package/dist/application/task-lifecycle/advance.js +26 -8
- package/dist/application/task-lifecycle/observe.js +43 -29
- package/dist/application/task-lifecycle/plan-transitions.js +5 -4
- package/dist/build-stamp.json +3 -3
- package/dist/cli/program.js +1 -1
- package/dist/commands/dag-rerun-task.js +2 -0
- package/dist/commands/task-source-prepare.js +3 -1
- package/dist/executors/dag-pi-executor.js +2584 -600
- package/dist/executors/pi-executor.js +22 -1
- package/dist/executors/pi-extension-resolver.js +14 -2
- package/dist/executors/pi-sdk-executor.js +140 -39
- package/dist/executors/shell-executor.js +135 -55
- package/dist/shared/dag-failure-category.js +6 -0
- package/dist/shared/frontend-execution-policy.js +23 -0
- package/dist/task/config-types.js +4 -0
- package/dist/task/contract/apply.js +36 -2
- package/dist/task/source-prepare/ledger-reconciliation.js +2 -2
- package/dist/task/source-prepare/ledger-review.js +6 -9
- package/dist/task/source-prepare/parse-intent.js +7 -0
- package/dist/task/source-prepare/semantic-intake.js +16 -26
- package/dist/task/source-prepare/source-fidelity-pi.js +28 -9
- package/dist/task/source-references.js +48 -23
- package/dist/worker/console/chat/assistant-content.js +23 -2
- package/dist/worker/console/chat/browser-policy.js +143 -0
- package/dist/worker/console/chat/browser-routes.js +148 -0
- package/dist/worker/console/chat/chat-event-store.js +4 -2
- package/dist/worker/console/chat/explore-tools.js +13 -0
- package/dist/worker/console/chat/pi-runtime.js +173 -94
- package/dist/worker/console/chat/resource-loader.js +4 -1
- package/dist/worker/console/chat/routes.js +208 -66
- package/dist/worker/console/chat/scm-routes.js +217 -0
- package/dist/worker/console/chat/scm-service.js +283 -0
- package/dist/worker/console/chat/scm-tools.js +111 -0
- package/dist/worker/console/chat/sdd-data-alignment.js +78 -11
- package/dist/worker/console/chat/session-catalog.js +32 -0
- package/dist/worker/console/chat/session-mode-view.js +48 -0
- package/dist/worker/console/chat/session-mode.js +218 -0
- package/dist/worker/console/chat/session-store.js +27 -7
- package/dist/worker/console/chat/shortcuts.js +6 -0
- package/dist/worker/console/chat/subagents/agent-tool.js +62 -0
- package/dist/worker/console/chat/subagents/explore-agent.js +169 -0
- package/dist/worker/console/chat/subagents/index.js +5 -0
- package/dist/worker/console/chat/subagents/orchestrator.js +273 -0
- package/dist/worker/console/chat/subagents/tool-policy.js +53 -0
- package/dist/worker/console/chat/subagents/types.js +13 -0
- package/dist/worker/console/chat/terminal-routes.js +216 -0
- package/dist/worker/console/chat/terminal-sessions.js +284 -0
- package/dist/worker/console/chat/terminal-tools.js +199 -0
- package/dist/worker/console/chat/tool-preview.js +21 -0
- package/dist/worker/console/chat/tools.js +13 -1
- package/dist/worker/console/chat/turn-process.js +1 -0
- package/dist/worker/console/interview/tools.js +1 -0
- package/dist/worker/console/server.js +2 -28
- package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-C6n9_m0P.js → abnfDiagram-N423BO3Z-C9eI7nEo.js} +1 -1
- package/dist/worker/console/static/assets/{arc-DQh-IfZ1.js → arc-VJWsxWhB.js} +1 -1
- package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-54NnrwUC.js → architectureDiagram-T3A2C74G-BGcyiMSo.js} +1 -1
- package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-pivRALGK.js → blockDiagram-VBNYF7ZC-BScnFwyi.js} +1 -1
- package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-BR7OV2NJ.js → c4Diagram-5PPSVZJV-Bl9_BsLi.js} +1 -1
- package/dist/worker/console/static/assets/channel-B6sQYuOE.js +1 -0
- package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-B1Aq6BcK.js → chunk-2GRJ4B5K-F1uKxiUt.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-CbdU0rjo.js → chunk-2Q5K7J3B-rSRMynVu.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5RXB4S5H-Dqi2GJeD.js → chunk-5RXB4S5H-DAsJm1WD.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5VM5RSS4-BYn1Hu4R.js → chunk-5VM5RSS4-DQIdVI0a.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-DRLjDL0k.js → chunk-6Q2QTUOP-4A_8rJ-Q.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-GF5L2VYU-CY9Xx2jV.js → chunk-GF5L2VYU-BHnT-vjh.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-JWPE2WC7-BNCZs7_z.js → chunk-JWPE2WC7-Rq7QKBkn.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-KBJHAD2P-DZ8AStLL.js → chunk-KBJHAD2P-BXh-AI2u.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-RYQCIY6F-DsxjYrzz.js → chunk-RYQCIY6F-BblcLy8m.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-XXDRQBXY-Ddx1KC1l.js → chunk-XXDRQBXY-zHZmVnB6.js} +1 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-Z6s5QoeI.js +1 -0
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-Z6s5QoeI.js +1 -0
- package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-W9TveCnK.js → cose-bilkent-JH36ORCC-Cmwz0Wi4.js} +1 -1
- package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-l9j_ztZH.js → cynefin-VYW2F7L2-Dq76MHQU.js} +1 -1
- package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-BMJMKi4G.js → cynefinDiagram-MW4NZA55-zPahV1fM.js} +1 -1
- package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-Bb4mG9pH.js → dagre-VZM6K2ZE-DQJ3xPc_.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-7IWD3JNH-BMgL_Qv0.js → diagram-7IWD3JNH-BwX7u6fv.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-Bvo2T4OQ.js → diagram-B4RE2ZJO-CodnDCco.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-LBJQPF4R-_5kWRN9c.js → diagram-LBJQPF4R-gAjtWkxG.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-Q27KOJAE-DqdMrltM.js → diagram-Q27KOJAE-CGCqz0cS.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-UB23O5K3-CDDYsNkp.js → diagram-UB23O5K3-RHwYEywd.js} +1 -1
- package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-c4nfnZUV.js → ebnfDiagram-BXEA7PRR-B6seb_p_.js} +1 -1
- package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-DnkUcNMs.js → erDiagram-JOGREHBK-CmwCKYe8.js} +1 -1
- package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-Dz0KGLZE.js → flowDiagram-UKHOOZJN-BfNsaZ0V.js} +1 -1
- package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-Cj1t1uka.js → ganttDiagram-PKOTCBZU-zmYgi_Z3.js} +1 -1
- package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-tp2FrBHd.js → gitGraphDiagram-DS77QQ5N-BDEzzSKF.js} +1 -1
- package/dist/worker/console/static/assets/index-DgenUAfc.js +468 -0
- package/dist/worker/console/static/assets/index-aF4u-Y__.css +1 -0
- package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-DQwJS8DH.js → infoDiagram-6WML65LV-DeSz8l42.js} +1 -1
- package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-eimCQWD4.js → ishikawaDiagram-WSZJBQD7-B1LV29aH.js} +1 -1
- package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-Dd9Gbwgv.js → journeyDiagram-NVQOT4AX-CCw4W2oU.js} +1 -1
- package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-Qve3cyft.js → kanban-definition-27J2QSJJ-BozaMoRJ.js} +1 -1
- package/dist/worker/console/static/assets/{linear-UXKSe36Z.js → linear-G1JR40SX.js} +1 -1
- package/dist/worker/console/static/assets/{mermaid.core-CWhj4JXN.js → mermaid.core-CCgPF0oA.js} +5 -5
- package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-yTcwf4SJ.js → mindmap-definition-FAOFIHXS-CEqnCHnD.js} +1 -1
- package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-_7qToaZP.js → pegDiagram-VL7TDLO6-DpmQPKuI.js} +1 -1
- package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-CXmrKmDm.js → pieDiagram-7S7Q4E2Y-BP501AxR.js} +1 -1
- package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-hMmrJyaS.js → quadrantDiagram-CIZ2JOQS-D1dBhl_A.js} +1 -1
- package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-BXw8tCBe.js → railroadDiagram-AXF67PYL-DgZDS5pY.js} +1 -1
- package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-BmjgnLZl.js → requirementDiagram-LRYGKXZP-BzB3pyIq.js} +1 -1
- package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-Bj77SPpN.js → sankeyDiagram-W5VNT64P-B9ZprFFP.js} +1 -1
- package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-B2FDVysL.js → sequenceDiagram-SI44F4Z6-CC2-_XrA.js} +1 -1
- package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-UChNY9ZZ.js → sizeCapture-X5ZJPWSS-UVtAUqgB.js} +1 -1
- package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-wbAEkbd7.js → stateDiagram-OKZ733FA-CWcS5JYG.js} +1 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-BooX8u1Q.js +1 -0
- package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-DCEkU8HR.js → swimlanes-SLNWSIFB-C4p-dn06.js} +2 -2
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-D64_eqqE.js +8 -0
- package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-BGp7H06U.js → timeline-definition-Z64GVDOM-Dnz52OHX.js} +1 -1
- package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-DsCIQuWR.js → vennDiagram-T6HMQDX7-CzTE0Nfu.js} +1 -1
- package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-cRZLP4Xe.js → wardleyDiagram-T6FBY63Y-NAR9cjQQ.js} +1 -1
- package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-CP0xLR9Y.js → xychartDiagram-ELKLHX3M-DVMk8413.js} +1 -1
- package/dist/worker/console/static/index.html +2 -2
- package/dist/worker/console/static-src/chat-view-types.js +1 -1
- package/dist/worker/console/static-src/operator-chat/chat-link.js +94 -0
- package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +142 -7
- package/dist/worker/console/static-src/operator-chat/pending-user-message.js +44 -0
- package/dist/worker/console/static-src/operator-chat/process-label.js +41 -0
- package/dist/worker/console/static-src/operator-chat/tools-catalog.js +21 -2
- package/dist/worker/console/static-src/operator-chat/turn-group-equality.js +13 -0
- package/dist/worker/console/static-src/operator-chat/turn-stream-controller.js +2 -0
- package/dist/worker/console/static-src/operator-chat/use-searchable-hidden.js +51 -0
- package/dist/worker/console/static-src/operator-chat/useChatSessions.js +33 -18
- package/dist/worker/console/static-src/operator-chat/useChatStream.js +48 -16
- package/dist/worker/console/static-src/operator-chat/useChatThread.js +170 -7
- package/dist/worker/console/static-src/operator-chat/useComposer.js +13 -7
- package/dist/worker/console/static-src/operator-chat/user-turn-anchor-equality.js +21 -0
- package/dist/worker/console/static-src/shell/workspace-route.js +4 -0
- package/dist/worker/console/workspace-context.js +15 -1
- package/dist/worker/observe/node-transparency.js +81 -72
- package/dist/worker/observe/routes.js +20 -1
- package/dist/worker/observe/static/constants.js +22 -22
- package/dist/worker/observe/static/dag-context-reason-labels.js +19 -0
- package/dist/worker/observe/static/dag-history-labels.js +1 -0
- package/dist/worker/observe/static/dag-inspector-humanize.d.ts +16 -0
- package/dist/worker/observe/static/dag-inspector-humanize.js +342 -0
- package/dist/worker/observe/static/dag-node-purpose.js +10 -10
- package/dist/worker/observe/static/dom.js +20 -1
- package/dist/worker/observe/static/format-pool.d.ts +2 -0
- package/dist/worker/observe/static/format-pool.js +6 -0
- package/dist/worker/observe/static/format.js +7 -0
- package/dist/worker/observe/static/index.html +4 -4
- package/dist/worker/observe/static/inspect-workspace.js +34 -7
- package/dist/worker/observe/static/inspector-submission.js +32 -0
- package/dist/worker/observe/static/kpi.js +1 -0
- package/dist/worker/observe/static/prompt-restart-candidates.js +4 -2
- package/dist/worker/observe/static/relations.js +7 -5
- package/dist/worker/observe/static/router.js +13 -0
- package/dist/worker/observe/static/run-processing.js +2 -0
- package/dist/worker/observe/static/shell-chrome.js +36 -3
- package/dist/worker/observe/static/state.js +35 -2
- package/dist/worker/observe/static/styles.css +431 -39
- package/dist/worker/observe/static/task-failure-labels.d.ts +4 -0
- package/dist/worker/observe/static/task-failure-labels.js +67 -0
- package/dist/worker/observe/static/task-history.js +12 -0
- package/dist/worker/observe/static/views/batch.js +6 -13
- package/dist/worker/observe/static/views/dag-graph.js +51 -4
- package/dist/worker/observe/static/views/dag-inspector.js +1069 -426
- package/dist/worker/observe/static/views/dag-trajectory.js +3 -0
- package/dist/worker/observe/static/views/dag.d.ts +6 -0
- package/dist/worker/observe/static/views/dag.js +64 -22
- package/dist/worker/observe/static/views/dags.js +2 -0
- package/dist/worker/observe/static/views/dashboard.js +21 -12
- package/dist/worker/observe/static/views/failures.js +21 -11
- package/dist/worker/observe/static/views/feature.js +11 -29
- package/dist/worker/observe/static/views/pool.js +37 -28
- package/dist/worker/observe/static/views/run.js +48 -5
- package/dist/worker/observe/static/views/session-timeline.js +194 -243
- package/dist/worker/observe/static/views/task.js +81 -62
- package/dist/workflows/dag/backend-test-plan-protocol.js +104 -0
- package/dist/workflows/dag/budget-enforcement.js +53 -3
- package/dist/workflows/dag/dag-retry-schema.js +3 -0
- package/dist/workflows/dag/frontend-capacity.js +9 -0
- package/dist/workflows/dag/frontend-contract-facts.js +130 -0
- package/dist/workflows/dag/frontend-design-policy.js +103 -17
- package/dist/workflows/dag/frontend-durable-tools.js +193 -0
- package/dist/workflows/dag/frontend-execution-groups.js +24 -0
- package/dist/workflows/dag/frontend-implementation-contract.js +423 -41
- package/dist/workflows/dag/frontend-input-projection.js +76 -0
- package/dist/workflows/dag/frontend-plan-completeness.js +186 -0
- package/dist/workflows/dag/frontend-plan-recovery-policy.js +18 -0
- package/dist/workflows/dag/frontend-plan-render.js +21 -3
- package/dist/workflows/dag/frontend-prewrite-gate.js +1 -1
- package/dist/workflows/dag/frontend-recovery-controller.js +32 -8
- package/dist/workflows/dag/frontend-recovery-lineage.js +13 -0
- package/dist/workflows/dag/frontend-recovery-plan.js +4 -1
- package/dist/workflows/dag/frontend-recovery-run.js +146 -16
- package/dist/workflows/dag/frontend-review-scopes.js +139 -0
- package/dist/workflows/dag/frontend-risk.js +2 -0
- package/dist/workflows/dag/frontend-session-budget.js +249 -0
- package/dist/workflows/dag/frontend-shadow-dual-write.js +37 -3
- package/dist/workflows/dag/frontend-shape-facts.js +12 -2
- package/dist/workflows/dag/frontend-shape.js +46 -7
- package/dist/workflows/dag/frontend-test-execution-evidence.js +49 -0
- package/dist/workflows/dag/frontend-typed-event-store.js +14 -0
- package/dist/workflows/dag/frontend-verification-trace.js +38 -4
- package/dist/workflows/dag/frontend-writer-admission.js +2 -2
- package/dist/workflows/dag/init-hybrid.js +70 -35
- package/dist/workflows/dag/node-execution.js +225 -226
- package/dist/workflows/dag/prompt.js +4 -0
- package/dist/workflows/dag/recovery-lease.js +106 -16
- package/dist/workflows/dag/rerun-feedback.js +1 -0
- package/dist/workflows/dag/rerun-plan.js +96 -4
- package/dist/workflows/dag/rerun-run.js +28 -6
- package/dist/workflows/dag/rerun-task.js +221 -18
- package/dist/workflows/dag/retry-policy.js +27 -10
- package/dist/workflows/dag/runner-exit-diagnostics.js +125 -0
- package/dist/workflows/dag/runner.js +246 -19
- package/dist/workflows/dag/structured-output-repair.js +4 -1
- package/dist/workflows/dag/types.js +10 -3
- package/dist/workflows/dag/validate.js +10 -8
- package/dist/workflows/dag/workspace-checkpoint.js +66 -0
- package/docs/operations/README.md +2 -0
- package/docs/templates/agent-dag.schema.json +2 -2
- package/docs/templates/backend-test-dag.json +6 -4
- package/docs/templates/frontend-design-contract.md +4 -4
- package/docs/templates/frontend-implementation-contract.schema.json +68 -4
- package/docs/templates/frontend-implementation-dag.json +5 -5
- package/harness.json +1 -1
- package/package.json +8 -6
- package/skills/frontend-contract/SKILL.md +2 -1
- package/skills/frontend-contract/references/contract-protocol.md +19 -3
- package/skills/frontend-design-review/SKILL.md +12 -11
- package/skills/frontend-plan/SKILL.md +22 -2
- package/skills/frontend-plan/references/decision-contract.md +114 -5
- package/skills/frontend-plan/references/design-decisions.md +32 -0
- package/skills/frontend-review/SKILL.md +10 -11
- package/skills/frontend-scout/references/scout-evidence.md +4 -0
- package/dist/worker/console/static/assets/channel-DsZxrgqe.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-CuToPeGV.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-CuToPeGV.js +0 -1
- package/dist/worker/console/static/assets/index-D9Sc0f0y.js +0 -449
- package/dist/worker/console/static/assets/index-DDQc5a50.css +0 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-yPoT19ft.js +0 -1
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-VWdarchG.js +0 -8
package/CHANGELOG.md
CHANGED
|
@@ -2,41 +2,75 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.42.1] - 2026-09-09
|
|
6
|
+
|
|
7
|
+
### 新增
|
|
8
|
+
|
|
9
|
+
- 新增了本发布周期内已经完成并通过验证的功能。
|
|
10
|
+
|
|
11
|
+
### 改进
|
|
12
|
+
|
|
13
|
+
- 完善了日常使用体验和运行稳定性。
|
|
14
|
+
|
|
15
|
+
### 修复
|
|
16
|
+
|
|
17
|
+
- 修复了影响使用体验或运行稳定性的问题。
|
|
18
|
+
|
|
19
|
+
## [0.42.0] - 2026-09-07
|
|
20
|
+
|
|
21
|
+
### 重点更新
|
|
22
|
+
|
|
23
|
+
- **Operator Chat 内置只读 Explore 子 Agent**:主会话可通过 `Agent` 工具委派代码库搜索、符号查找和调用链追踪;子会话 Fresh、one-shot,只暴露 `find`/`ls`/`safe-*`/git 只读工具,父 Turn 停止时一并中止。工具目录中的 Explore 条目改由服务端 `builtinSubagents` 能力字段驱动,后端调整内置子代理时前端自动跟随。
|
|
24
|
+
- **前端实现 DAG 稳定性集中修复**:修复 Plan coverage 会话提前停止导致会话数翻倍(切片穷尽才算完成);修复重试梯级遮蔽修复指令(账本修复指引优先于 compact-terminal-first 话术);修复 Plan 按 AC 分片重复发明同一批需求(UX registry 先全局提交再单一会话建模);修复 design 拒绝后自动恢复子 run 无法启动(staging 正确物化拓扑绑定并继承 committed shape facts);修复自动恢复实际重跑整棵 DAG、忽略冻结 reset plan 的问题;`stopReason=length` 截断改判为专门的 `output-limit` 可重试类别,不再误判 `empty-output`;重试额度默认从 3 次提升到 5 次。
|
|
25
|
+
- **前端 verification contract v2**:plan 不再手写五值 `type`,改为引用生成期冻结命令目录的 `commandId`,`type: component + npm run build` 这类非法组合在 Plan 工具边界即被拒绝;冻结验证命令引用的基建文件(如 vitest 配置)确定性并入 writeSet admission 边界,writer 不再被具体 writeSet 拦住;Verify bundle 按工作目录和冻结命令去重,static/behavior/Mock/lint lane 复用相同命令结果。
|
|
26
|
+
- **backend-test 判定链修复**:N2 不再把 provider 长度截断的 Markdown 计划误判为 `FINISHED`(截断归 `output-too-large`、缺 heading 归 `invalid-output`,均有界 artifact-first retry);N3 以唯一合法 Markdown Path 为 canonical 模块身份(Stem 展示单元格只作冗余展示);唯一 pytest collection repair 缺 `IMPLEMENTATION_OUTCOME` 不再阻断整条执行链(确定性恢复为候选 changed 后仍走全部门禁)。
|
|
27
|
+
- **契约幂等与 DAG 恢复强化**:契约重复 prepare 做内容级 no-op 短路(投影与已记录契约及磁盘哈希一致时不递增 revision、不写事务、writeSet gate digest 绑定 hash 不变则继续有效——实测 8.6 小时流水线 7 次修订只有 3 个不同 hash);workspace-drift 细化为内容级逐路径对比(漂移全落在重跑子图自身 readSet/writeSet 内时放行);superseded run 可作为 `dag rerun --from-node` 的事实供体;DAG 退出诊断改用只读异常监视器。
|
|
28
|
+
- **工具入参预览放宽**:工具入参预览从 1200 字放宽到 4000 字(与会话结果落盘上限对齐),详情栏支持「展开全部」(可视高度最多 720px),Explore 等长 brief 不再被预览截断误导。
|
|
29
|
+
|
|
30
|
+
### 改进
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
- DAG 退出诊断改用只读异常监视器,避免诊断逻辑改变宿主异常策略或中断其他并发 run 的取证;退出码使用实际 exit 事件参数。
|
|
35
|
+
- 前端分片 VT 归一化同步处理 `replaces` 引用,避免重试修正因分片前缀不同而无法覆盖旧事实。
|
|
36
|
+
- 强化 DAG 恢复与契约幂等:重跑计划不会复用 imported 节点读取的漂移输入、缺失/未完成节点,并且仅在 Git HEAD 相同、rename 与治理输入清单可完整判定时放行 scoped drift;`stopReason=length` 的 transport 别名可正确重试。契约 no-op 写入 request ledger 但不伪造事务,重复请求携带新 payload 会被拒绝,且 no-op prepare 不再无谓刷新 DAG。
|
|
37
|
+
- 修复契约重复 prepare 空转的问题(实测一次 8.6 小时的流水线里 7 次契约修订只有 3 个不同内容 hash,无内容变化的重复提交每次都走完整事务提交 → 契约投影 → DAG spec 生成 → strict validation → writeSet gate 审查):apply 现在做内容级 no-op 短路——投影结果与已记录契约及磁盘观测哈希完全一致时直接返回当前 ref,不递增 revision、不写日志化事务;writeSet gate digest 绑定 contractRevision+canonicalHash,hash 不变则已批准的 gate 继续有效,不再重复审批。磁盘漂移(observed ≠ ref)不走短路,仍是修复投影。
|
|
38
|
+
- 修复 workspace-drift 一刀切阻断 `dag rerun --from-node` 的问题:整指纹对比细化为内容级逐路径对比,漂移全部落在重跑子图自身 readSet/writeSet 内时放行(`workspace-drift-scoped`,重跑本就会重读/重写这些路径);其余情况(导入事实复用节点的输入漂移、无法判定路径的旧 checkpoint)保持严格阻断,高风险写者续跑路径维持整指纹严格判定不变。契约同 hash 重投影不再改写文件,与此叠加后恢复路径不再被无意义漂移阻断。
|
|
39
|
+
- superseded run 现在可作为 `dag rerun --from-node` 的事实供体:操作员取代的是 run 整体,其 FINISHED 只读上游节点(contract/scout 等)经既有导入机制继承,不再因父 run 被取代就强制全量重跑;writer 进重跑子图、决策门禁、未解决 ERROR 在闭包外等不安全场景各自的原有阻断不变。
|
|
40
|
+
- 修复前端 Plan coverage 会话提前停止导致会话数翻倍的问题(run 3 实测每会话平均仅 1.7 个 record 调用即写结论,把一个切片的活摊到两个会话):coverage 段指令与 COVERAGE BATCH 提示现在明确「切片穷尽才算完成」——本会话分配到的每个需求都必须有已提交的 coverage facts(verification targets 或 evidence gap)才能收尾,批量提交直至穷尽,提前停止会把剩余项拖成 MISSING-FACT 修复会话;MISSING-FACT 队列降级为校验兜底而非主要补齐机制。
|
|
41
|
+
- 修复前端 Plan 重试梯级遮蔽修复指令的问题:invalid-output / structured-output-truncated 的账本修复指引现在优先于 compact-terminal-first 等梯级话术。此前 length 失败把重试梯级单调升到 compact-terminal-first 后,后续 invalid-output 重试拿到的是「保持已提交账本完整」的档位指令,与「重提交修正后的 record_* facts」这一唯一治愈动作正面冲突,修复指引成为死代码;修复指引同步补上 duplicate/replace 语义(duplicate 收据是修正邀请而非禁令,replace=true 为同 id 全量替换,回填反向引用不属于重推导已提交事实)。`skills/frontend-plan` 新增跨段引用规则与 Bidirectional VT cross-reference invariant 小节:跨切片引用已提交 VT 时当场以同 id + replace=true 回填,双向引用在提交时即闭合,不再拖到 attempt 末尾的双向检查才暴露。
|
|
42
|
+
- 修复 DAG Pi 节点把 provider `stopReason=length` 的输出/上下文截断误判为 `empty-output` 失败的问题:仅 `empty-output` 基础上的长度截断会改判为专门的 `output-limit` 可重试类别(raw 类别保留诊断),已有精确修复指令的类别(output-too-large / invalid-output / protocol-invalid / structured-output-truncated / writer 类)原样保留,避免通用指令遮蔽任务专属修复提示;`output-limit` 通用增量指令(从已提交 typed facts 与现有工作区只补未完成部分、每个生成单元产出后立即校验格式并在当节点修复)作为兜底排在所有精确分支之后,前端规划梯级(compact-terminal-first 正是 length 场景的领域档位)与结构化冻结修复路径优先。只读/结构化/前端规划/后端测试补全策略的默认重试额度从 3 次提升到 5 次;旧 artifact 中的 `writer-thinking-exhausted` / `planner-thinking-exhausted` 终态标签仅作历史保留(Console/报告展示映射同步归入 executor 容量类),新执行不再产生。
|
|
43
|
+
- 前端 Scout 在中高复杂度任务中并行收集 target surface 与 design evidence;大型 Plan 将 requirement coverage 按批次并行映射,再按固定顺序归并到唯一 reducer,保持 Contract → Scout → Plan 依赖与确定性终态,同时缩短最长串行等待。
|
|
44
|
+
- 前端 Verify bundle 会在同一次执行中按工作目录和冻结命令去重:static、behavior、Mock、lint lane 复用相同命令结果,同时为每个 lane 保留独立证据,避免重复启动耗时的 typecheck/test/build 进程。
|
|
45
|
+
- 前端 Micro/Small shape 路由不再把 `test/`、`e2e/`、`docs/` 等验证或文档根目录误计为业务跨域;`src/**` + `test/**` 的局部 UI 改动现在可以正确命中轻量拓扑,真实跨包路径仍保持升级。
|
|
46
|
+
- 修复前端 Plan 漏读独立行为证据、重试丢失已重新录入的 UX 名称的问题;必交付文件改由 Contract 显式声明并绑定原始来源,避免把允许修改或参考路径误判为交付义务。缺失交付物和 UX 名称冲突现在可在 Plan 提交前发现并修正,发布 schema 同步支持组件覆盖与复用证据字段。
|
|
47
|
+
- 修复前端 DAG 的 Plan 按 AC 分片重复发明同一批需求、交互和 UI 状态的问题:Contract 的 canonical requirement 文本与来源片段改由 runtime 从冻结 ledger 写入,Plan 先基于全部需求提交一次全局 UX registry,再在单一全局 UX 会话中建模组件、状态和交互;来源声明的 UI 状态必须完整闭合,复用既有组件必须提供真实存在的文件证据,交付文件完整性与逐状态/交互组件覆盖由确定性 gate 校验。
|
|
48
|
+
- 修复顶部一级「观测」入口被恢复工作区残留的 DAG 或上次观测对象劫持的问题:现在点击该入口始终回到当前 Workspace 的运行总览,具体 DAG 仍通过「全屏观测」等显式入口打开。
|
|
49
|
+
- 修复节点检查器通俗字段旁的问号只有图标、悬浮时看不到具体说明的问题;问号现在支持鼠标悬浮和键盘聚焦,并显示对应字段含义及原技术字段。
|
|
50
|
+
- Next 发布测试升级到 Vitest 4.1.11,采用上游 worker RPC 修复,避免所有断言通过后仍因 `onTaskUpdate` 通讯超时阻断发包;同时隔离会改写构建产物的 package-surface 测试,并恢复两条此前被错误嵌套、实际未执行的 Console 更新回归;发布门禁继续严格检查 unhandled errors。
|
|
51
|
+
- 前端计划契约新增确定性锚定校验(恶劣网关冒烟 4 轮 design 拒绝的主因):behavior 验证目标必须至少引用一个 requirement,且在契约声明了 UI 状态或交互时必须引用至少一个已声明的 UI 状态(纯逻辑契约豁免)。校验位于共享 schema refine,plan 节点的自修阶梯当场拿到精确到字段的报错并修复,不再烧一整轮 design-review 才发现映射缺失;`skills/frontend-plan` 决策契约参考同步补充 canonical 示例(behavior target 形态、状态名逐字引用、stylingStrategy 禁止承诺任务源非目标能力)。
|
|
52
|
+
- 修复前端 design 拒绝后自动恢复子 run 无法启动的问题(恶劣网关前端冒烟三轮复现):staging 物化 child state 时现在按 child spec 写入 `frontendShapeState` 冻结拓扑绑定(此前 execute 前的绑定断言以 `frontend topology binding is missing` 在 398ms 内 fail-closed),并把父 run 中已导入边界节点(contract/scout 等 FINISHED 导入节点)的 committed shape facts 一并继承——否则 child 会在首个 shape 门禁以 `frontend-shape-fact-invalid` 整体 SKIPPED;reset 边界由重跑节点重新提交。同时修复 recovery child runId 派生误传参导致碰撞安全后缀失效、可与已归档 run 同名的问题(默认 `buildDagRunId` 现在正确收到 `{ cwd }` options)。
|
|
53
|
+
- 修复 backend-test N2 把 provider `stopReason=length` 的截断 Markdown 计划误判为 `FINISHED`、继而延迟到 N3 `missing-module-index` 的问题:长度截断现在在 producer 节点归类为 `output-too-large`;正常结束但缺少必需 heading、Module Index 八列表/模块行或使用代码围栏时归类为 `invalid-output`。两类失败均使用有界 artifact-first retry,下一 attempt 只携带控制器生成的限长协议诊断;N3 ownership/path/模块数门禁与业务 pytest 单次执行不放宽。
|
|
54
|
+
- 可选依赖 `@agent-context/sift` 从 `0.0.1-alpha.6` 精确 pin 升级到 `0.0.1-alpha.7`:新增 `retrieveLines` 行级分片取回与省略点内联 stash 路径/起始行号(模型可直接换算 read 行号),纯文本压缩策略更保守(不同编号/状态的内容不因句式相似而合并);桥接层沿用既有 `createSift`/`siftRequest`/`retrieve` API,行为与回退开关不变,仍不投影 init。
|
|
55
|
+
- 修复后端实现 DAG Pi 扩展 resolver 无法解析版本 pin spec 的问题:`packageNameFromSpec` 现在剥除尾部 `@<version>`/`@<dist-tag>`(保留 scoped 包名开头的 `@`),与 Console 插件面语义对齐。此前 settings 中的 `npm:pi-lens@3.8.72`(Console 升级插件写入的形式)会被当作包名 `pi-lens@3.8.72`,永远匹配不上别名表,读侧节点(contract/scout/plan/verify)的 `pi-lens` 全部静默降级为 `not-installed`;`pi-extensions.json` 观测产物可鉴别此场景。
|
|
56
|
+
- 修复前端自动恢复实际重跑整棵 DAG、忽略已冻结 reset plan 的问题:恢复 operation 现在校验 operationId/lease 归属,按 parent recovery plan 导入已完成事实并只执行 reset 子图;设计拒绝缺少 typed findings 时 fail-closed;多轮 continuation 会继续注入共享 recovery controller、递增并校验完整 lineage;崩溃重放会复用 completed child;缺少已绑定 child lineage 的伪成功 operation 不再标记 recovered;rerun-task 的全局 requestId 重放会校验请求类型、父 run 与完整 payload,避免串用其它请求结果。
|
|
5
57
|
- 冒烟再暴露 writeSet 授权缺口:冻结验证命令引用的基建文件(如 `--config` 的 vitest 配置)不在 plan verification targets 内时,writer 被具体 writeSet 拦住无法创建、verify-shell 必然失败。现在 admission 生效边界确定性并入冻结命令引用的文件(机械提取、仍受 allowedPaths/forbiddenPaths 约束),writer 聚焦检查失败后可自行补齐基建文件。
|
|
58
|
+
- 前端 verification contract v2:plan 不再手写五值 `type`,改为引用生成期冻结命令目录的 `commandId`,`mode(static|behavior)` 与 `commandLabel` 由 runtime 在物化时解析——`type: component + npm run build` 这类非法组合在 Plan 工具边界(`verification-target-unknown-command`)与物化校验(`verification-target-phase-mismatch`,behavior 命令必须绑定测试文件)即被拒绝,不再拖到 writer focused-check 才以 `invalid-output` 失败;展示用的 `scope` 不参与控制流。
|
|
6
59
|
- 修复 /inspect/* 静态资源(operator-chrome.js/css、观测文档)缺少 Cache-Control 的问题:现在与 Console SPA 一律 `no-store`。此前浏览器启发式缓存会让 Console 更新/重启后继续挂旧版导航模块,表现为顶部导航「回退」到只有操作/观测、缺少对话入口的旧版布局。
|
|
7
|
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
- 修复 backend-test 把 pytest `_MISSING` 哨兵当成普通 Name、可选 `min; bound=0` UNDETERMINED 的问题:`_MISSING` 与 `_OMIT` 同为省略键。
|
|
20
|
-
- 修复 backend-test 把可选字段 `min; bound=0` 的 `_OMIT` 判成 UNDETERMINED 的问题:省略键视为空最小;`OMITTED` TP 视为 missing。
|
|
21
|
-
- 修复 backend-test 对 `http_client(operation, json_body=dict)` 观察不到 payload 的问题:http-like Name-call 的第一参是参数化 method 变量时仍计入 `json_body`。
|
|
22
|
-
- 修复 backend-test 把 Markdown `Payload Required Paths: false` 当成路径、GET filter 整 Case UNSAFE 的问题:`true`/`false` 与 `none` 一样不是 path。
|
|
23
|
-
- 修复 backend-test 把列表反引号里的 `场景意图: ... bound=0` 解析失败、并把 `max+1` 的数字 1 当成 minLength 的问题:围栏行可解析,`+/-` 后缀数字不进 prose 窗。
|
|
24
|
-
- 修复 backend-test 把 fixture `http("POST", path, json_body={"title": ...})` 当成无 payload、整 Case PAYLOAD_SHAPE_MISMATCH 的问题:首参为 HTTP method 的 Name-call 进入 observedPaths。eligibility 门禁不放宽。
|
|
25
|
-
- 修复 backend-test 把 `intent=min; bound=0` 当成缺 bound 并落到 `maxLength`、导致空 content MISMATCH 的问题:无 `minLength=` / TP LEN 时保留 0;`max; bound=0` 仍是哨兵。
|
|
26
|
-
- 修复 backend-test 把 evidence-only pytest stub(模块 docstring + Case-ID、无 `def test_`)当成截断脚本、N9 `incomplete-write-set` 的问题:闭合 stub 可通过 completeness,半截 `def (` 仍 fail-closed。
|
|
27
|
-
- 修复 backend-test 把 Markdown 机器行 `intent=max-1; bound=99` 当成契约 max、导致 `x*99` MISMATCH 的问题:`max-1`/`max+1`/`min-1` 优先 `maxLength=` 与文案三元组。eligibility 门禁不放宽。
|
|
28
|
-
- 修复 backend-test 把 pytest 多写、Markdown 没有的 `0:1` extra symbol 当成 Markdown Test Point binding 缺陷并 BLOCKED 的问题:这类条目进入 N11 删除多余函数,不再清空 pytest repair。
|
|
29
|
-
- 修复 backend-test N12 只读 effective collection 再次跑 scenario-param 确定性写回、在 `filesystem-only` 下 `write-guard` 失败的问题:N12 只复验,不再改 pytest。N10 仍可修一次。
|
|
30
|
-
- 修复 backend-test 把 `脚本:无` 的 evidence-only Case 当成缺 pytest 符号送进 N11 的问题:精确 1:0 元用例不再触发 `missing-pytest-symbol` repair,N11 不得发明业务函数。真缺符号的 1:0 仍可修。eligibility 门禁不放宽。
|
|
31
|
-
- 修复 backend-test 把 Scenario Partitions 数据行的 exact `TP-SP-...` 清单写成第 8 列、导致 N6 `MISSING_PARTITION` 的问题:仅当尾列全是该 Partition 的 slot ID 时确定性裁成 7 列并写回 run-owned plan。7 列契约与非 slot 多余列 fail-closed 不放宽。
|
|
32
|
-
- 修复 backend-test scenario 把 `intent=max-1` 当成 unknown、以及 Markdown 只写「100 个字符的最大 / 1999、2000、2001」时解析不到 bound 的问题:`max-1` 进入 closed set,长度清单三元组与「N 个字符的最大」可得到 MATCH。eligibility 门禁不放宽。
|
|
33
|
-
- 修复 backend-test correspondence 把前面函数的 `pytest.param(..., id="TP-...")` 叠进后续 Case `parameterIds` 的问题:decorator 区域遇到上一 `def`/`class` 或非 decorator 续行即停,不再把整组打成 `TEST_POINT_BINDING_EXTRA`。eligibility 门禁不放宽。
|
|
34
|
-
- 修复 backend-test scenario facts 把内部 max/min/oversize helper 哨兵 `-1/-2/-3` 写成 `observedLength`、导致 N10 在 schema `min(0)` 上 `invalid-output` 的问题:这些 helper 仍按 Markdown bound MATCH,持久化长度只保留非负值。
|
|
35
|
-
- 修复 backend-test 把 GET `params=`/`query=` 过滤字段、Python `True`/`False` 布尔字面量和混合大小写 `pytest.param` 列表漏出 correspondence/payload/scenario 观察的问题:这些 variant 现在可以按 item 授权,而不再把整 Case 打成 `PAYLOAD_SHAPE_MISMATCH` / `VARIANT_PARAMETER_MISSING`。eligibility 门禁不放宽。
|
|
36
|
-
- 修复 backend-test 计划协议标题被翻译成中文后 N3 直接 `missing-module-index`、以及 Markdown writer 漏写精确 Scenario Partition slot 只能等到 N6 才失败的问题:N3 现在把 `## 模块索引/覆盖范围/覆盖矩阵/场景分区` 确定性改写成英文 canonical heading 并最多写回一次 run-owned `plan.md`,同时展开 slot 清单写入 `contracts/backend-test-scenario-partition-slots.json` 并注入 map child `requiredVariantSlots`。Markdown shard completeness 对缺失精确 `TP-SP-...` variant 报 `incomplete-partition-slot-set` 并允许一次有界补写。覆盖语义按方案 A:Case 数量可以少于枚举数量,但每个 slot 仍须独立 variant Test Point;`SINGLE`/`MULTIPLE` 不计覆盖。N6 fail-closed 不放宽。
|
|
37
|
-
- 修复 backend-test strict Markdown map writer 的 upstream artifact pointer 泄漏:当长上游输出的 `stdout.md` 不在当前节点 `readSet` 时,不再向 Pi 注入不可读取的 artifact 路径,避免模型触发 `read-outside-read-set` 后进入 pending;保留有界 preview,并新增回归覆盖严格 writer 边界。
|
|
60
|
+
- 新建、删除和切换对话的反馈更及时;会话列表默认展示 5 条,“展开其余会话”和“收起”也更整齐易用。
|
|
61
|
+
- 发送消息后会立即显示在对话流中,完成回合的过程摘要也更清晰,长时间等待连接时不会让输入内容消失。
|
|
62
|
+
- 文件预览支持页面内交互和独立窗口阅读,大型 HTML 内容也能完整打开。
|
|
63
|
+
- 模型配置更新后,继续使用旧会话时会自动采用最新认证信息,消息流顺序也更加稳定。
|
|
64
|
+
- 执行记录默认跟随最新内容,也可以暂停自动滚动并保留当前阅读位置。
|
|
65
|
+
- 任务执行、恢复和结果查看更加稳定,工作区和滚动区域的使用体验得到改进。
|
|
66
|
+
|
|
67
|
+
<details>
|
|
68
|
+
<summary>实现细节(开发者参考)</summary>
|
|
69
|
+
|
|
70
|
+
- Operator Chat 会话列表默认收敛为最近 5 条;展开与收起控件采用稳定的整行布局,折叠工作区后恢复默认列表;长历史会话改为分页加载,并在加载更早消息后保持原有滚动位置。
|
|
71
|
+
- Operator Chat 长会话增量构建活动 turn、复用已完成过程节点,并支持对已完成且无错误的历史 turn 进行 Compact,降低长消息流的渲染开销。
|
|
38
72
|
- 修复 backend-test Manifest 把模型生成的 Module Stem 展示单元格当成模块身份真源、导致 low-tier 输出(缺 `test_` 前缀或整段 Markdown 链接)在 N3 `module-markdown-path-mismatch` 反复失败的问题:N3 现在先解析唯一合法 Markdown Path 与 `<stem>.md` 相对链接作为 canonical 身份,再校验业务 ownership/split 与路径安全;Stem 单元格只作冗余展示并能确定性重写为 canonical 文件名 stem。strict `backendTest.moduleLayout` 改为先按唯一 required Markdown Path 定位模块,再恢复冻结 Markdown/Pytest path pair,避免错误 stem 提前丢弃整行,同时保留 Plan-only pytest path 修复。Markdown Path 缺失/多候选/越界或与 strict path pair 冲突、以及多行 canonicalize 后同 identity(`duplicate-canonical-module-stem`)继续 fail-closed,不再静默去重。同步加强 N2 prompt(Stem 单元格仅允许纯文件名 stem)。
|
|
39
|
-
- 修复 Next Release 的 io-heavy
|
|
73
|
+
- 修复 Next Release 的 io-heavy 测试不稳定:在保留发布单 worker、完整测试集合和严格 unhandled-error 门禁的同时,将 Vitest 升级到包含上游 RPC settlement 修复的 4.1.11,避免全绿测试因 `onTaskUpdate` timeout 退出 1;会重建共享 `dist/**` 的 package-surface 测试改由单 worker integration 池持有,避免与 controller identity 指纹检查竞态;并把误嵌套在 `dagDoctor` stub 中的 `consoleUpdateAndInit` suite 移回顶层、补齐 `workspaceId` 契约,使两条回归重新进入真实执行。
|
|
40
74
|
- 修复 backend-test 唯一 pytest collection repair 已产生受控非空修改、却因模型遗漏 `IMPLEMENTATION_OUTCOME` 而阻断整条执行链的问题:仅 N11 exact repair writer 可把完全缺失的 outcome 确定性恢复为候选 changed,随后仍必须由 N12 重新通过 scenario、correspondence、payload、collection、fixture 和 readiness 门禁;unknown/conflicting/blocked、空 diff、越界写入及 provider/context failure 继续 fail-closed。
|
|
41
75
|
- 新建和删除对话现在会立即在侧栏中反馈:新建时先显示“正在创建”,删除时平滑淡出;网络失败会自动恢复原会话,不再需要等待整张会话列表刷新后才看到变化。
|
|
42
76
|
- 新建对话会优先复用当前工作区中真正的空白会话,避免重复创建;有历史消息、工具调用、待发送内容或正在运行的会话不会被复用。
|
|
@@ -49,6 +83,50 @@
|
|
|
49
83
|
- 修复 Operator Chat 长工具链的消息错序:模型过程文字、思考和工具卡片现在按服务端事件顺序稳定交替展示,刷新历史会话后也保持相同顺序。
|
|
50
84
|
- 修复 Operator Chat 旧会话继续使用过期模型认证的问题:模型配置变化后,下一轮发送或手动重新加载会自动刷新模型目录和当前模型认证。
|
|
51
85
|
|
|
86
|
+
</details>
|
|
87
|
+
|
|
88
|
+
## [0.41.3] - 2026-09-04
|
|
89
|
+
|
|
90
|
+
### 改进
|
|
91
|
+
|
|
92
|
+
- 完善了本发布周期内的日常使用体验和运行稳定性。
|
|
93
|
+
|
|
94
|
+
### 修复
|
|
95
|
+
|
|
96
|
+
- 修复了部分功能在特定环境下无法正常使用的问题。
|
|
97
|
+
|
|
98
|
+
## [0.41.2] - 2026-09-04
|
|
99
|
+
|
|
100
|
+
### 修复
|
|
101
|
+
|
|
102
|
+
- 修复了 DAG 扩展解析、会话恢复和观测页面资源缓存等问题,让任务执行和对话页面在更新后更加可靠。
|
|
103
|
+
- 修复了孤儿会话和观测入口偶发失效的问题,重启或刷新后可以继续使用原有会话。
|
|
104
|
+
|
|
105
|
+
## [0.41.1] - 2026-09-02
|
|
106
|
+
|
|
107
|
+
### 修复
|
|
108
|
+
|
|
109
|
+
- 修复发布流程中的测试并发稳定性问题。
|
|
110
|
+
- 修复旧会话继续使用过期模型认证的问题,配置更新后会自动采用最新认证信息。
|
|
111
|
+
- 修复长工具链消息错序,历史会话也保持正确顺序。
|
|
112
|
+
- 统一工作区、Todo 和其他滚动区域的滚动条样式。
|
|
113
|
+
- 改进 HTML 文件预览,支持页面内交互和独立窗口完整阅读。
|
|
114
|
+
|
|
115
|
+
### 测试
|
|
116
|
+
|
|
117
|
+
- Pi MED 档测试改为校验模型档位形状,避免具体模型切换造成误报。
|
|
118
|
+
|
|
119
|
+
## [0.41.1-beta.0] - 2026-08-31
|
|
120
|
+
|
|
121
|
+
### 用户可见更新
|
|
122
|
+
|
|
123
|
+
- 前端自动化任务的规划、执行和结果检查更加稳定,失败后更容易继续处理。
|
|
124
|
+
- 长任务和复杂工作区的进度、文件和运行结果展示更加清晰。
|
|
125
|
+
- 插件管理、文件预览和任务详情等常用操作得到改进。
|
|
126
|
+
|
|
127
|
+
<details>
|
|
128
|
+
<summary>实现细节(开发者参考)</summary>
|
|
129
|
+
|
|
52
130
|
- 0.41.1-beta.0(frontend-node dogfood):将前端 DAG 的 Contract、Scout、Plan 切换为节点专属 skill/reference,bounded implement 仅注入有界代码规范;在保留默认 3K/12K 上下文预算的同时,避免 `frontend-plan-pi` 的必需 stable-id 追踪合同被静默截断。
|
|
53
131
|
- 拆分前端 DAG 的大一统 skill 注入:`frontend-contract-pi`、`frontend-scout-pi`、`frontend-plan-pi` 分别使用阶段专属 skill/reference,默认 12K runtime 预算内完整加载关键合同,不再让三个节点重复携带整份 node lifecycle、设计与代码规范;bounded implement 单独接收不授权扩展侦察的代码规范。新增真实默认预算回归断言,防 required reference 再次静默截断或因预算遗漏。
|
|
54
132
|
- 修复 frontend behavior verification 的伪 symbol 追踪:Plan 不再提交自由文本 `symbol`,改以非 static `verificationTarget.id` 作为稳定 token,并允许一个行为级 VT 覆盖多个相关 requirement;Implement 必须把 token 写入真实 `describe` / `it` / `test` 字面量标题。writer 完成边界新增轻量 trace preflight,缺失 token 时以 `needs-repair` 在 full verify 前失败;最终 trace gate 保留复验,并排除注释、普通字符串与 `VT-0010`/`VT-001` 前缀误命中。
|
|
@@ -269,19 +347,7 @@
|
|
|
269
347
|
- 右侧辅助栏统一承载文件、上下文、调用记录、运行活动和当前 DAG;点击消息流中的运行状态即可在同一侧栏查看运行、门禁与产物,并可自由调整侧栏宽度。
|
|
270
348
|
- 新增任务清单与结构化提问卡片,让长任务的进度和需要用户选择的内容更容易理解。
|
|
271
349
|
- 「对话 / 操作 / 观测」使用统一导航;操作和观测页面可以切换工作区查看对应数据。
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
### 修复
|
|
275
|
-
|
|
276
|
-
- 修复 Next Release 发布 workflow 的 io-heavy 测试并发不稳定:将该测试池固定为单 worker,避免全部测试通过后因过高并发触发 Vitest `onTaskUpdate` RPC settlement timeout,并消除 controller identity / package fingerprint 测试之间的共享状态竞态。
|
|
277
|
-
- 修复 Operator Chat 旧会话继续使用过期模型认证的问题:模型配置变化后,下一轮发送或手动重新加载会自动刷新模型目录和当前模型认证。
|
|
278
|
-
- 修复 Operator Chat 长工具链的消息错序:模型过程文字、思考和工具卡片现在按服务端事件顺序稳定交替展示,刷新历史会话后也保持相同顺序。
|
|
279
|
-
- 统一工作区、Todo 和其他滚动区域的滚动条样式,默认更轻巧,鼠标悬浮时也更容易辨认。
|
|
280
|
-
- HTML 文件预览现在支持页面内的标签切换等交互;较大的自包含 HTML 可以在新窗口中直接完整加载,不再受源码摘要长度限制。
|
|
281
|
-
|
|
282
|
-
### 测试
|
|
283
|
-
|
|
284
|
-
- `harness.json` Pi MED 档测试不再 pin 具体模型 id,改为校验 tier 形状,避免每次 dogfood 档位切换都造成测试失败。
|
|
350
|
+
</details>
|
|
285
351
|
|
|
286
352
|
## [0.41.0] - 2026-08-31
|
|
287
353
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
+
import { DAG_ABSOLUTE_MAX_WALL_CLOCK_MS } from "../../shared/timeout-policy.js";
|
|
2
3
|
import { createDagEventObserver } from "../../workflows/dag/event-observer.js";
|
|
3
4
|
import { composeDagRunObservers } from "../../workflows/dag/observer-compose.js";
|
|
4
5
|
import { createDagCanvasObserver, resolveCanvasPath, } from "../../workflows/dag/canvas-observer.js";
|
|
@@ -29,10 +30,11 @@ function buildRunDagNextSteps(runId) {
|
|
|
29
30
|
`loop-agent dag report --run-id ${runId} --markdown # advanced forensic`,
|
|
30
31
|
];
|
|
31
32
|
}
|
|
32
|
-
|
|
33
|
+
/** Shared production recovery seam for fresh runs and recovery continuations. */
|
|
34
|
+
export async function buildDefaultFrontendRecoveryDeps(repoRoot) {
|
|
33
35
|
// Keep the application layer free of a static worker→application cycle. The
|
|
34
36
|
// recovery controller is only needed after a frontend terminal failure.
|
|
35
|
-
const [{ openConsoleAppData }, { OperationStore }, { createOperationEventStore }, { LoopAgentClient }, { resolveSiblingLoopAgentBin }] = await Promise.all([
|
|
37
|
+
const [{ openConsoleAppData }, { OperationStore }, { createOperationEventStore }, { LoopAgentClient }, { resolveSiblingLoopAgentBin },] = await Promise.all([
|
|
36
38
|
import("../../infrastructure/console/app-data.js"),
|
|
37
39
|
import("../../infrastructure/console/operation-store.js"),
|
|
38
40
|
import("../../worker/console/operation-sse.js"),
|
|
@@ -46,6 +48,9 @@ async function buildDefaultFrontendRecoveryDeps(repoRoot) {
|
|
|
46
48
|
});
|
|
47
49
|
const client = new LoopAgentClient({
|
|
48
50
|
loopAgentBin: resolveSiblingLoopAgentBin(),
|
|
51
|
+
// rerun-task awaits the entire continuation, not just task preparation.
|
|
52
|
+
// Use the same hard ceiling as the DAG runner and Console entry point.
|
|
53
|
+
defaultTimeoutMs: DAG_ABSOLUTE_MAX_WALL_CLOCK_MS,
|
|
49
54
|
artifactRoot: path.join(appData.root, "client-artifacts", appData.fingerprint),
|
|
50
55
|
resolveIdentity: true,
|
|
51
56
|
});
|
|
@@ -53,6 +58,7 @@ async function buildDefaultFrontendRecoveryDeps(repoRoot) {
|
|
|
53
58
|
store,
|
|
54
59
|
operationRunnerDeps: {
|
|
55
60
|
store,
|
|
61
|
+
defaultTimeoutMs: DAG_ABSOLUTE_MAX_WALL_CLOCK_MS,
|
|
56
62
|
events,
|
|
57
63
|
client,
|
|
58
64
|
repoRoot,
|
|
@@ -13,6 +13,7 @@ export const campaignBudgetLimitsSchema = z
|
|
|
13
13
|
maxTokens: z.number().int().positive().optional(),
|
|
14
14
|
maxWallTimeMs: z.number().int().positive().optional(),
|
|
15
15
|
maxExecutorCalls: z.number().int().positive().optional(),
|
|
16
|
+
maxProviderRequests: z.number().int().positive().optional(),
|
|
16
17
|
maxRepairPasses: z.number().int().nonnegative().optional(),
|
|
17
18
|
maxConcurrency: z.number().int().positive().optional(),
|
|
18
19
|
maxContextChars: z.number().int().positive().optional(),
|
|
@@ -22,12 +23,13 @@ export const campaignBudgetLimitsSchema = z
|
|
|
22
23
|
const hasHardDim = limits.maxTokens !== undefined ||
|
|
23
24
|
limits.maxWallTimeMs !== undefined ||
|
|
24
25
|
limits.maxExecutorCalls !== undefined ||
|
|
26
|
+
limits.maxProviderRequests !== undefined ||
|
|
25
27
|
limits.maxRepairPasses !== undefined ||
|
|
26
28
|
limits.maxContextChars !== undefined;
|
|
27
29
|
if (!hasHardDim) {
|
|
28
30
|
ctx.addIssue({
|
|
29
31
|
code: z.ZodIssueCode.custom,
|
|
30
|
-
message: "budget.limits requires at least one of maxTokens, maxWallTimeMs, maxExecutorCalls, maxRepairPasses, maxContextChars",
|
|
32
|
+
message: "budget.limits requires at least one of maxTokens, maxWallTimeMs, maxExecutorCalls, maxProviderRequests, maxRepairPasses, maxContextChars",
|
|
31
33
|
});
|
|
32
34
|
}
|
|
33
35
|
});
|
|
@@ -47,6 +49,7 @@ export function createBudgetLedger(budget) {
|
|
|
47
49
|
tokens: null,
|
|
48
50
|
wallTimeMs: 0,
|
|
49
51
|
executorCalls: 0,
|
|
52
|
+
...(budget.mode === "hard" && budget.limits.maxProviderRequests !== undefined ? { providerRequests: 0 } : {}),
|
|
50
53
|
repairPasses: 0,
|
|
51
54
|
peakContextChars: 0,
|
|
52
55
|
missingTokenNodeIds: [],
|
|
@@ -136,6 +139,19 @@ export function recordNodeBudgetSample(ledger, sample) {
|
|
|
136
139
|
export function isHardBudgetBreached(ledger) {
|
|
137
140
|
return Boolean(ledger && ledger.mode === "hard" && ledger.status === "breached");
|
|
138
141
|
}
|
|
142
|
+
/** Reserve before dispatch. The caller must persist the shared ledger before granting admission. */
|
|
143
|
+
export function reserveProviderBudget(ledger, nodeId) {
|
|
144
|
+
if (ledger.limits.maxProviderRequests === undefined)
|
|
145
|
+
return undefined;
|
|
146
|
+
const used = ledger.consumed.providerRequests;
|
|
147
|
+
if (used === undefined || !Number.isInteger(used) || used < 0)
|
|
148
|
+
throw Error("FRONTEND_PROVIDER_BUDGET_INVALID: missing consumed provider requests");
|
|
149
|
+
const breach = checkLimit(ledger, "providerRequests", used, ledger.limits.maxProviderRequests, { nodeId, inclusive: true });
|
|
150
|
+
if (breach && ledger.mode === "hard")
|
|
151
|
+
return breach;
|
|
152
|
+
ledger.consumed.providerRequests = used + 1;
|
|
153
|
+
return undefined;
|
|
154
|
+
}
|
|
139
155
|
/** Mark all PENDING nodes as SKIPPED due to budget breach (fail closed). */
|
|
140
156
|
export function skipPendingNodesForBudgetBreach(nodes, breach) {
|
|
141
157
|
const skipped = [];
|
|
@@ -165,6 +181,7 @@ export function formatBudgetReportMarkdown(ledger) {
|
|
|
165
181
|
`| maxTokens | ${limits.maxTokens ?? "n/a"} |`,
|
|
166
182
|
`| maxWallTimeMs | ${limits.maxWallTimeMs ?? "n/a"} |`,
|
|
167
183
|
`| maxExecutorCalls | ${limits.maxExecutorCalls ?? "n/a"} |`,
|
|
184
|
+
`| maxProviderRequests | ${limits.maxProviderRequests ?? "n/a"} |`,
|
|
168
185
|
`| maxRepairPasses | ${limits.maxRepairPasses ?? "n/a"} |`,
|
|
169
186
|
`| maxConcurrency | ${limits.maxConcurrency ?? "n/a"} |`,
|
|
170
187
|
`| maxContextChars | ${limits.maxContextChars ?? "n/a"} |`,
|
|
@@ -176,6 +193,7 @@ export function formatBudgetReportMarkdown(ledger) {
|
|
|
176
193
|
`| tokens | ${c.tokens ?? "n/a (missing)"} |`,
|
|
177
194
|
`| wallTimeMs | ${c.wallTimeMs} |`,
|
|
178
195
|
`| executorCalls | ${c.executorCalls} |`,
|
|
196
|
+
`| providerRequests | ${c.providerRequests ?? "n/a"} |`,
|
|
179
197
|
`| repairPasses | ${c.repairPasses} |`,
|
|
180
198
|
`| peakContextChars | ${c.peakContextChars} |`,
|
|
181
199
|
`| missingTokenNodes | ${c.missingTokenNodeIds.join(", ") || "none"} |`,
|
|
@@ -552,11 +552,13 @@ export async function advanceTaskLifecycle(input) {
|
|
|
552
552
|
// Prefer basename-aligned names for multi-file product suites.
|
|
553
553
|
name: path.basename(prd.filePath).replace(/\.(md|markdown|txt)$/iu, "") || undefined,
|
|
554
554
|
});
|
|
555
|
-
|
|
555
|
+
if (imported.changed) {
|
|
556
|
+
importedMaterializedPaths.push(imported.materializedRelativePath);
|
|
557
|
+
}
|
|
556
558
|
}
|
|
557
559
|
// Latch even when prdPaths is empty so a mis-planned import cannot loop.
|
|
558
560
|
importedPrdThisCall = true;
|
|
559
|
-
if (
|
|
561
|
+
if (importedMaterializedPaths.length > 0) {
|
|
560
562
|
record = {
|
|
561
563
|
...appendTransition(record, "prd-imported"),
|
|
562
564
|
pendingPrdRefresh: true,
|
|
@@ -568,12 +570,15 @@ export async function advanceTaskLifecycle(input) {
|
|
|
568
570
|
completed.push("prd-imported");
|
|
569
571
|
await saveLifecycleRecord(input.repoRoot, record);
|
|
570
572
|
}
|
|
573
|
+
refreshManagedContractThisCall = Boolean(record.pendingPrdRefresh ||
|
|
574
|
+
hasContractChangingInput({ ...effectiveInput, prdPaths: undefined }));
|
|
571
575
|
snapshot = await observeTaskLifecycle(input.repoRoot, input.taskId);
|
|
572
576
|
// Two-phase Console bridge: when this call only had --prd and no
|
|
573
577
|
// engineering boundary, stop after archive. Re-plan would otherwise
|
|
574
578
|
// immediately prepare (hasPrdInput latched false + alreadyImported)
|
|
575
579
|
// and burn one-shot Semantic Intake before multi-file imports finish.
|
|
576
|
-
if (!hasBoundary &&
|
|
580
|
+
if (!hasBoundary && record.pendingPrdRefresh &&
|
|
581
|
+
(input.prdPaths?.length ?? 0) > 0) {
|
|
577
582
|
return {
|
|
578
583
|
taskId: input.taskId,
|
|
579
584
|
lifecycleState: "intake-incomplete",
|
|
@@ -842,13 +847,18 @@ export async function advanceTaskLifecycle(input) {
|
|
|
842
847
|
break;
|
|
843
848
|
}
|
|
844
849
|
preparedContractThisCall = true;
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
850
|
+
const contractChanged = prepareResult.apply?.noOp !== true;
|
|
851
|
+
if (contractChanged &&
|
|
852
|
+
(startupRepairAction ||
|
|
853
|
+
refreshManagedContractThisCall ||
|
|
854
|
+
Boolean(input.fromDraftPath))) {
|
|
848
855
|
// The old DAG and gate were bound to the pre-mutation contract.
|
|
849
|
-
refreshManagedContractThisCall = false;
|
|
850
856
|
regenerateDagThisCall = true;
|
|
851
857
|
}
|
|
858
|
+
// Consume the refresh request even when projection was a content no-op;
|
|
859
|
+
// otherwise the re-plan would invoke prepare-contract repeatedly in this
|
|
860
|
+
// advance call and eventually hit the step limit.
|
|
861
|
+
refreshManagedContractThisCall = false;
|
|
852
862
|
record = {
|
|
853
863
|
...appendTransition(record, "contract-managed"),
|
|
854
864
|
pendingPrdRefresh: false,
|
|
@@ -1153,7 +1163,7 @@ export async function advanceTaskLifecycle(input) {
|
|
|
1153
1163
|
continue;
|
|
1154
1164
|
}
|
|
1155
1165
|
if (action.type === "promote") {
|
|
1156
|
-
const runId =
|
|
1166
|
+
const runId = snapshot.currentRun?.runId;
|
|
1157
1167
|
if (!runId) {
|
|
1158
1168
|
blockers.push({
|
|
1159
1169
|
code: "PROMOTE_RUN_MISSING",
|
|
@@ -1181,6 +1191,13 @@ export async function advanceTaskLifecycle(input) {
|
|
|
1181
1191
|
continue;
|
|
1182
1192
|
}
|
|
1183
1193
|
if (action.type === "closeout") {
|
|
1194
|
+
if (!snapshot.promotion?.ready || !snapshot.currentRun) {
|
|
1195
|
+
blockers.push({
|
|
1196
|
+
code: "CLOSEOUT_EVIDENCE_STALE",
|
|
1197
|
+
message: "closeout requires promoted evidence for the current contract run",
|
|
1198
|
+
});
|
|
1199
|
+
break;
|
|
1200
|
+
}
|
|
1184
1201
|
const closed = await closeoutTask(input.repoRoot, input.taskId);
|
|
1185
1202
|
closeout = { path: closed.progressPath };
|
|
1186
1203
|
record = appendTransition(record, "closeout-completed");
|
|
@@ -1188,6 +1205,7 @@ export async function advanceTaskLifecycle(input) {
|
|
|
1188
1205
|
...record,
|
|
1189
1206
|
closeout: {
|
|
1190
1207
|
path: closed.progressPath,
|
|
1208
|
+
runId: snapshot.currentRun.runId,
|
|
1191
1209
|
completedAt: new Date().toISOString(),
|
|
1192
1210
|
},
|
|
1193
1211
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { access, readFile, readdir } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { getTaskDir, getTaskPaths,
|
|
3
|
+
import { getTaskDir, getTaskPaths, loadTaskConfig, } from "../../task/runtime.js";
|
|
4
|
+
import { getArtifactPath } from "../../shared/artifacts-core.js";
|
|
4
5
|
import { logicalRevisionForState, observeTaskContractState, } from "../../task/contract/index.js";
|
|
5
6
|
import { assessDagRunLiveness, listAllDagRunEntries, readDagRunSpec, readDagRunState, } from "../../workflows/dag/lifecycle.js";
|
|
6
7
|
import { resolveRunningControllerIdentity } from "../../shared/package-metadata.js";
|
|
@@ -202,6 +203,7 @@ export async function listExplicitlyAssociatedRuns(repoRoot, taskId) {
|
|
|
202
203
|
let stateStatus;
|
|
203
204
|
let failureCategory;
|
|
204
205
|
let lastMeaningfulProgressAt;
|
|
206
|
+
let contractBinding = null;
|
|
205
207
|
try {
|
|
206
208
|
const state = await readDagRunState(entry.runDir);
|
|
207
209
|
stateStatus = state.status;
|
|
@@ -238,20 +240,19 @@ export async function listExplicitlyAssociatedRuns(repoRoot, taskId) {
|
|
|
238
240
|
catch {
|
|
239
241
|
// state unreadable; may still match via binding
|
|
240
242
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
}
|
|
247
|
-
else if (spec.sourceBinding?.taskId === taskId) {
|
|
248
|
-
source = "source-binding";
|
|
249
|
-
}
|
|
243
|
+
try {
|
|
244
|
+
const spec = await readDagRunSpec(entry.runDir);
|
|
245
|
+
contractBinding = spec.taskContractBinding ?? null;
|
|
246
|
+
if (!source && spec.taskContractBinding?.taskId === taskId) {
|
|
247
|
+
source = "task-contract-binding";
|
|
250
248
|
}
|
|
251
|
-
|
|
252
|
-
|
|
249
|
+
else if (!source && spec.sourceBinding?.taskId === taskId) {
|
|
250
|
+
source = "source-binding";
|
|
253
251
|
}
|
|
254
252
|
}
|
|
253
|
+
catch {
|
|
254
|
+
// Association may remain visible, but unreadable identity cannot prove completion.
|
|
255
|
+
}
|
|
255
256
|
if (!source)
|
|
256
257
|
continue;
|
|
257
258
|
related.push({
|
|
@@ -262,6 +263,7 @@ export async function listExplicitlyAssociatedRuns(repoRoot, taskId) {
|
|
|
262
263
|
failureCategory,
|
|
263
264
|
lastMeaningfulProgressAt,
|
|
264
265
|
source,
|
|
266
|
+
contractBinding,
|
|
265
267
|
});
|
|
266
268
|
}
|
|
267
269
|
return related.sort((a, b) => a.runId.localeCompare(b.runId));
|
|
@@ -277,9 +279,10 @@ function deriveLifecycleState(input) {
|
|
|
277
279
|
return "running";
|
|
278
280
|
if (input.closeoutExists && input.promotionReady)
|
|
279
281
|
return "evidence-closed";
|
|
280
|
-
if (input.
|
|
281
|
-
|
|
282
|
-
|
|
282
|
+
if (input.currentRun?.lifecycle === "completed" &&
|
|
283
|
+
input.currentRun.status === "finished")
|
|
284
|
+
return "run-succeeded";
|
|
285
|
+
if (input.latestRun?.lifecycle === "completed" && input.latestRun.status !== "finished") {
|
|
283
286
|
// A newly opened current writeSet gate supersedes an older failed run so
|
|
284
287
|
// operators can approve and start the next DAG run. Success stays terminal
|
|
285
288
|
// here so promote/closeout is not hijacked by a residual open gate.
|
|
@@ -381,6 +384,19 @@ export async function observeTaskLifecycle(repoRoot, taskId) {
|
|
|
381
384
|
const runs = await listExplicitlyAssociatedRuns(repoRoot, taskId);
|
|
382
385
|
const activeRun = runs.find((run) => run.lifecycle === "active" || run.lifecycle === "paused") ?? null;
|
|
383
386
|
const latestRun = runs.length > 0 ? runs[runs.length - 1] : null;
|
|
387
|
+
const ref = contractState.ref;
|
|
388
|
+
const currentRun = contractState.effectiveStatus === "managed" && ref
|
|
389
|
+
? runs.filter((run) => {
|
|
390
|
+
const binding = run.contractBinding;
|
|
391
|
+
return (binding?.taskId === taskId &&
|
|
392
|
+
binding.revision === ref.revision &&
|
|
393
|
+
binding.canonicalHash === ref.canonicalHash &&
|
|
394
|
+
binding.taskConfigSha256 === ref.taskConfigSha256 &&
|
|
395
|
+
binding.projectionVersion === ref.projectionVersion &&
|
|
396
|
+
binding.canonicalizerVersion === ref.canonicalizerVersion &&
|
|
397
|
+
binding.taskConfigSchemaVersion === ref.taskConfigSchemaVersion);
|
|
398
|
+
}).at(-1) ?? null
|
|
399
|
+
: null;
|
|
384
400
|
const strictValidated = Boolean(record?.strictValidatedAt) &&
|
|
385
401
|
Boolean(record?.lastDagSpecHash) &&
|
|
386
402
|
record?.lastDagSpecHash === specHash;
|
|
@@ -433,17 +449,13 @@ export async function observeTaskLifecycle(repoRoot, taskId) {
|
|
|
433
449
|
!rejectedCurrent
|
|
434
450
|
? buildWriteSetGate({ taskId, bound: gateBound, delta: gateDelta })
|
|
435
451
|
: null;
|
|
436
|
-
const
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
}
|
|
441
|
-
catch {
|
|
442
|
-
legacyState = null;
|
|
443
|
-
}
|
|
444
|
-
const promotionReady = Boolean(legacyState?.artifacts.modifyLog && legacyState?.artifacts.verifyResult);
|
|
452
|
+
const currentSucceeded = currentRun?.lifecycle === "completed" && currentRun.status === "finished";
|
|
453
|
+
const promotionReady = Boolean(currentSucceeded && record?.promotion?.runId === currentRun?.runId &&
|
|
454
|
+
await exists(getArtifactPath(taskDir, "implement")) &&
|
|
455
|
+
await exists(getArtifactPath(taskDir, "verify")));
|
|
445
456
|
const closeout = closeoutPath(repoRoot, taskId);
|
|
446
|
-
const closeoutExists =
|
|
457
|
+
const closeoutExists = Boolean(promotionReady && record?.closeout?.runId === currentRun?.runId &&
|
|
458
|
+
record?.closeout?.path === closeout && await exists(closeout));
|
|
447
459
|
const awaitingDecision = activeRun?.lifecycle === "paused" ||
|
|
448
460
|
activeRun?.status === "paused" ||
|
|
449
461
|
Boolean(activeRun?.status === "waiting-for-human");
|
|
@@ -463,8 +475,9 @@ export async function observeTaskLifecycle(repoRoot, taskId) {
|
|
|
463
475
|
gateOpen: Boolean(gate),
|
|
464
476
|
activeRun,
|
|
465
477
|
latestRun,
|
|
478
|
+
currentRun,
|
|
466
479
|
promotionReady,
|
|
467
|
-
closeoutExists
|
|
480
|
+
closeoutExists,
|
|
468
481
|
needsAttention: Boolean(needsAttention),
|
|
469
482
|
awaitingDecision: Boolean(awaitingDecision),
|
|
470
483
|
});
|
|
@@ -510,14 +523,15 @@ export async function observeTaskLifecycle(repoRoot, taskId) {
|
|
|
510
523
|
gate,
|
|
511
524
|
activeRun,
|
|
512
525
|
latestRun,
|
|
526
|
+
currentRun,
|
|
513
527
|
runs,
|
|
514
528
|
promotion: {
|
|
515
|
-
required: Boolean(
|
|
516
|
-
ready: promotionReady
|
|
529
|
+
required: Boolean(currentSucceeded),
|
|
530
|
+
ready: promotionReady,
|
|
517
531
|
},
|
|
518
532
|
closeout: {
|
|
519
533
|
path: closeout,
|
|
520
|
-
exists: closeoutExists
|
|
534
|
+
exists: closeoutExists,
|
|
521
535
|
},
|
|
522
536
|
completedTransitions: record?.completedTransitions ?? [],
|
|
523
537
|
blockers: sourceFidelityReady
|
|
@@ -225,9 +225,9 @@ export function planTransitions(input) {
|
|
|
225
225
|
}
|
|
226
226
|
}
|
|
227
227
|
if (!input.skipFinalize &&
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
228
|
+
!dagRefreshRequired &&
|
|
229
|
+
!shouldImportPrd &&
|
|
230
|
+
snapshot.lifecycleState === "run-succeeded") {
|
|
231
231
|
if (!snapshot.promotion?.ready) {
|
|
232
232
|
actions.push({ type: "promote" });
|
|
233
233
|
expectedTransitions.push("promotion-completed");
|
|
@@ -237,7 +237,8 @@ export function planTransitions(input) {
|
|
|
237
237
|
expectedTransitions.push("closeout-completed");
|
|
238
238
|
}
|
|
239
239
|
}
|
|
240
|
-
if (snapshot.lifecycleState === "evidence-closed"
|
|
240
|
+
if (snapshot.lifecycleState === "evidence-closed" &&
|
|
241
|
+
!dagRefreshRequired && !shouldImportPrd) {
|
|
241
242
|
return {
|
|
242
243
|
actions: [{ type: "stop", reason: "terminal" }],
|
|
243
244
|
gate: null,
|
package/dist/build-stamp.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"version": "0.42.
|
|
4
|
-
"gitSha": "
|
|
5
|
-
"builtAt": "2026-09-
|
|
3
|
+
"version": "0.42.1",
|
|
4
|
+
"gitSha": "c5b2a591968093ab6ec1b62d7be6fc6c02b4ade7",
|
|
5
|
+
"builtAt": "2026-09-09T13:13:47.201Z"
|
|
6
6
|
}
|
package/dist/cli/program.js
CHANGED
|
@@ -440,7 +440,7 @@ const RAW_SUBCOMMAND_USAGE = {
|
|
|
440
440
|
"dag approve": 'usage: dag approve --run-id <id> --option <A|B|...> [--notes "..."]',
|
|
441
441
|
"dag reject": 'usage: dag reject --run-id <id> --reason "..."',
|
|
442
442
|
"dag rerun": "usage: dag rerun --run-id <id> --from-node <node-id> --plan [--json] | dag rerun --run-id <id> --from-node <node-id> --plan-hash <hash> --request-id <key> --reason <text> [--json]",
|
|
443
|
-
"dag rerun-task": "usage: dag rerun-task --run-id <id> --reason <text> --request-id <key> [--profile auto|minimal|standard|reviewed|supervised] [--task-id <id>] [--json]",
|
|
443
|
+
"dag rerun-task": "usage: dag rerun-task --run-id <id> --reason <text> --request-id <key> [--profile auto|minimal|standard|reviewed|supervised] [--task-id <id>] [--frontend-recovery --recovery-operation-id <id>] [--json]",
|
|
444
444
|
"dag reconcile-run": "usage: dag reconcile-run --run-id <id> [--action supersede|abandon] [--reason <text>]",
|
|
445
445
|
"dag doctor": "usage: dag doctor [--run-id <id>]\nInspect health issues before approve/reject/resume; no --json (output is already structured JSON).",
|
|
446
446
|
"dag report": "usage: dag report [--run-id <id>] [--lifecycle active|paused|completed|all] [--json|--markdown] [--failed-only] [--latest] [--paused-latest]\nRead-only run report; --json gives structured facts (canonical: `dag report --run-id <id> --lifecycle completed --json`).",
|
|
@@ -11,6 +11,8 @@ export async function runDagRerunTask(repoRoot, rawArgs) {
|
|
|
11
11
|
profileExplicit: parsed.profileExplicit,
|
|
12
12
|
taskIdOverride: parsed.taskIdOverride,
|
|
13
13
|
execute: parsed.execute,
|
|
14
|
+
frontendRecovery: parsed.frontendRecovery,
|
|
15
|
+
recoveryOperationId: parsed.recoveryOperationId,
|
|
14
16
|
});
|
|
15
17
|
console.log(JSON.stringify(result, null, 2));
|
|
16
18
|
if (!result.ok) {
|
|
@@ -373,7 +373,9 @@ function printHuman(result) {
|
|
|
373
373
|
}
|
|
374
374
|
}
|
|
375
375
|
if (result.apply) {
|
|
376
|
-
lines.push(
|
|
376
|
+
lines.push(result.apply.noOp
|
|
377
|
+
? ` apply: revision=${result.apply.ref.revision} (unchanged; identical content, no new transaction)`
|
|
378
|
+
: ` apply: revision=${result.apply.ref.revision} txId=${result.apply.txId ?? "n/a"}`);
|
|
377
379
|
}
|
|
378
380
|
if (result.error) {
|
|
379
381
|
lines.push(` error: ${result.error.code}: ${result.error.message}`);
|