@tea-agent/loop-agent 0.40.0-next.1 → 0.40.0-next.11
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/AGENTS.md +1 -1
- package/CHANGELOG.md +114 -109
- package/README.md +2 -2
- package/dist/application/dag/generate-task-dag.js +6 -2
- package/dist/application/task-lifecycle/advance.js +12 -0
- package/dist/build-stamp.json +3 -3
- package/dist/cli/update/runtime-activity.js +1 -29
- package/dist/commands/dag-rerun.js +1 -1
- package/dist/executors/dag-pi-executor.js +69 -7
- package/dist/executors/pi-executor.js +4 -2
- package/dist/executors/pi-sdk-executor.js +46 -1
- package/dist/executors/pi-writer-tool-policy.js +57 -1
- package/dist/executors/shell-executor.js +107 -20
- package/dist/executors/workspace-write-snapshot.js +68 -0
- package/dist/governance/checks.js +1 -0
- package/dist/infrastructure/harness/atomic-write.js +23 -0
- package/dist/shared/dag-prompt-override.js +4 -5
- package/dist/shared/update/npm-client.js +33 -11
- package/dist/task/config-types.js +10 -0
- package/dist/task/contract/apply.js +11 -1
- package/dist/task/contract/constants.js +2 -0
- package/dist/task/contract/hash.js +3 -0
- package/dist/task/contract/observe.js +25 -4
- package/dist/task/contract/paths.js +2 -1
- package/dist/task/contract/project.js +15 -1
- package/dist/task/contract/schema.js +2 -0
- package/dist/task/contract/transaction.js +12 -0
- package/dist/task/source-prepare/completeness.js +188 -0
- package/dist/task/source-prepare/fragment-inventory.js +474 -0
- package/dist/task/source-prepare/index.js +3 -0
- package/dist/task/source-prepare/ledger-reconciliation.js +127 -0
- package/dist/task/source-prepare/ledger-review.js +214 -0
- package/dist/task/source-prepare/ledger.js +545 -0
- package/dist/task/source-prepare/prepare.js +262 -1
- package/dist/task/source-prepare/semantic-intake.js +19 -3
- package/dist/task/source-prepare/source-fidelity-pi.js +384 -0
- package/dist/task/source-prepare/types.js +22 -0
- package/dist/worker/cli.js +12 -26
- package/dist/worker/console/chat/chat-event-store.js +75 -5
- package/dist/worker/console/chat/context-panel.js +7 -0
- package/dist/worker/console/chat/deferred-turn.js +12 -0
- package/dist/worker/console/chat/pi-runtime.js +331 -18
- package/dist/worker/console/chat/provider-error.js +98 -0
- package/dist/worker/console/chat/routes.js +389 -56
- package/dist/worker/console/chat/session-stats.js +179 -0
- package/dist/worker/console/chat/session-store.js +93 -63
- package/dist/worker/console/chat/todos.js +115 -0
- package/dist/worker/console/chat/tool-preview.js +42 -0
- package/dist/worker/console/chat/turn-process.js +20 -55
- package/dist/worker/console/chat/user-questions.js +266 -0
- package/dist/worker/console/chat/workspace-landing.js +79 -0
- package/dist/worker/console/console-handoff.js +82 -0
- package/dist/worker/console/console-update-and-init.js +115 -0
- package/dist/worker/console/console-update-runtime.js +84 -0
- package/dist/worker/console/dag-execution-receipt.js +20 -2
- package/dist/worker/console/draft-store.js +49 -0
- package/dist/worker/console/native-directory-picker.js +13 -0
- package/dist/worker/console/operation-store.js +1 -1
- package/dist/worker/console/operator-actions.js +133 -7
- package/dist/worker/console/operator-surface-health.js +1 -0
- package/dist/worker/console/prd-intake-bridge.js +13 -0
- package/dist/worker/console/routes.js +312 -1
- package/dist/worker/console/security.js +4 -4
- package/dist/worker/console/server.js +583 -172
- package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-Br92EGb7.js → abnfDiagram-N423BO3Z-Bs-CDAXM.js} +1 -1
- package/dist/worker/console/static/assets/{arc-oulImtQq.js → arc-CAkA3We3.js} +1 -1
- package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-tyHc6aqO.js → architectureDiagram-T3A2C74G-DEmI_zqr.js} +1 -1
- package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-CY86BSpT.js → blockDiagram-VBNYF7ZC-uDHANebE.js} +1 -1
- package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-BKKsDmNs.js → c4Diagram-5PPSVZJV-Bv97b4_B.js} +1 -1
- package/dist/worker/console/static/assets/channel-amxUpk7o.js +1 -0
- package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-CXZdjl3B.js → chunk-2GRJ4B5K-shmQKsFz.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-B-aIFDQ5.js → chunk-2Q5K7J3B-BAraNvcN.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5RXB4S5H-BDgAW_B2.js → chunk-5RXB4S5H-BirhxUop.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5VM5RSS4-DABa4UPR.js → chunk-5VM5RSS4-C9LgUJpR.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-aGbysVOx.js → chunk-6Q2QTUOP-DrU-s-t7.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-GF5L2VYU-B8MSZDVs.js → chunk-GF5L2VYU-Tx-H_FA2.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-JWPE2WC7-CpelV73g.js → chunk-JWPE2WC7-BjLtNFrR.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-KBJHAD2P-BE04ty3z.js → chunk-KBJHAD2P-UNLVwSsy.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-RYQCIY6F-BUxTkaaR.js → chunk-RYQCIY6F-CBEUX8XD.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-XXDRQBXY-CYYBVKfX.js → chunk-XXDRQBXY-WTL7IZOq.js} +1 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-bejwBVIz.js +1 -0
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-bejwBVIz.js +1 -0
- package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-CEQF_xmQ.js → cose-bilkent-JH36ORCC-CkHG6W3s.js} +1 -1
- package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-CqpxN5IT.js → cynefin-VYW2F7L2-BRzFqTaL.js} +1 -1
- package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-B3PzanVi.js → cynefinDiagram-MW4NZA55-2_CFp_i7.js} +1 -1
- package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-BSUGCNx1.js → dagre-VZM6K2ZE-BJtsmdkE.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-7IWD3JNH-CdLevU5T.js → diagram-7IWD3JNH-DNEFFo6w.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-BjpF_Kok.js → diagram-B4RE2ZJO-B_IWV7eo.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-LBJQPF4R-C4I6NJny.js → diagram-LBJQPF4R-DvvRx2dz.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-Q27KOJAE-C8hecCr5.js → diagram-Q27KOJAE-CsibsWLg.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-UB23O5K3-Daod6tOS.js → diagram-UB23O5K3-les_djBQ.js} +1 -1
- package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-BvvmazGv.js → ebnfDiagram-BXEA7PRR-BEm2n7qJ.js} +1 -1
- package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-DeN_vfV4.js → erDiagram-JOGREHBK-BI7vHHVm.js} +1 -1
- package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-D6dq1t9z.js → flowDiagram-UKHOOZJN-CUFCERrB.js} +1 -1
- package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-DziIdNY4.js → ganttDiagram-PKOTCBZU-wxyLiGWt.js} +1 -1
- package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-Dy4s5CXr.js → gitGraphDiagram-DS77QQ5N-Bt897K8Z.js} +1 -1
- package/dist/worker/console/static/assets/index-BHhUOTri.css +1 -0
- package/dist/worker/console/static/assets/index-DqJbO3-p.js +407 -0
- package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-Czv5eYx2.js → infoDiagram-6WML65LV-DYNx_IPv.js} +1 -1
- package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-Bsk3nFRT.js → ishikawaDiagram-WSZJBQD7-CzpLNEu6.js} +1 -1
- package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-DxGmNj5K.js → journeyDiagram-NVQOT4AX-97f9owNU.js} +1 -1
- package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-CYCFqkO_.js → kanban-definition-27J2QSJJ-BxM9hyBn.js} +1 -1
- package/dist/worker/console/static/assets/{linear-B0YzRwrd.js → linear-ByuxcHvp.js} +1 -1
- package/dist/worker/console/static/assets/{mermaid.core-t3EZtIGh.js → mermaid.core-DwPGvpCv.js} +5 -5
- package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-BTXpTv0T.js → mindmap-definition-FAOFIHXS-DCoqG9RT.js} +1 -1
- package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-DU8UkKqA.js → pegDiagram-VL7TDLO6-BLSBmBMx.js} +1 -1
- package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-DP4y8ohp.js → pieDiagram-7S7Q4E2Y-B0t_0oJW.js} +1 -1
- package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-B07vNaYR.js → quadrantDiagram-CIZ2JOQS-sTzDk7Nt.js} +1 -1
- package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-xDWktb2i.js → railroadDiagram-AXF67PYL-B3jRdATC.js} +1 -1
- package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-BLNMKqeS.js → requirementDiagram-LRYGKXZP-D-cTtXEN.js} +1 -1
- package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-n0adalxH.js → sankeyDiagram-W5VNT64P-B25igJRE.js} +1 -1
- package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-BbnS-2DL.js → sequenceDiagram-SI44F4Z6-jW_lM1_D.js} +1 -1
- package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-B4uPpCLu.js → sizeCapture-X5ZJPWSS-CrzTgsHE.js} +1 -1
- package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA--MMbB0fX.js → stateDiagram-OKZ733FA-B01MvlqE.js} +1 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-BvFKEtm2.js +1 -0
- package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-BXUgp2QY.js → swimlanes-SLNWSIFB-YcF12FiU.js} +2 -2
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-DIB2eVg-.js +8 -0
- package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-CsaMxki7.js → timeline-definition-Z64GVDOM-ClnRcg2s.js} +1 -1
- package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-C2IuG9iH.js → vennDiagram-T6HMQDX7-B6gr_z-q.js} +1 -1
- package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-CmEWOXCW.js → wardleyDiagram-T6FBY63Y-CvSgguGH.js} +1 -1
- package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-D_9LE0MG.js → xychartDiagram-ELKLHX3M-23OtSZCb.js} +1 -1
- package/dist/worker/console/static/index.html +2 -2
- package/dist/worker/console/static-src/app/console-types.js +68 -4
- package/dist/worker/console/static-src/app/useConsoleShell.js +30 -12
- package/dist/worker/console/static-src/app/useOperatorActions.js +41 -6
- package/dist/worker/console/static-src/app/useRecoveryConsole.js +10 -11
- package/dist/worker/console/static-src/app/useRunProgress.js +2 -1
- package/dist/worker/console/static-src/app/useTaskWizard.js +74 -2
- package/dist/worker/console/static-src/night/useNightBoard.js +8 -5
- package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +141 -8
- package/dist/worker/console/static-src/operator-chat/compaction-message.js +79 -0
- package/dist/worker/console/static-src/operator-chat/details-dag-actions.js +122 -0
- package/dist/worker/console/static-src/operator-chat/refs.js +3 -0
- package/dist/worker/console/static-src/operator-chat/runtime-selection-labels.js +27 -0
- package/dist/worker/console/static-src/operator-chat/spatial-overlay.js +1 -2
- package/dist/worker/console/static-src/operator-chat/turn-stream-controller.js +25 -0
- package/dist/worker/console/static-src/operator-chat/turn-submission.js +3 -2
- package/dist/worker/console/static-src/operator-chat/useChatSessions.js +181 -87
- package/dist/worker/console/static-src/operator-chat/useChatStream.js +159 -44
- package/dist/worker/console/static-src/operator-chat/useChatThread.js +177 -8
- package/dist/worker/console/static-src/operator-chat/useRepoBrowser.js +63 -9
- package/dist/worker/console/static-src/operator-chat/useWorkspaceBrowserGate.js +4 -0
- package/dist/worker/console/static-src/operator-chat/workspace-layout-mode.js +3 -3
- package/dist/worker/console/static-src/shell/useWorkspaces.js +299 -0
- package/dist/worker/console/static-src/shell/workspace-route.js +339 -0
- package/dist/worker/console/workspace-context.js +234 -0
- package/dist/worker/console/workspace-registry.js +214 -0
- package/dist/worker/observability/init-runtime-activity.js +26 -0
- package/dist/worker/observe/node-input.js +88 -2
- package/dist/worker/observe/routes.js +188 -0
- package/dist/worker/observe/server.js +4 -0
- package/dist/worker/observe/static/api.js +29 -9
- package/dist/worker/observe/static/app.js +18 -70
- package/dist/worker/observe/static/dag-node-purpose.d.ts +6 -0
- package/dist/worker/observe/static/dag-node-purpose.js +203 -0
- package/dist/worker/observe/static/format.js +37 -0
- package/dist/worker/observe/static/index.html +6 -1
- package/dist/worker/observe/static/inspect-workspace.js +307 -0
- package/dist/worker/observe/static/operator-chrome.css +145 -20
- package/dist/worker/observe/static/operator-chrome.d.ts +20 -3
- package/dist/worker/observe/static/operator-chrome.js +330 -100
- package/dist/worker/observe/static/prompt-restart-candidates.d.ts +18 -0
- package/dist/worker/observe/static/prompt-restart-candidates.js +36 -0
- package/dist/worker/observe/static/router.d.ts +46 -0
- package/dist/worker/observe/static/router.js +25 -1
- package/dist/worker/observe/static/state.d.ts +50 -0
- package/dist/worker/observe/static/state.js +174 -2
- package/dist/worker/observe/static/styles.css +357 -35
- package/dist/worker/observe/static/views/dag-graph.js +4 -2
- package/dist/worker/observe/static/views/dag-inspector.js +533 -79
- package/dist/worker/observe/static/views/dag.d.ts +13 -0
- package/dist/worker/observe/static/views/dag.js +6 -4
- package/dist/worker/observe/static/views/dashboard.js +6 -4
- package/dist/worker/observe/static/views/night.js +2 -2
- package/dist/worker/observe/static/views/pool.js +1 -0
- package/dist/worker/observe/static/views/run.js +3 -1
- package/dist/worker/observe/static/views/task.js +56 -1
- package/dist/workflows/dag/backend-test-case-coverage-analysis.js +186 -8
- package/dist/workflows/dag/backend-test-markdown-workflow.js +176 -1
- package/dist/workflows/dag/backend-test-pytest-collection.js +168 -16
- package/dist/workflows/dag/backend-test-result-contract.js +4 -0
- package/dist/workflows/dag/backend-test-scenario-param.js +339 -53
- package/dist/workflows/dag/backend-test-writer-completeness.js +28 -17
- package/dist/workflows/dag/dynamic-runtime/map.js +1 -0
- package/dist/workflows/dag/frontend-implementation-contract.js +88 -2
- package/dist/workflows/dag/frontend-plan-render.js +24 -0
- package/dist/workflows/dag/frontend-prewrite-gate.js +197 -0
- package/dist/workflows/dag/frontend-review-context.js +92 -10
- package/dist/workflows/dag/init-hybrid.js +239 -52
- package/dist/workflows/dag/interrupt-request.js +3 -3
- package/dist/workflows/dag/lifecycle.js +3 -3
- package/dist/workflows/dag/node-execution.js +45 -0
- package/dist/workflows/dag/types.js +62 -12
- package/docs/README.md +2 -0
- package/docs/architecture/evolution.md +45 -0
- package/docs/init-surface.manifest.json +1 -0
- package/docs/operations/local-development-environment.md +21 -0
- package/docs/templates/README.md +1 -1
- package/docs/templates/agent-dag.schema.json +18 -0
- package/docs/templates/backend-test-dag.json +267 -238
- package/docs/templates/frontend-implementation-contract.schema.json +681 -24
- package/harness.json +3 -3
- package/package.json +3 -1
- package/skills/loop-agent/references/hybrid-dag.md +7 -0
- package/dist/worker/console/static/assets/channel-TY36zt-i.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-Dk7QCChM.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-Dk7QCChM.js +0 -1
- package/dist/worker/console/static/assets/index-C3GgHg-g.css +0 -1
- package/dist/worker/console/static/assets/index-Ci8ksvBm.js +0 -406
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-BqOigMQ4.js +0 -1
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-Caxz9UA2.js +0 -8
- package/dist/worker/console/static-src/operator-chat/activity-rail-presentation.js +0 -73
- package/dist/worker/console/static-src/operator-chat/useActivityRailTransition.js +0 -59
package/AGENTS.md
CHANGED
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
4. 涉及测试纪律/验证声明/调试时继续读:`docs/governance/harness-methodology-*.md`。
|
|
42
42
|
5. 查看最近提交、相关 plan/progress/report;`git status --short --branch`;跑最小基线验证。
|
|
43
43
|
6. 后端/接口/pytest → `taskKind: "backend-test"`(不是 `--profile`);知识回写 `knowledge-sync`;图谱开荒 `knowledge-graph-bootstrap`。`--profile` 仅 `auto|minimal|standard|reviewed|supervised`。
|
|
44
|
-
7. 看板/observe → `agent-worker console`(默认 repo=当前目录、port=8790;listen 成功后默认打开系统浏览器,`--no-open` 禁止)(`/inspect/`
|
|
44
|
+
7. 看板/observe → `agent-worker console`(默认 repo=当前目录、port=8790;listen 成功后默认打开系统浏览器,`--no-open` 禁止)(`/inspect/` 只读;唯一实验例外:节点 inspector 默认出现「提示词重启」tab 并注入 scoped mutation token;设置 `HARNESS_DAG_RERUN_PROMPT_OVERRIDE=0|false|off` 可紧急关闭,此时零 token 零 tab);`observe serve` 已下线(`OBSERVE_SERVE_REMOVED` + exit 2);`observe snapshot` 仍可用。
|
|
45
45
|
8. 分支合并 → 先读 `docs/operations/branch-merge-guideline.md`。
|
|
46
46
|
9. 涉及版本发布、npm 渠道、release 分支、GitHub Actions 发布链或 dist-tag → 先读 `docs/operations/version-and-release-management.md`。
|
|
47
47
|
|
package/CHANGELOG.md
CHANGED
|
@@ -4,117 +4,122 @@
|
|
|
4
4
|
|
|
5
5
|
### 重点更新
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
- Operator Chat
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
- Console
|
|
12
|
-
- 前端风险分级细分 manifest 触及语义:`allowedPaths` 含 `package.json`/lockfile 或需求文本提到 package.json 不再单独触发 `new-dependency` high-risk(改一行 script、调构建参数的任务不再被顶到强制全门禁并误标高风险),只有任务文本同时出现安装语言(npm install / yarn add / pnpm add / 新增依赖等)才升级;仅路径触及时记 `new-dependency:manifest-path-without-install-language` 拒绝信号,审计可溯。
|
|
13
|
-
- 前端验证 fallback 生成期诚实化:真实项目无可读取的 `package.json` scripts 且未探测到本地 tsc 时,不再注入必然失败的 `npm run typecheck` / `npm run build` / `npm test`(纯静态 / vanilla JS 站点原会在 verify 阶段假失败),改为执行显式 no-op 标记命令(`No frontend verification command configured`,进入冻结命令集可被 contract 引用,trace 如实记录 not-run),并写生成期 advisory 提示用 `--verify` 或执行约束显式声明验证命令后重新生成 DAG。无 repoRoot 的单测 fixture 保留历史 generic fallback。**标记不构成验证证据(fail-closed)**:verification trace 将绑定标记的 target 判为失败、只含标记的 static 证据判为 unavailable,repair 分类归为 non-repairable `contract`,verify 节点以 `frontend verification unavailable` 硬失败阻断 review/closeout——无真实验证命令的 run 无法走完绿灯链。
|
|
14
|
-
- frontend-test `passed` 回执链改按 dispatch 序号判序(B-HASH-01):`summarizePlaywrightCliReceipts` 先按 `sequence` 排序再判 open→find→cleanup 连续链;并行 `find`/`screenshot` 按完成时间落盘导致的乱序不再误杀执行已通过的 case(Wave 1 实测 4 条 passed 被改判 `browser-command-evidence-missing`)。真 gap / 重复序号仍 fail-closed。
|
|
15
|
-
- `tool-policy` 失败归一为 `executor`(B-REC-03):前端 preflight 能力拒绝(缺 `@playwright/cli` JS entry、allowlist 拒绝)不再落 `unknown`→`manual-review`+`humanRequired`;`dag report` 给出 `rerun-after-fix`,Console `standaloneTaskRerun` 的 R2 gate 放行 run-failed 同 task 整单重跑,无需人工决策门或 sibling task。
|
|
16
|
-
- Operator Chrome Band1 模式切换入口补显式 `aria-label`(B-FIND-01,方案 A):`操作`/`观测` mode link 原为 inline-flex 裸文本节点,不参与 name-from-content,a11y snapshot 序列化为无名 link,`find` 无法断言;补 `aria-label` 后实测 `find "观测"` 1 命中、click 后 `find "运行总览"` 1 命中,AC-FE-CHROME-003 恢复可见断言路径。
|
|
17
|
-
- Inspect 异常 Task 页空态文案统一(B-FIND-02):`failures.js` 运行时空态由 `当前没有失败或阻塞的 Task。` 改回与静态 `#failures-empty`、页面标题及回归目录 AC-FE-INS-004 一致的 `当前没有异常 Task`,消除静态/运行时文案漂移;实测新文案 find 1 命中、旧文案 0 命中。
|
|
18
|
-
|
|
19
|
-
- `next-release.yml` 防重复发布守卫补充幂等语义:`mode=recover`(dist-tags.next 已指向出自本 HEAD 的 tarball)时,手动 `workflow_dispatch` 重入不再撞 duplicate publish 硬失败,改为写 summary 后干净退出(§5.1 规则 4);非 recover 的重复发布仍硬失败。
|
|
20
|
-
|
|
21
|
-
- frozen repair 工具审计改为按 attempt 段扫描(B1):`session-events.jsonl` 跨 attempt 共享追加,attempt>1 的 `auditRepairAttemptToolUse` 现在只审本 attempt 字节段(newline 对齐),planner attempt 1 的 ls/find 不再被误判给 repair 轮;repair prompt 显式声明 read-only 工具契约与 allowlist 边界(B2),并内嵌 openspec-citations 输出格式正例;`LOOP_AGENT_IGNORE_STALE_DIST=1` 环境变量旁路 stale-dist guard(B3),Console spawn 的 sibling CLI 可继承。
|
|
22
|
-
- frontend plan/revision 结构化输出改为冻结 repair context + hash-bound canonical artifact:attempt>1 不再重放完整 planner prompt;成功后 stdout 只保留 artifact 路径,design review / prewrite 只消费已校验 artifact,不再从节点文本 merge。失败分类补齐 `structured-repair-exhausted` / `governance-blocked`,并修正 `structured-output-truncated` / `output-too-large` 的归一化映射。
|
|
23
|
-
- 将 `@earendil-works/pi-ai` 与 `@earendil-works/pi-coding-agent` 从可选依赖提升为精确 pin 的运行时依赖 `0.83.0`,将运行时直接导入的 `typebox` 精确声明为 `1.3.7`,并在根包声明 Node.js `>=22.19.0`。安装 `@tea-agent/loop-agent` 会默认装上 Pi SDK(含 `--omit=optional` 场景);`@cursor/sdk` 仍保持 optional。availability / readiness 探针、隔离 tarball canary、发布包契约测试与安装/本地环境说明同步对齐。
|
|
24
|
-
- backend-test Scenario Partition 仅接受绑定源有限 enum/分类集合的 GET/list query/path 轴;非法 Domain(空/重复/保留 token、无有限域、与 OpenAPI enum 不一致)报 `INVALID_PARTITION_DOMAIN` / `NO_FINITE_DOMAIN` / `PARTITION_SOURCE_MISMATCH` 根因,不再生成空后缀 `TP-SP-...-`、重复 slot,也不再级联 `MISSING_*_SLOT`。N6 对这些根因码 fail-closed;合法源分区缺槽仍阻断。N2 禁止为自由串/主键/required-only/boundary-only 建分区;N5 允许删除无源非法 Partition 及其派生槽位。
|
|
25
|
-
- npm `next` 渠道发布改为提交数节流:main push 仅当距上次 next 发布的 source commit ≥ 5 个 commit 时才自动发布(新增 `scripts/next-publish-gate.mjs`,读已发布 tarball build-stamp 对比 HEAD);不足阈值时 workflow 绿色跳过,手动 `workflow_dispatch` 不受限(切 release 线前强制出包 / 紧急补发)。发布文档真源 §4.1/§5.1/§7/§12 同步。
|
|
26
|
-
|
|
27
|
-
### 新增
|
|
28
|
-
|
|
29
|
-
- Operator Chat 时间线左缘新增「用户消息锚点栏」:每个用户输入一枚横向小条(12×3px 微圆角),紧凑等距排列并在时间线高度内垂直居中;条数超出栏高时相邻锚点自动聚合为稍宽的聚合条(悬停展开「N 条聚合输入」逐条列表,时间 + 单行预览,逐条点击定位)。悬停时小条向对话一侧平滑伸长(12→18px)并变橙,浮窗右侧弹出(白底圆角,正文最多 3 行、超出省略号,附序号与时间);单击平滑滚动定位到对应消息(精确停靠在视口顶部偏移 8px);覆盖视口顶部的锚点保持高亮。空会话自动隐藏;历史分页/流式更新/窗口缩放时自动重算(rAF 节流)。
|
|
30
|
-
- frontend-test 产物根可配置:`task.json.frontendTest.testRoot` 缺省仍为 `testcase/frontend`,省略时生成的 DAG 路径与历史默认根一致;自定义根(如 `qa/frontend-test`)在编译期冻结并驱动 writer、gate、playwright 围栏与 `allowedPaths`。`.harness/**` 等隐藏/治理树在生成期拒绝。
|
|
31
|
-
- 实验能力「编辑失败节点提示词后从节点重跑」(默认关闭):内部开关 `HARNESS_DAG_RERUN_PROMPT_OVERRIDE=1` 启用后,`dag rerun` 支持 `--prompt-override <nodeId>@<file>`(全文替换)与 `--prompt-override-append <nodeId>@<file>`(追加指令:保留冻结原提示词,末尾追加 `<operator_addendum>` 块)。仅限 ERROR 且位于 reset closure 内的节点;mode + base/最终 prompt sha256 计入 planHash(execute 漂移即 `PLAN_DRIFT`),父 run spec 冻结、provenance(含 mode)落 `continuation.promptOverrides`。Console 新增 `dagPromptOverrideConfig` 开关探测 action,`dagRerunPlan`/`dagRerun` 接受 `promptOverrides`(`{nodeId, prompt, mode?}`);Inspect DAG 节点 inspector 新增「提示词重启」tab——默认「追加指令」模式(只读底稿 + 追加编辑器),可切换「全文替换(高级)」,预检通过展示执行估算,提交后续跑并跳转新 run,全程不离开图页;开关开启时 `/inspect` 只注入 **scoped** 变体凭据(独立 cookie + `__INSPECT_MUTATION_TOKEN__`,与 Console 通用 token 互不可重放),mutations 路由对 inspect 凭据仅放行 `dagRerunPlan`/`dagRerun`(其余 action 403 `ACTION_NOT_IN_INSPECT_SCOPE`),Inspect 不获得通用写能力;开关关闭时不注入任何 token、tab 不出现,检视面保持严格只读。
|
|
32
|
-
- 观察面 DAG Inspector 节点详情适配 Pi 扩展:执行器输入摘要展示节点声明的 `piExtensions` 短 id;新增「Pi 扩展运行事实」展示 `pi-extensions.json` 的 resolved(包名@版本)与 missing 降级原因(缺包降级不再静默);产物未生成/损坏时降级提示不阻断接口,绝对路径不外泄。
|
|
33
|
-
- 后端实现 DAG(standard / review-gated / supervised)的 Pi 节点支持按桶显式加载本机 Pi 导航扩展:读侧节点(除 closeout)加载 `pi-codegraph` + `pi-lens`,写侧节点只加载 `pi-codegraph`(pi-lens 的 `ast_grep_replace` 可绕过 writeSet,不加载);前端/测试模板与省略字段节点保持扩展全关。扩展发现始终关闭,只经白名单解析 `~/.pi/agent` 与项目 `.pi` settings 的已装包(缺包降级不失败,产物 `pi-extensions.json` 记录 requested/resolved/missing);session 后 pin 工具面剔 builtin 同名、deny 面与写工具,writer 的 `edit`/`write` 仍为 policy-wrapped;`.codegraph/**` index 同步不再计入 write-guard 越界。
|
|
34
|
-
- Pi SDK 终态 session-events JSONL 顶层增加可选 `finish_reason`:仅当 `message_end` / `turn_end` / `assistant_message` 明确携带非空终止原因时由序列化层提升,不伪造默认值,也不回流 `stopReason` 诊断。
|
|
35
|
-
- `backendTest` 布局配置纳入 Task Contract managed 注入面:`task advance` 新增 `--backend-test <json>`,可在公共任务生命周期内把 `testRoot`/`markdownRel`/`scriptRel`/`sharedSetupDoc`/`mode`/`gapDoc`/`executeScope` 写进 `task.json`,不再需要手工编辑(手工编辑会让任务漂移成 `externally-modified` 并拒绝 `--approve-gate`)。给出即整体替换、省略即保留既有配置(历史手写配置因此自愈)、`'{}'` 为显式清空回默认布局;重复 advance 幂等,契约保持 `managed`。`task contract diff` 把值变更标 routine `BACKEND_TEST_CONFIG_CHANGED`、丢键/清空额外标 elevated `BACKEND_TEST_CONFIG_WEAKENED`。
|
|
36
|
-
- Operator Chat 文件预览抽屉新增图标「新窗口打开」:用当前已加载内容在独立浏览器窗口打开全页阅读视图,窗口内可切换「预览 / 查看原文」(带宽高的 `window.open` popup,Markdown 排版、HTML 铺满视口的空 sandbox iframe、JSON pretty-print / 其它文本等宽滚动);打开成功后断开 `opener` 且不立刻 revoke Blob,避免空白页;弹窗被拦截时 header 附近报错且不关闭抽屉
|
|
37
|
-
- backend-test 适配 A–D:可配置 `backendTest` 布局(`testRoot`/`markdownRel`/`scriptRel`)、用户公共前置文档引用与模块顶部 `user_shared_setup`(不写 conftest)、查询轴 Scenario Partitions 确定性展开与 fail-closed 门禁、`mode=gap-fill` 13 节点增量 DAG。Slot ID 以声明的 Partition ID 为真源(`TP-<Partition ID>-...`)。
|
|
38
|
-
- 前端 plan 唯一机器契约化(JSON-only):`frontend-plan-pi` / `frontend-plan-revision-pi` 输出收敛为「一行导语 + 唯一 fenced `json` 契约 + 唯一 `openspec-citations` 引用块」,彻底移除「可选 Markdown 说明」;plan.md(`contracts/frontend-plan.md`)改由 prewrite gate 用纯函数 `renderFrontendPlanMarkdown` 确定性渲染(不新增 DAG 节点/不新增 Pi 调用)
|
|
39
|
-
- 契约 schema 新增 5 个可选字段(`implementationSteps` / `stylingStrategy` / `dependencyPolicy` / `residualRisks` / `realIntegrationGap`),`schemaVersion` 保持 1;`docs/templates/frontend-implementation-contract.schema.json` 同步
|
|
40
|
-
- revision 输出改为 RFC 7386 merge-patch delta + 引用块:gate 配置新增 `revisionPatch`,生效时在 `planFallbackFromNodeIds[0]` 原始契约上应用 `applyFrontendImplementationContractPatch` 后进入既有分析/规范化/物化管线;旧 DAG 缺字段按整契约处理
|
|
41
|
-
- canonical contract 序列化(UTF-8)超过 64KB → `retryable-invalid` + 新增 `contract-too-large` failureCode(体积守卫兜底)
|
|
42
|
-
- `design-review` / `final-design-review` 提示改为消费契约 JSON(注入契约字段摘要),不再要求读取 plan prose
|
|
43
|
-
- Console「模型与认证」页新增模型矩阵编辑器:展示并允许编辑 `harness.json executors.pi` 的 LOW/MED/HIGH 三档模型;输入框从 readiness 结构化投影 `piModelMatrix` 预填(provider/model 或裸 model id),本地内联校验(空串 / `default` 哨兵 / 畸形 `provider/`、`/model`、`a//b`)非法时禁用保存;保存经既有 `POST /api/operator/v1/operations` 派发 `savePiModelMatrix`,复用 HTTP 层 `evaluateMutationGate`(boot capability cookie + `x-loop-console-confirmation` 头 + Origin/Host/Sec-Fetch-Site),读全文档后原子写 tmp+fsync+rename(保留 `$schema` 与其余字段),成功后自动重测 readiness 并对活动 Chat session 触发 `/sessions/:id/reload`(409 `PI_SESSION_BUSY` 给出可恢复提示)
|
|
44
|
-
- `GET /api/operator/v1/readiness` 的 probe 新增 `piModelMatrix` 结构化投影(向后兼容,不改动既有 `modelsMessage`)
|
|
45
|
-
- 组件选型规范合规(ADR 0016):契约 schema 新增可选 `uiComponentChoices[]`(`{ purpose, component, decision(specified|reuse-existing|new), specReference{path,section,line}|null, rationale }`),`specified` 必须给非空 `specReference`、`new` 不得携带、空串拒绝;`schemaVersion` 保持 1;`docs/templates/frontend-implementation-contract.schema.json` 同步
|
|
46
|
-
- `frontend-prewrite-gate` 新增三个 `retryable-invalid` failureCode:`component-spec-reference-invalid`(specReference.path 非受支持规范路径)、`component-spec-not-cited`(未在 openspec-citations 引用块引用或未真实读取)、`component-choices-missing`(组件/主题候选桶非空且契约有 UI 可见工作而 `uiComponentChoices` 缺失/空)
|
|
47
|
-
- gate 配置新增可选 `componentSpecCandidatePaths`(旧 DAG 缺字段兼容);`init-hybrid` 从 `designEvidence.classified.component ∪ theme ∪ rule.components` 冻结注入,capability context 强调组件/主题桶语义,plan/revision/design-review/final-design-review 提示加入硬规则与 BAD/GOOD 示例
|
|
48
|
-
- `frontend-plan.md` 新增 `Component Selection (spec conformance)` 章节(纯函数确定性渲染,缺省 `_(not specified)_`)
|
|
49
|
-
|
|
50
|
-
- `frontend-prewrite-gate` 的 OpenSpec 读取校验支持 `task.json.frontendOpenspec` 配置:`policy` 缺省 `cited`(候选 = `requiredReadPaths` ∪ 任务源显式引用的 openspec 路径),`scan-strict` 保留止血任务后的全量必读语义;`requiredReadPaths` 中非 openspec 支持路径在生成期确定性失败
|
|
51
|
-
- 确定性引用块协议:生效 plan 输出在 fenced `json` 契约块后追加 `openspec-citations` fenced 块(每行一个 JSON `{"path","section","line"}`);gate 解析并与生效 plan/review 节点的成功 read 事件核验,新增 `openspec-citation-block-unparseable` / `openspec-not-cited` / `openspec-citation-not-read` 三个 retryable-invalid failureCode(防捏造、防遗漏)
|
|
52
|
-
- `src/shared/openspec-spec.ts` 新增 `extractTaskSourceOpenspecPaths` 纯函数(反引号内联、markdown 链接目标、裸路径 token → 归一化 → spec 过滤 → 治理子树排除 → 去重排序)
|
|
53
|
-
- 生成期把 `openspecPolicy` 与候选来源元数据(`openspecCandidateSources.declared` / `taskSourceCited` / `scanStrict`)冻结进 prewrite gate 配置;`task advance` 的 advisories 说明当前模式与候选来源
|
|
54
|
-
|
|
55
|
-
### 改进
|
|
56
|
-
|
|
57
|
-
- DAG 节点检查器「执行过程」按执行器分流:Pi 仍看 session-events;有命令的 shell 展示 `shell-command-receipt` 与 stdout/stderr;`frontendBrowserToolPreflight` 等内部处理器展示步骤回执(历史 run 可从 capability / attempt 产物合成)。空态不再把 shell/static 误说成「暂无过程日志」。节点输入补充 named handler 名称。脚本仍属于节点输入,不假装已执行。
|
|
58
|
-
- DAG 节点检查器「节点输出」在整段内容为完整 JSON 对象或数组时改为缩进代码块展示,不再把紧凑 `JSON.stringify` 挤成一段 Markdown 段落;截断或非法 JSON、普通 Markdown 仍走原阅读器。
|
|
59
|
-
- frontend DAG 的 materialized source references 恢复统一的有界 excerpt 与按需 read 指针,不再把 requirement/acceptance 文档全文复制进每个相关节点,也不再强制 contract/plan 重读全部绑定源文件,降低长需求在多节点中的重复上下文占用。
|
|
60
|
-
- frontend-test prepare-package 会从 `docs/templates/`、`harness.json` `governanceRoot`/templates 以及 init 投影的 `ai_workspace/loop-agent/templates/` 拷贝标准场景;full init 目标仓不再静默落到仅含 `STD-FE-SMOKE-ENTRY` 的 fallback。
|
|
61
|
-
- frontend-test 环境探测区分 connection-refused(curl 7)与 HTTP 4xx/5xx,并提示先启动本地前端后再从 probe 节点续跑;不再把所有不可达都写成同一句 `frontend-base-url-unreachable`。
|
|
62
|
-
- frontend-test 报告解析用例 Markdown 的 `##`/`###` 标题与有序列表(`测试步骤` / `预期结果` / `前置条件与重置`);缺 `测试目的` 时回退到用例 H1,避免主 HTML 出现空步骤。
|
|
63
|
-
- `dag rerun --from-node` 把尚未启动的 writer/map 视为首次执行;frontend-test probe 这种失败的 exclusive shell 可以带着下游未跑节点续跑,不必整图 `standaloneTaskRerun`。
|
|
64
|
-
- Pi SDK 节点在 stall watchdog(默认 15 分钟无 provider 活动)触发后,会先 abort 当前等待,并在同一会话自动发送一次「继续」;仅 abort 已确认且尚未调用 write 工具时恢复,失败仍判 timeout。绝对墙钟超时与 CLI 后端不走这条恢复。
|
|
65
|
-
- DAG 节点检查器「执行过程」时间线默认展开原始协议事件(`message_start` / `message_end`),按钮文案为「隐藏原始协议事件」;用户可点选关闭,同会话内选择会保持。
|
|
66
|
-
- Operator Chat 的乐观停止现在把“视觉已停止”和 Turn ownership 分开:Abort 获得可靠终态前明确显示“正在停止”,此时可为原会话保存一条服务端持久化的“停止后发送”消息;后一次覆盖前一次,切换会话、刷新页面或 Console 重启不会丢失,旧 Turn 结束后复用正常 Turn 准入路径自动发送,并以固定 `clientRequestId` 防止重复执行。
|
|
67
|
-
- Operator Chat 修复快速终止时“停止后发送”与普通发送之间的准入空洞:发送路径改读实时 ownership;若 deferred 请求恰好撞上旧 Turn 终态,会先按服务端状态对账,再使用同一 `clientRequestId` 自动转为普通发送,不再要求用户刷新重试或丢失本次提交。
|
|
68
|
-
- `dag rerun-task` 现在会把父 run 最后一轮仍未解决的 `verify-pi` / review 反馈、证据引用和修订轮次带入新完整 DAG;planner、implementer 与 verifier/reviewer 必须修复或举证说明不再适用,不能仅因文件已存在就返回 `already-satisfied`。Console 同步区分「自动修订」「从失败节点恢复」「带反馈重新执行任务」。
|
|
69
|
-
- DAG 恢复与治理收敛收窄为两条最小路径:标准治理 `request-revision` 仅在 `maxFixLoops > 0` 时同 run 回到 `implement-pi`;writer 遇到 `unavailable` / `network` / `rate-limit` / `timeout` 时,`dag rerun --from-node` 重跑 writer 本身及安全下游,不再把 parent `ERROR` 改写成 `FINISHED`,任意自定义 shell 也不能仅凭 `verifyEvidence` 获得续跑资格。
|
|
70
|
-
- `frontend-plan-pi` 改为 runtime skeleton + editable RFC 7386 patch:`schemaVersion`、source binding、risk、writer target files 与生产 Mock 安全位由 DAG 冻结且不可被 plan/revision 覆盖;节点 validator 将补丁编译为 canonical 完整契约后再交给 review/prewrite,并在 `contracts/candidates/<nodeId>/` 保存每次 raw/extracted/normalized/validation 证据。任务提示与三类结构化重试(invalid-output / provider length 截断 / output-too-large)同步收敛为单一 patch + 唯一 `openspec-citations`;无法在声明文件中解析的可选 verification symbol 会被确定性移除并留下 normalization action,避免格式冲突、完整契约重复输出和说明性 symbol 延迟到 trace 才失败。
|
|
71
|
-
- Operator Chat 恢复工具对齐真实能力:系统提示改用 `dagReport` / `dagRerunPlan` / `dagRerun` / `standaloneTaskRerun` / `workerTaskRetry` 真名,不再写 `operator_*` 或把 `dagResume` 当成模型可执行项;`dagDoctor` / `dagStatus` / `workerPoolDoctor` 改为 typed `runId`/`taskId`,不再让模型猜 CLI `args[]`。ADR 0013 自定义 base prompt 上限由 1900 统一调整为 2500(2026-08-18,废止 0.8×2498 比例),预算用于写清节点续跑 / 整单重生 / Worker 重排队分流,以及多轮迭代恢复纪律(先一句话总结上一轮错误、修根因不修症状、禁止原样重交、同错两轮后停下报告)。
|
|
72
|
-
- Operator Chat 模型工具面收敛:`advanced` 分类的命令(workflow/loop/benchmark/knowledge-graph 等 8 个只读低频入口)不再进入模型工具白名单,模型注意力集中到高频工具;保留的 27 个 model-callable 官方 CLI 动作全部换上「做什么 + 何时用」语义描述,不再是无信息的 `Official CLI action coverage for ...` 模板;dispatcher 对官方尾部动作的识别从描述前缀匹配改为结构化 `OFFICIAL_TAIL_ACTION_IDS` 集合判断。审查收口:`knowledgeCurate` 纠正为 `mutation`/`advanced`(条件写盘,移出模型面,防经 read 通道传 `--output` 写盘);`promoteRun`/`closeoutTask` 描述去掉 dispatch 不保证的生命周期断言,如实标注为 task-advance 别名并提示先核 run/任务状态。工具清单渲染修复:promptSnippet 去掉重复工具名前缀(SDK 渲染自带 `- name:`,原实现名字出现两遍);`inspect`/`status`/`spineCheck`/`sourceInstructions` 四条占位描述换成语义描述;task-advance 家族(`newTask`/`dagRunTask`)标注与标准流 `taskAdvance` 的关系,避免模型在 5 个相似入口间选错。可调用性修复:`observeLink` 补上 4 个可选参数 schema(dagRunId/taskId/featureId/workerRunId,原空 schema + additionalProperties:false 导致模型传参必被拒、工具名存实亡);Pi 工具参数 schema 现在携带注册表里的参数描述(Type.String/Boolean/Number/Array 注入 `description`,原实现丢弃参数描述、模型只能看到参数名)。
|
|
73
|
-
|
|
74
|
-
- Operator Chat 对齐 pi-web:建会话不再传封闭 `tools` 白名单(避免 SDK 把扩展 MCP 工具滤出 registry),创建后 `bindExtensions` 发 `session_start`,再钉激活集。扩展注册的 MCP 工具可被模型调用;`apply_patch` / `full-tools` / `shell` / `coding-chat` 仍排除。
|
|
75
|
-
- 对话侧栏 Plugins 右侧新增只读 MCP 弹窗:展示 `mcp.json` 配置的服务,以及当前会话真正注册/激活的 MCP 工具;没有配置也没有工具时保持真实空态。
|
|
76
|
-
- 对话侧栏原 Packages 入口改名为 Plugins,与 pi-web / Pi 用户面一致;内部仍是 package inventory。
|
|
77
|
-
- 对话进行中底部上下文占用百分比保持常驻:token 用量事件不再冲掉上一帧的 contextUsage,并在回合中持续刷新。
|
|
78
|
-
- 上一轮大量 bash 结束后再发新消息,旧工具条不再整批挂到新气泡下面:无主工具不再丢进最新一组,历史按完整回合裁切,空助手气泡若还挂着工具会留下来当锚点。
|
|
79
|
-
- 侧栏文件树点击目录行直接插入 `@目录/` 引用(箭头单独负责展开/收起);输入框 @ 补全也列出目录,排在文件前面。
|
|
80
|
-
- 对话进行中点「停止」立即安静下来(乐观停止,对齐 pi-web):不再等 POST /abort 往返;后端 abort 等待从 8s 降到 2.5s,未终结时由状态对账收敛。
|
|
81
|
-
- 侧栏文件树实时刷新:agent 回合结束、浏览器标签页回到前台、手动点「刷新」时重拉根目录+全部已展开目录(此前手动刷新只拉根目录,子目录永远旧缓存)。
|
|
82
|
-
- Skills / Packages / Models 面板不再把 Pi 的 warning / collision 原文堆在列表上方:改成标题条一颗摘要芯片(如「14 条提示」),点开按「需要处理 / 名称不规范 / 同名未生效」分组,文案用自然语言,路径只显示末两段;名称不规范的技能在列表旁标「提示」,详情里说明「现在这样也能用」。加载失败仍单独成组,可点「再读一次」。
|
|
83
|
-
- Skills / Packages 双栏改为左右各自滚动;资源弹窗挂到 `document.body`,按顶部对话导航的实时高度在剩余视口居中,不再被 sticky 顶栏挡住上沿。
|
|
84
|
-
- 标准、评审和监督型 DAG 现在会在当前运行中重试短暂的验证故障;写入节点只有在确认工作区完全未变更时才会重试,避免因网络波动重新执行整条任务。
|
|
85
|
-
- 后端测试支持自定义目录、公共前置说明、查询场景分区和增量补缺模式;相关布局可通过 `task advance --backend-test` 纳入受管任务契约,不再需要手工修改 `task.json`。
|
|
86
|
-
|
|
87
|
-
- 裸 `agent-worker console` 在 listen 前会按本机自然日询问一次 npm `latest` 升级;继承当前 npm registry,失败不阻断启动,Console URL 仍只写 stdout。
|
|
88
|
-
- npm `next` 发布成功后会更新 `npm-next` 分支锚点;可用 `loop-agent inspect next` 查看已发布版本、源码提交、构建时间和本地尚未发布的提交。
|
|
89
|
-
- Operator Chat 的文件预览可在新窗口中打开,并可切换排版预览与原始内容;弹窗被浏览器拦截时会保留当前抽屉并给出提示。
|
|
90
|
-
- Pi SDK 的会话事件可透出模型明确返回的结束原因,便于诊断截断、停止和异常结束。
|
|
91
|
-
|
|
92
|
-
- 初始化模型配置新增 Pi/OpenCode 脱敏目录:代码只暴露白名单模型元数据和凭据就绪状态,执行初始化的模型结合目标项目自主选择并直接写入 LOW/MED/HIGH;只有实质歧义才询问用户。
|
|
93
|
-
- npm `next` 自动发布改为每累计 5 个提交触发一次,减少无意义构建;手动发布仍可随时执行。
|
|
94
|
-
- `dag rerun-task` 会继承上一轮尚未解决的验证和评审反馈,避免新一轮忽略旧问题或误判为已经完成。
|
|
95
|
-
- DAG 恢复入口会根据失败类型区分“从节点继续”和“完整重跑”,并避免把失败节点改写成成功状态。
|
|
96
|
-
- Operator Chat 停止会话时会显示真实进度;用户可预先提交一条“停止后发送”的消息,刷新页面或重启 Console 也不会丢失。
|
|
97
|
-
- Operator Chat 的命令说明和参数提示与实际能力保持一致,减少选错恢复入口或误用占位参数。
|
|
98
|
-
- 测试套件按 CPU、内存、平台和当前 DAG 压力动态分配资源,并减少重复启动进程,完整验证耗时更稳定。
|
|
99
|
-
|
|
100
|
-
### 修复
|
|
101
|
-
|
|
102
|
-
- backend-test 用例覆盖分析的 payload 形状提取在无 `python` 可执行文件的环境(现代 macOS 只有 `python3`)静默降级为空结果,导致 payload 观测路径全空、`PAYLOAD_SHAPE_MISMATCH` 误报;解释器解析改为 POSIX 优先 `python3`、Windows 优先 `python`(与 scenario-param 语法校验一致),仅在解释器缺失时尝试下一候选,分析输入自身的失败不再重试。
|
|
103
|
-
- Inspector「执行过程」时间轴按「执行分次」选择过滤:session-events 是跨 attempt 共享追加的单文件,此前所有次执行的事件重合显示、切换顶部分次不生效;现在按 `agent_start` 边界分段,选中第 N 次执行只显示该段并标注「已按第 N 次执行过滤 · 共 M 次执行」,单次执行与 pass 选择保持全量展示,检测不到边界时显式提示并回退全量。
|
|
104
|
-
- 前端 plan/revision 的 `openspec-citations` fence 提取改为行锚定正则:直接闭合的空 fence(无候选行、紧跟关闭 fence)此前被判定为「不存在 citation 块」而进入格式重试循环,现在计为合法的唯一 citation 块;重复、损坏或非唯一的 fence 仍被拒绝。
|
|
105
|
-
- `npm test` 前置段失败导致后续段(io-heavy / integration)被跳过时,`scripts/run-tests.mjs` 显式输出警告与补跑命令,不再静默跳过(此前失败汇总会被误读为全量覆盖)。
|
|
106
|
-
- npm 包现在会包含 `inspect next` 运行时依赖的查询脚本,安装后的 CLI 不再因缺少包内文件而无法启动。
|
|
107
|
-
- 初始化更新改为一次扫描与规划:固定投影按 recorded ownership 确定性增删改,多个语义合并按单文件写边界串行排队,全部完成后只做一次最终验证;已完成的 `--status` / `--report` 只读取哈希锚定证据,不再重复运行项目脚本。`harness.json` 按属性结构演进并保留项目值,仍存在于 Pi 的 LOW/MED/HIGH 保持不变,只重选失效档位;fresh init、update 与 doctor 会在 Pi 无可用模型时提前阻断。
|
|
108
|
-
- CLI 新版本检查与 `init upgrade` 的版本门禁会从调用开始就使用 npm 当前配置:目标项目 `.npmrc`、用户级/全局 `npm config set registry`、环境变量与 scoped registry 均继续由 npm 按原生优先级解析;企业镜像失败时不会偷偷回退官方源,并以脱敏原因区分超时、npm 启动失败、查询失败和无效响应。
|
|
109
|
-
- 同一浏览器、同一 hostname、不同端口的多个 Operator Console 不再争用认证 Cookie;不同项目和同一项目的多个 Console 可以并行对话,往返页面无需刷新。Console 重启后旧页面仍会被安全拒绝,刷新后恢复。
|
|
110
|
-
- Markdown 表格只处理横向溢出,鼠标停在表格上时仍可正常上下滚动对话。
|
|
111
|
-
- Windows 上执行后端测试场景参数的 Python 语法检查时,会跳过不可用的 Microsoft Store 占位程序,避免错误回滚合法改动。
|
|
112
|
-
- 旧版前端 DAG 也能识别增量计划修订,不再因契约格式差异反复重试;无法合并的修订会提示重新生成 DAG。
|
|
7
|
+
- backend-test 的 pytest repair 现在继续使用 run-owned plan,不再搜索测试目录 README;correspondence finding 会直接指向 docstring、参数 ID、符号、脚本或 payload 的修复位置,collection/scenario repair 与 generated-local Python 写边界保持一致,并在单次 Pi 会话达到 24 轮或 80K 最大 usage snapshot 前受控返回 partial failure。
|
|
8
|
+
- Operator Chat 现在可以在同一个页面管理多个工作区;每个会话始终使用创建它的工作区,切换对话时地址栏保持简洁稳定。
|
|
9
|
+
- 对话消息流整体调整为更紧凑、清晰的布局,思考过程、工具执行、阶段性结果和最终回答会按真实发生顺序展示。
|
|
10
|
+
- 上下文过大时会自动压缩并继续原请求,消息流会依次展示触发原因、压缩进度和压缩结果;手动压缩也使用同一套展示方式。
|
|
11
|
+
- 对话进行中可以连续提交多条消息,并支持编辑、删除或立即插入当前回复;刷新页面或重启 Console 后,未发送内容仍会保留。
|
|
113
12
|
|
|
114
|
-
###
|
|
13
|
+
### 新增
|
|
14
|
+
|
|
15
|
+
- 右侧辅助栏统一承载文件、上下文、调用记录、运行活动和当前 DAG;点击消息流中的运行状态即可在同一侧栏查看运行、门禁与产物,并可自由调整侧栏宽度。
|
|
16
|
+
- 新增任务清单与结构化提问卡片,让长任务的进度和需要用户选择的内容更容易理解。
|
|
17
|
+
- 「对话 / 操作 / 观测」使用统一导航;操作和观测页面可以切换工作区查看对应数据。
|
|
18
|
+
|
|
19
|
+
### 改进
|
|
20
|
+
|
|
21
|
+
- 后端测试的计划与生成阶段只读取任务明确绑定的需求、环境报告和本轮产物,减少无关仓库内容干扰结果,并让后续步骤继续使用同一份已确认计划。
|
|
22
|
+
- Operator Chat 的任务清单工具描述补齐多步骤与 DAG 使用纪律:开始前按具体步骤规划、保持进行中约束、完成后立即更新完整列表,并用面向用户的阶段呈现 DAG 进度,简单任务自动跳过。
|
|
23
|
+
- 正式发布会自动同步更新版本日志和文档站摘要;发布说明优先生成简洁自然的中文,生成服务不可用时也能安全完成发布。
|
|
24
|
+
- 输入框整合模型与推理等级选择,并只展示有真实数据的轮次、耗时、速度和缓存统计。
|
|
25
|
+
- 工作区、会话列表、文件标签和侧栏交互更加紧凑自然,折叠、切换和页面过渡更加流畅。
|
|
26
|
+
- 设置页改用自然中文展示当前工作区的模型状态,减少内部状态和重复信息。
|
|
27
|
+
- DAG 检查器简化节点说明、执行记录和提示词重启面板,长内容更容易阅读和定位。
|
|
28
|
+
|
|
29
|
+
### 修复
|
|
30
|
+
|
|
31
|
+
- 修复文档审计扫描本地 `.scratch/` 临时证据与打包目录、导致仓库 preflight 和发布前验证被非治理文件阻断的问题。
|
|
32
|
+
- 修复 backend-test 把 Markdown 明确声明的 enum-invalid、wrong-type、null、empty 和精确非法 custom literal 当作 payload enum 契约漂移、错误消耗唯一一次 pytest repair 的问题;豁免现在按 pytest parameter ID、目标字段和值逐 TP 绑定,positive/nominal drift 与 path 缺陷仍严格阻断。
|
|
33
|
+
- 修复 backend-test 无法从同一生成模块的安全 payload helper 中绑定 field-target positional/keyword/default 参数,以及无法识别精确 `_without(payload, field)` 删除语义的问题;computed、动态、二层、跨模块和危险 helper 仍保持 `UNDETERMINED`。
|
|
34
|
+
- 修复 backend-test 无法静态证明同一生成模块内安全 payload helper、导致 request-level nominal 场景长期停留在 `UNDETERMINED` 的问题;超长边界 observed 现在持久化为有界摘要并保留真实长度,空白修复建议也明确使用真实空格而非字面 escape 文本。
|
|
35
|
+
- 修复 backend-test 把 Markdown 中 `\\u0020`/`\\x20` 空白表示与 pytest 真实空白字符串误判为 scenario-param 不一致的问题;readiness 的逐项排除现在携带有界的 TP、字段、expected/observed raw/normalized 和源码位置诊断,同时不对普通业务字符做 trim、大小写折叠或宽松解码。
|
|
36
|
+
- 修复 Console 把 backend-test writer 的局部保护文件误判为整个 writeSet 越界的问题;任务级禁止路径仍保持硬阻断,合法 DAG 可继续取得 autonomous execution receipt。
|
|
37
|
+
- 修复 backend-test 对 `resource_client.call(..., payload=...)` 一类本地 transport 的 payload AST 假阴性;readiness 新增固定分类/Case 排除汇总和 pytest 启动事实,payload repair finding 同时携带 expected/observed/missing path 清单。
|
|
38
|
+
- 修复后端测试在 payload、fixture 与 Markdown→pytest 对应关系同时异常时只修复其中一类问题的问题;pytest 侧缺陷现在通过结构化 `repairFindings` 合并进入唯一一次有界 repair,Markdown Test Point 未分类或重复分类则在生成阶段定向重试并禁止下游猜修。
|
|
39
|
+
- 修复重命名会话时输入框没有回显当前标题的问题。
|
|
40
|
+
- 修复停止回复后输入区恢复迟缓、排队消息偶发丢失,以及切换会话后旧状态残留的问题。
|
|
41
|
+
- 修复宽表格、文件预览、滚动条和窄屏布局中的多处显示异常。
|
|
42
|
+
- 修复部分 Windows 环境读取运行状态时的偶发失败,并提高前后端任务验证的可靠性。
|
|
43
|
+
|
|
44
|
+
## [0.39.1] - 2026-08-25
|
|
45
|
+
|
|
46
|
+
### 重点更新
|
|
47
|
+
|
|
48
|
+
- 前端实现流程会逐项核对原始需求与验收标准,减少长需求被遗漏、误解或静默排除的情况。
|
|
49
|
+
- Console 新增可选择稳定版或预发布版的更新入口,更新前会检查正在运行的任务,完成后自动恢复当前页面。
|
|
50
|
+
|
|
51
|
+
### 新增
|
|
52
|
+
|
|
53
|
+
- DAG 检查器可以查看失败节点的提示词版本,并在确认后从选定内容重新执行。
|
|
54
|
+
- 后端测试会核对本轮文件清单与实际引用关系,避免历史文件或错误依赖混入测试结果。
|
|
55
|
+
|
|
56
|
+
### 改进
|
|
57
|
+
|
|
58
|
+
- 设置页移除重复的模型配置入口,模型管理继续集中在对话页。
|
|
59
|
+
- 关键治理文档完成复核,当前能力、限制和操作方式保持一致。
|
|
60
|
+
|
|
61
|
+
## [0.39.0] - 2026-08-23
|
|
62
|
+
|
|
63
|
+
### 重点更新
|
|
64
|
+
|
|
65
|
+
- Operator Chat 支持通过方向键找回历史输入,并可在当前回复进行时预先排队下一条消息。
|
|
66
|
+
- 任务向导新增实时进度、当前节点、运行时长和失败摘要,长时间任务更容易判断是否正常推进。
|
|
67
|
+
|
|
68
|
+
### 新增
|
|
69
|
+
|
|
70
|
+
- 前端测试支持自定义测试目录和文件布局,适配不同项目结构。
|
|
71
|
+
|
|
72
|
+
### 改进
|
|
73
|
+
|
|
74
|
+
- 运行结束后会自动降低刷新频率,并为失败状态提供更直接的处理建议。
|
|
75
|
+
- npm 预发布包会记录准确版本,安装后显示的版本与实际发布制品保持一致。
|
|
76
|
+
|
|
77
|
+
## [0.38.4] - 2026-08-23
|
|
78
|
+
|
|
79
|
+
### 重点更新
|
|
80
|
+
|
|
81
|
+
- 初始化与升级流程更好地支持企业 npm 镜像、已有模型配置和一次性安全更新。
|
|
82
|
+
- Console 与 DAG 检查器补充了运行状态、失败节点和提示词重启等诊断能力。
|
|
83
|
+
|
|
84
|
+
### 新增
|
|
85
|
+
|
|
86
|
+
- 新增 `inspect next`,可以查看当前 npm 预发布版本对应的源码和本地尚未发布的变化。
|
|
87
|
+
- 前端测试可以从项目治理目录和初始化模板读取标准场景,并提供更完整的执行报告。
|
|
88
|
+
|
|
89
|
+
### 修复
|
|
90
|
+
|
|
91
|
+
- 修复 npm 包缺少运行文件、macOS Python 命令差异、Windows 场景检查和部分滚动显示问题。
|
|
92
|
+
- 修复前端计划引用、失败恢复和测试回执在复杂项目中的多处误判。
|
|
93
|
+
|
|
94
|
+
## [0.38.3] - 2026-08-22
|
|
95
|
+
|
|
96
|
+
### 重点更新
|
|
97
|
+
|
|
98
|
+
- Operator Chat 的文件预览可以在新窗口打开,并能在排版预览与原始内容之间切换。
|
|
99
|
+
- 长时间模型任务遇到输出截断或暂时停滞时,恢复过程更加可靠。
|
|
100
|
+
|
|
101
|
+
### 新增
|
|
102
|
+
|
|
103
|
+
- 安装 loop-agent 时会默认包含 Pi 运行能力,减少额外配置步骤。
|
|
104
|
+
- DAG 检查器可以查看不同执行器的运行过程和更清晰的节点输出。
|
|
105
|
+
|
|
106
|
+
### 改进
|
|
107
|
+
|
|
108
|
+
- 后端测试增强了自定义目录、场景分区和生成文件的校验。
|
|
109
|
+
- 文件浏览、结束原因和前端计划恢复信息更容易查看和诊断。
|
|
110
|
+
|
|
111
|
+
## [0.38.2] - 2026-08-20
|
|
112
|
+
|
|
113
|
+
### 重点更新
|
|
114
|
+
|
|
115
|
+
- 后端测试支持自定义输出目录、公共前置说明、查询场景分区和增量补缺模式。
|
|
116
|
+
- Operator Chat 的停止与后续发送更加可靠,停止过程中提交的下一条消息不会因刷新或重启丢失。
|
|
117
|
+
|
|
118
|
+
### 改进
|
|
115
119
|
|
|
116
|
-
-
|
|
117
|
-
-
|
|
120
|
+
- DAG 重新执行时会继承上一轮尚未解决的验证和评审反馈,减少重复失败。
|
|
121
|
+
- 恢复入口会根据失败原因选择从节点继续或完整重跑,并给出更明确的操作建议。
|
|
122
|
+
- npm 预发布改为按提交数量节流,减少没有必要的重复发布。
|
|
118
123
|
|
|
119
124
|
## [0.38.1] - 2026-08-18
|
|
120
125
|
|
package/README.md
CHANGED
|
@@ -116,7 +116,7 @@ loop-agent dag report --run-id <run-id>
|
|
|
116
116
|
| --- | --- | --- |
|
|
117
117
|
| 受治理 CLI | `loop-agent …` / `agent-worker …` | 权威写入与诊断 |
|
|
118
118
|
| Loop Operator Console | `agent-worker console` | Official 本地控制面(默认 repo=当前目录、`127.0.0.1:8790`,含 Operate 与 Inspect) |
|
|
119
|
-
| Inspect(只读) | `agent-worker console` → `/inspect/`;`observe snapshot` | 统一 Console 内只读检视;`observe serve` 已下线(REMOVED / exit 2
|
|
119
|
+
| Inspect(只读) | `agent-worker console` → `/inspect/`;`observe snapshot` | 统一 Console 内只读检视;`observe serve` 已下线(REMOVED / exit 2)。实验例外:节点 inspector 默认显示失败节点「提示词重启」tab;紧急回退可设置 `HARNESS_DAG_RERUN_PROMPT_OVERRIDE=0`(也接受 `false` / `off`),关闭后不注入任何 mutation token |
|
|
120
120
|
|
|
121
121
|
```bash
|
|
122
122
|
# 终端 A:Console(任务/运行操作面;canonical mutation 只经 sibling loop-agent)
|
|
@@ -126,7 +126,7 @@ agent-worker console doctor --repo .
|
|
|
126
126
|
|
|
127
127
|
```
|
|
128
128
|
|
|
129
|
-
裸 `agent-worker console`
|
|
129
|
+
裸 `agent-worker console` 不在终端询问升级。Operate 右上角提供非阻塞的更新入口,默认选择 npm `latest` 稳定版,也可由操作者显式选择 `next` 预发布版;更新前会先检查活跃运行和全局安装来源。`console doctor`、帮助和版本命令均不触发更新检查。
|
|
130
130
|
|
|
131
131
|
访问 Console <http://127.0.0.1:8790/>;**Operator Chat Official** 是 Console 内的主引导交互,默认打开「对话」工作区。构建时设置 `VITE_OPERATOR_CHAT_DEFAULT_LANDING=tasks` 可改回 Tasks;URL hash(`#/tasks`)与 localStorage 仍优先于默认值。顶部「检视」以及 `/inspect/` 提供只读 Dashboard、DAG、时间线与 artifacts;`loop-agent …` / `agent-worker …` CLI direct path 仍是受治理 fallback。当前状态为 **code ready, dogfood pending/unmet**,不宣称已替代 openCode 或其他外部主会话。
|
|
132
132
|
|
|
@@ -109,8 +109,12 @@ function findForbiddenOverlapsForPacket(task) {
|
|
|
109
109
|
const overlaps = [];
|
|
110
110
|
for (const writeSetEntry of task.writeSet ?? []) {
|
|
111
111
|
for (const forbiddenPath of task.forbiddenPaths ?? []) {
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
// A narrower forbidden child may intentionally carve a protected
|
|
113
|
+
// file out of a broader node writeSet. The runtime write guard gives
|
|
114
|
+
// forbiddenPaths precedence; report a packet conflict only when the
|
|
115
|
+
// writeSet entry itself is inside the forbidden boundary. Console G2
|
|
116
|
+
// separately rechecks task-global forbidden paths with live scope.
|
|
117
|
+
if (pathMatchesPattern(writeSetEntry, forbiddenPath)) {
|
|
114
118
|
overlaps.push({ writeSetEntry, forbiddenPath });
|
|
115
119
|
}
|
|
116
120
|
}
|
|
@@ -3,6 +3,7 @@ import path from "node:path";
|
|
|
3
3
|
import { createTask, getTaskPaths, loadTaskConfig, } from "../../task/runtime.js";
|
|
4
4
|
import { importPrdDocument } from "../../task/source-references.js";
|
|
5
5
|
import { prepareTaskSource } from "../../task/source-prepare/index.js";
|
|
6
|
+
import { resolveProductionSourceFidelityPi } from "../../task/source-prepare/source-fidelity-pi.js";
|
|
6
7
|
import { isIntakeSoftGapCode, resolvePrdImportRole, } from "../../task/source-prepare/artifact-meta.js";
|
|
7
8
|
import { sanitizeDraftPlaceholders } from "../../task/source-prepare/placeholder-paths.js";
|
|
8
9
|
import { evaluateSemanticIntakeEligibility, isSemanticIntakeDisabled, readSemanticIntakeAttempted, runSemanticIntake, } from "../../task/source-prepare/semantic-intake.js";
|
|
@@ -585,6 +586,15 @@ export async function advanceTaskLifecycle(input) {
|
|
|
585
586
|
continue;
|
|
586
587
|
}
|
|
587
588
|
if (action.type === "prepare-contract") {
|
|
589
|
+
// 生产 source fidelity Pi 接线(AC-PROD-001/005):仅 frontend-implementation
|
|
590
|
+
// 任务注入 reconcile executor + 独立 reviewer;ineligible 返回 undefined 不接线。
|
|
591
|
+
// 主路径与 semantic-intake retry 路径共用同一接线,保证任意一条生产路径都实际
|
|
592
|
+
// 触发 reconciliation executor(修复前两处均缺省导致生产路径从不调用 Pi)。
|
|
593
|
+
const sourceFidelity = await resolveProductionSourceFidelityPi({
|
|
594
|
+
repoRoot: input.repoRoot,
|
|
595
|
+
taskId: input.taskId,
|
|
596
|
+
taskKind: input.taskKind,
|
|
597
|
+
});
|
|
588
598
|
let draftIntent = null;
|
|
589
599
|
if (input.fromDraftPath) {
|
|
590
600
|
try {
|
|
@@ -635,6 +645,7 @@ export async function advanceTaskLifecycle(input) {
|
|
|
635
645
|
verifyCommands: effectiveInput.verifyCommands,
|
|
636
646
|
backendTest: input.backendTest,
|
|
637
647
|
},
|
|
648
|
+
...(sourceFidelity ? { sourceFidelity } : {}),
|
|
638
649
|
});
|
|
639
650
|
if (!prepareResult.ok) {
|
|
640
651
|
const gapCodes = (prepareResult.gaps ?? [])
|
|
@@ -712,6 +723,7 @@ export async function advanceTaskLifecycle(input) {
|
|
|
712
723
|
verifyCommands: effectiveInput.verifyCommands,
|
|
713
724
|
backendTest: input.backendTest,
|
|
714
725
|
},
|
|
726
|
+
...(sourceFidelity ? { sourceFidelity } : {}),
|
|
715
727
|
});
|
|
716
728
|
if (retry.ok) {
|
|
717
729
|
warnings.push({
|
package/dist/build-stamp.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"version": "0.40.0-next.
|
|
4
|
-
"gitSha": "
|
|
5
|
-
"builtAt": "2026-08-
|
|
3
|
+
"version": "0.40.0-next.11",
|
|
4
|
+
"gitSha": "a23cf8d31616835f9fa670d7135ee4a5bd84feba",
|
|
5
|
+
"builtAt": "2026-08-28T16:52:35.690Z"
|
|
6
6
|
}
|
|
@@ -1,29 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { buildGlobalSnapshot } from "../../worker/observability/read-model.js";
|
|
4
|
-
/**
|
|
5
|
-
* Read-only runtime guard for init-surface writes.
|
|
6
|
-
*
|
|
7
|
-
* DAG activeness is anchored to real directories in the canonical active
|
|
8
|
-
* lifecycle root. Worker activeness reuses the Observe read model so Task Pool
|
|
9
|
-
* status precedence and composite identity stay owned by the Worker adapter.
|
|
10
|
-
* Projection failures block writes because liveness cannot be proven safely.
|
|
11
|
-
*/
|
|
12
|
-
export async function readInitRuntimeActivity(repoRoot) {
|
|
13
|
-
const resolvedRoot = path.resolve(repoRoot);
|
|
14
|
-
const activeDagRoot = path.join(resolvedRoot, ".harness", "dag-runs", "active");
|
|
15
|
-
const entries = await readdir(activeDagRoot, { withFileTypes: true }).catch(() => []);
|
|
16
|
-
const activeDagRunIds = entries
|
|
17
|
-
.filter((entry) => entry.isDirectory() && entry.name !== ".gitkeep")
|
|
18
|
-
.map((entry) => entry.name)
|
|
19
|
-
.sort();
|
|
20
|
-
const snapshot = await buildGlobalSnapshot({ repoRoot: resolvedRoot });
|
|
21
|
-
return {
|
|
22
|
-
activeDagRunIds,
|
|
23
|
-
activeWorkerBatches: snapshot.health.worker.activeBatches,
|
|
24
|
-
activeWorkerTasks: snapshot.health.worker.activeTasks,
|
|
25
|
-
...(snapshot.projectionError
|
|
26
|
-
? { workerProjectionError: snapshot.projectionError.message }
|
|
27
|
-
: {}),
|
|
28
|
-
};
|
|
29
|
-
}
|
|
1
|
+
export { readInitRuntimeActivity } from "../../worker/observability/init-runtime-activity.js";
|
|
@@ -117,7 +117,7 @@ export async function runDagRerun(repoRoot, rawArgs) {
|
|
|
117
117
|
parsed.promptOverrideAppendSpecs.length > 0;
|
|
118
118
|
if (hasOverrides) {
|
|
119
119
|
if (!isDagRerunPromptOverrideEnabled()) {
|
|
120
|
-
throw new Error("prompt override rerun is disabled
|
|
120
|
+
throw new Error("prompt override rerun is disabled by HARNESS_DAG_RERUN_PROMPT_OVERRIDE; unset it or use a value other than 0, false, or off to enable this experimental capability");
|
|
121
121
|
}
|
|
122
122
|
promptOverrides = [
|
|
123
123
|
...(await loadPromptOverrides(parsed.promptOverrideSpecs, "replace")),
|
|
@@ -4,11 +4,12 @@ import { readFile } from "node:fs/promises";
|
|
|
4
4
|
import { writeDagNodeJsonArtifact, writeTextArtifactFile, } from "../infrastructure/harness/artifact-store.js";
|
|
5
5
|
import { executePiStep, resolvePiBackend, } from "./pi-executor.js";
|
|
6
6
|
import { resolveDagPiExtensions, } from "./pi-extension-resolver.js";
|
|
7
|
-
import { buildPiWriterToolPolicyContext, createPiWriterCustomTools, } from "./pi-writer-tool-policy.js";
|
|
7
|
+
import { buildPiWriterToolPolicyContext, createPiReaderCustomTools, createPiWriterCustomTools, } from "./pi-writer-tool-policy.js";
|
|
8
8
|
import { cleanupPlaywrightCliDefaultSession, createPlaywrightCliTool, PI_COMMAND_CAPABILITY_REGISTRY, resolveCaseIdFromWriteSet, resolveEvidenceDirFromWriteSet, } from "./pi-playwright-cli-tool.js";
|
|
9
9
|
import { dagCommandPolicyAllows, resolveDagCommandPolicy, } from "../workflows/dag/types.js";
|
|
10
10
|
import { redactPromptForLog, truncateOutput, } from "../shared/output-truncation.js";
|
|
11
11
|
import { GitStatusUnavailableError, pathsChangedDuringRun, readGitStatusPorcelain, recoverRootNulArtifact, snapshotGitStatusPathFingerprints, snapshotGitStatusPorcelain, validateShellWriteGuard, } from "./shell-write-guard.js";
|
|
12
|
+
import { captureWorkspaceWriteSnapshot, diffWorkspaceWriteSnapshots, } from "./workspace-write-snapshot.js";
|
|
12
13
|
import { isTargetTemplateTransientRetryNode, isWriterEmptyDiffRetryCandidate, isWriterTransportRetryCandidate, INCOMPLETE_WRITE_SET_RETRY_CATEGORY, WRITER_CLEAN_TIMEOUT_RETRY_CATEGORY, WRITER_EMPTY_DIFF_RETRY_CATEGORY, } from "../workflows/dag/retry-policy.js";
|
|
13
14
|
import { assessBackendTestMdPlanCompleteness, assessBackendTestMdWriterCompleteness, assessBackendTestPytestPlanCompleteness, assessBackendTestPytestWriterCompleteness, assessBackendTestShardChildCompleteness, backendTestWriterProgressRoleForTask, classifyBackendTestWriterCompletenessFailure, isBackendTestCompletenessRetryCandidate, isBackendTestMdPlanTask, isBackendTestPytestPlanTask, isBackendTestShardChildTask, writeBackendTestWriterProgressArtifacts, } from "../workflows/dag/backend-test-writer-completeness.js";
|
|
14
15
|
import { resolveBackendTestLayout } from "../workflows/dag/backend-test-layout.js";
|
|
@@ -181,6 +182,9 @@ export function resolveDagPiStepName(task) {
|
|
|
181
182
|
return resolvePiExecutorStep(resolveDagPiPersona(task));
|
|
182
183
|
}
|
|
183
184
|
export function resolveDagPiToolNames(task) {
|
|
185
|
+
if ((task.readSet?.length ?? 0) > 0) {
|
|
186
|
+
return isDagPiWriteTask(task) ? ["read", "edit", "write"] : ["read"];
|
|
187
|
+
}
|
|
184
188
|
if (!isDagPiWriteTask(task))
|
|
185
189
|
return [...DAG_PI_READONLY_TOOLS];
|
|
186
190
|
const tools = [...DAG_PI_WRITE_TOOLS];
|
|
@@ -237,6 +241,9 @@ export function buildDagPiUserMessage(task, persona, step) {
|
|
|
237
241
|
`You are executing hybrid DAG node "${task.id}" (role=${role}, piPersona=${persona}, piStep=${step}, writePolicy=${writePolicy}).`,
|
|
238
242
|
"The system prompt contains the full DAG envelope: objective, constraints, upstream context, and task.",
|
|
239
243
|
"Use read-only tools only. Do not edit, write, or commit repository files.",
|
|
244
|
+
(task.readSet?.length ?? 0) > 0
|
|
245
|
+
? `Strict read set: ${task.readSet.join(", ")}. The read tool rejects every other repository path; do not search for substitutes.`
|
|
246
|
+
: undefined,
|
|
240
247
|
"Return your conclusion as plain Markdown text suitable for downstream DAG nodes.",
|
|
241
248
|
"Do not wrap the output in code fences and do not add conversational preamble.",
|
|
242
249
|
].join(" ");
|
|
@@ -446,9 +453,28 @@ export async function executeDagPiNode(input, meta, piStepFn = executePiStep, wr
|
|
|
446
453
|
};
|
|
447
454
|
}
|
|
448
455
|
let beforeStatus;
|
|
456
|
+
let beforeWorkspaceSnapshot;
|
|
449
457
|
let beforePathFingerprints;
|
|
450
|
-
/** tools-only
|
|
451
|
-
const
|
|
458
|
+
/** tools-only and filesystem-only keep the tool sandbox but skip Git baseline. */
|
|
459
|
+
const filesystemOnly = isWriteTask && meta.spec.backendTestWorkspaceControl === "filesystem-only";
|
|
460
|
+
const skipGitWriteGuard = isWriteTask && (input.task.writeGuardPolicy === "tools-only" || filesystemOnly);
|
|
461
|
+
if (isWriteTask && filesystemOnly) {
|
|
462
|
+
try {
|
|
463
|
+
beforeWorkspaceSnapshot = await captureWorkspaceWriteSnapshot({
|
|
464
|
+
rootCwd: input.cwd,
|
|
465
|
+
paths: input.task.writeSet ?? input.task.allowedPaths,
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
catch (error) {
|
|
469
|
+
return {
|
|
470
|
+
ok: false,
|
|
471
|
+
stdout: "",
|
|
472
|
+
stderr: `workspace filesystem baseline unavailable before Pi execution: ${error instanceof Error ? error.message : String(error)}`,
|
|
473
|
+
failureCategory: "write-guard",
|
|
474
|
+
durationMs: Date.now() - started,
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
}
|
|
452
478
|
if (isWriteTask && !skipGitWriteGuard) {
|
|
453
479
|
try {
|
|
454
480
|
beforeStatus = await writeGuardDependencies.readGitStatusPorcelain(input.cwd, { phase: "pi-writer-before" });
|
|
@@ -493,9 +519,17 @@ export async function executeDagPiNode(input, meta, piStepFn = executePiStep, wr
|
|
|
493
519
|
ok: false, stdout: "", stderr: "pi command capability requires an explicit bounded write tool profile", failureCategory: "tool-policy", durationMs: Date.now() - started,
|
|
494
520
|
};
|
|
495
521
|
}
|
|
496
|
-
|
|
522
|
+
const strictReadSet = (input.task.readSet?.length ?? 0) > 0;
|
|
523
|
+
if (isWriteTask || allowsPlaywrightCli || strictReadSet) {
|
|
497
524
|
try {
|
|
498
525
|
const customTools = [];
|
|
526
|
+
if (strictReadSet) {
|
|
527
|
+
const readContext = buildPiWriterToolPolicyContext({
|
|
528
|
+
repoRoot: input.cwd,
|
|
529
|
+
readSet: input.task.readSet,
|
|
530
|
+
});
|
|
531
|
+
customTools.push(...(await createPiReaderCustomTools(readContext)));
|
|
532
|
+
}
|
|
499
533
|
if (isWriteTask) {
|
|
500
534
|
const policyContext = buildPiWriterToolPolicyContext({
|
|
501
535
|
repoRoot: input.cwd,
|
|
@@ -503,6 +537,7 @@ export async function executeDagPiNode(input, meta, piStepFn = executePiStep, wr
|
|
|
503
537
|
writeSet: input.task.writeSet,
|
|
504
538
|
forbiddenPaths: input.task.forbiddenPaths,
|
|
505
539
|
writePolicy: input.task.writePolicy,
|
|
540
|
+
readSet: input.task.readSet,
|
|
506
541
|
});
|
|
507
542
|
customTools.push(...(await createPiWriterCustomTools(policyContext)));
|
|
508
543
|
}
|
|
@@ -620,6 +655,9 @@ export async function executeDagPiNode(input, meta, piStepFn = executePiStep, wr
|
|
|
620
655
|
timeoutMs: input.timeoutMs,
|
|
621
656
|
stallTimeoutMs: input.stallTimeoutMs,
|
|
622
657
|
abortGraceMs: input.abortGraceMs,
|
|
658
|
+
...(input.task.contextBudget
|
|
659
|
+
? { contextBudget: input.task.contextBudget }
|
|
660
|
+
: {}),
|
|
623
661
|
...(writerToolPolicy ? { writerToolPolicy } : {}),
|
|
624
662
|
...(piExtensionPaths && piExtensionPaths.length > 0
|
|
625
663
|
? { piExtensionPaths }
|
|
@@ -668,6 +706,9 @@ export async function executeDagPiNode(input, meta, piStepFn = executePiStep, wr
|
|
|
668
706
|
persona,
|
|
669
707
|
step,
|
|
670
708
|
});
|
|
709
|
+
if (input.task.id === "generate-backend-md-plan-pi" && result.assistantText?.trim()) {
|
|
710
|
+
await writeTextArtifactFile(path.join(meta.runDir, input.task.id, "plan.md"), result.assistantText.trim() + "\n");
|
|
711
|
+
}
|
|
671
712
|
const mapped = mapPiResultToDagNodeResult(result, input.task.writerOutcomePolicy
|
|
672
713
|
? WRITER_OUTCOME_PROTOCOL_LINE
|
|
673
714
|
: input.task.firstProtocolLine);
|
|
@@ -678,6 +719,27 @@ export async function executeDagPiNode(input, meta, piStepFn = executePiStep, wr
|
|
|
678
719
|
let writeGuardViolations = [];
|
|
679
720
|
let changeManifestAfterStatus;
|
|
680
721
|
let changeManifestChangedFiles;
|
|
722
|
+
let afterWorkspaceSnapshot;
|
|
723
|
+
if (filesystemOnly && beforeWorkspaceSnapshot) {
|
|
724
|
+
try {
|
|
725
|
+
afterWorkspaceSnapshot = await captureWorkspaceWriteSnapshot({
|
|
726
|
+
rootCwd: input.cwd,
|
|
727
|
+
paths: input.task.writeSet ?? input.task.allowedPaths,
|
|
728
|
+
});
|
|
729
|
+
changeManifestChangedFiles = diffWorkspaceWriteSnapshots(beforeWorkspaceSnapshot, afterWorkspaceSnapshot);
|
|
730
|
+
const guard = validateShellWriteGuardFromDiff({
|
|
731
|
+
changedFiles: changeManifestChangedFiles,
|
|
732
|
+
task: input.task,
|
|
733
|
+
concurrentSiblingWriteSets: meta.concurrentSiblingWriteSets,
|
|
734
|
+
});
|
|
735
|
+
writeGuardOk = guard.ok;
|
|
736
|
+
writeGuardViolations = guard.violations;
|
|
737
|
+
}
|
|
738
|
+
catch (error) {
|
|
739
|
+
writeGuardOk = false;
|
|
740
|
+
writeGuardViolations = [`workspace snapshot unavailable: ${error instanceof Error ? error.message : String(error)}`];
|
|
741
|
+
}
|
|
742
|
+
}
|
|
681
743
|
if (beforeStatus !== undefined) {
|
|
682
744
|
let recoveryEvidence;
|
|
683
745
|
let removalPendingRecheck;
|
|
@@ -850,7 +912,7 @@ export async function executeDagPiNode(input, meta, piStepFn = executePiStep, wr
|
|
|
850
912
|
}
|
|
851
913
|
}
|
|
852
914
|
if (writeGuardOk &&
|
|
853
|
-
beforeStatus !== undefined &&
|
|
915
|
+
(beforeStatus !== undefined || beforeWorkspaceSnapshot !== undefined) &&
|
|
854
916
|
changeManifestChangedFiles !== undefined) {
|
|
855
917
|
await persistWriterChangeManifest({
|
|
856
918
|
runDir: meta.runDir,
|
|
@@ -860,8 +922,8 @@ export async function executeDagPiNode(input, meta, piStepFn = executePiStep, wr
|
|
|
860
922
|
approvalSourceNodeId: input.task.resolvedFinalWriteSetApproval?.approvalSourceNodeId,
|
|
861
923
|
approvalDigest: input.task.resolvedFinalWriteSetApproval?.approvalDigest,
|
|
862
924
|
changedFiles: changeManifestChangedFiles,
|
|
863
|
-
beforeStatus,
|
|
864
|
-
afterStatus: changeManifestAfterStatus ??
|
|
925
|
+
beforeStatus: beforeStatus ?? JSON.stringify(beforeWorkspaceSnapshot),
|
|
926
|
+
afterStatus: changeManifestAfterStatus ?? JSON.stringify(afterWorkspaceSnapshot),
|
|
865
927
|
});
|
|
866
928
|
}
|
|
867
929
|
let completenessFailure;
|
|
@@ -1005,12 +1005,14 @@ export function shouldRetryWithFallback(stderr, stdout) {
|
|
|
1005
1005
|
return ["quota", "rate-limit", "unavailable", "network"].includes(category);
|
|
1006
1006
|
}
|
|
1007
1007
|
export function classifyPiFailure(input) {
|
|
1008
|
+
if (input.exitCode === 0 && input.assistantText.trim())
|
|
1009
|
+
return "success";
|
|
1010
|
+
if (input.stderr.toLowerCase().includes("context-budget-exhausted:"))
|
|
1011
|
+
return "context-budget-exhausted";
|
|
1008
1012
|
if (input.timedOut)
|
|
1009
1013
|
return "timeout";
|
|
1010
1014
|
if (input.outputTooLarge)
|
|
1011
1015
|
return "output-too-large";
|
|
1012
|
-
if (input.exitCode === 0 && input.assistantText.trim())
|
|
1013
|
-
return "success";
|
|
1014
1016
|
const combined = `${input.stderr}\n${input.stdout}`.toLowerCase();
|
|
1015
1017
|
// Prefer explicit rate-limit / HTTP 429 before generic "limit" quota phrases.
|
|
1016
1018
|
// Chinese gateways often say "请求频率已达到限制" without English "rate limit".
|