@iowarp/clio-coder 0.3.7 → 0.3.9
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 +80 -0
- package/README.md +13 -4
- package/dist/{acp-SK4MD6MM.js → acp-7LOELQFP.js} +13 -13
- package/dist/{agents-2FN2K6ME.js → agents-FIBG2SHA.js} +41 -37
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-QIYZWM5I.js → auth-OI4LIH2I.js} +31 -24
- package/dist/builtins-AD25UL3C.js +17 -0
- package/dist/{chunk-5FR74PWO.js → chunk-2JDWVJND.js} +2 -2
- package/dist/chunk-3DPEIQKN.js +113 -0
- package/dist/{chunk-EOOQZZDE.js → chunk-3DUR4WUA.js} +19 -19
- package/dist/{chunk-WHJYKASB.js → chunk-3MRC2YSQ.js} +2 -2
- package/dist/{chunk-EBEFWSGL.js → chunk-3UUY7R3Z.js} +14 -10
- package/dist/{chunk-LADCF22A.js → chunk-3V5AYSEQ.js} +113 -54
- package/dist/{chunk-BMWK7ZIZ.js → chunk-465CC7FK.js} +16 -13
- package/dist/{chunk-5WIGXA4T.js → chunk-47CMYGET.js} +111 -4
- package/dist/{chunk-CEYBNUGC.js → chunk-4H6ULJ3H.js} +378 -36
- package/dist/{chunk-YTYFXUI3.js → chunk-4LJX2PUC.js} +9 -9
- package/dist/{chunk-DOOEX22V.js → chunk-56KB5IJP.js} +5 -5
- package/dist/{chunk-SPULKLCF.js → chunk-5DQRIYDZ.js} +2 -2
- package/dist/{chunk-TSHXZTOQ.js → chunk-5HFBWUMU.js} +23 -11
- package/dist/{chunk-5UJ6ECTS.js → chunk-5PVQ4SRS.js} +80 -8
- package/dist/{chunk-ZWLZP4ZT.js → chunk-5QKCQQ3E.js} +359 -17
- package/dist/{chunk-6M7VS3J3.js → chunk-5T7RBWN2.js} +111 -5
- package/dist/chunk-774ILSRL.js +172 -0
- package/dist/chunk-7C6RYZGQ.js +391 -0
- package/dist/{chunk-GH5622CP.js → chunk-A2NJGIB3.js} +2 -2
- package/dist/{chunk-C4JBQ5SR.js → chunk-AD7Y7STJ.js} +6 -6
- package/dist/{chunk-GEYXPTRF.js → chunk-AEYBF3TB.js} +33 -12
- package/dist/{chunk-2SFS6XQE.js → chunk-AMKHQW3C.js} +3 -2
- package/dist/{chunk-D4MDIG46.js → chunk-B5CSFE7B.js} +7 -7
- package/dist/{chunk-MXI6J5JF.js → chunk-B5XRQOLB.js} +10 -10
- package/dist/{chunk-X2KV5FXT.js → chunk-BVDVID7E.js} +2 -2
- package/dist/{chunk-JNXPYBB4.js → chunk-CA42X6KT.js} +3 -3
- package/dist/{chunk-VREKEFLL.js → chunk-D73KXYPF.js} +3 -3
- package/dist/{chunk-JTSEDYVQ.js → chunk-DG4M6ZUE.js} +7 -7
- package/dist/{chunk-DQA7QLMD.js → chunk-EBOC7MT3.js} +10 -25
- package/dist/{chunk-KZ2H5X4G.js → chunk-ECUO3KDP.js} +129 -14
- package/dist/{chunk-JRIO5UD2.js → chunk-EQ63NRB7.js} +5 -5
- package/dist/{chunk-YD734TPH.js → chunk-FALJGAWU.js} +2 -2
- package/dist/{chunk-GWS3VEIW.js → chunk-FWDFM5ZU.js} +24 -3
- package/dist/{chunk-XEGB6BCN.js → chunk-GAYUJ7LE.js} +68 -14
- package/dist/{chunk-UND3GU2L.js → chunk-H7IXIC72.js} +2 -2
- package/dist/{chunk-IR4CFBFN.js → chunk-HAY4ZE2P.js} +12 -12
- package/dist/{chunk-UVDSQ6LW.js → chunk-HCBCAYZU.js} +74 -147
- package/dist/{chunk-4DWFMQDR.js → chunk-HJB5IUKP.js} +89 -145
- package/dist/{chunk-M4AKACEO.js → chunk-HKO36JWF.js} +33 -5
- package/dist/{chunk-KCMKRQX4.js → chunk-HPCTNZM2.js} +45 -82
- package/dist/{chunk-465YSENW.js → chunk-IFBNV6H6.js} +3 -3
- package/dist/{chunk-FJ3H4MN5.js → chunk-IHKBWSXF.js} +2 -2
- package/dist/chunk-JEQQR47K.js +3025 -0
- package/dist/{chunk-FO5ZOVUY.js → chunk-KV2AOLDF.js} +27 -7
- package/dist/chunk-LU7P4LHA.js +33 -0
- package/dist/{chunk-6TUKSZVF.js → chunk-LXPJXFM5.js} +11 -11
- package/dist/{chunk-VQNODYQ4.js → chunk-MIX5N5AC.js} +488 -3668
- package/dist/chunk-MLOK6ZOS.js +2888 -0
- package/dist/{chunk-ZZMN5OM4.js → chunk-MV2VUEJC.js} +2 -2
- package/dist/{chunk-MVVUPGPW.js → chunk-MXHC5QYU.js} +6 -6
- package/dist/{chunk-OBMAI2DP.js → chunk-N3PBVRTZ.js} +12 -388
- package/dist/{chunk-WJHBC77E.js → chunk-N5XKWMDW.js} +17 -7
- package/dist/{chunk-5C3AQNDW.js → chunk-NNNWO6F2.js} +124 -36
- package/dist/{chunk-UFQ3F4FW.js → chunk-NQ6UCCOD.js} +4 -4
- package/dist/chunk-NUGM5KR6.js +165 -0
- package/dist/{chunk-DMD2AGVS.js → chunk-NZU6YDNV.js} +20 -18
- package/dist/{chunk-WHGPSPT5.js → chunk-O6I4CIEU.js} +151 -13
- package/dist/{chunk-XN3L4EYL.js → chunk-OEDBCISO.js} +2 -2
- package/dist/{chunk-PD3MESLB.js → chunk-P3JGPQFL.js} +4 -4
- package/dist/{chunk-UHXRNZ2J.js → chunk-PNY46YEY.js} +23 -6
- package/dist/{chunk-THKY7CD7.js → chunk-PZ4I4JE2.js} +134 -29
- package/dist/{chunk-SROCI7ZU.js → chunk-QQ7EKM72.js} +5 -5
- package/dist/{chunk-QCTRSGHQ.js → chunk-R7LNVMCS.js} +91 -53
- package/dist/{chunk-GOXNB3AO.js → chunk-RAPCMZL4.js} +75 -4
- package/dist/chunk-RKKLTLYB.js +45 -0
- package/dist/{chunk-OB5HIGJY.js → chunk-RKRLDWD3.js} +4 -1
- package/dist/{chunk-DJNLUABN.js → chunk-S4COXYBG.js} +588 -32
- package/dist/{chunk-3HAPLH5M.js → chunk-T3Z6VAAF.js} +172 -11
- package/dist/{chunk-FOT2FX5J.js → chunk-TD7UE2L5.js} +12 -10
- package/dist/{chunk-UUANF5CR.js → chunk-TEO2TLVN.js} +856 -967
- package/dist/{chunk-FCSXB6T2.js → chunk-UOSL25KY.js} +14 -2
- package/dist/{chunk-EELBMBT6.js → chunk-VKBMFOYV.js} +74 -15
- package/dist/chunk-VO2LKSTM.js +165 -0
- package/dist/{chunk-5C77SEEY.js → chunk-VPTUJU4P.js} +3 -3
- package/dist/{chunk-WEH5XRJQ.js → chunk-WIE7ZOSW.js} +2 -2
- package/dist/{chunk-J7PIKKWC.js → chunk-WXCJ7VME.js} +8 -8
- package/dist/{chunk-4DGYLA73.js → chunk-XDOQXGFO.js} +22 -7
- package/dist/{chunk-PPAMZ32Z.js → chunk-XK56QHLX.js} +6 -1
- package/dist/{chunk-AB4XIIVB.js → chunk-YKOFT37S.js} +6 -6
- package/dist/chunk-YSEHGPCT.js +127 -0
- package/dist/{chunk-HFSBBKSQ.js → chunk-YW7UVM5V.js} +138 -3
- package/dist/cli/index.js +32 -32
- package/dist/{clio-WBVQEBKO.js → clio-LT5V7SSZ.js} +9 -9
- package/dist/{code-nav-FGGFIE7L.js → code-nav-LMW275PA.js} +5 -5
- package/dist/codewiki/build-worker.js +4 -4
- package/dist/{components-F7OEATSO.js → components-ZFA3SAER.js} +8 -8
- package/dist/{config-TRBL3RCF.js → config-RXS5T3JT.js} +98 -65
- package/dist/{configure-OLCVPHNM.js → configure-2WYWSCSD.js} +26 -22
- package/dist/{context-MJIJ6GOX.js → context-I3BTOTCS.js} +12 -12
- package/dist/{context-XEWE3MOJ.js → context-MVOORGMF.js} +54 -47
- package/dist/{context-WFPKQSM6.js → context-PALKKQYL.js} +28 -28
- package/dist/{context-clear-KNOS2JPB.js → context-clear-N2WOYZ2K.js} +53 -46
- package/dist/{context-index-SSR5ECNE.js → context-index-HNG3MOME.js} +6 -6
- package/dist/{context-working-set-EUXAZI6N.js → context-working-set-MIEVECVZ.js} +17 -18
- package/dist/{dispatch-runner-B7MTOVKL.js → dispatch-runner-VVA4SRRH.js} +90 -61
- package/dist/{docs-FLJTIDSE.js → docs-7LQ23DLM.js} +8 -8
- package/dist/doctor-TWBWFK5V.js +165 -0
- package/dist/eval-IJ5VEZDJ.js +4483 -0
- package/dist/{evidence-JZNBUOQZ.js → evidence-L5APPXNV.js} +68 -61
- package/dist/{evolve-FJVC4KKI.js → evolve-RGNKFJ52.js} +47 -40
- package/dist/{extensions-IQL36S7K.js → extensions-7WYWUX5A.js} +13 -7
- package/dist/{fleet-BDKYJFCP.js → fleet-6CNVBZZP.js} +113 -76
- package/dist/{fleet-commands-ZFIWZSB3.js → fleet-commands-L2SXSYEI.js} +10 -10
- package/dist/{fleet-graph-Y6HPXIVF.js → fleet-graph-2J3OOIPO.js} +17 -15
- package/dist/{fleet-preflight-BHSNPBMH.js → fleet-preflight-CZRJ4JP5.js} +5 -6
- package/dist/{fleet-validate-BIYREGIK.js → fleet-validate-C5RI6DP7.js} +20 -19
- package/dist/{init-LQUB5COQ.js → init-VBN2ACVA.js} +70 -63
- package/dist/{library-NJAHIGG4.js → library-JHGUMLY2.js} +22 -20
- package/dist/{memory-OG6HOYKM.js → memory-K4OQIYWG.js} +49 -42
- package/dist/{models-5ZG5XY7J.js → models-2NCZUWDD.js} +35 -29
- package/dist/{monitor-TJ7AMTGB.js → monitor-MMVTJABD.js} +64 -45
- package/dist/{orchestrator-WZYB54DM.js → orchestrator-ZKBPCHW6.js} +1971 -520
- package/dist/{paths-XUC7GS6E.js → paths-DBXMZMDU.js} +5 -5
- package/dist/registry-LG64LTF4.js +11 -0
- package/dist/{reset-PXQT45IY.js → reset-DD5JGOY3.js} +11 -11
- package/dist/{run-FQ74YF62.js → run-QEGNX7FL.js} +89 -83
- package/dist/{share-FW7SVCL3.js → share-JKD3BQMW.js} +20 -18
- package/dist/{skills-7E7IRB3R.js → skills-LMQIKDOZ.js} +23 -21
- package/dist/{skills-eval-LI75W6OK.js → skills-eval-I7X2774U.js} +59 -52
- package/dist/{steer-GGWFUJUD.js → steer-CF5TDANS.js} +3 -3
- package/dist/support-I7LOJLIF.js +38 -0
- package/dist/{targets-4CIFKCTW.js → targets-RUSR6B5Z.js} +77 -42
- package/dist/{terminal-lease-WUZY7ZV5.js → terminal-lease-QYVORFR4.js} +6 -4
- package/dist/{trace-PNCASAXC.js → trace-ODOQIVIW.js} +61 -6
- package/dist/{uninstall-7FV7IP4E.js → uninstall-ZJF5H5ZN.js} +8 -8
- package/dist/{upgrade-K2HVIVMQ.js → upgrade-XANW3FXB.js} +29 -26
- package/dist/{usage-GTZELZQX.js → usage-4H7ZRXQT.js} +110 -61
- package/dist/{verifiers-RLAHT27O.js → verifiers-UZXNBZEB.js} +13 -13
- package/dist/{verify-BX3BRKH5.js → verify-BVKWTNDL.js} +9 -9
- package/dist/{wiki-generate-ASIFASCN.js → wiki-generate-MY7WV2QI.js} +76 -69
- package/dist/worker/entry.js +69 -66
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +1 -1
- package/docs/artifact-versions.md +11 -5
- package/docs/built-in-agents.md +1 -1
- package/docs/capacity-and-scheduling.md +23 -2
- package/docs/commands-and-modes.md +2 -2
- package/docs/configuration-and-targets.md +37 -5
- package/docs/context-engine.md +63 -4
- package/docs/documentation-coverage.md +3 -3
- package/docs/documentation-guide.md +1 -1
- package/docs/environment-variables.md +2 -0
- package/docs/eval-runner.md +262 -11
- package/docs/evals-internal.md +72 -2
- package/docs/evidence-and-memory.md +77 -12
- package/docs/evolution.md +1 -1
- package/docs/extensions-and-sharing.md +3 -1
- package/docs/fleet-dispatch.md +34 -9
- package/docs/glossary.md +21 -1
- package/docs/installation-and-lifecycle.md +1 -1
- package/docs/middleware-and-components.md +1 -1
- package/docs/model-catalog.md +1 -1
- package/docs/observability.md +54 -3
- package/docs/proactive-memory.md +127 -14
- package/docs/prompt-envelope-and-tools.md +22 -2
- package/docs/provider-adapter-cookbook.md +1 -1
- package/docs/release-cut-checklist.md +60 -41
- package/docs/safety-model.md +1 -1
- package/docs/scientific-validation.md +1 -1
- package/docs/skills-marketplace.md +1 -1
- package/docs/tool-usage.md +1 -1
- package/docs/trace-store.md +1 -1
- package/docs/troubleshooting.md +87 -0
- package/docs/tui-design.md +1 -1
- package/docs/worker-dispatch-mechanics.md +1 -1
- package/package.json +2 -2
- package/src/cli/agents.ts +1 -1
- package/src/cli/argv.ts +5 -0
- package/src/cli/config-inspect.ts +33 -6
- package/src/cli/config.ts +1 -1
- package/src/cli/configure.ts +107 -23
- package/src/cli/doctor-state-size.ts +82 -0
- package/src/cli/doctor.ts +7 -1
- package/src/cli/eval.ts +80 -16
- package/src/cli/evidence.ts +30 -25
- package/src/cli/extensions.ts +5 -1
- package/src/cli/fleet-preflight.ts +2 -12
- package/src/cli/fleet.ts +32 -3
- package/src/cli/shared.ts +1 -0
- package/src/cli/targets.ts +45 -11
- package/src/cli/trace.ts +63 -4
- package/src/cli/usage.ts +63 -14
- package/src/cli/validate-model.ts +60 -5
- package/src/core/bus-events.ts +54 -1
- package/src/core/cache-telemetry.ts +42 -0
- package/src/core/commit-attribution.ts +4 -4
- package/src/core/config.ts +18 -0
- package/src/core/defaults.ts +36 -6
- package/src/core/endpoint-key.ts +27 -0
- package/src/core/path-boundary.ts +100 -0
- package/src/core/residency-target-key.ts +25 -0
- package/src/core/response-schema.ts +36 -2
- package/src/domains/agents/extension.ts +2 -11
- package/src/domains/agents/fleet-contract.ts +30 -12
- package/src/domains/agents/recipe.ts +7 -1
- package/src/domains/agents/registry.ts +73 -5
- package/src/domains/agents/result-contract.ts +128 -17
- package/src/domains/agents/write-boundary.ts +15 -50
- package/src/domains/config/classify.ts +3 -0
- package/src/domains/context/codewiki/coordinator.ts +12 -4
- package/src/domains/context/project-rules.ts +51 -1
- package/src/domains/dispatch/admission.ts +40 -3
- package/src/domains/dispatch/assignment-reconcile.ts +22 -5
- package/src/domains/dispatch/assignment-store.ts +151 -14
- package/src/domains/dispatch/capacity-lease.ts +98 -9
- package/src/domains/dispatch/contract.ts +26 -1
- package/src/domains/dispatch/delegation-plan.ts +2 -5
- package/src/domains/dispatch/execution-plan.ts +44 -4
- package/src/domains/dispatch/execution-role.ts +9 -1
- package/src/domains/dispatch/extension.ts +309 -96
- package/src/domains/dispatch/fleet-run.ts +78 -4
- package/src/domains/dispatch/gate-role-prompts.ts +38 -0
- package/src/domains/dispatch/heartbeat.ts +32 -8
- package/src/domains/dispatch/index.ts +6 -1
- package/src/domains/dispatch/intent-requirements.ts +40 -0
- package/src/domains/dispatch/intent.ts +84 -8
- package/src/domains/dispatch/orphan-recovery.ts +5 -0
- package/src/domains/dispatch/path-scope.ts +370 -0
- package/src/domains/dispatch/receipt-integrity.ts +2 -1
- package/src/domains/dispatch/reservation-store.ts +116 -8
- package/src/domains/dispatch/state.ts +4 -0
- package/src/domains/dispatch/types.ts +14 -7
- package/src/domains/dispatch/validation.ts +6 -3
- package/src/domains/dispatch/worker-spawn.ts +25 -11
- package/src/domains/dispatch/write-boundary-enforcer.ts +62 -0
- package/src/domains/dispatch/write-boundary.ts +262 -22
- package/src/domains/eval/artifacts/store.ts +62 -0
- package/src/domains/eval/compare/behavioral.ts +224 -0
- package/src/domains/eval/compare/compare.ts +355 -2
- package/src/domains/eval/compare/envelope.ts +128 -0
- package/src/domains/eval/compare/gates.ts +24 -6
- package/src/domains/eval/compare/thresholds.ts +30 -3
- package/src/domains/eval/execution-provenance.ts +240 -0
- package/src/domains/eval/metrics/aggregate.ts +136 -0
- package/src/domains/eval/metrics/call-ledger-stream.ts +112 -0
- package/src/domains/eval/metrics/evidence.ts +79 -2
- package/src/domains/eval/metrics/tracked.ts +413 -0
- package/src/domains/eval/provenance.ts +117 -0
- package/src/domains/eval/reports/comparison.ts +128 -0
- package/src/domains/eval/reports/junit.ts +17 -3
- package/src/domains/eval/reports/markdown.ts +3 -3
- package/src/domains/eval/reports/text.ts +14 -0
- package/src/domains/eval/run-compare.ts +20 -0
- package/src/domains/eval/runners/clio-run.ts +139 -2
- package/src/domains/eval/runners/external-command.ts +28 -3
- package/src/domains/eval/schema/adapter.ts +111 -0
- package/src/domains/eval/schema/artifact.ts +20 -0
- package/src/domains/eval/schema/behavioral-metrics.ts +204 -0
- package/src/domains/eval/schema/behavioral.ts +520 -0
- package/src/domains/eval/schema/execution-envelope.ts +194 -0
- package/src/domains/eval/schema/serving.ts +74 -0
- package/src/domains/eval/schema/suite.ts +38 -8
- package/src/domains/eval/schema/validate.ts +58 -3
- package/src/domains/eval/schema/verdict.ts +237 -0
- package/src/domains/eval/suites/resolve.ts +2 -0
- package/src/domains/eval/suites/run.ts +264 -33
- package/src/domains/eval/verifiers/command.ts +2 -1
- package/src/domains/eval/workspaces/temp-copy.ts +145 -13
- package/src/domains/evidence/build.ts +68 -21
- package/src/domains/evidence/eval.ts +2 -12
- package/src/domains/evidence/findings-markdown.ts +33 -0
- package/src/domains/evidence/index.ts +21 -0
- package/src/domains/evidence/provenance.ts +46 -11
- package/src/domains/evidence/run-trust.ts +7 -113
- package/src/domains/evidence/trust-projection.ts +274 -0
- package/src/domains/evidence/trust-status.ts +145 -17
- package/src/domains/evidence/types.ts +4 -0
- package/src/domains/extensions/compatibility.ts +285 -0
- package/src/domains/extensions/discovery.ts +126 -4
- package/src/domains/extensions/resources.ts +21 -9
- package/src/domains/extensions/state.ts +18 -5
- package/src/domains/extensions/types.ts +6 -1
- package/src/domains/lifecycle/doctor.ts +209 -2
- package/src/domains/memory/index.ts +14 -0
- package/src/domains/memory/task-bank-promotion.ts +64 -0
- package/src/domains/memory/task-memory-policy.ts +77 -8
- package/src/domains/memory/task-memory-spend.ts +131 -0
- package/src/domains/memory/task-memory-status.ts +7 -0
- package/src/domains/memory/task-memory-telemetry.ts +2 -0
- package/src/domains/middleware/index.ts +1 -0
- package/src/domains/middleware/memory-intervention.ts +69 -5
- package/src/domains/middleware/memory-step-endpoint.ts +71 -0
- package/src/domains/observability/background-memory-usage.ts +140 -0
- package/src/domains/observability/cost.ts +1 -1
- package/src/domains/observability/index.ts +7 -0
- package/src/domains/observability/out-of-turn-usage.ts +51 -2
- package/src/domains/observability/trace-store.ts +192 -2
- package/src/domains/prompts/compiler.ts +100 -13
- package/src/domains/prompts/contract.ts +3 -5
- package/src/domains/providers/endpoint-capacity.ts +96 -0
- package/src/domains/providers/extension.ts +30 -2
- package/src/domains/providers/index.ts +10 -0
- package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +243 -1
- package/src/domains/providers/runtime-resolution.ts +8 -1
- package/src/domains/providers/runtimes/common/probe-helpers.ts +31 -9
- package/src/domains/providers/runtimes/local-native/llamacpp-anthropic.ts +1 -1
- package/src/domains/providers/runtimes/local-native/llamacpp-completion.ts +1 -1
- package/src/domains/providers/runtimes/local-native/llamacpp-embed.ts +1 -1
- package/src/domains/providers/runtimes/local-native/llamacpp-rerank.ts +1 -1
- package/src/domains/providers/runtimes/local-native/llamacpp.ts +4 -1
- package/src/domains/providers/runtimes/local-native/lmstudio.ts +4 -1
- package/src/domains/providers/runtimes/local-native/ollama-native.ts +6 -1
- package/src/domains/providers/types/capability-flags.ts +2 -0
- package/src/domains/providers/types/target-descriptor.ts +2 -0
- package/src/domains/resources/common-loader.ts +3 -0
- package/src/domains/resources/prompts/loader.ts +184 -17
- package/src/domains/safety/call-target.ts +52 -0
- package/src/domains/safety/policy-engine.ts +5 -5
- package/src/domains/safety/run-effects.ts +96 -2
- package/src/domains/safety/scope.ts +7 -12
- package/src/domains/session/context-accounting.ts +52 -1
- package/src/domains/session/context-ledger.ts +37 -13
- package/src/domains/session/index.ts +6 -0
- package/src/domains/session/prompt-cache.ts +140 -0
- package/src/domains/session/prompt-manifest.ts +42 -0
- package/src/engine/acp/adapter.ts +18 -3
- package/src/engine/acp/server.ts +4 -1
- package/src/engine/ai.ts +35 -0
- package/src/engine/apis/llamacpp-residency.ts +55 -3
- package/src/engine/apis/lmstudio.ts +25 -5
- package/src/engine/apis/ollama-native.ts +2 -1
- package/src/engine/apis/openai-completions.ts +80 -17
- package/src/engine/apis/residency-lock.ts +3 -1
- package/src/engine/apis/residency.ts +34 -1
- package/src/engine/prompt-templates.ts +18 -1
- package/src/engine/provider-payload.ts +29 -1
- package/src/engine/worker-runtime.ts +6 -3
- package/src/entry/orchestrator.ts +176 -30
- package/src/interactive/chat-loop-messages.ts +26 -7
- package/src/interactive/chat-loop.ts +318 -41
- package/src/interactive/chat-panel.ts +62 -8
- package/src/interactive/clio-editor.ts +45 -8
- package/src/interactive/context-activity.ts +5 -1
- package/src/interactive/context-meter.ts +1 -1
- package/src/interactive/context-overlay.ts +40 -10
- package/src/interactive/cost-overlay.ts +64 -6
- package/src/interactive/dispatch-board.ts +127 -5
- package/src/interactive/fleet-run-preview.ts +41 -15
- package/src/interactive/handoff-round.ts +41 -2
- package/src/interactive/interactive-application.ts +24 -1
- package/src/interactive/interactive-event-projection.ts +14 -0
- package/src/interactive/interactive-input-runtime.ts +8 -0
- package/src/interactive/interactive-presentation.ts +4 -0
- package/src/interactive/interactive-shell.ts +20 -17
- package/src/interactive/interactive-slash-runtime.ts +27 -4
- package/src/interactive/memory-overlay.ts +8 -0
- package/src/interactive/mutation-preview.ts +295 -0
- package/src/interactive/overlay-general-openers.ts +16 -0
- package/src/interactive/overlay-key-routing.ts +38 -0
- package/src/interactive/overlay-lifecycle.ts +38 -5
- package/src/interactive/overlay-permission-lifecycle.ts +22 -2
- package/src/interactive/overlay-session-lifecycle.ts +73 -9
- package/src/interactive/overlays/ask-user.ts +91 -19
- package/src/interactive/overlays/help-reference.ts +4 -0
- package/src/interactive/overlays/prompts.ts +11 -1
- package/src/interactive/overlays/settings.ts +176 -48
- package/src/interactive/permission-hint.ts +34 -2
- package/src/interactive/permission-overlay.ts +159 -9
- package/src/interactive/prewarm.ts +197 -0
- package/src/interactive/render-trace.ts +162 -15
- package/src/interactive/renderers/tool-execution.ts +4 -0
- package/src/interactive/side-question.ts +58 -1
- package/src/interactive/slash-commands.ts +7 -2
- package/src/interactive/status/controller.ts +11 -0
- package/src/interactive/status/state-machine.ts +54 -2
- package/src/interactive/status/types.ts +7 -0
- package/src/interactive/terminal-lease.ts +2 -0
- package/src/interactive/turn-context.ts +299 -31
- package/src/interactive/turn-persistence.ts +14 -4
- package/src/interactive/turn-prewarm.ts +364 -0
- package/src/interactive/turn-queues.ts +7 -4
- package/src/interactive/turn-runtime.ts +8 -1
- package/src/interactive/turn-state.ts +23 -0
- package/src/interactive/view/artifacts.ts +42 -9
- package/src/interactive/view/view-overlay.ts +43 -6
- package/src/interactive/worker-receipts.ts +14 -2
- package/src/interactive/worker-stream.ts +8 -0
- package/src/tools/ask-user.ts +43 -2
- package/src/tools/dispatch-admission.ts +12 -13
- package/src/tools/dispatch-arguments.ts +27 -0
- package/src/tools/dispatch-plan.ts +46 -9
- package/src/tools/dispatch-runner.ts +48 -13
- package/src/tools/dispatch-scout.ts +1 -1
- package/src/tools/monitor.ts +13 -0
- package/src/tools/registry.ts +16 -0
- package/src/tools/worker-evidence.ts +19 -13
- package/src/worker/spec-contract.ts +2 -1
- package/dist/chunk-AOCYTWAV.js +0 -449
- package/dist/chunk-HWUFFB6L.js +0 -83
- package/dist/chunk-R346GLFC.js +0 -31
- package/dist/chunk-ZGH7FGS5.js +0 -1079
- package/dist/doctor-RN4YKO2X.js +0 -87
- package/dist/eval-RUBJVSNQ.js +0 -2557
|
@@ -1,11 +1,33 @@
|
|
|
1
1
|
import { createRequire as __clioCreateRequire } from "node:module"; const require = __clioCreateRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
RUN_RECEIPT_INTEGRITY_ALGORITHM,
|
|
4
|
+
RUN_RECEIPT_INTEGRITY_VERSION,
|
|
5
|
+
adaptGateDecisionReviewStatus,
|
|
6
|
+
adaptGroundedEvidenceValidationStatus,
|
|
7
|
+
composeTrustStatus,
|
|
8
|
+
formatTrustAxes,
|
|
9
|
+
formatTrustSummary,
|
|
10
|
+
inspectRunReceiptTrustStatus,
|
|
11
|
+
isReceiptIntegrity,
|
|
12
|
+
isTrustStatusIdentifier,
|
|
13
|
+
loadEvalArtifact,
|
|
14
|
+
normalizeTrustStatus,
|
|
15
|
+
parseEvalArtifactV4,
|
|
16
|
+
redactArtifactForStorage,
|
|
17
|
+
retiredIntegrityVersionOf,
|
|
18
|
+
sha256,
|
|
19
|
+
sumEvalHarnessMetrics,
|
|
20
|
+
trustVerdict,
|
|
21
|
+
verifyReceiptIntegrity,
|
|
22
|
+
withReceiptIntegrity
|
|
23
|
+
} from "./chunk-MLOK6ZOS.js";
|
|
2
24
|
import {
|
|
3
25
|
protectedArtifactFromSessionEntry,
|
|
4
26
|
protectedArtifactStateFromSessionEntries,
|
|
5
27
|
readAuditRows,
|
|
6
28
|
readSessionEntriesForId,
|
|
7
29
|
responseModelIdObservationFromRecord
|
|
8
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-LXPJXFM5.js";
|
|
9
31
|
import {
|
|
10
32
|
applyTaskWorktree,
|
|
11
33
|
captureWorkspaceSnapshot,
|
|
@@ -13,26 +35,19 @@ import {
|
|
|
13
35
|
createTaskWorktree,
|
|
14
36
|
createWriteBoundaryEnforcer,
|
|
15
37
|
gitCheckoutRoot
|
|
16
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-ECUO3KDP.js";
|
|
17
39
|
import {
|
|
18
40
|
executionPlanAncestors,
|
|
19
41
|
spliceExecutionPlan
|
|
20
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-HKO36JWF.js";
|
|
21
43
|
import {
|
|
22
44
|
parseRigorOverride,
|
|
23
45
|
resolveRigor
|
|
24
46
|
} from "./chunk-RVG5JXAL.js";
|
|
25
47
|
import {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
loadEvalArtifact,
|
|
30
|
-
parseEvalArtifactV4,
|
|
31
|
-
redactArtifactForStorage,
|
|
32
|
-
sumEvalHarnessMetrics,
|
|
33
|
-
verifyReceiptIntegrity,
|
|
34
|
-
withReceiptIntegrity
|
|
35
|
-
} from "./chunk-ZGH7FGS5.js";
|
|
48
|
+
FLEET_COMMAND_BASE_ENV,
|
|
49
|
+
normalizeWriteBoundary
|
|
50
|
+
} from "./chunk-HPCTNZM2.js";
|
|
36
51
|
import {
|
|
37
52
|
LOCAL_NODE_ID,
|
|
38
53
|
computeSettingsFingerprint,
|
|
@@ -43,11 +58,7 @@ import {
|
|
|
43
58
|
receiptAttestationFields,
|
|
44
59
|
routeFactVerdict,
|
|
45
60
|
spawnNativeWorker
|
|
46
|
-
} from "./chunk-
|
|
47
|
-
import {
|
|
48
|
-
FLEET_COMMAND_BASE_ENV,
|
|
49
|
-
normalizeWriteBoundary
|
|
50
|
-
} from "./chunk-KCMKRQX4.js";
|
|
61
|
+
} from "./chunk-5HFBWUMU.js";
|
|
51
62
|
import {
|
|
52
63
|
AGENT_LEDGER_PROMPT_MAX_CHARS,
|
|
53
64
|
RETRYABLE_OUTCOMES,
|
|
@@ -69,6 +80,8 @@ import {
|
|
|
69
80
|
claudeSubprocessPermissionConfigForAutonomy,
|
|
70
81
|
competeStanceLiner,
|
|
71
82
|
createRunEffectsRecorder,
|
|
83
|
+
declaredScopeReplacementDiagnostic,
|
|
84
|
+
declaredScopeReplacementNotice,
|
|
72
85
|
describeCallAction,
|
|
73
86
|
isBoundedGateRolePrompt,
|
|
74
87
|
isClaudeCanonicalTool,
|
|
@@ -77,6 +90,7 @@ import {
|
|
|
77
90
|
networkToolsDisabled,
|
|
78
91
|
projectExecutionHandoffs,
|
|
79
92
|
renderAgentLedger,
|
|
93
|
+
resolveDispatchPathScope,
|
|
80
94
|
resolveToolBudgetEnvelope,
|
|
81
95
|
responseSchemaConflictsWithTools,
|
|
82
96
|
runKindSupportsLiveSteering,
|
|
@@ -84,11 +98,7 @@ import {
|
|
|
84
98
|
serializeWorkerRuntimeDescriptor,
|
|
85
99
|
toolPromptHintsForNames,
|
|
86
100
|
validateJobSpec
|
|
87
|
-
} from "./chunk-
|
|
88
|
-
import {
|
|
89
|
-
WRITE_ROOT_REFUSED_TOOLS,
|
|
90
|
-
assessFinishContract
|
|
91
|
-
} from "./chunk-OBMAI2DP.js";
|
|
101
|
+
} from "./chunk-4H6ULJ3H.js";
|
|
92
102
|
import {
|
|
93
103
|
decideRoute,
|
|
94
104
|
defaultRoutingIntent,
|
|
@@ -106,7 +116,7 @@ import {
|
|
|
106
116
|
routingIntentRejection,
|
|
107
117
|
sameRouteIdentity,
|
|
108
118
|
toRouteCandidate
|
|
109
|
-
} from "./chunk-
|
|
119
|
+
} from "./chunk-VPTUJU4P.js";
|
|
110
120
|
import {
|
|
111
121
|
appliesRecipeResultContract,
|
|
112
122
|
gateRouteCorrelation,
|
|
@@ -114,40 +124,38 @@ import {
|
|
|
114
124
|
requestExecutionRole,
|
|
115
125
|
routeCorrelationFactsForRun,
|
|
116
126
|
withAttemptRole
|
|
117
|
-
} from "./chunk-
|
|
127
|
+
} from "./chunk-H7IXIC72.js";
|
|
118
128
|
import {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
parseAgentLedgerBody
|
|
122
|
-
} from "./chunk-CMZWFGD2.js";
|
|
123
|
-
import {
|
|
124
|
-
compareCodepoints
|
|
125
|
-
} from "./chunk-GH5622CP.js";
|
|
129
|
+
assessFinishContract
|
|
130
|
+
} from "./chunk-7C6RYZGQ.js";
|
|
126
131
|
import {
|
|
127
|
-
|
|
128
|
-
} from "./chunk-
|
|
132
|
+
WRITE_ROOT_REFUSED_TOOLS
|
|
133
|
+
} from "./chunk-N3PBVRTZ.js";
|
|
129
134
|
import {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
mapAutonomy
|
|
133
|
-
} from "./chunk-HWUFFB6L.js";
|
|
134
|
-
import {
|
|
135
|
-
parseJsonObjectPayload,
|
|
136
|
-
parseVerifierResult,
|
|
137
|
-
resultContractAuthorship,
|
|
138
|
-
validateRecipeResult
|
|
139
|
-
} from "./chunk-DJNLUABN.js";
|
|
135
|
+
compareCodepoints
|
|
136
|
+
} from "./chunk-A2NJGIB3.js";
|
|
140
137
|
import {
|
|
141
138
|
agentSpecFingerprint,
|
|
142
139
|
assertAgentSpecPolicy,
|
|
143
140
|
classify,
|
|
144
141
|
isUserVisibleAgent,
|
|
145
142
|
normalizeAgentSpec,
|
|
146
|
-
|
|
147
|
-
|
|
143
|
+
parseJsonObjectPayload,
|
|
144
|
+
parseVerifierResult,
|
|
145
|
+
pathBoundaryCovers,
|
|
146
|
+
resolveAgentToolCompatibility,
|
|
147
|
+
resultContractAuthorship,
|
|
148
|
+
validateRecipeResult
|
|
149
|
+
} from "./chunk-S4COXYBG.js";
|
|
148
150
|
import {
|
|
149
151
|
detectValidationCommand
|
|
150
152
|
} from "./chunk-MV3K5QF2.js";
|
|
153
|
+
import {
|
|
154
|
+
DEFAULT_AUTONOMY_LEVEL,
|
|
155
|
+
autonomyDenyRejection,
|
|
156
|
+
isSkillActivation,
|
|
157
|
+
mapAutonomy
|
|
158
|
+
} from "./chunk-RAPCMZL4.js";
|
|
151
159
|
import {
|
|
152
160
|
isProjectVerifierCheckId,
|
|
153
161
|
isVerificationScriptName
|
|
@@ -160,6 +168,11 @@ import {
|
|
|
160
168
|
import {
|
|
161
169
|
canonicalizeExistingPath
|
|
162
170
|
} from "./chunk-ECH6PKUQ.js";
|
|
171
|
+
import {
|
|
172
|
+
canonicalJson,
|
|
173
|
+
endpointIdentityHash,
|
|
174
|
+
parseAgentLedgerBody
|
|
175
|
+
} from "./chunk-CMZWFGD2.js";
|
|
163
176
|
import {
|
|
164
177
|
truncateUtf8
|
|
165
178
|
} from "./chunk-6XLNIQDB.js";
|
|
@@ -169,46 +182,58 @@ import {
|
|
|
169
182
|
} from "./chunk-CGKSTWHD.js";
|
|
170
183
|
import {
|
|
171
184
|
canonicalizeWireModelId,
|
|
185
|
+
endpointCapacitiesForStatuses,
|
|
186
|
+
endpointCapacityForStatus,
|
|
187
|
+
endpointLabel,
|
|
172
188
|
firstRuntimeResolutionError,
|
|
189
|
+
foregroundStreamUsage,
|
|
173
190
|
isDispatchEligibleRuntime,
|
|
174
|
-
resolveEffectivePricing,
|
|
175
191
|
resolveModelCapabilities,
|
|
176
192
|
resolveRuntimeTarget,
|
|
177
193
|
runtimeResolutionWarnings,
|
|
178
194
|
runtimeTargetSnapshot
|
|
179
|
-
} from "./chunk-
|
|
180
|
-
import {
|
|
181
|
-
targetRequiresAuth
|
|
182
|
-
} from "./chunk-JRIO5UD2.js";
|
|
195
|
+
} from "./chunk-MIX5N5AC.js";
|
|
183
196
|
import {
|
|
184
197
|
ceilChars
|
|
185
|
-
} from "./chunk-
|
|
186
|
-
import {
|
|
187
|
-
DEFAULT_DELEGATION_CONNECT_TIMEOUT_MS,
|
|
188
|
-
DEFAULT_DELEGATION_TURN_TIMEOUT_MS,
|
|
189
|
-
DEFAULT_SETTINGS,
|
|
190
|
-
THINKING_LEVELS
|
|
191
|
-
} from "./chunk-4DGYLA73.js";
|
|
192
|
-
import {
|
|
193
|
-
atomicWrite
|
|
194
|
-
} from "./chunk-FO5ZOVUY.js";
|
|
195
|
-
import {
|
|
196
|
-
assertSafeId
|
|
197
|
-
} from "./chunk-R346GLFC.js";
|
|
198
|
+
} from "./chunk-AEYBF3TB.js";
|
|
198
199
|
import {
|
|
199
200
|
attributeCommitMessage,
|
|
200
201
|
gitCommitAttributionEnabled,
|
|
201
202
|
reportCommitAttributionDiagnostic,
|
|
202
203
|
withManagedGitCommitAttributionEnvironment
|
|
203
|
-
} from "./chunk-
|
|
204
|
+
} from "./chunk-B5CSFE7B.js";
|
|
204
205
|
import {
|
|
205
206
|
MAX_TIMER_DELAY_MS,
|
|
206
207
|
rawDurationMs
|
|
207
208
|
} from "./chunk-FQ4SKYE4.js";
|
|
209
|
+
import {
|
|
210
|
+
BusChannels
|
|
211
|
+
} from "./chunk-RKRLDWD3.js";
|
|
212
|
+
import {
|
|
213
|
+
assertSafeId,
|
|
214
|
+
atomicWrite
|
|
215
|
+
} from "./chunk-KV2AOLDF.js";
|
|
216
|
+
import {
|
|
217
|
+
AI_AGENT_NAME
|
|
218
|
+
} from "./chunk-6EJMN2Y3.js";
|
|
219
|
+
import {
|
|
220
|
+
readClioVersion,
|
|
221
|
+
readPiMonoVersion,
|
|
222
|
+
resolvePackageRoot
|
|
223
|
+
} from "./chunk-IWHMRKLL.js";
|
|
224
|
+
import {
|
|
225
|
+
DEFAULT_DELEGATION_CONNECT_TIMEOUT_MS,
|
|
226
|
+
DEFAULT_DELEGATION_TURN_TIMEOUT_MS,
|
|
227
|
+
DEFAULT_SETTINGS,
|
|
228
|
+
THINKING_LEVELS
|
|
229
|
+
} from "./chunk-XDOQXGFO.js";
|
|
208
230
|
import {
|
|
209
231
|
GUARDRAIL_DEFAULTS,
|
|
210
232
|
resolveGuardrail
|
|
211
233
|
} from "./chunk-4ZG3XFUR.js";
|
|
234
|
+
import {
|
|
235
|
+
targetRequiresAuth
|
|
236
|
+
} from "./chunk-EQ63NRB7.js";
|
|
212
237
|
import {
|
|
213
238
|
FILE_LOCK_ACQUIRE_TIMEOUT_MS,
|
|
214
239
|
withStateFileLock,
|
|
@@ -225,16 +250,8 @@ import {
|
|
|
225
250
|
stateRootRemoved
|
|
226
251
|
} from "./chunk-BNAZZHFG.js";
|
|
227
252
|
import {
|
|
228
|
-
|
|
229
|
-
} from "./chunk-
|
|
230
|
-
import {
|
|
231
|
-
BusChannels
|
|
232
|
-
} from "./chunk-OB5HIGJY.js";
|
|
233
|
-
import {
|
|
234
|
-
readClioVersion,
|
|
235
|
-
readPiMonoVersion,
|
|
236
|
-
resolvePackageRoot
|
|
237
|
-
} from "./chunk-IWHMRKLL.js";
|
|
253
|
+
resolveEffectivePricing
|
|
254
|
+
} from "./chunk-VO2LKSTM.js";
|
|
238
255
|
import {
|
|
239
256
|
init_esm_shims
|
|
240
257
|
} from "./chunk-3R73A4XB.js";
|
|
@@ -1055,7 +1072,7 @@ function clone(lease) {
|
|
|
1055
1072
|
function valid(value) {
|
|
1056
1073
|
if (typeof value !== "object" || value === null) return false;
|
|
1057
1074
|
const lease = value;
|
|
1058
|
-
return typeof lease.leaseId === "string" && typeof lease.assignmentId === "string" && typeof lease.nodeId === "string" && (lease.host === void 0 || typeof lease.host === "string") && Number.isInteger(lease.ownerPid) && typeof lease.processBirthToken === "string" && typeof lease.acquiredAt === "string" && typeof lease.expiresAt === "string" && typeof lease.heartbeatAt === "string" && (lease.reservationOwnerId === null || typeof lease.reservationOwnerId === "string") && (lease.reservationMemberId === null || typeof lease.reservationMemberId === "string");
|
|
1075
|
+
return typeof lease.leaseId === "string" && typeof lease.assignmentId === "string" && typeof lease.nodeId === "string" && (lease.endpointKey === void 0 || typeof lease.endpointKey === "string") && (lease.host === void 0 || typeof lease.host === "string") && Number.isInteger(lease.ownerPid) && typeof lease.processBirthToken === "string" && typeof lease.acquiredAt === "string" && typeof lease.expiresAt === "string" && typeof lease.heartbeatAt === "string" && (lease.reservationOwnerId === null || typeof lease.reservationOwnerId === "string") && (lease.reservationMemberId === null || typeof lease.reservationMemberId === "string");
|
|
1059
1076
|
}
|
|
1060
1077
|
function validTimestamp(value) {
|
|
1061
1078
|
if (typeof value !== "string") return false;
|
|
@@ -1119,6 +1136,7 @@ var MEMBER_STATUSES = /* @__PURE__ */ new Set(["held", "consumed", "released"]);
|
|
|
1119
1136
|
function heldReservationUsage(values) {
|
|
1120
1137
|
let global = 0;
|
|
1121
1138
|
const nodes = {};
|
|
1139
|
+
const endpoints = {};
|
|
1122
1140
|
for (const value of values) {
|
|
1123
1141
|
if (typeof value !== "object" || value === null)
|
|
1124
1142
|
throw new Error("dispatch capacity store has invalid reservation records");
|
|
@@ -1128,6 +1146,7 @@ function heldReservationUsage(values) {
|
|
|
1128
1146
|
if (record.status !== "active") continue;
|
|
1129
1147
|
const byWave = /* @__PURE__ */ new Map();
|
|
1130
1148
|
const byNodeWave = /* @__PURE__ */ new Map();
|
|
1149
|
+
const byEndpointWave = /* @__PURE__ */ new Map();
|
|
1131
1150
|
for (const raw of record.members) {
|
|
1132
1151
|
if (typeof raw !== "object" || raw === null)
|
|
1133
1152
|
throw new Error("dispatch capacity store has invalid reservation records");
|
|
@@ -1140,13 +1159,34 @@ function heldReservationUsage(values) {
|
|
|
1140
1159
|
const nodeWaves = byNodeWave.get(member.nodeId) ?? /* @__PURE__ */ new Map();
|
|
1141
1160
|
nodeWaves.set(wave, (nodeWaves.get(wave) ?? 0) + 1);
|
|
1142
1161
|
byNodeWave.set(member.nodeId, nodeWaves);
|
|
1162
|
+
if (member.endpointKey !== void 0 && typeof member.endpointKey !== "string")
|
|
1163
|
+
throw new Error("dispatch capacity store has invalid reservation records");
|
|
1164
|
+
if (typeof member.endpointKey === "string") {
|
|
1165
|
+
const endpointWaves = byEndpointWave.get(member.endpointKey) ?? /* @__PURE__ */ new Map();
|
|
1166
|
+
endpointWaves.set(wave, (endpointWaves.get(wave) ?? 0) + 1);
|
|
1167
|
+
byEndpointWave.set(member.endpointKey, endpointWaves);
|
|
1168
|
+
}
|
|
1143
1169
|
}
|
|
1144
1170
|
global += Math.max(0, ...byWave.values());
|
|
1145
1171
|
for (const [id, waves] of byNodeWave) nodes[id] = (nodes[id] ?? 0) + Math.max(0, ...waves.values());
|
|
1172
|
+
for (const [key, waves] of byEndpointWave) endpoints[key] = (endpoints[key] ?? 0) + Math.max(0, ...waves.values());
|
|
1146
1173
|
}
|
|
1147
|
-
return { global, nodes };
|
|
1174
|
+
return { global, nodes, endpoints };
|
|
1148
1175
|
}
|
|
1149
|
-
function
|
|
1176
|
+
function describeEndpointCapacityHolders(holders) {
|
|
1177
|
+
const parts = [];
|
|
1178
|
+
const add = (count, singular, plural) => {
|
|
1179
|
+
if (count > 0) parts.push(`${count} ${count === 1 ? singular : plural}`);
|
|
1180
|
+
};
|
|
1181
|
+
add(holders.leases, "active lease", "active leases");
|
|
1182
|
+
add(holders.reservations, "held reservation", "held reservations");
|
|
1183
|
+
add(holders.foregroundStreams, "foreground stream", "foreground streams");
|
|
1184
|
+
if (parts.length === 0) return "no active lease, held reservation, or foreground stream currently holds a slot";
|
|
1185
|
+
const named = parts.length === 1 ? parts[0] : parts.length === 2 ? `${parts[0]} and ${parts[1]}` : `${parts.slice(0, -1).join(", ")}, and ${parts.at(-1)}`;
|
|
1186
|
+
const total = holders.leases + holders.reservations + holders.foregroundStreams;
|
|
1187
|
+
return `${named} ${total === 1 ? "holds" : "hold"} ${total === 1 ? "the slot" : "the slots"}`;
|
|
1188
|
+
}
|
|
1189
|
+
function assertCapacity(file, nodeId, endpointKey, limits) {
|
|
1150
1190
|
const held2 = heldReservationUsage(file.reservations);
|
|
1151
1191
|
const globalUsed = file.leases.length + held2.global;
|
|
1152
1192
|
if (globalUsed >= limits.global) {
|
|
@@ -1161,6 +1201,23 @@ function assertCapacity(file, nodeId, limits) {
|
|
|
1161
1201
|
if (used >= nodeLimit)
|
|
1162
1202
|
throw new Error(`dispatch: admission denied: node '${nodeId}' capacity reached (${used}/${nodeLimit})`);
|
|
1163
1203
|
}
|
|
1204
|
+
if (endpointKey !== void 0) {
|
|
1205
|
+
const endpointLimit = limits.endpoints[endpointKey];
|
|
1206
|
+
if (endpointLimit !== void 0) {
|
|
1207
|
+
if (endpointLimit < 1)
|
|
1208
|
+
throw new Error(`dispatch: admission denied: endpoint '${endpointLabel(endpointKey)}' capacity unavailable`);
|
|
1209
|
+
const holders = {
|
|
1210
|
+
leases: file.leases.filter((lease) => lease.endpointKey === endpointKey).length,
|
|
1211
|
+
reservations: held2.endpoints[endpointKey] ?? 0,
|
|
1212
|
+
foregroundStreams: foregroundStreamUsage()[endpointKey] ?? 0
|
|
1213
|
+
};
|
|
1214
|
+
const used = holders.leases + holders.reservations + holders.foregroundStreams;
|
|
1215
|
+
if (used >= endpointLimit)
|
|
1216
|
+
throw new Error(
|
|
1217
|
+
`dispatch: admission denied: endpoint '${endpointLabel(endpointKey)}' capacity reached (${used}/${endpointLimit} slots): ${describeEndpointCapacityHolders(holders)}; collect in-flight runs or point workers at a second server`
|
|
1218
|
+
);
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1164
1221
|
}
|
|
1165
1222
|
function acquireCapacityLease(input) {
|
|
1166
1223
|
return withStateFileLockSync(capacityStateLockPath(), () => {
|
|
@@ -1174,10 +1231,12 @@ function acquireCapacityLease(input) {
|
|
|
1174
1231
|
);
|
|
1175
1232
|
const existing = file.leases.find((lease2) => lease2.assignmentId === input.assignmentId);
|
|
1176
1233
|
if (existing) {
|
|
1177
|
-
if (existing.nodeId !== input.nodeId) {
|
|
1234
|
+
if (existing.nodeId !== input.nodeId || existing.endpointKey !== input.endpointKey) {
|
|
1178
1235
|
const without = { ...file, leases: file.leases.filter((lease2) => lease2 !== existing) };
|
|
1179
|
-
assertCapacity(without, input.nodeId, input.limits);
|
|
1236
|
+
assertCapacity(without, input.nodeId, input.endpointKey, input.limits);
|
|
1180
1237
|
existing.nodeId = input.nodeId;
|
|
1238
|
+
if (input.endpointKey === void 0) delete existing.endpointKey;
|
|
1239
|
+
else existing.endpointKey = input.endpointKey;
|
|
1181
1240
|
}
|
|
1182
1241
|
existing.heartbeatAt = new Date(nowMs).toISOString();
|
|
1183
1242
|
existing.expiresAt = new Date(nowMs + (input.ttlMs ?? DEFAULT_CAPACITY_LEASE_TTL_MS)).toISOString();
|
|
@@ -1185,7 +1244,7 @@ function acquireCapacityLease(input) {
|
|
|
1185
1244
|
return clone(existing);
|
|
1186
1245
|
}
|
|
1187
1246
|
input.onAcquiredUnderLock?.(file);
|
|
1188
|
-
assertCapacity(file, input.nodeId, input.limits);
|
|
1247
|
+
assertCapacity(file, input.nodeId, input.endpointKey, input.limits);
|
|
1189
1248
|
const token = input.processBirthToken ?? processBirthToken(input.ownerPid ?? process.pid);
|
|
1190
1249
|
if (!token) throw new Error("dispatch: cannot establish process birth token");
|
|
1191
1250
|
const at = new Date(nowMs).toISOString();
|
|
@@ -1193,6 +1252,7 @@ function acquireCapacityLease(input) {
|
|
|
1193
1252
|
leaseId: `lease-${nowMs.toString(36)}-${randomBytes(6).toString("hex")}`,
|
|
1194
1253
|
assignmentId: input.assignmentId,
|
|
1195
1254
|
nodeId: input.nodeId,
|
|
1255
|
+
...input.endpointKey !== void 0 ? { endpointKey: input.endpointKey } : {},
|
|
1196
1256
|
host: hostname(),
|
|
1197
1257
|
ownerPid: input.ownerPid ?? process.pid,
|
|
1198
1258
|
processBirthToken: token,
|
|
@@ -1264,8 +1324,23 @@ function capacityDrain(nowMs = Date.now()) {
|
|
|
1264
1324
|
function capacityLeaseUsage(options) {
|
|
1265
1325
|
const leases = listCapacityLeases(options);
|
|
1266
1326
|
const nodes = {};
|
|
1267
|
-
|
|
1268
|
-
|
|
1327
|
+
const foreground = foregroundStreamUsage();
|
|
1328
|
+
const endpoints = { ...foreground };
|
|
1329
|
+
const endpointHolders = Object.fromEntries(
|
|
1330
|
+
Object.entries(foreground).map(([endpointKey, foregroundStreams]) => [
|
|
1331
|
+
endpointKey,
|
|
1332
|
+
{ leases: 0, reservations: 0, foregroundStreams }
|
|
1333
|
+
])
|
|
1334
|
+
);
|
|
1335
|
+
for (const lease of leases) {
|
|
1336
|
+
nodes[lease.nodeId] = (nodes[lease.nodeId] ?? 0) + 1;
|
|
1337
|
+
if (lease.endpointKey !== void 0) {
|
|
1338
|
+
endpoints[lease.endpointKey] = (endpoints[lease.endpointKey] ?? 0) + 1;
|
|
1339
|
+
const holders = endpointHolders[lease.endpointKey] ?? { leases: 0, reservations: 0, foregroundStreams: 0 };
|
|
1340
|
+
endpointHolders[lease.endpointKey] = { ...holders, leases: holders.leases + 1 };
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
return { global: leases.length, nodes, endpoints, endpointHolders };
|
|
1269
1344
|
}
|
|
1270
1345
|
function createNodeLeaseUsageReader(options) {
|
|
1271
1346
|
const cacheMs = options.cacheMs ?? 200;
|
|
@@ -1438,9 +1513,42 @@ function agentLedgerContribution(id, runId) {
|
|
|
1438
1513
|
return { posted: contribution.posted, refused: contribution.refused, digest };
|
|
1439
1514
|
}
|
|
1440
1515
|
|
|
1516
|
+
// src/domains/dispatch/intent-requirements.ts
|
|
1517
|
+
init_esm_shims();
|
|
1518
|
+
function renderDispatchIntentRequirements(intent) {
|
|
1519
|
+
if (intent === void 0 || intent.expectedOutputs.length === 0 && intent.verification.length === 0) return null;
|
|
1520
|
+
const lines = [
|
|
1521
|
+
"# Declared Result Requirements",
|
|
1522
|
+
"These entries are requirements to satisfy and verify. They are not evidence that an output exists or a check passed."
|
|
1523
|
+
];
|
|
1524
|
+
if (intent.expectedOutputs.length > 0) {
|
|
1525
|
+
lines.push("", "Expected outputs:", ...intent.expectedOutputs.map((output) => `- ${output}`));
|
|
1526
|
+
}
|
|
1527
|
+
if (intent.verification.length > 0) {
|
|
1528
|
+
lines.push(
|
|
1529
|
+
"",
|
|
1530
|
+
"Verification requirements:",
|
|
1531
|
+
...intent.verification.map(
|
|
1532
|
+
(entry) => `- ${entry.check} must pass within its declared timeout of ${entry.timeoutMs}ms`
|
|
1533
|
+
)
|
|
1534
|
+
);
|
|
1535
|
+
}
|
|
1536
|
+
return lines.join("\n");
|
|
1537
|
+
}
|
|
1538
|
+
function renderDispatchReviewerTask(originalTask, builderRunId, cycle, intent) {
|
|
1539
|
+
const requirements = renderDispatchIntentRequirements(intent);
|
|
1540
|
+
return [
|
|
1541
|
+
`Review the work of builder run ${builderRunId} (review cycle ${cycle}).`,
|
|
1542
|
+
"The builder's final answer is provided as input data; verify it against the workspace, do not trust it blindly.",
|
|
1543
|
+
"Original task the builder was given:",
|
|
1544
|
+
originalTask,
|
|
1545
|
+
...requirements === null ? [] : [requirements]
|
|
1546
|
+
].join("\n\n");
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1441
1549
|
// src/domains/dispatch/receipt-findings.ts
|
|
1442
1550
|
init_esm_shims();
|
|
1443
|
-
import { createHash as
|
|
1551
|
+
import { createHash as createHash11 } from "node:crypto";
|
|
1444
1552
|
|
|
1445
1553
|
// src/domains/evidence/index.ts
|
|
1446
1554
|
init_esm_shims();
|
|
@@ -1455,12 +1563,14 @@ init_esm_shims();
|
|
|
1455
1563
|
|
|
1456
1564
|
// src/domains/dispatch/extension.ts
|
|
1457
1565
|
init_esm_shims();
|
|
1458
|
-
import { createHash as
|
|
1566
|
+
import { createHash as createHash8, randomBytes as randomBytes6 } from "node:crypto";
|
|
1459
1567
|
import { existsSync as existsSync12, readdirSync as readdirSync4, readFileSync as readFileSync12 } from "node:fs";
|
|
1460
1568
|
import { isAbsolute as isAbsolute2, relative, resolve as resolvePath, sep } from "node:path";
|
|
1569
|
+
import { performance as performance5 } from "node:perf_hooks";
|
|
1461
1570
|
|
|
1462
1571
|
// src/engine/acp/adapter.ts
|
|
1463
1572
|
init_esm_shims();
|
|
1573
|
+
import { performance as performance4 } from "node:perf_hooks";
|
|
1464
1574
|
|
|
1465
1575
|
// src/engine/acp/event-mapper.ts
|
|
1466
1576
|
init_esm_shims();
|
|
@@ -2229,7 +2339,14 @@ function errorEvents(messageText2) {
|
|
|
2229
2339
|
function startAcpDelegationRun(input) {
|
|
2230
2340
|
const connectTimeoutMs = input.agent.connectTimeoutMs ?? DEFAULT_DELEGATION_CONNECT_TIMEOUT_MS;
|
|
2231
2341
|
const turnTimeoutMs = input.agent.turnTimeoutMs ?? DEFAULT_DELEGATION_TURN_TIMEOUT_MS;
|
|
2232
|
-
const
|
|
2342
|
+
const now = input.now ?? Date.now;
|
|
2343
|
+
const monotonicNow = input.monotonicNow ?? (() => performance4.now());
|
|
2344
|
+
const heartbeatWallAnchor = now();
|
|
2345
|
+
const heartbeatMonotonicAnchor = monotonicNow();
|
|
2346
|
+
const heartbeatAt = {
|
|
2347
|
+
current: heartbeatWallAnchor,
|
|
2348
|
+
monotonic: heartbeatMonotonicAnchor
|
|
2349
|
+
};
|
|
2233
2350
|
const queue = new AsyncEventQueue();
|
|
2234
2351
|
const usage = emptyUsage();
|
|
2235
2352
|
const mapper = new AcpEventMapper();
|
|
@@ -2256,7 +2373,9 @@ function startAcpDelegationRun(input) {
|
|
|
2256
2373
|
cancelTimer = null;
|
|
2257
2374
|
};
|
|
2258
2375
|
const emit = (event) => {
|
|
2259
|
-
|
|
2376
|
+
const stamp = monotonicNow();
|
|
2377
|
+
heartbeatAt.monotonic = stamp;
|
|
2378
|
+
heartbeatAt.current = heartbeatWallAnchor + (stamp - heartbeatMonotonicAnchor);
|
|
2260
2379
|
queue.push(event);
|
|
2261
2380
|
};
|
|
2262
2381
|
const mediator = new AcpToolMediator({
|
|
@@ -2431,62 +2550,6 @@ function startAcpDelegationRun(input) {
|
|
|
2431
2550
|
// src/domains/prompts/compiler.ts
|
|
2432
2551
|
init_esm_shims();
|
|
2433
2552
|
import { join as join3 } from "node:path";
|
|
2434
|
-
|
|
2435
|
-
// src/domains/prompts/hash.ts
|
|
2436
|
-
init_esm_shims();
|
|
2437
|
-
import { createHash as createHash2 } from "node:crypto";
|
|
2438
|
-
function sha256(input) {
|
|
2439
|
-
return createHash2("sha256").update(input, "utf8").digest("hex");
|
|
2440
|
-
}
|
|
2441
|
-
function canonicalJson2(value) {
|
|
2442
|
-
return serialize(value);
|
|
2443
|
-
}
|
|
2444
|
-
function serialize(value) {
|
|
2445
|
-
if (value === null) return "null";
|
|
2446
|
-
if (typeof value === "number") {
|
|
2447
|
-
if (!Number.isFinite(value)) {
|
|
2448
|
-
throw new Error(`canonicalJson: non-finite number ${String(value)} is not representable`);
|
|
2449
|
-
}
|
|
2450
|
-
return JSON.stringify(value);
|
|
2451
|
-
}
|
|
2452
|
-
if (typeof value === "string" || typeof value === "boolean") {
|
|
2453
|
-
return JSON.stringify(value);
|
|
2454
|
-
}
|
|
2455
|
-
if (typeof value === "bigint") {
|
|
2456
|
-
throw new Error("canonicalJson: bigint is not representable");
|
|
2457
|
-
}
|
|
2458
|
-
if (typeof value === "symbol" || typeof value === "function") {
|
|
2459
|
-
throw new Error(`canonicalJson: ${typeof value} is not representable`);
|
|
2460
|
-
}
|
|
2461
|
-
if (value === void 0) {
|
|
2462
|
-
throw new Error("canonicalJson: undefined is not representable at root");
|
|
2463
|
-
}
|
|
2464
|
-
if (Array.isArray(value)) {
|
|
2465
|
-
const parts = [];
|
|
2466
|
-
for (let i = 0; i < value.length; i++) {
|
|
2467
|
-
if (!(i in value) || value[i] === void 0) {
|
|
2468
|
-
parts.push("null");
|
|
2469
|
-
continue;
|
|
2470
|
-
}
|
|
2471
|
-
parts.push(serialize(value[i]));
|
|
2472
|
-
}
|
|
2473
|
-
return `[${parts.join(",")}]`;
|
|
2474
|
-
}
|
|
2475
|
-
if (typeof value === "object") {
|
|
2476
|
-
const obj = value;
|
|
2477
|
-
const keys = Object.keys(obj).sort();
|
|
2478
|
-
const parts = [];
|
|
2479
|
-
for (const key of keys) {
|
|
2480
|
-
const child = obj[key];
|
|
2481
|
-
if (child === void 0) continue;
|
|
2482
|
-
parts.push(`${JSON.stringify(key)}:${serialize(child)}`);
|
|
2483
|
-
}
|
|
2484
|
-
return `{${parts.join(",")}}`;
|
|
2485
|
-
}
|
|
2486
|
-
throw new Error(`canonicalJson: unsupported value of type ${typeof value}`);
|
|
2487
|
-
}
|
|
2488
|
-
|
|
2489
|
-
// src/domains/prompts/compiler.ts
|
|
2490
2553
|
var FLEET_ROUTING_GUIDANCE = 'Fleet routing: pin the `agent` id from the Fleet section; agent:"auto" baselines from the task text and is a fallback, not a router.';
|
|
2491
2554
|
var WORKER_CLAIM_GUIDANCE = 'Never claim a completion, a validation, or a file change that no tool call in this run supports. If you did not run it or write it here, say "not verified" and report what you did do.';
|
|
2492
2555
|
function lookupFragment(table, id, role) {
|
|
@@ -2698,15 +2761,45 @@ function renderProjectBlock(contextFiles) {
|
|
|
2698
2761
|
|
|
2699
2762
|
${trimmedFiles}`;
|
|
2700
2763
|
}
|
|
2701
|
-
function renderMemoryBlock(memorySection) {
|
|
2764
|
+
function renderMemoryBlock(memorySection, legacyDuplicateHeader = false) {
|
|
2702
2765
|
const trimmed = memorySection?.trim() ?? "";
|
|
2703
|
-
|
|
2766
|
+
if (trimmed.length === 0) return "";
|
|
2767
|
+
if (legacyDuplicateHeader) return `# Memory
|
|
2768
|
+
|
|
2769
|
+
${trimmed}`;
|
|
2770
|
+
return /^#\s+Memory\s*$/.test(trimmed.split("\n", 1)[0] ?? "") ? trimmed : `# Memory
|
|
2704
2771
|
|
|
2705
2772
|
${trimmed}`;
|
|
2706
2773
|
}
|
|
2707
2774
|
function estimatePromptTokens(text) {
|
|
2708
2775
|
return ceilChars(text.trim().length);
|
|
2709
2776
|
}
|
|
2777
|
+
var SESSION_PROMPT_SECTION_ORDER = [
|
|
2778
|
+
"identity",
|
|
2779
|
+
"operating-contract",
|
|
2780
|
+
"delegation",
|
|
2781
|
+
"skills",
|
|
2782
|
+
"safety",
|
|
2783
|
+
"tool-contract",
|
|
2784
|
+
"fleet",
|
|
2785
|
+
"retrieval-hints",
|
|
2786
|
+
"project-context",
|
|
2787
|
+
"memory",
|
|
2788
|
+
"runtime"
|
|
2789
|
+
];
|
|
2790
|
+
var LEGACY_SESSION_PROMPT_SECTION_ORDER = [
|
|
2791
|
+
"identity",
|
|
2792
|
+
"operating-contract",
|
|
2793
|
+
"delegation",
|
|
2794
|
+
"skills",
|
|
2795
|
+
"safety",
|
|
2796
|
+
"runtime",
|
|
2797
|
+
"tool-contract",
|
|
2798
|
+
"fleet",
|
|
2799
|
+
"retrieval-hints",
|
|
2800
|
+
"memory",
|
|
2801
|
+
"project-context"
|
|
2802
|
+
];
|
|
2710
2803
|
function compile(table, inputs) {
|
|
2711
2804
|
const identity = lookupFragment(table, inputs.identity, "identity");
|
|
2712
2805
|
const operatingContract = lookupFragment(table, inputs.operatingContract, "operating contract");
|
|
@@ -2726,24 +2819,29 @@ function compile(table, inputs) {
|
|
|
2726
2819
|
const docsRouting = selfAwareness && sessionHasContext(session) ? table.byId.get("identity.docs-routing") : void 0;
|
|
2727
2820
|
if (selfAwareness) {
|
|
2728
2821
|
const packageRoot = resolvePackageRoot();
|
|
2729
|
-
const
|
|
2730
|
-
identityBody = [identity.body.trim(),
|
|
2822
|
+
const rendered2 = selfAwareness.body.replace("{CLIO_DOCS_PATH}", join3(packageRoot, "docs")).replace("{CLIO_SRC_PATH}", join3(packageRoot, "src")).replace("{CLIO_CODEWIKI_PATH}", join3(packageRoot, "dist", "assets", "codewiki.json"));
|
|
2823
|
+
identityBody = [identity.body.trim(), rendered2.trim(), ...docsRouting ? [docsRouting.body.trim()] : []].join(
|
|
2731
2824
|
"\n\n"
|
|
2732
2825
|
);
|
|
2733
2826
|
}
|
|
2734
2827
|
const delegation = sessionCanDispatch(session) ? table.byId.get("operating.delegation") : void 0;
|
|
2735
2828
|
const skills = sessionHasContext(session) ? table.byId.get("operating.skills") : void 0;
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2829
|
+
const legacy = inputs.sectionOrder === "legacy-0.3.8";
|
|
2830
|
+
const rendered = /* @__PURE__ */ new Map([
|
|
2831
|
+
["identity", identityBody],
|
|
2832
|
+
["operating-contract", operatingContract.body],
|
|
2833
|
+
["delegation", delegation?.body ?? ""],
|
|
2834
|
+
["skills", skills?.body ?? ""],
|
|
2835
|
+
["safety", renderSafetySection(safety, autonomyLevel)],
|
|
2836
|
+
["runtime", renderRuntimeBlock(session)],
|
|
2837
|
+
["tool-contract", renderToolContractBlock(session)],
|
|
2838
|
+
["fleet", renderFleetBlock(session)],
|
|
2839
|
+
["retrieval-hints", renderRetrievalHintsBlock(session)],
|
|
2840
|
+
["memory", renderMemoryBlock(session.memorySection, legacy)],
|
|
2841
|
+
["project-context", renderProjectBlock(session.contextFiles)]
|
|
2842
|
+
]);
|
|
2843
|
+
const order = legacy ? LEGACY_SESSION_PROMPT_SECTION_ORDER : SESSION_PROMPT_SECTION_ORDER;
|
|
2844
|
+
for (const id of order) push(id, rendered.get(id) ?? "");
|
|
2747
2845
|
for (const fragment of inputs.additionalFragments ?? []) {
|
|
2748
2846
|
push(fragment.id, fragment.body);
|
|
2749
2847
|
}
|
|
@@ -3308,6 +3406,9 @@ init_esm_shims();
|
|
|
3308
3406
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
3309
3407
|
var MAX_RESERVATION_RECORDS = 500;
|
|
3310
3408
|
var DEFAULT_RESERVATION_TTL_MS = 15 * 6e4;
|
|
3409
|
+
function endpointCapacityDenial(input) {
|
|
3410
|
+
return `dispatch: admission denied: endpoint '${endpointLabel(input.endpointKey)}' capacity exceeded (${input.used + input.requested}/${input.limit} slots): ${describeEndpointCapacityHolders(input)}; reduce the same-wave worker count, collect in-flight runs, or point workers at a second server`;
|
|
3411
|
+
}
|
|
3311
3412
|
function copyRecord(record) {
|
|
3312
3413
|
return { ...record, members: record.members.map((member) => ({ ...member })) };
|
|
3313
3414
|
}
|
|
@@ -3315,7 +3416,7 @@ function validRecord(value) {
|
|
|
3315
3416
|
if (typeof value !== "object" || value === null) return false;
|
|
3316
3417
|
const record = value;
|
|
3317
3418
|
return typeof record.ownerId === "string" && typeof record.ownerPid === "number" && Number.isInteger(record.ownerPid) && record.ownerPid > 0 && (record.topology === "parallel" || record.topology === "detached" || record.topology === "sequential" || record.topology === "pipeline" || record.topology === "review" || record.topology === "compete") && (record.status === "active" || record.status === "released" || record.status === "rolled_back" || record.status === "expired") && typeof record.createdAt === "string" && typeof record.expiresAt === "string" && (record.settledAt === null || typeof record.settledAt === "string") && Array.isArray(record.members) && record.members.every(
|
|
3318
|
-
(member) => typeof member.memberId === "string" && Number.isInteger(member.wave) && typeof member.nodeId === "string" && typeof member.costUpperBoundUsd === "number" && Number.isFinite(member.costUpperBoundUsd) && member.costUpperBoundUsd >= 0 && (member.status === "held" || member.status === "consumed" || member.status === "released") && (member.consumedAt === null || typeof member.consumedAt === "string") && (member.releasedAt === null || typeof member.releasedAt === "string")
|
|
3419
|
+
(member) => typeof member.memberId === "string" && Number.isInteger(member.wave) && typeof member.nodeId === "string" && (member.endpointKey === void 0 || typeof member.endpointKey === "string") && typeof member.costUpperBoundUsd === "number" && Number.isFinite(member.costUpperBoundUsd) && member.costUpperBoundUsd >= 0 && (member.status === "held" || member.status === "consumed" || member.status === "released") && (member.consumedAt === null || typeof member.consumedAt === "string") && (member.releasedAt === null || typeof member.releasedAt === "string")
|
|
3319
3420
|
);
|
|
3320
3421
|
}
|
|
3321
3422
|
function parseReservations(values) {
|
|
@@ -3352,9 +3453,13 @@ function reservationAllocation(tasks) {
|
|
|
3352
3453
|
)
|
|
3353
3454
|
);
|
|
3354
3455
|
const nodeSlots = peakBy(tasks.map((task) => ({ wave: task.wave, key: task.nodeId })));
|
|
3456
|
+
const endpointSlots = peakBy(
|
|
3457
|
+
tasks.flatMap((task) => task.endpointKey === void 0 ? [] : [{ wave: task.wave, key: task.endpointKey }])
|
|
3458
|
+
);
|
|
3355
3459
|
return {
|
|
3356
3460
|
globalSlots,
|
|
3357
3461
|
nodeSlots,
|
|
3462
|
+
endpointSlots,
|
|
3358
3463
|
budgetUsd: tasks.reduce((sum, task) => sum + task.costUpperBoundUsd, 0)
|
|
3359
3464
|
};
|
|
3360
3465
|
}
|
|
@@ -3387,6 +3492,26 @@ function allocateReservation(tasks, existing, capacity) {
|
|
|
3387
3492
|
return { ok: false, reason: `node '${nodeId}' capacity exceeded (${used + slots}/${node.limit})` };
|
|
3388
3493
|
}
|
|
3389
3494
|
}
|
|
3495
|
+
for (const [endpointKey, slots] of Object.entries(requested.endpointSlots)) {
|
|
3496
|
+
const endpoint = capacity.endpoints[endpointKey];
|
|
3497
|
+
if (!endpoint || !Number.isFinite(endpoint.limit)) continue;
|
|
3498
|
+
const heldSlots = held2.reduce((sum, allocation) => sum + (allocation.endpointSlots[endpointKey] ?? 0), 0);
|
|
3499
|
+
const used = endpoint.active + heldSlots;
|
|
3500
|
+
if (used + slots > endpoint.limit) {
|
|
3501
|
+
return {
|
|
3502
|
+
ok: false,
|
|
3503
|
+
reason: endpointCapacityDenial({
|
|
3504
|
+
endpointKey,
|
|
3505
|
+
limit: endpoint.limit,
|
|
3506
|
+
used,
|
|
3507
|
+
requested: slots,
|
|
3508
|
+
leases: endpoint.leases ?? endpoint.active - (endpoint.foregroundStreams ?? 0),
|
|
3509
|
+
reservations: heldSlots,
|
|
3510
|
+
foregroundStreams: endpoint.foregroundStreams ?? 0
|
|
3511
|
+
})
|
|
3512
|
+
};
|
|
3513
|
+
}
|
|
3514
|
+
}
|
|
3390
3515
|
const existingBudget = activeRecords.reduce((sum, record) => sum + outstandingBudget(record), 0);
|
|
3391
3516
|
const projected = capacity.budget.currentUsd + existingBudget + requested.budgetUsd;
|
|
3392
3517
|
if (projected >= capacity.budget.ceilingUsd) {
|
|
@@ -3414,7 +3539,9 @@ function createDispatchReservation(input) {
|
|
|
3414
3539
|
if (!planned.ok) {
|
|
3415
3540
|
replaceReservations(state, records);
|
|
3416
3541
|
writeCapacityStateUnsafe(state);
|
|
3417
|
-
throw new Error(
|
|
3542
|
+
throw new Error(
|
|
3543
|
+
planned.reason.startsWith("dispatch:") ? planned.reason : `dispatch: reservation denied: ${planned.reason}`
|
|
3544
|
+
);
|
|
3418
3545
|
}
|
|
3419
3546
|
const createdAt = new Date(nowMs).toISOString();
|
|
3420
3547
|
const record = {
|
|
@@ -3437,6 +3564,7 @@ function transferDispatchReservationToLease(input) {
|
|
|
3437
3564
|
return acquireCapacityLease({
|
|
3438
3565
|
assignmentId: input.assignmentId,
|
|
3439
3566
|
nodeId: input.nodeId,
|
|
3567
|
+
...input.endpointKey !== void 0 ? { endpointKey: input.endpointKey } : {},
|
|
3440
3568
|
limits: input.limits,
|
|
3441
3569
|
nowMs,
|
|
3442
3570
|
...input.ttlMs !== void 0 ? { ttlMs: input.ttlMs } : {},
|
|
@@ -3464,10 +3592,37 @@ function rebindDispatchReservationMember(input) {
|
|
|
3464
3592
|
if (member.status === "released") {
|
|
3465
3593
|
throw new Error(`dispatch: reservation member '${input.memberId}' was already released`);
|
|
3466
3594
|
}
|
|
3467
|
-
if (member.nodeId === input.nodeId && member.costUpperBoundUsd === input.costUpperBoundUsd) {
|
|
3595
|
+
if (member.nodeId === input.nodeId && member.endpointKey === input.endpointKey && member.costUpperBoundUsd === input.costUpperBoundUsd) {
|
|
3468
3596
|
return copyRecord(record);
|
|
3469
3597
|
}
|
|
3470
3598
|
const others = records.filter((entry) => entry.status === "active" && entry.ownerId !== input.ownerId);
|
|
3599
|
+
if (member.endpointKey !== input.endpointKey && input.endpointKey !== void 0) {
|
|
3600
|
+
const endpointKey = input.endpointKey;
|
|
3601
|
+
const endpoint = input.capacity.endpoints[endpointKey];
|
|
3602
|
+
if (endpoint !== void 0 && Number.isFinite(endpoint.limit)) {
|
|
3603
|
+
const siblingSlots = record.members.filter(
|
|
3604
|
+
(entry) => entry !== member && entry.status !== "released" && entry.endpointKey === endpointKey
|
|
3605
|
+
).length;
|
|
3606
|
+
const otherHeld = others.reduce(
|
|
3607
|
+
(sum, entry) => sum + (reservationAllocation(outstandingTasks(entry)).endpointSlots[endpointKey] ?? 0),
|
|
3608
|
+
0
|
|
3609
|
+
);
|
|
3610
|
+
const used = endpoint.active + otherHeld + siblingSlots;
|
|
3611
|
+
if (used + 1 > endpoint.limit) {
|
|
3612
|
+
throw new Error(
|
|
3613
|
+
endpointCapacityDenial({
|
|
3614
|
+
endpointKey,
|
|
3615
|
+
limit: endpoint.limit,
|
|
3616
|
+
used,
|
|
3617
|
+
requested: 1,
|
|
3618
|
+
leases: endpoint.leases ?? endpoint.active - (endpoint.foregroundStreams ?? 0),
|
|
3619
|
+
reservations: otherHeld + siblingSlots,
|
|
3620
|
+
foregroundStreams: endpoint.foregroundStreams ?? 0
|
|
3621
|
+
})
|
|
3622
|
+
);
|
|
3623
|
+
}
|
|
3624
|
+
}
|
|
3625
|
+
}
|
|
3471
3626
|
if (member.nodeId !== input.nodeId) {
|
|
3472
3627
|
const node = input.capacity.nodes[input.nodeId];
|
|
3473
3628
|
if (node !== void 0 && Number.isFinite(node.limit)) {
|
|
@@ -3495,6 +3650,8 @@ function rebindDispatchReservationMember(input) {
|
|
|
3495
3650
|
);
|
|
3496
3651
|
}
|
|
3497
3652
|
member.nodeId = input.nodeId;
|
|
3653
|
+
if (input.endpointKey === void 0) delete member.endpointKey;
|
|
3654
|
+
else member.endpointKey = input.endpointKey;
|
|
3498
3655
|
member.costUpperBoundUsd = Math.max(0, input.costUpperBoundUsd);
|
|
3499
3656
|
writeStore2(records);
|
|
3500
3657
|
return copyRecord(record);
|
|
@@ -3517,6 +3674,24 @@ function releaseDispatchReservationMember(ownerId, memberId, nowMs = Date.now())
|
|
|
3517
3674
|
return copyRecord(record);
|
|
3518
3675
|
});
|
|
3519
3676
|
}
|
|
3677
|
+
function releaseDispatchReservation(ownerId, nowMs = Date.now()) {
|
|
3678
|
+
return withStateFileLockSync(capacityStateLockPath(), () => {
|
|
3679
|
+
const records = readStore2();
|
|
3680
|
+
const record = records.find((entry) => entry.ownerId === ownerId);
|
|
3681
|
+
if (!record) return null;
|
|
3682
|
+
if (record.status !== "active") return copyRecord(record);
|
|
3683
|
+
const settledAt = new Date(nowMs).toISOString();
|
|
3684
|
+
for (const member of record.members) {
|
|
3685
|
+
if (member.status === "released") continue;
|
|
3686
|
+
member.status = "released";
|
|
3687
|
+
member.releasedAt = settledAt;
|
|
3688
|
+
}
|
|
3689
|
+
record.status = "released";
|
|
3690
|
+
record.settledAt = settledAt;
|
|
3691
|
+
writeStore2(records);
|
|
3692
|
+
return copyRecord(record);
|
|
3693
|
+
});
|
|
3694
|
+
}
|
|
3520
3695
|
function rollbackDispatchReservation(ownerId, nowMs = Date.now()) {
|
|
3521
3696
|
return withStateFileLockSync(capacityStateLockPath(), () => {
|
|
3522
3697
|
const records = readStore2();
|
|
@@ -3621,6 +3796,15 @@ var PUMP_MIN_MS = 10;
|
|
|
3621
3796
|
var PUMP_MAX_MS = 500;
|
|
3622
3797
|
function describeAdmissionFailure(input) {
|
|
3623
3798
|
if (input.state === "canceled") return "dispatch: admission canceled before a capacity slot opened";
|
|
3799
|
+
if (input.endpointKey !== void 0) {
|
|
3800
|
+
const endpointLimit = input.limits.endpoints[input.endpointKey];
|
|
3801
|
+
const endpointActive = input.usage.endpoints[input.endpointKey] ?? 0;
|
|
3802
|
+
if (endpointLimit !== void 0 && endpointActive >= endpointLimit) {
|
|
3803
|
+
const holders = input.usage.endpointHolders?.[input.endpointKey];
|
|
3804
|
+
const occupancy = holders === void 0 ? "the supplied capacity snapshot does not attribute the occupied slots" : describeEndpointCapacityHolders(holders);
|
|
3805
|
+
return `dispatch: admission denied: endpoint '${endpointLabel(input.endpointKey)}' capacity reached (${endpointActive}/${endpointLimit} slots): ${occupancy}; collect in-flight runs or point workers at a second server`;
|
|
3806
|
+
}
|
|
3807
|
+
}
|
|
3624
3808
|
const nodeLimit = input.limits.nodes[input.nodeId];
|
|
3625
3809
|
const nodeActive = input.usage.nodes[input.nodeId] ?? 0;
|
|
3626
3810
|
const where = nodeLimit === void 0 ? `${input.usage.global}/${input.limits.global} worker slots in use` : `${nodeActive}/${nodeLimit} worker slots in use on '${input.nodeId}', ${input.usage.global}/${input.limits.global} globally`;
|
|
@@ -3662,6 +3846,10 @@ function createCapacityAdmissionController(options) {
|
|
|
3662
3846
|
admittedLease = request.value();
|
|
3663
3847
|
return true;
|
|
3664
3848
|
} catch (error) {
|
|
3849
|
+
if (error instanceof Error && /endpoint '.*' capacity reached/u.test(error.message)) {
|
|
3850
|
+
queue.fail(request.requestId, error);
|
|
3851
|
+
return false;
|
|
3852
|
+
}
|
|
3665
3853
|
if (error instanceof Error && /capacity reached/.test(error.message)) return false;
|
|
3666
3854
|
queue.fail(request.requestId, error instanceof Error ? error : new Error(String(error)));
|
|
3667
3855
|
return false;
|
|
@@ -3712,11 +3900,13 @@ function createCapacityAdmissionController(options) {
|
|
|
3712
3900
|
memberId: input.reservation.memberId,
|
|
3713
3901
|
assignmentId: input.assignmentId,
|
|
3714
3902
|
nodeId: input.nodeId,
|
|
3903
|
+
...input.endpointKey !== void 0 ? { endpointKey: input.endpointKey } : {},
|
|
3715
3904
|
limits: options.limits(),
|
|
3716
3905
|
nowMs: now()
|
|
3717
3906
|
}) : acquireCapacityLease({
|
|
3718
3907
|
assignmentId: input.assignmentId,
|
|
3719
3908
|
nodeId: input.nodeId,
|
|
3909
|
+
...input.endpointKey !== void 0 ? { endpointKey: input.endpointKey } : {},
|
|
3720
3910
|
limits: options.limits(),
|
|
3721
3911
|
nowMs: now()
|
|
3722
3912
|
})
|
|
@@ -3728,6 +3918,7 @@ function createCapacityAdmissionController(options) {
|
|
|
3728
3918
|
describeAdmissionFailure({
|
|
3729
3919
|
state: outcome.state,
|
|
3730
3920
|
nodeId: input.nodeId,
|
|
3921
|
+
...input.endpointKey !== void 0 ? { endpointKey: input.endpointKey } : {},
|
|
3731
3922
|
waitedMs: now() - queuedAt,
|
|
3732
3923
|
overdueAtQueueMs: queuedAt - input.deadlineAt,
|
|
3733
3924
|
queueDepth: queue.size(),
|
|
@@ -3906,6 +4097,12 @@ async function reconcileOrphanAssignments(deps) {
|
|
|
3906
4097
|
const summary = { recovered: 0, abandoned: 0 };
|
|
3907
4098
|
for (const record of deps.listRunning()) {
|
|
3908
4099
|
if (record.status !== "running") continue;
|
|
4100
|
+
if (deps.ownerAlive(record)) continue;
|
|
4101
|
+
if (record.verdictOwner !== void 0) {
|
|
4102
|
+
await deps.settle(record.assignmentId, record.assignmentId, "failed", record.verdictOwner);
|
|
4103
|
+
summary.abandoned += 1;
|
|
4104
|
+
continue;
|
|
4105
|
+
}
|
|
3909
4106
|
const views = record.attempts.map((runId) => deps.lookupAttempt(runId)).filter((view) => view !== null);
|
|
3910
4107
|
const succeeded = views.find((view) => view.succeeded);
|
|
3911
4108
|
if (succeeded) {
|
|
@@ -3934,10 +4131,15 @@ var MAX_ASSIGNMENT_RECORDS = 1e3;
|
|
|
3934
4131
|
function storePath2() {
|
|
3935
4132
|
return join4(clioStateDir(), "assignments.json");
|
|
3936
4133
|
}
|
|
4134
|
+
function validProcessOwner(value) {
|
|
4135
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
4136
|
+
const owner = value;
|
|
4137
|
+
return Number.isSafeInteger(owner.pid) && (owner.pid ?? 0) > 0 && typeof owner.processBirthToken === "string" && typeof owner.acquiredAt === "string" && Number.isFinite(Date.parse(owner.acquiredAt));
|
|
4138
|
+
}
|
|
3937
4139
|
function validRecord2(value) {
|
|
3938
4140
|
if (typeof value !== "object" || value === null) return false;
|
|
3939
4141
|
const record = value;
|
|
3940
|
-
return typeof record.assignmentId === "string" && Array.isArray(record.attempts) && record.attempts.every((runId) => typeof runId === "string") && (record.terminalRunId === null || typeof record.terminalRunId === "string") && (record.status === "running" || record.status === "succeeded" || record.status === "failed" || record.status === "canceled" || record.status === "timed_out");
|
|
4142
|
+
return typeof record.assignmentId === "string" && Array.isArray(record.attempts) && record.attempts.every((runId) => typeof runId === "string") && (record.terminalRunId === null || typeof record.terminalRunId === "string") && (record.verdictOwner === void 0 || record.verdictOwner === "fleet") && (record.processOwner === void 0 || validProcessOwner(record.processOwner)) && (record.status === "running" || record.status === "succeeded" || record.status === "failed" || record.status === "canceled" || record.status === "timed_out");
|
|
3941
4143
|
}
|
|
3942
4144
|
function readStore3() {
|
|
3943
4145
|
const path2 = storePath2();
|
|
@@ -3951,7 +4153,24 @@ function readStore3() {
|
|
|
3951
4153
|
}
|
|
3952
4154
|
}
|
|
3953
4155
|
function copyRecord2(record) {
|
|
3954
|
-
return {
|
|
4156
|
+
return {
|
|
4157
|
+
...record,
|
|
4158
|
+
attempts: [...record.attempts],
|
|
4159
|
+
...record.processOwner === void 0 ? {} : { processOwner: { ...record.processOwner } }
|
|
4160
|
+
};
|
|
4161
|
+
}
|
|
4162
|
+
var defaultProcessOwnerProbe = {
|
|
4163
|
+
birthToken: processBirthToken,
|
|
4164
|
+
tokenProvesDeath: BIRTH_TOKEN_SOURCE_AVAILABLE,
|
|
4165
|
+
alive: processAlive
|
|
4166
|
+
};
|
|
4167
|
+
function assignmentProcessOwnerAlive(record, probe = defaultProcessOwnerProbe) {
|
|
4168
|
+
const owner = record.processOwner;
|
|
4169
|
+
if (owner === void 0) return false;
|
|
4170
|
+
const current = probe.birthToken(owner.pid);
|
|
4171
|
+
if (current === null || current !== owner.processBirthToken) return false;
|
|
4172
|
+
if (probe.tokenProvesDeath === false) return probe.alive?.(owner.pid) ?? false;
|
|
4173
|
+
return true;
|
|
3955
4174
|
}
|
|
3956
4175
|
function writeStore3(assignments) {
|
|
3957
4176
|
const file = {
|
|
@@ -3996,41 +4215,75 @@ async function renameStoredAssignment(fromAssignmentId, toAssignmentId) {
|
|
|
3996
4215
|
});
|
|
3997
4216
|
return copyRecord2(result);
|
|
3998
4217
|
}
|
|
3999
|
-
function
|
|
4000
|
-
|
|
4218
|
+
function currentProcessOwner() {
|
|
4219
|
+
const token = processBirthToken();
|
|
4220
|
+
if (token === null) throw new Error("dispatch: cannot establish assignment owner process birth token");
|
|
4221
|
+
return {
|
|
4222
|
+
pid: process.pid,
|
|
4223
|
+
processBirthToken: token,
|
|
4224
|
+
acquiredAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4225
|
+
};
|
|
4226
|
+
}
|
|
4227
|
+
function openRecord(assignmentId) {
|
|
4228
|
+
return {
|
|
4001
4229
|
assignmentId,
|
|
4002
|
-
|
|
4003
|
-
|
|
4230
|
+
attempts: [],
|
|
4231
|
+
terminalRunId: null,
|
|
4232
|
+
status: "running",
|
|
4233
|
+
processOwner: currentProcessOwner()
|
|
4234
|
+
};
|
|
4235
|
+
}
|
|
4236
|
+
function ensureRunningProcessOwner(record) {
|
|
4237
|
+
if (record.status !== "running" || record.processOwner !== void 0) return record;
|
|
4238
|
+
return { ...record, processOwner: currentProcessOwner() };
|
|
4239
|
+
}
|
|
4240
|
+
function clearProcessOwner(record) {
|
|
4241
|
+
const result = { ...record };
|
|
4242
|
+
delete result.processOwner;
|
|
4243
|
+
return result;
|
|
4244
|
+
}
|
|
4245
|
+
function registerAssignment(assignmentId) {
|
|
4246
|
+
return updateRecord(assignmentId, (current) => ensureRunningProcessOwner(current ?? openRecord(assignmentId)));
|
|
4247
|
+
}
|
|
4248
|
+
function claimAssignmentVerdict(assignmentId, owner) {
|
|
4249
|
+
return updateRecord(assignmentId, (current) => ({
|
|
4250
|
+
...ensureRunningProcessOwner(current ?? openRecord(assignmentId)),
|
|
4251
|
+
verdictOwner: owner
|
|
4252
|
+
}));
|
|
4004
4253
|
}
|
|
4005
4254
|
function recordAssignmentAttempt(assignmentId, runId) {
|
|
4006
4255
|
return updateRecord(assignmentId, (current) => {
|
|
4007
|
-
const base = current ??
|
|
4256
|
+
const base = ensureRunningProcessOwner(current ?? openRecord(assignmentId));
|
|
4008
4257
|
return base.attempts.includes(runId) ? base : { ...base, attempts: [...base.attempts, runId] };
|
|
4009
4258
|
});
|
|
4010
4259
|
}
|
|
4011
4260
|
function failQueuedAssignment(assignmentId) {
|
|
4012
4261
|
return updateRecord(assignmentId, (current) => {
|
|
4013
|
-
const base = current ??
|
|
4014
|
-
|
|
4262
|
+
const base = current ?? openRecord(assignmentId);
|
|
4263
|
+
if (base.verdictOwner !== void 0) return base;
|
|
4264
|
+
return base.status === "running" ? clearProcessOwner({ ...base, status: "failed" }) : base;
|
|
4015
4265
|
});
|
|
4016
4266
|
}
|
|
4017
4267
|
function timeoutStoredAssignment(assignmentId) {
|
|
4018
4268
|
return updateRecord(assignmentId, (current) => {
|
|
4019
|
-
const base = current ??
|
|
4020
|
-
|
|
4269
|
+
const base = current ?? openRecord(assignmentId);
|
|
4270
|
+
if (base.verdictOwner !== void 0) return base;
|
|
4271
|
+
return base.status === "running" ? clearProcessOwner({ ...base, status: "timed_out" }) : base;
|
|
4021
4272
|
});
|
|
4022
4273
|
}
|
|
4023
4274
|
function cancelStoredAssignment(assignmentId) {
|
|
4024
4275
|
return updateRecord(assignmentId, (current) => {
|
|
4025
|
-
const base = current ??
|
|
4026
|
-
|
|
4276
|
+
const base = current ?? openRecord(assignmentId);
|
|
4277
|
+
if (base.verdictOwner !== void 0) return base;
|
|
4278
|
+
return base.status === "running" ? clearProcessOwner({ ...base, status: "canceled" }) : base;
|
|
4027
4279
|
});
|
|
4028
4280
|
}
|
|
4029
|
-
function settleStoredAssignment(assignmentId, terminalRunId, status) {
|
|
4281
|
+
function settleStoredAssignment(assignmentId, terminalRunId, status, owner) {
|
|
4030
4282
|
return updateRecord(assignmentId, (current) => {
|
|
4031
|
-
const base = current ??
|
|
4283
|
+
const base = current ?? openRecord(assignmentId);
|
|
4032
4284
|
const attempts = base.attempts.includes(terminalRunId) ? base.attempts : [...base.attempts, terminalRunId];
|
|
4033
|
-
return { ...base, attempts
|
|
4285
|
+
if (base.verdictOwner !== owner) return { ...base, attempts };
|
|
4286
|
+
return clearProcessOwner({ ...base, attempts, terminalRunId, status });
|
|
4034
4287
|
});
|
|
4035
4288
|
}
|
|
4036
4289
|
|
|
@@ -4235,7 +4488,7 @@ function assessCapabilityMismatch(input) {
|
|
|
4235
4488
|
|
|
4236
4489
|
// src/domains/dispatch/checkout-writer-lease.ts
|
|
4237
4490
|
init_esm_shims();
|
|
4238
|
-
import { createHash as
|
|
4491
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
4239
4492
|
import { existsSync as existsSync5, mkdirSync, readFileSync as readFileSync5, realpathSync, unlinkSync } from "node:fs";
|
|
4240
4493
|
import { dirname, join as join6 } from "node:path";
|
|
4241
4494
|
var held = /* @__PURE__ */ new Map();
|
|
@@ -4245,7 +4498,7 @@ function canonicalCheckout(checkout) {
|
|
|
4245
4498
|
}
|
|
4246
4499
|
function checkoutWriterLeasePath(checkout) {
|
|
4247
4500
|
const canonical = canonicalCheckout(checkout);
|
|
4248
|
-
const key =
|
|
4501
|
+
const key = createHash2("sha256").update(canonical, "utf8").digest("hex");
|
|
4249
4502
|
return join6(clioStateDir(), "checkout-writer-leases", `${key}.json`);
|
|
4250
4503
|
}
|
|
4251
4504
|
function validRecord3(value) {
|
|
@@ -4445,8 +4698,11 @@ function isInfrastructureFailure(failureClass) {
|
|
|
4445
4698
|
// src/domains/dispatch/heartbeat.ts
|
|
4446
4699
|
init_esm_shims();
|
|
4447
4700
|
var DEFAULT_HEARTBEAT_SPEC = { windowMs: 5e3, graceMs: 1e4 };
|
|
4448
|
-
function
|
|
4449
|
-
|
|
4701
|
+
function heartbeatMonotonicAt(heartbeat) {
|
|
4702
|
+
return heartbeat.monotonic ?? heartbeat.current;
|
|
4703
|
+
}
|
|
4704
|
+
function classifyHeartbeat(heartbeatMonotonicAt2, monotonicNow, spec) {
|
|
4705
|
+
const age = monotonicNow - heartbeatMonotonicAt2;
|
|
4450
4706
|
if (age <= spec.windowMs) return "alive";
|
|
4451
4707
|
if (age <= spec.windowMs + spec.graceMs) return "stale";
|
|
4452
4708
|
return "dead";
|
|
@@ -4455,14 +4711,14 @@ function classifyHeartbeat(heartbeatAt, now, spec) {
|
|
|
4455
4711
|
// src/domains/dispatch/host-verification.ts
|
|
4456
4712
|
init_esm_shims();
|
|
4457
4713
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
4458
|
-
import { createHash as
|
|
4714
|
+
import { createHash as createHash4, randomUUID } from "node:crypto";
|
|
4459
4715
|
import { existsSync as existsSync6, mkdirSync as mkdirSync3, readFileSync as readFileSync6, renameSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
4460
4716
|
import { dirname as dirname2, join as join8, resolve as resolve3 } from "node:path";
|
|
4461
4717
|
|
|
4462
4718
|
// src/domains/dispatch/code-step.ts
|
|
4463
4719
|
init_esm_shims();
|
|
4464
4720
|
import { execFileSync, spawn as spawn2 } from "node:child_process";
|
|
4465
|
-
import { createHash as
|
|
4721
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
4466
4722
|
import { mkdirSync as mkdirSync2, writeFileSync } from "node:fs";
|
|
4467
4723
|
import { isAbsolute, join as join7, resolve as resolve2 } from "node:path";
|
|
4468
4724
|
var CODE_STEP_CAPTURE_MAX_BYTES = 1048576;
|
|
@@ -4482,10 +4738,10 @@ function canonicalCodeReport(report) {
|
|
|
4482
4738
|
});
|
|
4483
4739
|
}
|
|
4484
4740
|
function codeReportDigest(report) {
|
|
4485
|
-
return
|
|
4741
|
+
return createHash3("sha256").update(canonicalCodeReport(report), "utf8").digest("hex");
|
|
4486
4742
|
}
|
|
4487
4743
|
function sha2562(value) {
|
|
4488
|
-
return
|
|
4744
|
+
return createHash3("sha256").update(value, "utf8").digest("hex");
|
|
4489
4745
|
}
|
|
4490
4746
|
function tailUtf8(value, limit, marker) {
|
|
4491
4747
|
if (value.length <= limit) return { text: value.toString("utf8"), truncated: false };
|
|
@@ -4535,7 +4791,7 @@ function workspaceHasChanges(root) {
|
|
|
4535
4791
|
return status.trim().length > 0;
|
|
4536
4792
|
}
|
|
4537
4793
|
function newCodeRunId() {
|
|
4538
|
-
return `code-${
|
|
4794
|
+
return `code-${createHash3("sha256").update(`${process.pid}:${Date.now()}:${Math.random()}`).digest("hex").slice(0, 12)}`;
|
|
4539
4795
|
}
|
|
4540
4796
|
async function spawnCommand(input, cwd, argv) {
|
|
4541
4797
|
const command = input.command;
|
|
@@ -4699,7 +4955,7 @@ ${spawned.spawnError}
|
|
|
4699
4955
|
var OUTPUT_TAIL_BYTES = 2048;
|
|
4700
4956
|
var MEMO_VERSION = 1;
|
|
4701
4957
|
function sha2563(value) {
|
|
4702
|
-
return
|
|
4958
|
+
return createHash4("sha256").update(value, "utf8").digest("hex");
|
|
4703
4959
|
}
|
|
4704
4960
|
function outputTail(value) {
|
|
4705
4961
|
const bytes = Buffer.from(value, "utf8");
|
|
@@ -5468,7 +5724,7 @@ function selectApprovedRecoveryCandidates(input) {
|
|
|
5468
5724
|
// src/domains/dispatch/reproducibility.ts
|
|
5469
5725
|
init_esm_shims();
|
|
5470
5726
|
import { spawnSync } from "node:child_process";
|
|
5471
|
-
import { createHash as
|
|
5727
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
5472
5728
|
function collectReproducibilityMetadata(cwd, safety) {
|
|
5473
5729
|
const branch = git(cwd, ["rev-parse", "--abbrev-ref", "HEAD"]);
|
|
5474
5730
|
const commit = git(cwd, ["rev-parse", "HEAD"]);
|
|
@@ -5505,7 +5761,7 @@ function git(cwd, args) {
|
|
|
5505
5761
|
return trimmed.length > 0 ? trimmed : null;
|
|
5506
5762
|
}
|
|
5507
5763
|
function sha2564(input) {
|
|
5508
|
-
return
|
|
5764
|
+
return createHash5("sha256").update(input, "utf8").digest("hex");
|
|
5509
5765
|
}
|
|
5510
5766
|
|
|
5511
5767
|
// src/domains/dispatch/route-observer.ts
|
|
@@ -5515,7 +5771,7 @@ import { join as join12 } from "node:path";
|
|
|
5515
5771
|
|
|
5516
5772
|
// src/domains/dispatch/gate-decisions.ts
|
|
5517
5773
|
init_esm_shims();
|
|
5518
|
-
import { createHash as
|
|
5774
|
+
import { createHash as createHash6, randomBytes as randomBytes4 } from "node:crypto";
|
|
5519
5775
|
import { closeSync, existsSync as existsSync8, fsyncSync, mkdirSync as mkdirSync4, openSync, readdirSync as readdirSync2, readFileSync as readFileSync8, rmSync } from "node:fs";
|
|
5520
5776
|
import { dirname as dirname3, join as join10, resolve as resolve4 } from "node:path";
|
|
5521
5777
|
function parseReviewGateResult(output) {
|
|
@@ -5705,7 +5961,7 @@ function decisionPayload(decision) {
|
|
|
5705
5961
|
};
|
|
5706
5962
|
}
|
|
5707
5963
|
function decisionDigest(decision) {
|
|
5708
|
-
return
|
|
5964
|
+
return createHash6("sha256").update(JSON.stringify(decisionPayload(decision)), "utf8").digest("hex");
|
|
5709
5965
|
}
|
|
5710
5966
|
function artifactWithoutIntegrity(artifact) {
|
|
5711
5967
|
const result = {
|
|
@@ -5841,7 +6097,7 @@ function pendingRecordPayload(record) {
|
|
|
5841
6097
|
};
|
|
5842
6098
|
}
|
|
5843
6099
|
function pendingRecordDigest(record) {
|
|
5844
|
-
return
|
|
6100
|
+
return createHash6("sha256").update(JSON.stringify(pendingRecordPayload(record)), "utf8").digest("hex");
|
|
5845
6101
|
}
|
|
5846
6102
|
function pendingRecordWithoutIntegrity(record) {
|
|
5847
6103
|
if (record.kind === "output") {
|
|
@@ -6332,7 +6588,7 @@ function isPhaseTiming(value) {
|
|
|
6332
6588
|
|
|
6333
6589
|
// src/domains/dispatch/route-quality.ts
|
|
6334
6590
|
init_esm_shims();
|
|
6335
|
-
import { createHash as
|
|
6591
|
+
import { createHash as createHash7 } from "node:crypto";
|
|
6336
6592
|
function compareStrings(left, right) {
|
|
6337
6593
|
return left < right ? -1 : left > right ? 1 : 0;
|
|
6338
6594
|
}
|
|
@@ -6447,19 +6703,19 @@ function reduceRouteQuality(input) {
|
|
|
6447
6703
|
return { label, checks, correlatedGates, sourceDigests: [...sourceDigests].sort(compareStrings) };
|
|
6448
6704
|
}
|
|
6449
6705
|
function routeQualityEvalDigest(artifact) {
|
|
6450
|
-
return
|
|
6706
|
+
return createHash7("sha256").update(canonicalJson2(artifact), "utf8").digest("hex");
|
|
6451
6707
|
}
|
|
6452
|
-
function
|
|
6708
|
+
function canonicalJson2(value) {
|
|
6453
6709
|
if (value === null) return "null";
|
|
6454
6710
|
if (typeof value === "string" || typeof value === "boolean") return JSON.stringify(value);
|
|
6455
6711
|
if (typeof value === "number") {
|
|
6456
6712
|
if (!Number.isFinite(value)) throw new Error("route quality eval digest requires finite numbers");
|
|
6457
6713
|
return JSON.stringify(value);
|
|
6458
6714
|
}
|
|
6459
|
-
if (Array.isArray(value)) return `[${value.map(
|
|
6715
|
+
if (Array.isArray(value)) return `[${value.map(canonicalJson2).join(",")}]`;
|
|
6460
6716
|
if (typeof value === "object") {
|
|
6461
6717
|
const record = value;
|
|
6462
|
-
return `{${Object.keys(record).sort(compareStrings).map((key) => `${JSON.stringify(key)}:${
|
|
6718
|
+
return `{${Object.keys(record).sort(compareStrings).map((key) => `${JSON.stringify(key)}:${canonicalJson2(record[key])}`).join(",")}}`;
|
|
6463
6719
|
}
|
|
6464
6720
|
throw new Error(`route quality eval digest cannot represent ${typeof value}`);
|
|
6465
6721
|
}
|
|
@@ -7165,7 +7421,7 @@ function requestOriginFor(req) {
|
|
|
7165
7421
|
return req.requestOrigin ?? "agent";
|
|
7166
7422
|
}
|
|
7167
7423
|
function sha2565(input) {
|
|
7168
|
-
return
|
|
7424
|
+
return createHash8("sha256").update(input, "utf8").digest("hex");
|
|
7169
7425
|
}
|
|
7170
7426
|
function promptHash(systemPrompt) {
|
|
7171
7427
|
return systemPrompt.length > 0 ? sha2565(systemPrompt) : null;
|
|
@@ -7304,6 +7560,7 @@ function recordWorkerRunEffect(recorder, event) {
|
|
|
7304
7560
|
if (event.type === "tool_execution_end") recorder.finish(toolCallId, event.isError === true);
|
|
7305
7561
|
}
|
|
7306
7562
|
var DISPATCH_DRAIN_GRACE_MS = 2e3;
|
|
7563
|
+
var RUN_WRITE_TARGET_HISTORY = 512;
|
|
7307
7564
|
async function awaitEventDrain(drained, graceMs = DISPATCH_DRAIN_GRACE_MS) {
|
|
7308
7565
|
let timer;
|
|
7309
7566
|
const grace = new Promise((resolve5) => {
|
|
@@ -7391,9 +7648,10 @@ function mergeRouteWarningDetail(routeWarning, base) {
|
|
|
7391
7648
|
function pickOrchestratorScope(safety) {
|
|
7392
7649
|
return safety.scopes.workspace;
|
|
7393
7650
|
}
|
|
7394
|
-
function pickWorkerScope(safety, requestedActions) {
|
|
7651
|
+
function pickWorkerScope(safety, requestedActions, pathScope) {
|
|
7395
7652
|
if (requestedActions.every((action) => action === "read")) return safety.scopes.readonly;
|
|
7396
|
-
return safety.scopes.workspace;
|
|
7653
|
+
if (pathScope.writeBoundaries.length === 0) return safety.scopes.workspace;
|
|
7654
|
+
return { ...safety.scopes.workspace, allowedWriteRoots: pathScope.writeBoundaries };
|
|
7397
7655
|
}
|
|
7398
7656
|
function deriveRequestedActions(tools, safety) {
|
|
7399
7657
|
const actions = /* @__PURE__ */ new Set();
|
|
@@ -7520,6 +7778,10 @@ function projectContextProvenanceFor(tier, messages) {
|
|
|
7520
7778
|
function hasPersonaOverride(req) {
|
|
7521
7779
|
return typeof req.systemPrompt === "string" && req.systemPrompt.trim().length > 0;
|
|
7522
7780
|
}
|
|
7781
|
+
function hasCallerPersonaOverride(req) {
|
|
7782
|
+
if (!hasPersonaOverride(req)) return false;
|
|
7783
|
+
return !isBoundedGateRolePrompt({ role: req.gate?.role, autonomy: req.autonomy, systemPrompt: req.systemPrompt });
|
|
7784
|
+
}
|
|
7523
7785
|
function personaOverrideFor(req, staticCompositionHash) {
|
|
7524
7786
|
if (!hasPersonaOverride(req) || staticCompositionHash === null) return null;
|
|
7525
7787
|
return { promptHash: staticCompositionHash };
|
|
@@ -7556,19 +7818,6 @@ function renderWorkerProjectContext(project, options = {}) {
|
|
|
7556
7818
|
function workerProjectContextIncludesVerification(body) {
|
|
7557
7819
|
return body.includes("\nVerification expectations:\n");
|
|
7558
7820
|
}
|
|
7559
|
-
var PATH_TOKEN_RE = /(?:[\w.-]+\/)+[\w.-]+|\b[\w-]+\.[A-Za-z0-9]{1,8}\b/g;
|
|
7560
|
-
function workerWorkingContextPaths(req) {
|
|
7561
|
-
const out = /* @__PURE__ */ new Set();
|
|
7562
|
-
for (const root of req.writeRoots ?? []) out.add(root);
|
|
7563
|
-
const text = `${req.task}
|
|
7564
|
-
${req.briefing ?? ""}`;
|
|
7565
|
-
for (const match of text.matchAll(PATH_TOKEN_RE)) {
|
|
7566
|
-
const token = match[0];
|
|
7567
|
-
if (token.startsWith("http://") || token.startsWith("https://")) continue;
|
|
7568
|
-
out.add(token);
|
|
7569
|
-
}
|
|
7570
|
-
return [...out];
|
|
7571
|
-
}
|
|
7572
7821
|
function buildDynamicPromptMessages(req, dynamicContext = {}) {
|
|
7573
7822
|
const messages = [];
|
|
7574
7823
|
if (dynamicContext.workspace) {
|
|
@@ -7589,6 +7838,10 @@ function buildDynamicPromptMessages(req, dynamicContext = {}) {
|
|
|
7589
7838
|
const body = `Safety posture: autonomy ${autonomy}. ${workerSafetyOneLiner(autonomy, permission)} Worker permission routing: ${permission}.`;
|
|
7590
7839
|
messages.push({ id: "dispatch-safety-posture", body, contentHash: sha2565(body) });
|
|
7591
7840
|
}
|
|
7841
|
+
const requirements = renderDispatchIntentRequirements(req.intent);
|
|
7842
|
+
if (requirements !== null) {
|
|
7843
|
+
messages.push({ id: "dispatch-intent-requirements", body: requirements, contentHash: sha2565(requirements) });
|
|
7844
|
+
}
|
|
7592
7845
|
if (req.competeStance !== void 0) {
|
|
7593
7846
|
const body = competeStanceLiner(req.competeStance);
|
|
7594
7847
|
messages.push({ id: "dispatch-compete-stance", body, contentHash: sha2565(body) });
|
|
@@ -7719,9 +7972,6 @@ function explicitToolCapability(providers, target, wireModelId) {
|
|
|
7719
7972
|
const fromKnowledgeBase = hit?.entry.capabilities?.tools;
|
|
7720
7973
|
return typeof fromKnowledgeBase === "boolean" ? fromKnowledgeBase : null;
|
|
7721
7974
|
}
|
|
7722
|
-
function writeConfinedRequest(req) {
|
|
7723
|
-
return req.writeRoots !== void 0 && req.writeRoots.length > 0;
|
|
7724
|
-
}
|
|
7725
7975
|
function effectiveToolNames(allowedTools, target, writeConfined = false, denied = /* @__PURE__ */ new Set()) {
|
|
7726
7976
|
if (!targetToolCapability(target)) return [];
|
|
7727
7977
|
const networkStripped = networkToolsDisabled();
|
|
@@ -7866,7 +8116,7 @@ function readWorkerTargets(settings) {
|
|
|
7866
8116
|
const targetOrder = settings?.targets?.map((target) => target.id) ?? [];
|
|
7867
8117
|
return { workerDefault, workerProfiles, agentBindings, targetOrder };
|
|
7868
8118
|
}
|
|
7869
|
-
function resolveDispatchAdmissionStage(req, recipe, safety) {
|
|
8119
|
+
function resolveDispatchAdmissionStage(req, recipe, safety, pathScope) {
|
|
7870
8120
|
const recipeTools = recipe.tools;
|
|
7871
8121
|
const candidateTools = recipeTools && recipeTools.length > 0 ? Array.from(recipeTools) : [];
|
|
7872
8122
|
const allowedTools = applyToolProfile(candidateTools, req.toolProfile, { agentId: req.agentId, task: req.task });
|
|
@@ -7879,7 +8129,7 @@ function resolveDispatchAdmissionStage(req, recipe, safety) {
|
|
|
7879
8129
|
}
|
|
7880
8130
|
const requestedActions = deriveRequestedActions(allowedTools, safety);
|
|
7881
8131
|
const orchScope = pickOrchestratorScope(safety);
|
|
7882
|
-
const workerScope = pickWorkerScope(safety, requestedActions);
|
|
8132
|
+
const workerScope = pickWorkerScope(safety, requestedActions, pathScope);
|
|
7883
8133
|
const verdict = admit(
|
|
7884
8134
|
{
|
|
7885
8135
|
requestedScope: workerScope,
|
|
@@ -7903,7 +8153,7 @@ function resolveDelegationAdmissionStage(req, safety) {
|
|
|
7903
8153
|
const allowedTools = applyToolProfile([], req.toolProfile);
|
|
7904
8154
|
const requestedActions = deriveRequestedActions(allowedTools, safety);
|
|
7905
8155
|
const orchScope = pickOrchestratorScope(safety);
|
|
7906
|
-
const workerScope = pickWorkerScope(safety, requestedActions);
|
|
8156
|
+
const workerScope = pickWorkerScope(safety, requestedActions, resolveDispatchPathScope(req));
|
|
7907
8157
|
const verdict = admit(
|
|
7908
8158
|
{
|
|
7909
8159
|
requestedScope: workerScope,
|
|
@@ -7970,9 +8220,8 @@ function buildDispatchWorkerSpec(input, config) {
|
|
|
7970
8220
|
};
|
|
7971
8221
|
}
|
|
7972
8222
|
if (input.req.responseSchema !== void 0) spec.responseSchema = input.req.responseSchema;
|
|
7973
|
-
|
|
7974
|
-
|
|
7975
|
-
}
|
|
8223
|
+
const workerResultContract = appliesRecipeResultContract(input.req.gate?.role) ? input.req.resultContractOverride ?? input.recipe?.resultContract : void 0;
|
|
8224
|
+
if (workerResultContract) spec.resultContract = workerResultContract;
|
|
7976
8225
|
const product = input.req.product ?? input.recipe?.product;
|
|
7977
8226
|
if (product) spec.product = product;
|
|
7978
8227
|
const resolutionSnapshot = runtimeTargetSnapshot(input.target.runtimeResolution);
|
|
@@ -8005,10 +8254,7 @@ function buildDispatchWorkerSpec(input, config) {
|
|
|
8005
8254
|
if (escalation) spec.escalation = { timeoutMs: escalation.timeoutMs, fallback: escalation.fallback };
|
|
8006
8255
|
}
|
|
8007
8256
|
assertRuntimeCanHonorWorkerPermissionMode(input.target.runtime, spec.onPermission);
|
|
8008
|
-
if (input.
|
|
8009
|
-
const jobCwd = input.req.cwd !== void 0 && input.req.cwd.length > 0 ? input.req.cwd : process.cwd();
|
|
8010
|
-
spec.writeRoots = input.req.writeRoots.map((root) => resolvePath(jobCwd, root));
|
|
8011
|
-
}
|
|
8257
|
+
if (input.pathScope.writeBoundaries.length > 0) spec.writeRoots = [...input.pathScope.writeBoundaries];
|
|
8012
8258
|
assertWriteRootsEnforceable(input.target.runtime, spec.writeRoots);
|
|
8013
8259
|
if (input.admission.toolProfile !== void 0) spec.toolProfile = input.admission.toolProfile;
|
|
8014
8260
|
spec.autonomy = input.effectiveAutonomy;
|
|
@@ -8397,18 +8643,28 @@ function createDispatchBundle(context, options) {
|
|
|
8397
8643
|
return DEFAULT_RESILIENCE_COOLDOWN_MS;
|
|
8398
8644
|
};
|
|
8399
8645
|
const now = options?.now ?? (() => Date.now());
|
|
8646
|
+
const monotonicNow = options?.monotonicNow ?? (() => performance5.now());
|
|
8400
8647
|
const routeObserver = options?.routeObserver ?? createRouteObserver({});
|
|
8401
8648
|
let ledger = null;
|
|
8402
8649
|
let heartbeatTimer = null;
|
|
8403
8650
|
const active = /* @__PURE__ */ new Map();
|
|
8404
8651
|
const targetCooldowns = /* @__PURE__ */ new Map();
|
|
8405
8652
|
const ownedReservations = /* @__PURE__ */ new Set();
|
|
8653
|
+
const runWriteAttributions = /* @__PURE__ */ new Map();
|
|
8654
|
+
const recordRunWriteAttribution = (runId, attribution) => {
|
|
8655
|
+
runWriteAttributions.set(runId, attribution);
|
|
8656
|
+
while (runWriteAttributions.size > RUN_WRITE_TARGET_HISTORY) {
|
|
8657
|
+
const oldest = runWriteAttributions.keys().next();
|
|
8658
|
+
if (oldest.done === true) break;
|
|
8659
|
+
runWriteAttributions.delete(oldest.value);
|
|
8660
|
+
}
|
|
8661
|
+
};
|
|
8406
8662
|
const capacityAdmission = createCapacityAdmissionController({
|
|
8407
8663
|
limits: () => {
|
|
8408
8664
|
const settings = getEffectiveSettings();
|
|
8409
8665
|
const nodes = { local: configuredGlobalCapacity(settings) };
|
|
8410
8666
|
for (const node of settings?.fleet?.nodes ?? []) nodes[node.id] = node.maxWorkers;
|
|
8411
|
-
return { global: configuredGlobalCapacity(settings), nodes };
|
|
8667
|
+
return { global: configuredGlobalCapacity(settings), nodes, endpoints: configuredEndpointLimits() };
|
|
8412
8668
|
},
|
|
8413
8669
|
now,
|
|
8414
8670
|
reservedPlanPeak: (planId) => reservedPlanPeakSlots(planId, (error) => reportDispatchDiagnostic("read reserved plan peak", error))
|
|
@@ -8419,6 +8675,19 @@ function createDispatchBundle(context, options) {
|
|
|
8419
8675
|
onError: (error) => reportDispatchDiagnostic("read capacity lease usage", error)
|
|
8420
8676
|
})
|
|
8421
8677
|
);
|
|
8678
|
+
function configuredEndpointLimits() {
|
|
8679
|
+
return Object.fromEntries(
|
|
8680
|
+
Object.entries(endpointCapacitiesForStatuses(providers.list())).map(([key, value]) => [key, value.limit])
|
|
8681
|
+
);
|
|
8682
|
+
}
|
|
8683
|
+
function endpointCapacityForTarget(targetId) {
|
|
8684
|
+
const status = providers.list().find((entry) => entry.target.id === targetId);
|
|
8685
|
+
if (status === void 0) return null;
|
|
8686
|
+
const endpoint = endpointCapacityForStatus(status);
|
|
8687
|
+
if (endpoint === null) return null;
|
|
8688
|
+
const configured = endpointCapacitiesForStatuses(providers.list())[endpoint.key];
|
|
8689
|
+
return configured ?? endpoint;
|
|
8690
|
+
}
|
|
8422
8691
|
function reservationCapacitySnapshot(settings) {
|
|
8423
8692
|
const preflight = scheduling.preflight();
|
|
8424
8693
|
const usage = capacityLeaseUsage();
|
|
@@ -8427,9 +8696,21 @@ function createDispatchBundle(context, options) {
|
|
|
8427
8696
|
};
|
|
8428
8697
|
for (const node of settings?.fleet?.nodes ?? [])
|
|
8429
8698
|
nodes[node.id] = { active: usage.nodes[node.id] ?? 0, limit: node.maxWorkers };
|
|
8699
|
+
const endpoints = Object.fromEntries(
|
|
8700
|
+
Object.entries(configuredEndpointLimits()).map(([key, limit]) => [
|
|
8701
|
+
key,
|
|
8702
|
+
{
|
|
8703
|
+
active: usage.endpoints[key] ?? 0,
|
|
8704
|
+
limit,
|
|
8705
|
+
leases: usage.endpointHolders[key]?.leases ?? 0,
|
|
8706
|
+
foregroundStreams: usage.endpointHolders[key]?.foregroundStreams ?? 0
|
|
8707
|
+
}
|
|
8708
|
+
])
|
|
8709
|
+
);
|
|
8430
8710
|
return {
|
|
8431
8711
|
global: { active: usage.global, limit: configuredGlobalCapacity(settings) },
|
|
8432
8712
|
nodes,
|
|
8713
|
+
endpoints,
|
|
8433
8714
|
budget: { currentUsd: preflight.currentUsd, ceilingUsd: preflight.ceilingUsd }
|
|
8434
8715
|
};
|
|
8435
8716
|
}
|
|
@@ -8440,6 +8721,7 @@ function createDispatchBundle(context, options) {
|
|
|
8440
8721
|
memberId: task.memberId,
|
|
8441
8722
|
wave: task.wave,
|
|
8442
8723
|
nodeId: task.resolution.node.id,
|
|
8724
|
+
...task.resolution.endpoint !== void 0 ? { endpointKey: task.resolution.endpoint.key } : {},
|
|
8443
8725
|
costUpperBoundUsd: task.resolution.routeApproval?.totalCostUpperBoundUsd ?? task.resolution.costUpperBoundUsd
|
|
8444
8726
|
})),
|
|
8445
8727
|
capacity: reservationCapacitySnapshot(getEffectiveSettings()),
|
|
@@ -8481,7 +8763,7 @@ function createDispatchBundle(context, options) {
|
|
|
8481
8763
|
const configured = settings?.budget.concurrency;
|
|
8482
8764
|
return scheduling.maxWorkers?.() ?? (configured === "auto" || configured === void 0 ? 4 : Math.max(1, configured));
|
|
8483
8765
|
}
|
|
8484
|
-
async function admitAssignmentCapacity(req, nodeId, timing) {
|
|
8766
|
+
async function admitAssignmentCapacity(req, nodeId, timing, endpoint) {
|
|
8485
8767
|
const queuedAt = now();
|
|
8486
8768
|
timing.queuedAt = new Date(queuedAt).toISOString();
|
|
8487
8769
|
const assignmentId = req.lineage?.rootRunId ?? `pending-${queuedAt.toString(36)}-${randomBytes6(6).toString("hex")}`;
|
|
@@ -8497,9 +8779,14 @@ function createDispatchBundle(context, options) {
|
|
|
8497
8779
|
const admitted = await capacityAdmission.admit({
|
|
8498
8780
|
assignmentId,
|
|
8499
8781
|
nodeId,
|
|
8782
|
+
...endpoint !== null && endpoint !== void 0 ? { endpointKey: endpoint.key } : {},
|
|
8500
8783
|
deadlineAt,
|
|
8501
8784
|
...plan,
|
|
8502
|
-
|
|
8785
|
+
// A fleet's first attempt carries lineage and still owns the held
|
|
8786
|
+
// reservation member that admission must transfer into its lease.
|
|
8787
|
+
// Retries carry the same reservation identity after that member was
|
|
8788
|
+
// consumed, so they reacquire/rebind the assignment lease normally.
|
|
8789
|
+
...req.reservation !== void 0 && (req.lineage === void 0 || req.lineage.attempt === 0) ? { reservation: req.reservation } : {}
|
|
8503
8790
|
});
|
|
8504
8791
|
timing.admittedAt = new Date(admitted.admittedAt).toISOString();
|
|
8505
8792
|
return admitted.lease;
|
|
@@ -8511,12 +8798,13 @@ function createDispatchBundle(context, options) {
|
|
|
8511
8798
|
throw error;
|
|
8512
8799
|
}
|
|
8513
8800
|
}
|
|
8514
|
-
function rebindReservationSlot(req, nodeId, costUsd, settings) {
|
|
8801
|
+
function rebindReservationSlot(req, nodeId, endpoint, costUsd, settings) {
|
|
8515
8802
|
if (req.reservation === void 0 || req.lineage === void 0) return;
|
|
8516
8803
|
const capacity = reservationCapacitySnapshot(settings);
|
|
8517
8804
|
const rebind = {
|
|
8518
8805
|
...req.reservation,
|
|
8519
8806
|
nodeId,
|
|
8807
|
+
...endpoint !== null ? { endpointKey: endpoint.key } : {},
|
|
8520
8808
|
costUpperBoundUsd: req.routeApproval?.totalCostUpperBoundUsd ?? costUsd,
|
|
8521
8809
|
capacity,
|
|
8522
8810
|
nowMs: now()
|
|
@@ -8583,10 +8871,23 @@ function createDispatchBundle(context, options) {
|
|
|
8583
8871
|
persistAssignment(settleStoredAssignment(rootRunId, attemptRunId, "failed"), `${rootRunId}:finalize-error`);
|
|
8584
8872
|
capacityAdmission.releaseAssignment(rootRunId);
|
|
8585
8873
|
}
|
|
8874
|
+
function retryChainIsLive(run) {
|
|
8875
|
+
if (run.aborted) return false;
|
|
8876
|
+
const reservation = run.req.reservation;
|
|
8877
|
+
if (reservation === void 0) return assignments.get(run.lineage.rootRunId)?.status === "running";
|
|
8878
|
+
try {
|
|
8879
|
+
const record = getDispatchReservation(reservation.ownerId);
|
|
8880
|
+
const member = record?.members.find((entry) => entry.memberId === reservation.memberId);
|
|
8881
|
+
return record?.status === "active" && member !== void 0 && member.status !== "released";
|
|
8882
|
+
} catch (error) {
|
|
8883
|
+
reportDispatchDiagnostic(`read retry liveness for reservation member ${reservation.memberId}`, error);
|
|
8884
|
+
return false;
|
|
8885
|
+
}
|
|
8886
|
+
}
|
|
8586
8887
|
function maybeScheduleRetry(run, outcome, detail, receipt, failureClass) {
|
|
8587
8888
|
if (draining) return { scheduled: false };
|
|
8588
8889
|
const rootRunId = run.lineage.rootRunId;
|
|
8589
|
-
if (
|
|
8890
|
+
if (!retryChainIsLive(run)) return { scheduled: false };
|
|
8590
8891
|
if (!RETRYABLE_OUTCOMES.has(outcome)) {
|
|
8591
8892
|
retryBackoff.delete(rootRunId);
|
|
8592
8893
|
return { scheduled: false };
|
|
@@ -8695,7 +8996,7 @@ function createDispatchBundle(context, options) {
|
|
|
8695
8996
|
});
|
|
8696
8997
|
}
|
|
8697
8998
|
async function executeRetry(run, attempt, reason = "retry", decision = decideRetry("internal", run.lineage.attempt, assignmentPolicyFor(run.req).maxRetries)) {
|
|
8698
|
-
if (draining ||
|
|
8999
|
+
if (draining || !retryChainIsLive(run)) return;
|
|
8699
9000
|
const excludesNode = decision.excludedRouteParts.includes("node");
|
|
8700
9001
|
const rerouteHops = excludesNode && run.node !== null ? [...run.req.reroutes ?? [], { attempt, fromNode: run.node.id, toNode: "", reason }] : run.req.reroutes;
|
|
8701
9002
|
const retryReq = {
|
|
@@ -8851,8 +9152,8 @@ function createDispatchBundle(context, options) {
|
|
|
8851
9152
|
fleetRegistry.recordChannelSuccess(run.node.id);
|
|
8852
9153
|
}
|
|
8853
9154
|
}
|
|
8854
|
-
function heartbeatIso(
|
|
8855
|
-
return new Date(
|
|
9155
|
+
function heartbeatIso(heartbeat) {
|
|
9156
|
+
return new Date(heartbeat.current).toISOString();
|
|
8856
9157
|
}
|
|
8857
9158
|
function heartbeatRunStatus(status) {
|
|
8858
9159
|
return status === "alive" ? "running" : status;
|
|
@@ -8871,22 +9172,22 @@ function createDispatchBundle(context, options) {
|
|
|
8871
9172
|
event: {
|
|
8872
9173
|
type: "heartbeat_status",
|
|
8873
9174
|
status,
|
|
8874
|
-
heartbeatAt: run.heartbeatAt ? heartbeatIso(run.heartbeatAt
|
|
9175
|
+
heartbeatAt: run.heartbeatAt ? heartbeatIso(run.heartbeatAt) : null
|
|
8875
9176
|
}
|
|
8876
9177
|
});
|
|
8877
9178
|
}
|
|
8878
9179
|
function checkActiveHeartbeats() {
|
|
8879
9180
|
if (!ledger) return;
|
|
8880
|
-
const
|
|
9181
|
+
const tickMonotonic = monotonicNow();
|
|
8881
9182
|
for (const run of active.values()) {
|
|
8882
9183
|
if (run.aborted || run.stallKilled || !run.heartbeatAt) continue;
|
|
8883
|
-
const
|
|
8884
|
-
if (!Number.isFinite(
|
|
9184
|
+
const heartbeatMonotonic = heartbeatMonotonicAt(run.heartbeatAt);
|
|
9185
|
+
if (!Number.isFinite(heartbeatMonotonic) || !Number.isFinite(run.heartbeatAt.current)) continue;
|
|
8885
9186
|
if (run.runtimeKind === "acp-delegation") {
|
|
8886
|
-
ledger.update(run.runId, { heartbeatAt: heartbeatIso(
|
|
9187
|
+
ledger.update(run.runId, { heartbeatAt: heartbeatIso(run.heartbeatAt) });
|
|
8887
9188
|
const stallMs = run.stallTimeoutMs;
|
|
8888
9189
|
if (stallMs === null || stallMs <= 0) continue;
|
|
8889
|
-
if (
|
|
9190
|
+
if (tickMonotonic - heartbeatMonotonic <= stallMs) continue;
|
|
8890
9191
|
run.stallKilled = true;
|
|
8891
9192
|
run.heartbeatStatus = "dead";
|
|
8892
9193
|
emitHeartbeatStatus(run, "dead");
|
|
@@ -8896,10 +9197,10 @@ function createDispatchBundle(context, options) {
|
|
|
8896
9197
|
}
|
|
8897
9198
|
continue;
|
|
8898
9199
|
}
|
|
8899
|
-
const status = classifyHeartbeat(
|
|
9200
|
+
const status = classifyHeartbeat(heartbeatMonotonic, tickMonotonic, heartbeatSpec);
|
|
8900
9201
|
const patch = {
|
|
8901
9202
|
status: heartbeatRunStatus(status),
|
|
8902
|
-
heartbeatAt: heartbeatIso(
|
|
9203
|
+
heartbeatAt: heartbeatIso(run.heartbeatAt)
|
|
8903
9204
|
};
|
|
8904
9205
|
ledger.update(run.runId, patch);
|
|
8905
9206
|
if (status === "alive" && run.node !== null && run.node.kind === "ssh") {
|
|
@@ -9005,6 +9306,19 @@ function createDispatchBundle(context, options) {
|
|
|
9005
9306
|
if (cooldownMs <= 0) return;
|
|
9006
9307
|
targetCooldowns.set(key, { until: now() + cooldownMs, reason: failureClass });
|
|
9007
9308
|
}
|
|
9309
|
+
function publishDispatchPathScope(req, pathScope) {
|
|
9310
|
+
const replacementDiagnostic = declaredScopeReplacementDiagnostic(pathScope);
|
|
9311
|
+
if (replacementDiagnostic !== null) {
|
|
9312
|
+
reportDispatchDiagnostic("typed scope replacement", new Error(replacementDiagnostic));
|
|
9313
|
+
}
|
|
9314
|
+
const notice = declaredScopeReplacementNotice(pathScope);
|
|
9315
|
+
if (notice !== null) {
|
|
9316
|
+
context.bus.emit(BusChannels.DispatchScopeNotice, {
|
|
9317
|
+
...notice,
|
|
9318
|
+
agentId: req.agentId
|
|
9319
|
+
});
|
|
9320
|
+
}
|
|
9321
|
+
}
|
|
9008
9322
|
async function resolveLifecycle(req, settings) {
|
|
9009
9323
|
const recipe = agents.get(req.agentId);
|
|
9010
9324
|
if (!recipe) {
|
|
@@ -9016,7 +9330,7 @@ function createDispatchBundle(context, options) {
|
|
|
9016
9330
|
`dispatch: agent '${req.agentId}' is a ${spec.audience} agent reserved for Clio internal orchestration`
|
|
9017
9331
|
);
|
|
9018
9332
|
}
|
|
9019
|
-
if (
|
|
9333
|
+
if (hasCallerPersonaOverride(req) && (spec.audience === "shadow" || spec.audience === "internal")) {
|
|
9020
9334
|
throw new Error(`dispatch: persona overrides are not allowed for ${spec.audience} agent '${req.agentId}'`);
|
|
9021
9335
|
}
|
|
9022
9336
|
const capabilityMismatch = req.gate !== void 0 ? null : assessCapabilityMismatch({
|
|
@@ -9028,7 +9342,9 @@ function createDispatchBundle(context, options) {
|
|
|
9028
9342
|
specs: agents.listSpecs()
|
|
9029
9343
|
});
|
|
9030
9344
|
if (capabilityMismatch?.verdict === "refuse") throw new Error(capabilityMismatch.detail);
|
|
9031
|
-
const
|
|
9345
|
+
const pathScope = resolveDispatchPathScope(req);
|
|
9346
|
+
publishDispatchPathScope(req, pathScope);
|
|
9347
|
+
const admission = resolveDispatchAdmissionStage(req, recipe, safety, pathScope);
|
|
9032
9348
|
const targets = readWorkerTargets(settings);
|
|
9033
9349
|
const target = resolveDispatchTarget(
|
|
9034
9350
|
req,
|
|
@@ -9046,7 +9362,7 @@ function createDispatchBundle(context, options) {
|
|
|
9046
9362
|
const sessionAutonomy = settings?.autonomy ?? "auto-edit";
|
|
9047
9363
|
const effectiveAutonomy = clampWorkerAutonomy(sessionAutonomy, req.autonomy);
|
|
9048
9364
|
const effectiveTools = withLedgerToolNarrowing(
|
|
9049
|
-
effectiveToolNames(admission.allowedTools, target,
|
|
9365
|
+
effectiveToolNames(admission.allowedTools, target, pathScope.writeBoundaries.length > 0, deniedToolNames(req)),
|
|
9050
9366
|
req
|
|
9051
9367
|
);
|
|
9052
9368
|
assertPostRuntimeToolCompatibility(req.agentId, spec, effectiveTools, target);
|
|
@@ -9071,7 +9387,7 @@ function createDispatchBundle(context, options) {
|
|
|
9071
9387
|
dynamic: false
|
|
9072
9388
|
},
|
|
9073
9389
|
cwd,
|
|
9074
|
-
workingContextPaths:
|
|
9390
|
+
workingContextPaths: pathScope.workingContextPaths
|
|
9075
9391
|
});
|
|
9076
9392
|
const systemPrompt = compiledWorkerPrompt.systemPrompt;
|
|
9077
9393
|
const budgetEnvelope = resolveEffectiveWorkerBudget({
|
|
@@ -9105,6 +9421,7 @@ function createDispatchBundle(context, options) {
|
|
|
9105
9421
|
const limitations = runtimeLimitations(runtimeKind, target.runtime.id);
|
|
9106
9422
|
return {
|
|
9107
9423
|
recipe,
|
|
9424
|
+
pathScope,
|
|
9108
9425
|
admission: effectiveAdmission,
|
|
9109
9426
|
target,
|
|
9110
9427
|
cwd,
|
|
@@ -9138,12 +9455,7 @@ function createDispatchBundle(context, options) {
|
|
|
9138
9455
|
function resolveAcpDelegationLifecycle(req, settings) {
|
|
9139
9456
|
const agentId = req.delegationAgentId;
|
|
9140
9457
|
if (!agentId) throw new Error("dispatch: missing delegationAgentId");
|
|
9141
|
-
|
|
9142
|
-
role: req.gate?.role,
|
|
9143
|
-
autonomy: req.autonomy,
|
|
9144
|
-
systemPrompt: req.systemPrompt
|
|
9145
|
-
});
|
|
9146
|
-
if (hasPersonaOverride(req) && !boundedGateRolePrompt) {
|
|
9458
|
+
if (hasCallerPersonaOverride(req)) {
|
|
9147
9459
|
throw new Error(`dispatch: persona overrides are not allowed for ACP delegation agent '${agentId}'`);
|
|
9148
9460
|
}
|
|
9149
9461
|
if (req.agentId && maybeAgents) {
|
|
@@ -9172,6 +9484,7 @@ function createDispatchBundle(context, options) {
|
|
|
9172
9484
|
);
|
|
9173
9485
|
}
|
|
9174
9486
|
const cwd = req.cwd ?? process.cwd();
|
|
9487
|
+
const pathScope = resolveDispatchPathScope(req);
|
|
9175
9488
|
const personaBody = workerPersonaBody(req, null, []);
|
|
9176
9489
|
const systemPrompt = personaBody;
|
|
9177
9490
|
const tier = configured.projectContext ?? "none";
|
|
@@ -9191,6 +9504,7 @@ function createDispatchBundle(context, options) {
|
|
|
9191
9504
|
const personaOverride = personaOverrideFor(req, staticCompositionHash);
|
|
9192
9505
|
return {
|
|
9193
9506
|
admission,
|
|
9507
|
+
pathScope,
|
|
9194
9508
|
agentConfig: configured,
|
|
9195
9509
|
cwd,
|
|
9196
9510
|
systemPrompt,
|
|
@@ -9215,13 +9529,14 @@ function createDispatchBundle(context, options) {
|
|
|
9215
9529
|
}
|
|
9216
9530
|
async function dispatchAcpDelegation(req, settings, timing, routeDecision, observer) {
|
|
9217
9531
|
const lifecycle = resolveAcpDelegationLifecycle(req, settings);
|
|
9532
|
+
publishDispatchPathScope(req, lifecycle.pathScope);
|
|
9218
9533
|
timing.decisionCompletedAt = new Date(now()).toISOString();
|
|
9219
9534
|
const targetId = `delegation:${lifecycle.agentConfig.id}`;
|
|
9220
9535
|
const runtimeId = "acp";
|
|
9221
9536
|
const wireModelId = lifecycle.agentConfig.id;
|
|
9222
9537
|
assertTargetNotCoolingDown(req, targetId, runtimeId, wireModelId);
|
|
9223
9538
|
assertBudgetAdmitsRoute(req, { rates: null, provenance: "unknown" }, settings);
|
|
9224
|
-
const capacityLease = await admitAssignmentCapacity(req, "local", timing);
|
|
9539
|
+
const capacityLease = await admitAssignmentCapacity(req, "local", timing, null);
|
|
9225
9540
|
const leaseSlot = createLeaseSlotGuard(capacityAdmission, capacityLease.leaseId, req.lineage !== void 0);
|
|
9226
9541
|
const ledgerRef = (() => {
|
|
9227
9542
|
try {
|
|
@@ -9243,7 +9558,9 @@ function createDispatchBundle(context, options) {
|
|
|
9243
9558
|
cwd: lifecycle.cwd,
|
|
9244
9559
|
safety,
|
|
9245
9560
|
autonomy: lifecycle.autonomy,
|
|
9246
|
-
clientVersion: readClioVersion()
|
|
9561
|
+
clientVersion: readClioVersion(),
|
|
9562
|
+
now,
|
|
9563
|
+
monotonicNow
|
|
9247
9564
|
});
|
|
9248
9565
|
} catch (error) {
|
|
9249
9566
|
leaseSlot.release();
|
|
@@ -9396,7 +9713,7 @@ function createDispatchBundle(context, options) {
|
|
|
9396
9713
|
ledgerRef.update(envelope.id, {
|
|
9397
9714
|
status: "running",
|
|
9398
9715
|
pid: acp.pid,
|
|
9399
|
-
heartbeatAt: heartbeatIso(acp.heartbeatAt
|
|
9716
|
+
heartbeatAt: heartbeatIso(acp.heartbeatAt),
|
|
9400
9717
|
lineage,
|
|
9401
9718
|
identity,
|
|
9402
9719
|
node: LOCAL_RUN_NODE,
|
|
@@ -9526,6 +9843,7 @@ function createDispatchBundle(context, options) {
|
|
|
9526
9843
|
requestOrigin: lifecycle.requestOrigin,
|
|
9527
9844
|
task: req.task,
|
|
9528
9845
|
...req.intent !== void 0 ? { intent: structuredClone(req.intent) } : {},
|
|
9846
|
+
pathScope: structuredClone(lifecycle.pathScope.provenance),
|
|
9529
9847
|
targetId,
|
|
9530
9848
|
wireModelId,
|
|
9531
9849
|
runtimeId,
|
|
@@ -9755,7 +10073,7 @@ function createDispatchBundle(context, options) {
|
|
|
9755
10073
|
cacheReadTokenCount: receiptDraft.cacheReadTokenCount ?? 0,
|
|
9756
10074
|
cacheWriteTokenCount: receiptDraft.cacheWriteTokenCount ?? 0,
|
|
9757
10075
|
reasoningTokenCount: receiptDraft.reasoningTokenCount ?? 0,
|
|
9758
|
-
heartbeatAt: heartbeatIso(acp.heartbeatAt
|
|
10076
|
+
heartbeatAt: heartbeatIso(acp.heartbeatAt)
|
|
9759
10077
|
};
|
|
9760
10078
|
ledgerRef.update(envelope.id, ledgerPatch);
|
|
9761
10079
|
const receipt = ledgerRef.recordReceipt(envelope.id, sealRouteDecision(receiptDraft, routeDecision));
|
|
@@ -9892,7 +10210,7 @@ function createDispatchBundle(context, options) {
|
|
|
9892
10210
|
"dispatch: writeRoots cannot be enforced on an ACP delegation target; the external agent runs its own tool surface. Dispatch to a native or claude-sdk worker."
|
|
9893
10211
|
);
|
|
9894
10212
|
}
|
|
9895
|
-
rebindReservationSlot(req, "local", UNKNOWN_PRICING_ADMISSION_ESTIMATE_USD, settings);
|
|
10213
|
+
rebindReservationSlot(req, "local", null, UNKNOWN_PRICING_ADMISSION_ESTIMATE_USD, settings);
|
|
9896
10214
|
routeObservation = observeShadowRoute(req, void 0, settings);
|
|
9897
10215
|
return attachRouteObservation({
|
|
9898
10216
|
...await dispatchAcpDelegation(req, settings, timing, routeObservation.decision, observer),
|
|
@@ -9923,10 +10241,12 @@ function createDispatchBundle(context, options) {
|
|
|
9923
10241
|
model: lifecycle.target.wireModelId,
|
|
9924
10242
|
node: placement?.node?.id ?? "local"
|
|
9925
10243
|
};
|
|
10244
|
+
const endpoint = endpointCapacityForTarget(lifecycle.target.target.id);
|
|
9926
10245
|
assertRouteWithinApprovedEnvelope(req, effectiveRoute);
|
|
9927
10246
|
rebindReservationSlot(
|
|
9928
10247
|
req,
|
|
9929
10248
|
effectiveRoute.node,
|
|
10249
|
+
endpoint,
|
|
9930
10250
|
conservativeRouteAdmissionEstimateUsd(lifecycle.target.effectivePricing, admissionMaxOutputTokens(settings)),
|
|
9931
10251
|
settings
|
|
9932
10252
|
);
|
|
@@ -9944,7 +10264,7 @@ function createDispatchBundle(context, options) {
|
|
|
9944
10264
|
},
|
|
9945
10265
|
shadow: () => observeShadowRoute(req, placed, settings)
|
|
9946
10266
|
});
|
|
9947
|
-
const capacityLease = await admitAssignmentCapacity(req, placement?.node.id ?? "local", timing);
|
|
10267
|
+
const capacityLease = await admitAssignmentCapacity(req, placement?.node.id ?? "local", timing, endpoint);
|
|
9948
10268
|
const leaseSlot = createLeaseSlotGuard(capacityAdmission, capacityLease.leaseId, req.lineage !== void 0);
|
|
9949
10269
|
const ledgerRef = (() => {
|
|
9950
10270
|
try {
|
|
@@ -9961,6 +10281,7 @@ function createDispatchBundle(context, options) {
|
|
|
9961
10281
|
const spec = buildDispatchWorkerSpec(
|
|
9962
10282
|
{
|
|
9963
10283
|
req,
|
|
10284
|
+
pathScope: lifecycle.pathScope,
|
|
9964
10285
|
target: lifecycle.target,
|
|
9965
10286
|
admission: lifecycle.admission,
|
|
9966
10287
|
recipe: lifecycle.recipe,
|
|
@@ -10001,6 +10322,8 @@ function createDispatchBundle(context, options) {
|
|
|
10001
10322
|
try {
|
|
10002
10323
|
worker = (placement?.spawn ?? spawnWorker)(spec, {
|
|
10003
10324
|
cwd: lifecycle.cwd,
|
|
10325
|
+
now,
|
|
10326
|
+
monotonicNow,
|
|
10004
10327
|
...agentLedgerId !== null ? { onLedgerPost } : {}
|
|
10005
10328
|
});
|
|
10006
10329
|
} catch (error) {
|
|
@@ -10050,7 +10373,18 @@ function createDispatchBundle(context, options) {
|
|
|
10050
10373
|
const upstreamResponses = [];
|
|
10051
10374
|
const skillActivations = [];
|
|
10052
10375
|
const finishContractEntries = [];
|
|
10053
|
-
|
|
10376
|
+
let runIdForPermissionAudit = null;
|
|
10377
|
+
const runEffects = createRunEffectsRecorder(lifecycle.cwd, {
|
|
10378
|
+
onWriteRecordDowngraded(downgrade) {
|
|
10379
|
+
const runId = runIdForPermissionAudit;
|
|
10380
|
+
if (runId === null) return;
|
|
10381
|
+
context.bus.emit(BusChannels.DispatchProgress, {
|
|
10382
|
+
runId,
|
|
10383
|
+
agentId: req.agentId,
|
|
10384
|
+
event: { type: "clio_write_record_downgraded", payload: downgrade }
|
|
10385
|
+
});
|
|
10386
|
+
}
|
|
10387
|
+
});
|
|
10054
10388
|
let finishContractAssistantText = "";
|
|
10055
10389
|
let finishContractAssistantTurnId = null;
|
|
10056
10390
|
let failureMessage;
|
|
@@ -10058,7 +10392,6 @@ function createDispatchBundle(context, options) {
|
|
|
10058
10392
|
const trustedOutcomeCodes = /* @__PURE__ */ new Set();
|
|
10059
10393
|
let reportedUntrustedOutcome = false;
|
|
10060
10394
|
const acceptsOutcomeCodeEvents = lifecycle.runtimeKind === "http" || lifecycle.runtimeKind === "sdk" && lifecycle.target.runtime.id === "claude-sdk";
|
|
10061
|
-
let runIdForPermissionAudit = null;
|
|
10062
10395
|
let workerPolicyPermissionCounter = 0;
|
|
10063
10396
|
const outputCapture = createWorkerOutputCapture();
|
|
10064
10397
|
const markObservedPhase = (field) => {
|
|
@@ -10271,7 +10604,7 @@ function createDispatchBundle(context, options) {
|
|
|
10271
10604
|
...req.council !== void 0 ? { council: req.council } : {},
|
|
10272
10605
|
...req.plan !== void 0 ? { plan: req.plan } : {},
|
|
10273
10606
|
...lifecycle.personaOverride ? { personaOverride: lifecycle.personaOverride } : {},
|
|
10274
|
-
...heartbeatAt ? { heartbeatAt: heartbeatIso(heartbeatAt
|
|
10607
|
+
...heartbeatAt ? { heartbeatAt: heartbeatIso(heartbeatAt) } : {}
|
|
10275
10608
|
});
|
|
10276
10609
|
observer?.onAdmitted({
|
|
10277
10610
|
runId: envelope.id,
|
|
@@ -10281,6 +10614,7 @@ function createDispatchBundle(context, options) {
|
|
|
10281
10614
|
await ledgerRef.persist();
|
|
10282
10615
|
const fleetIdentity = {
|
|
10283
10616
|
budget: lifecycle.budgetEnvelope,
|
|
10617
|
+
...endpoint !== null ? { endpoint: { key: endpoint.key, label: endpoint.label, limit: endpoint.limit } } : {},
|
|
10284
10618
|
...placement !== void 0 && placement !== null ? { node: placement.node.id } : {},
|
|
10285
10619
|
...req.gate !== void 0 ? { gate: { role: req.gate.role, cycle: req.gate.cycle } } : {},
|
|
10286
10620
|
...req.council !== void 0 ? { council: req.council } : {},
|
|
@@ -10404,9 +10738,9 @@ function createDispatchBundle(context, options) {
|
|
|
10404
10738
|
if (req.fleetGateReceipt === void 0) return null;
|
|
10405
10739
|
try {
|
|
10406
10740
|
const content = readFileSync12(resolvePath(lifecycle.cwd, req.fleetGateReceipt.path));
|
|
10407
|
-
return { path: req.fleetGateReceipt.path, pathHash:
|
|
10741
|
+
return { path: req.fleetGateReceipt.path, pathHash: createHash8("sha256").update(content).digest("hex") };
|
|
10408
10742
|
} catch {
|
|
10409
|
-
return { path: req.fleetGateReceipt.path, pathHash:
|
|
10743
|
+
return { path: req.fleetGateReceipt.path, pathHash: createHash8("sha256").update("").digest("hex") };
|
|
10410
10744
|
}
|
|
10411
10745
|
})();
|
|
10412
10746
|
const ledgerContribution = (() => {
|
|
@@ -10435,6 +10769,7 @@ function createDispatchBundle(context, options) {
|
|
|
10435
10769
|
outcomeCode,
|
|
10436
10770
|
lineage,
|
|
10437
10771
|
...req.intent !== void 0 ? { intent: structuredClone(req.intent) } : {},
|
|
10772
|
+
pathScope: structuredClone(lifecycle.pathScope.provenance),
|
|
10438
10773
|
identity,
|
|
10439
10774
|
node: placement?.node ?? LOCAL_RUN_NODE,
|
|
10440
10775
|
...receiptAttestationFields(worker.attestation?.() ?? null),
|
|
@@ -10762,13 +11097,35 @@ function createDispatchBundle(context, options) {
|
|
|
10762
11097
|
dynamicHash: receiptDraft.dynamicHash ?? null,
|
|
10763
11098
|
...receiptDraft.cacheReadTokenCount !== void 0 ? { cacheReadTokenCount: receiptDraft.cacheReadTokenCount } : {},
|
|
10764
11099
|
...receiptDraft.cacheWriteTokenCount !== void 0 ? { cacheWriteTokenCount: receiptDraft.cacheWriteTokenCount } : {},
|
|
10765
|
-
...activeRun.heartbeatAt ? { heartbeatAt: heartbeatIso(activeRun.heartbeatAt
|
|
11100
|
+
...activeRun.heartbeatAt ? { heartbeatAt: heartbeatIso(activeRun.heartbeatAt) } : {}
|
|
10766
11101
|
};
|
|
10767
11102
|
if (receiptDraft.reasoningTokenCount !== void 0) {
|
|
10768
11103
|
ledgerPatch.reasoningTokenCount = receiptDraft.reasoningTokenCount;
|
|
10769
11104
|
}
|
|
10770
11105
|
ledgerRef.update(envelope.id, ledgerPatch);
|
|
10771
11106
|
const receipt = ledgerRef.recordReceipt(envelope.id, sealRouteDecision(receiptDraft, routeObservation.decision));
|
|
11107
|
+
const toolTelemetryComplete = receipt.safety?.toolTelemetry?.coverage === "complete";
|
|
11108
|
+
const downgrades = observedRunEffects.writeRecordDowngrades.map((entry) => ({
|
|
11109
|
+
reason: entry.reason,
|
|
11110
|
+
tool: entry.tool,
|
|
11111
|
+
toolCallId: entry.toolCallId,
|
|
11112
|
+
runId: envelope.id,
|
|
11113
|
+
stepId: null
|
|
11114
|
+
}));
|
|
11115
|
+
if (!toolTelemetryComplete) {
|
|
11116
|
+
downgrades.push({
|
|
11117
|
+
reason: "incomplete_tool_telemetry",
|
|
11118
|
+
tool: null,
|
|
11119
|
+
toolCallId: null,
|
|
11120
|
+
runId: envelope.id,
|
|
11121
|
+
stepId: null
|
|
11122
|
+
});
|
|
11123
|
+
}
|
|
11124
|
+
recordRunWriteAttribution(envelope.id, {
|
|
11125
|
+
recorded: [...observedRunEffects.mutatedPaths],
|
|
11126
|
+
complete: toolTelemetryComplete && observedRunEffects.writeRecordComplete,
|
|
11127
|
+
downgrades
|
|
11128
|
+
});
|
|
10772
11129
|
await ledgerRef.persist();
|
|
10773
11130
|
if (worktreeReceipt?.applied === true && req.taskWorktree !== void 0) {
|
|
10774
11131
|
try {
|
|
@@ -10972,10 +11329,11 @@ function createDispatchBundle(context, options) {
|
|
|
10972
11329
|
`dispatch: agent '${req.agentId}' is a ${agentSpec.audience} agent reserved for Clio internal orchestration`
|
|
10973
11330
|
);
|
|
10974
11331
|
}
|
|
10975
|
-
if (
|
|
11332
|
+
if (hasCallerPersonaOverride(req) && (agentSpec.audience === "shadow" || agentSpec.audience === "internal")) {
|
|
10976
11333
|
throw new Error(`dispatch: persona overrides are not allowed for ${agentSpec.audience} agent '${req.agentId}'`);
|
|
10977
11334
|
}
|
|
10978
|
-
const
|
|
11335
|
+
const pathScope = resolveDispatchPathScope(req);
|
|
11336
|
+
const admission = resolveDispatchAdmissionStage(req, recipe, safety, pathScope);
|
|
10979
11337
|
const targets = readWorkerTargets(settings);
|
|
10980
11338
|
const target = resolveDispatchTarget(
|
|
10981
11339
|
req,
|
|
@@ -10988,14 +11346,14 @@ function createDispatchBundle(context, options) {
|
|
|
10988
11346
|
);
|
|
10989
11347
|
enforceCapabilityGate(target.target.id, target.modelCapabilities, req.requiredCapabilities);
|
|
10990
11348
|
const effectiveTools = withLedgerToolNarrowing(
|
|
10991
|
-
effectiveToolNames(admission.allowedTools, target,
|
|
11349
|
+
effectiveToolNames(admission.allowedTools, target, pathScope.writeBoundaries.length > 0, deniedToolNames(req)),
|
|
10992
11350
|
req
|
|
10993
11351
|
);
|
|
10994
11352
|
assertPostRuntimeToolCompatibility(req.agentId, agentSpec, effectiveTools, target);
|
|
10995
11353
|
assertRuntimeCanHonorWorkerPermissionMode(target.runtime, settings?.workers.onPermission ?? "deny");
|
|
10996
11354
|
assertWorkerBudgetEnforceable(target.runtime, agentSpec.budget !== null || req.budget !== void 0);
|
|
10997
11355
|
assertResponseSchemaEnforceable(target.runtime, target.modelCapabilities, req.responseSchema, effectiveTools.length);
|
|
10998
|
-
assertWriteRootsEnforceable(target.runtime,
|
|
11356
|
+
assertWriteRootsEnforceable(target.runtime, pathScope.writeBoundaries);
|
|
10999
11357
|
assertProtectedArtifactsEnforceable(
|
|
11000
11358
|
target.runtime.id,
|
|
11001
11359
|
target.runtime.kind !== "subprocess",
|
|
@@ -11008,12 +11366,14 @@ function createDispatchBundle(context, options) {
|
|
|
11008
11366
|
allowedTools: effectiveTools,
|
|
11009
11367
|
settings
|
|
11010
11368
|
});
|
|
11369
|
+
const endpoint = endpointCapacityForTarget(target.target.id);
|
|
11011
11370
|
return {
|
|
11012
11371
|
agentId: req.agentId,
|
|
11013
11372
|
specFingerprint: agentSpecFingerprint(agentSpec),
|
|
11014
11373
|
targetId: target.target.id,
|
|
11015
11374
|
wireModelId: target.wireModelId,
|
|
11016
11375
|
runtimeId: target.runtime.id,
|
|
11376
|
+
...endpoint !== null ? { endpoint: { key: endpoint.key, label: endpoint.label, limit: endpoint.limit } } : {},
|
|
11017
11377
|
node: previewNode(req).node,
|
|
11018
11378
|
thinkingLevel: target.thinkingLevel,
|
|
11019
11379
|
toolSignature: toolSignature(effectiveTools),
|
|
@@ -11376,6 +11736,7 @@ function createDispatchBundle(context, options) {
|
|
|
11376
11736
|
const reconciledLedger = ledger;
|
|
11377
11737
|
const reconciled = await reconcileOrphanAssignments({
|
|
11378
11738
|
listRunning: () => listStoredAssignments().filter((record) => record.status === "running"),
|
|
11739
|
+
ownerAlive: assignmentProcessOwnerAlive,
|
|
11379
11740
|
lookupAttempt: (runId) => {
|
|
11380
11741
|
const envelope = reconciledLedger?.get(runId) ?? null;
|
|
11381
11742
|
if (!envelope) return null;
|
|
@@ -11385,7 +11746,7 @@ function createDispatchBundle(context, options) {
|
|
|
11385
11746
|
succeeded: envelope.outcome === "succeeded"
|
|
11386
11747
|
};
|
|
11387
11748
|
},
|
|
11388
|
-
settle: (assignmentId, terminalRunId, status) => settleStoredAssignment(assignmentId, terminalRunId, status)
|
|
11749
|
+
settle: (assignmentId, terminalRunId, status, owner) => settleStoredAssignment(assignmentId, terminalRunId, status, owner)
|
|
11389
11750
|
});
|
|
11390
11751
|
if ((reconciled.recovered > 0 || reconciled.abandoned > 0) && process.env.CLIO_CODER_INTERACTIVE !== "1") {
|
|
11391
11752
|
process.stderr.write(
|
|
@@ -11423,19 +11784,21 @@ function createDispatchBundle(context, options) {
|
|
|
11423
11784
|
}
|
|
11424
11785
|
function snapshot() {
|
|
11425
11786
|
const tickNow = now();
|
|
11787
|
+
const tickMonotonic = monotonicNow();
|
|
11426
11788
|
const running = [];
|
|
11427
11789
|
const totals = { ...finalizedTotals };
|
|
11428
11790
|
const costAmounts = [...finalizedCosts];
|
|
11429
11791
|
for (const run of active.values()) {
|
|
11430
11792
|
let heartbeat = "n/a";
|
|
11431
|
-
if (run.heartbeatAt && Number.isFinite(run.heartbeatAt
|
|
11793
|
+
if (run.heartbeatAt && Number.isFinite(heartbeatMonotonicAt(run.heartbeatAt))) {
|
|
11794
|
+
const heartbeatMonotonic = heartbeatMonotonicAt(run.heartbeatAt);
|
|
11432
11795
|
if (run.runtimeKind === "acp-delegation") {
|
|
11433
11796
|
const stallMs = run.stallTimeoutMs;
|
|
11434
11797
|
if (stallMs !== null && stallMs > 0) {
|
|
11435
|
-
heartbeat =
|
|
11798
|
+
heartbeat = tickMonotonic - heartbeatMonotonic > stallMs ? "dead" : "alive";
|
|
11436
11799
|
}
|
|
11437
11800
|
} else {
|
|
11438
|
-
heartbeat = classifyHeartbeat(
|
|
11801
|
+
heartbeat = classifyHeartbeat(heartbeatMonotonic, tickMonotonic, heartbeatSpec);
|
|
11439
11802
|
}
|
|
11440
11803
|
}
|
|
11441
11804
|
const meter = run.meter;
|
|
@@ -11549,6 +11912,7 @@ function createDispatchBundle(context, options) {
|
|
|
11549
11912
|
routeCandidates,
|
|
11550
11913
|
reservations: {
|
|
11551
11914
|
prepare: prepareReservation,
|
|
11915
|
+
release: (ownerId) => releaseDispatchReservation(ownerId, now()),
|
|
11552
11916
|
rollback: (ownerId) => rollbackDispatchReservation(ownerId, now()),
|
|
11553
11917
|
rollbackUnconsumed: (ownerId) => rollbackUnconsumedDispatchReservation(ownerId, now()),
|
|
11554
11918
|
get: getDispatchReservation
|
|
@@ -11566,6 +11930,19 @@ function createDispatchBundle(context, options) {
|
|
|
11566
11930
|
if (!ledger) return null;
|
|
11567
11931
|
return ledger.get(runId);
|
|
11568
11932
|
},
|
|
11933
|
+
observedRunWrites(runId) {
|
|
11934
|
+
const attribution = runWriteAttributions.get(runId);
|
|
11935
|
+
return attribution?.complete === true ? [...attribution.recorded] : null;
|
|
11936
|
+
},
|
|
11937
|
+
observedRunWriteAttribution(runId) {
|
|
11938
|
+
const attribution = runWriteAttributions.get(runId);
|
|
11939
|
+
if (attribution === void 0) return null;
|
|
11940
|
+
return {
|
|
11941
|
+
recorded: [...attribution.recorded],
|
|
11942
|
+
complete: attribution.complete,
|
|
11943
|
+
downgrades: attribution.downgrades?.map((entry) => ({ ...entry })) ?? []
|
|
11944
|
+
};
|
|
11945
|
+
},
|
|
11569
11946
|
assignments: {
|
|
11570
11947
|
get: (id) => assignments.get(id),
|
|
11571
11948
|
getStored: (id) => getStoredAssignment(id),
|
|
@@ -11691,7 +12068,7 @@ async function writeCodeStepRecord(rootId, record) {
|
|
|
11691
12068
|
|
|
11692
12069
|
// src/domains/dispatch/delegation-plan.ts
|
|
11693
12070
|
init_esm_shims();
|
|
11694
|
-
import { createHash as
|
|
12071
|
+
import { createHash as createHash9 } from "node:crypto";
|
|
11695
12072
|
var DELEGATION_PROPOSAL_BRIEFING_MAX_BYTES = 12e3;
|
|
11696
12073
|
function buildDelegationProposalBriefing(proposals) {
|
|
11697
12074
|
const value = proposals.map((proposal) => `PROPOSAL ${proposal.agent}
|
|
@@ -11708,9 +12085,6 @@ ${proposal.output}`).join("\n\n");
|
|
|
11708
12085
|
return `${source.subarray(0, end).toString("utf8")}${suffix}`;
|
|
11709
12086
|
}
|
|
11710
12087
|
var ID_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/u;
|
|
11711
|
-
function insideBoundary(path2, boundary) {
|
|
11712
|
-
return boundary.some((root) => root.endsWith("/") ? path2.startsWith(root) : path2 === root);
|
|
11713
|
-
}
|
|
11714
12088
|
function malformed(detail) {
|
|
11715
12089
|
return { ok: false, reason: "delegation_plan_malformed", detail };
|
|
11716
12090
|
}
|
|
@@ -11755,7 +12129,7 @@ function validateDelegationPlan(input) {
|
|
|
11755
12129
|
} catch (error) {
|
|
11756
12130
|
return malformed(`task '${task.id}' has invalid writes: ${error instanceof Error ? error.message : String(error)}`);
|
|
11757
12131
|
}
|
|
11758
|
-
const outside = writes.find((path2) => !
|
|
12132
|
+
const outside = writes.find((path2) => !pathBoundaryCovers(input.writes, path2));
|
|
11759
12133
|
if (outside !== void 0) {
|
|
11760
12134
|
return {
|
|
11761
12135
|
ok: false,
|
|
@@ -11802,7 +12176,7 @@ function validateDelegationPlan(input) {
|
|
|
11802
12176
|
}
|
|
11803
12177
|
}
|
|
11804
12178
|
const plan = { tasks };
|
|
11805
|
-
return { ok: true, plan, hash:
|
|
12179
|
+
return { ok: true, plan, hash: createHash9("sha256").update(JSON.stringify(plan)).digest("hex") };
|
|
11806
12180
|
}
|
|
11807
12181
|
|
|
11808
12182
|
// src/domains/dispatch/execution-scheduler.ts
|
|
@@ -12230,7 +12604,7 @@ function gateFailureLines(output) {
|
|
|
12230
12604
|
|
|
12231
12605
|
// src/domains/dispatch/fleet-run.ts
|
|
12232
12606
|
init_esm_shims();
|
|
12233
|
-
import { createHash as
|
|
12607
|
+
import { createHash as createHash10 } from "node:crypto";
|
|
12234
12608
|
import { readFileSync as readFileSync13 } from "node:fs";
|
|
12235
12609
|
import { join as join15 } from "node:path";
|
|
12236
12610
|
|
|
@@ -12347,13 +12721,47 @@ async function executeFleetRun(input) {
|
|
|
12347
12721
|
dynamicPlans: []
|
|
12348
12722
|
};
|
|
12349
12723
|
await writeFleetRun(fleetRunRecord);
|
|
12724
|
+
await claimAssignmentVerdict(fleetRootId, "fleet");
|
|
12725
|
+
const fileStepAttempt = (terminalRunId) => recordAssignmentAttempt(fleetRootId, terminalRunId);
|
|
12726
|
+
const settleFleetAssignment = (cleanRun2) => settleStoredAssignment(
|
|
12727
|
+
fleetRootId,
|
|
12728
|
+
fleetRunRecord.steps.at(-1)?.result.terminalRunId ?? fleetRootId,
|
|
12729
|
+
cleanRun2 ? "succeeded" : "failed",
|
|
12730
|
+
"fleet"
|
|
12731
|
+
).catch(() => void 0);
|
|
12350
12732
|
const boundaryEnforcer = createWriteBoundaryEnforcer({
|
|
12351
12733
|
root: workspaceRoot,
|
|
12352
12734
|
rootId: fleetRootId,
|
|
12353
12735
|
boundaryFor: (stepId) => livePlan.steps.find((step) => step.id === stepId)?.writes,
|
|
12736
|
+
recordedWritesFor: (stepId) => {
|
|
12737
|
+
const step = livePlan.steps.find((entry) => entry.id === stepId);
|
|
12738
|
+
if (step === void 0) return null;
|
|
12739
|
+
if (step.kind !== "agent") {
|
|
12740
|
+
return {
|
|
12741
|
+
recorded: [],
|
|
12742
|
+
complete: false,
|
|
12743
|
+
downgrades: [
|
|
12744
|
+
{
|
|
12745
|
+
reason: "code_step_untracked",
|
|
12746
|
+
tool: null,
|
|
12747
|
+
toolCallId: null,
|
|
12748
|
+
runId: null,
|
|
12749
|
+
stepId
|
|
12750
|
+
}
|
|
12751
|
+
]
|
|
12752
|
+
};
|
|
12753
|
+
}
|
|
12754
|
+
const receipt = receiptsByStep.get(stepId);
|
|
12755
|
+
if (receipt === void 0) return null;
|
|
12756
|
+
if (dispatch.observedRunWriteAttribution !== void 0) {
|
|
12757
|
+
return dispatch.observedRunWriteAttribution(receipt.runId);
|
|
12758
|
+
}
|
|
12759
|
+
const recorded = dispatch.observedRunWrites?.(receipt.runId) ?? null;
|
|
12760
|
+
return recorded === null ? null : { recorded, complete: true, downgrades: [] };
|
|
12761
|
+
},
|
|
12354
12762
|
onVerdict(verdict, path2) {
|
|
12355
|
-
if (verdict.
|
|
12356
|
-
notice(`write boundary ${verdict.window}: ${verdict.detail
|
|
12763
|
+
if (verdict.detail === null) return;
|
|
12764
|
+
notice(`write boundary ${verdict.window}: ${verdict.detail} record=${path2}`, "write-boundary");
|
|
12357
12765
|
}
|
|
12358
12766
|
});
|
|
12359
12767
|
const receipts = [];
|
|
@@ -12384,6 +12792,7 @@ async function executeFleetRun(input) {
|
|
|
12384
12792
|
costUsd: receiptsByStep.get(stepId)?.costUsd ?? 0,
|
|
12385
12793
|
result: replayedResult
|
|
12386
12794
|
});
|
|
12795
|
+
await fileStepAttempt(replayedResult.terminalRunId);
|
|
12387
12796
|
}
|
|
12388
12797
|
const planStep = (stepId) => livePlan.steps.find((entry) => entry.id === stepId);
|
|
12389
12798
|
let validationFresh = false;
|
|
@@ -12546,7 +12955,7 @@ async function executeFleetRun(input) {
|
|
|
12546
12955
|
} catch {
|
|
12547
12956
|
gateBytes = "";
|
|
12548
12957
|
}
|
|
12549
|
-
gatePathHash =
|
|
12958
|
+
gatePathHash = createHash10("sha256").update(gateBytes).digest("hex");
|
|
12550
12959
|
const command = input.commands?.commands.get(step.gate.commandId);
|
|
12551
12960
|
if (gateBytes.length === 0 || command === void 0) {
|
|
12552
12961
|
stepSucceeded = false;
|
|
@@ -12719,7 +13128,7 @@ async function executeFleetRun(input) {
|
|
|
12719
13128
|
cancel: (assignmentId) => dispatch.abort(assignmentId),
|
|
12720
13129
|
release: (ownerId) => {
|
|
12721
13130
|
if (ownerId === NO_WORKER_RESERVATION) return;
|
|
12722
|
-
dispatch.reservations?.
|
|
13131
|
+
dispatch.reservations?.release(ownerId);
|
|
12723
13132
|
},
|
|
12724
13133
|
releaseUnconsumed: (ownerId) => {
|
|
12725
13134
|
if (ownerId === NO_WORKER_RESERVATION) return;
|
|
@@ -12728,6 +13137,7 @@ async function executeFleetRun(input) {
|
|
|
12728
13137
|
onStepSettled: async (step, stepResult) => {
|
|
12729
13138
|
fleetRunRecord.steps.push({ stepId: step.id, result: stepResult });
|
|
12730
13139
|
await writeFleetRun(fleetRunRecord);
|
|
13140
|
+
await fileStepAttempt(stepResult.terminalRunId);
|
|
12731
13141
|
},
|
|
12732
13142
|
spliceAfter(currentPlan, step, stepResult) {
|
|
12733
13143
|
if (stepResult.delegationPlan === void 0) return null;
|
|
@@ -12767,6 +13177,7 @@ async function executeFleetRun(input) {
|
|
|
12767
13177
|
} catch (error) {
|
|
12768
13178
|
fleetRunRecord.endedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
12769
13179
|
await writeFleetRun(fleetRunRecord);
|
|
13180
|
+
await settleFleetAssignment(false);
|
|
12770
13181
|
throw error;
|
|
12771
13182
|
}
|
|
12772
13183
|
fleetRunRecord.endedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -12774,6 +13185,8 @@ async function executeFleetRun(input) {
|
|
|
12774
13185
|
const required = livePlan.steps.filter((step) => step.loop === void 0 && !result.unneeded.includes(step.id));
|
|
12775
13186
|
const failedLoops = result.loops.filter((loop) => !loop.resolved);
|
|
12776
13187
|
const succeededStepCount = required.filter((step) => result.results.get(step.id)?.succeeded === true).length;
|
|
13188
|
+
const cleanRun = failedLoops.length === 0 && result.skipped.length === 0 && succeededStepCount === required.length;
|
|
13189
|
+
await settleFleetAssignment(cleanRun);
|
|
12777
13190
|
return {
|
|
12778
13191
|
rootId: fleetRootId,
|
|
12779
13192
|
planHash: input.plan.hash,
|
|
@@ -12783,7 +13196,7 @@ async function executeFleetRun(input) {
|
|
|
12783
13196
|
requiredStepCount: required.length,
|
|
12784
13197
|
succeededStepCount,
|
|
12785
13198
|
resolvedLoopCount: result.loops.length - failedLoops.length,
|
|
12786
|
-
cleanRun
|
|
13199
|
+
cleanRun
|
|
12787
13200
|
};
|
|
12788
13201
|
}
|
|
12789
13202
|
|
|
@@ -12828,6 +13241,36 @@ function attributeEvidenceFailure(facts) {
|
|
|
12828
13241
|
return "unknown";
|
|
12829
13242
|
}
|
|
12830
13243
|
|
|
13244
|
+
// src/domains/evidence/findings-markdown.ts
|
|
13245
|
+
init_esm_shims();
|
|
13246
|
+
function renderEvidenceFindingsMarkdown(findings, trustStatus) {
|
|
13247
|
+
const lines = ["# Findings", "", "## Canonical trust", ""];
|
|
13248
|
+
if (trustStatus.runs.length === 0) {
|
|
13249
|
+
lines.push("No linked run trust status.");
|
|
13250
|
+
} else {
|
|
13251
|
+
for (const run of trustStatus.runs) {
|
|
13252
|
+
lines.push(
|
|
13253
|
+
`- run=${run.runId}`,
|
|
13254
|
+
` tier: ${trustVerdict(run.status)}`,
|
|
13255
|
+
` summary: ${formatTrustSummary(run.status)}`,
|
|
13256
|
+
` axes: ${formatTrustAxes(run.status)}`
|
|
13257
|
+
);
|
|
13258
|
+
}
|
|
13259
|
+
}
|
|
13260
|
+
lines.push("", "## Finding records", "");
|
|
13261
|
+
if (findings.length === 0) {
|
|
13262
|
+
lines.push("No findings.");
|
|
13263
|
+
} else {
|
|
13264
|
+
for (const item of findings) {
|
|
13265
|
+
const run = item.runId === null ? "" : ` run=${item.runId}`;
|
|
13266
|
+
lines.push(`- ${item.id} [${item.severity}] ${item.tag}${run}: ${item.message}`);
|
|
13267
|
+
}
|
|
13268
|
+
}
|
|
13269
|
+
lines.push("");
|
|
13270
|
+
return `${lines.join("\n")}
|
|
13271
|
+
`;
|
|
13272
|
+
}
|
|
13273
|
+
|
|
12831
13274
|
// src/domains/evidence/provenance.ts
|
|
12832
13275
|
init_esm_shims();
|
|
12833
13276
|
var PERSONA_HASH_PREFIX_CHARS = 12;
|
|
@@ -12840,6 +13283,19 @@ function extractRunProvenance(receipt) {
|
|
|
12840
13283
|
if (receipt.autonomyEnforcement !== void 0) view.autonomyEnforcement = receipt.autonomyEnforcement;
|
|
12841
13284
|
return view;
|
|
12842
13285
|
}
|
|
13286
|
+
function admitRunProvenance(view, status) {
|
|
13287
|
+
const admitted = {};
|
|
13288
|
+
if (status === void 0 || status.artifactIntegrity.state === "verified") {
|
|
13289
|
+
if (view.pipeline !== void 0) admitted.pipeline = view.pipeline;
|
|
13290
|
+
if (view.personaOverride !== void 0) admitted.personaOverride = view.personaOverride;
|
|
13291
|
+
if (view.escalation !== void 0) admitted.escalation = view.escalation;
|
|
13292
|
+
}
|
|
13293
|
+
const autonomy = status?.autonomyEnforcement.state;
|
|
13294
|
+
if (view.autonomyEnforcement !== void 0 && (autonomy === "enforced" || autonomy === "approximated" || autonomy === "bypassed")) {
|
|
13295
|
+
admitted.autonomyEnforcement = view.autonomyEnforcement;
|
|
13296
|
+
}
|
|
13297
|
+
return admitted;
|
|
13298
|
+
}
|
|
12843
13299
|
function hasRunProvenance(view) {
|
|
12844
13300
|
return view.pipeline !== void 0 || view.personaOverride !== void 0 || view.escalation !== void 0 || view.autonomyEnforcement !== void 0;
|
|
12845
13301
|
}
|
|
@@ -12910,13 +13366,14 @@ function formatPersonaHashPrefix(promptHash2) {
|
|
|
12910
13366
|
if (promptHash2.length <= PERSONA_HASH_PREFIX_CHARS) return promptHash2;
|
|
12911
13367
|
return `${promptHash2.slice(0, PERSONA_HASH_PREFIX_CHARS)}...`;
|
|
12912
13368
|
}
|
|
12913
|
-
function provenanceTranscriptLines(
|
|
13369
|
+
function provenanceTranscriptLines(source, status) {
|
|
13370
|
+
const view = admitRunProvenance(source, status);
|
|
12914
13371
|
const lines = [];
|
|
12915
13372
|
if (view.pipeline !== void 0) {
|
|
12916
13373
|
const { fromRunId, position, inputBytes, inputTruncated } = view.pipeline;
|
|
12917
|
-
const
|
|
13374
|
+
const source2 = fromRunId ?? "unknown";
|
|
12918
13375
|
const truncation = inputTruncated ? "input truncated" : "not truncated";
|
|
12919
|
-
lines.push(`pipeline: step ${position}, input ${inputBytes} bytes from ${
|
|
13376
|
+
lines.push(`pipeline: step ${position}, input ${inputBytes} bytes from ${source2} (${truncation})`);
|
|
12920
13377
|
}
|
|
12921
13378
|
if (view.personaOverride !== void 0) {
|
|
12922
13379
|
lines.push(`persona override: prompt hash ${formatPersonaHashPrefix(view.personaOverride.promptHash)}`);
|
|
@@ -12926,14 +13383,15 @@ function provenanceTranscriptLines(view) {
|
|
|
12926
13383
|
lines.push(`escalations: ${requested} requested, ${approved} approved, ${denied} denied, ${timedOut} timed out`);
|
|
12927
13384
|
}
|
|
12928
13385
|
if (view.autonomyEnforcement !== void 0) {
|
|
12929
|
-
const {
|
|
13386
|
+
const { autonomy, externalMode, dangerousBypass } = view.autonomyEnforcement;
|
|
12930
13387
|
const mode = externalMode !== void 0 ? ` mode=${externalMode}` : "";
|
|
12931
13388
|
const bypass = dangerousBypass === true ? " dangerousBypass=true" : "";
|
|
12932
|
-
lines.push(`autonomy
|
|
13389
|
+
lines.push(`autonomy: ${autonomy}${mode}${bypass}`);
|
|
12933
13390
|
}
|
|
12934
13391
|
return lines;
|
|
12935
13392
|
}
|
|
12936
|
-
function provenanceCompactSuffix(
|
|
13393
|
+
function provenanceCompactSuffix(source, status) {
|
|
13394
|
+
const view = admitRunProvenance(source, status);
|
|
12937
13395
|
const parts = [];
|
|
12938
13396
|
if (view.pipeline !== void 0) {
|
|
12939
13397
|
const { fromRunId, position, inputBytes, inputTruncated } = view.pipeline;
|
|
@@ -12948,10 +13406,10 @@ function provenanceCompactSuffix(view) {
|
|
|
12948
13406
|
parts.push(`escalations=${requested}req/${approved}appr/${denied}deny/${timedOut}timeout`);
|
|
12949
13407
|
}
|
|
12950
13408
|
if (view.autonomyEnforcement !== void 0) {
|
|
12951
|
-
const {
|
|
13409
|
+
const { autonomy, externalMode, dangerousBypass } = view.autonomyEnforcement;
|
|
12952
13410
|
const mode = externalMode !== void 0 ? `/${externalMode}` : "";
|
|
12953
13411
|
const bypass = dangerousBypass === true ? "/bypass" : "";
|
|
12954
|
-
parts.push(`
|
|
13412
|
+
parts.push(`autonomy=${autonomy}${mode}${bypass}`);
|
|
12955
13413
|
}
|
|
12956
13414
|
return parts.length === 0 ? "" : ` ${parts.join(" ")}`;
|
|
12957
13415
|
}
|
|
@@ -12959,521 +13417,6 @@ function provenanceCompactSuffix(view) {
|
|
|
12959
13417
|
// src/domains/evidence/run-trust.ts
|
|
12960
13418
|
init_esm_shims();
|
|
12961
13419
|
|
|
12962
|
-
// src/domains/evidence/trust-status.ts
|
|
12963
|
-
init_esm_shims();
|
|
12964
|
-
var TRUST_STATUS_VERSION = 1;
|
|
12965
|
-
var TRUST_STATUS_MAX_ARTIFACT_REFERENCES = 16;
|
|
12966
|
-
var TRUST_STATUS_MAX_IDENTIFIER_LENGTH = 512;
|
|
12967
|
-
var TRUST_STATUS_AXES = [
|
|
12968
|
-
"artifactIntegrity",
|
|
12969
|
-
"validationGrounding",
|
|
12970
|
-
"independentReview",
|
|
12971
|
-
"contextProvenance",
|
|
12972
|
-
"autonomyEnforcement",
|
|
12973
|
-
"completionEvidence"
|
|
12974
|
-
];
|
|
12975
|
-
var TRUST_STATUS_STATES = {
|
|
12976
|
-
artifactIntegrity: ["verified", "failed", "absent", "unknown", "not_applicable"],
|
|
12977
|
-
validationGrounding: ["validated", "failed", "ungrounded", "absent", "unknown", "not_applicable"],
|
|
12978
|
-
independentReview: ["passed", "failed", "inconclusive", "not_independent", "absent", "unknown", "not_applicable"],
|
|
12979
|
-
contextProvenance: ["recorded", "invalid", "absent", "unknown", "not_applicable"],
|
|
12980
|
-
autonomyEnforcement: ["enforced", "approximated", "bypassed", "absent", "unknown", "not_applicable"],
|
|
12981
|
-
completionEvidence: ["evidenced", "incomplete", "limited", "absent", "unknown", "not_applicable"]
|
|
12982
|
-
};
|
|
12983
|
-
var SELF_REPORTED_ARTIFACT_KINDS = /* @__PURE__ */ new Set([
|
|
12984
|
-
"finish_contract_evidence",
|
|
12985
|
-
"run_receipt"
|
|
12986
|
-
]);
|
|
12987
|
-
var AXIS_STATES = {
|
|
12988
|
-
artifactIntegrity: new Set(TRUST_STATUS_STATES.artifactIntegrity),
|
|
12989
|
-
validationGrounding: new Set(TRUST_STATUS_STATES.validationGrounding),
|
|
12990
|
-
independentReview: new Set(TRUST_STATUS_STATES.independentReview),
|
|
12991
|
-
contextProvenance: new Set(TRUST_STATUS_STATES.contextProvenance),
|
|
12992
|
-
autonomyEnforcement: new Set(TRUST_STATUS_STATES.autonomyEnforcement),
|
|
12993
|
-
completionEvidence: new Set(TRUST_STATUS_STATES.completionEvidence)
|
|
12994
|
-
};
|
|
12995
|
-
var AXIS_SOURCES = {
|
|
12996
|
-
artifactIntegrity: /* @__PURE__ */ new Set(["receipt_integrity_verification", "compatibility"]),
|
|
12997
|
-
validationGrounding: /* @__PURE__ */ new Set(["run_receipt", "evidence_bundle", "compatibility"]),
|
|
12998
|
-
independentReview: /* @__PURE__ */ new Set(["gate_decision", "compatibility"]),
|
|
12999
|
-
contextProvenance: /* @__PURE__ */ new Set(["run_receipt", "evidence_bundle", "compatibility"]),
|
|
13000
|
-
autonomyEnforcement: /* @__PURE__ */ new Set(["run_receipt", "compatibility"]),
|
|
13001
|
-
completionEvidence: /* @__PURE__ */ new Set(["finish_contract", "compatibility"])
|
|
13002
|
-
};
|
|
13003
|
-
var SOURCE_AUTHORITIES = {
|
|
13004
|
-
receipt_integrity_verification: /* @__PURE__ */ new Set(["clio"]),
|
|
13005
|
-
run_receipt: /* @__PURE__ */ new Set(["clio", "validator", "runtime", "external_system", "unknown"]),
|
|
13006
|
-
gate_decision: /* @__PURE__ */ new Set(["clio", "reviewer", "operator", "unknown"]),
|
|
13007
|
-
evidence_bundle: /* @__PURE__ */ new Set(["clio"]),
|
|
13008
|
-
finish_contract: /* @__PURE__ */ new Set(["clio"]),
|
|
13009
|
-
compatibility: /* @__PURE__ */ new Set(["clio", "unknown"])
|
|
13010
|
-
};
|
|
13011
|
-
var ABSENCE_REASONS = /* @__PURE__ */ new Set([
|
|
13012
|
-
"not_recorded",
|
|
13013
|
-
"not_observed",
|
|
13014
|
-
"artifact_missing",
|
|
13015
|
-
"historical_format"
|
|
13016
|
-
]);
|
|
13017
|
-
var SOURCE_KINDS = /* @__PURE__ */ new Set([
|
|
13018
|
-
"receipt_integrity_verification",
|
|
13019
|
-
"run_receipt",
|
|
13020
|
-
"gate_decision",
|
|
13021
|
-
"evidence_bundle",
|
|
13022
|
-
"finish_contract",
|
|
13023
|
-
"compatibility"
|
|
13024
|
-
]);
|
|
13025
|
-
var AUTHORITY_KINDS = /* @__PURE__ */ new Set([
|
|
13026
|
-
"clio",
|
|
13027
|
-
"validator",
|
|
13028
|
-
"reviewer",
|
|
13029
|
-
"operator",
|
|
13030
|
-
"runtime",
|
|
13031
|
-
"external_system",
|
|
13032
|
-
"unknown"
|
|
13033
|
-
]);
|
|
13034
|
-
var ARTIFACT_KINDS = /* @__PURE__ */ new Set([
|
|
13035
|
-
"run_receipt",
|
|
13036
|
-
"validation_result",
|
|
13037
|
-
"gate_decision",
|
|
13038
|
-
"briefing",
|
|
13039
|
-
"project_context",
|
|
13040
|
-
"autonomy_policy",
|
|
13041
|
-
"finish_contract_evidence",
|
|
13042
|
-
"evidence_bundle",
|
|
13043
|
-
"session_entry"
|
|
13044
|
-
]);
|
|
13045
|
-
function isRecord10(value) {
|
|
13046
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
13047
|
-
}
|
|
13048
|
-
function hasExactKeys(value, keys) {
|
|
13049
|
-
const expected = new Set(keys);
|
|
13050
|
-
return Object.keys(value).length === expected.size && Object.keys(value).every((key) => expected.has(key));
|
|
13051
|
-
}
|
|
13052
|
-
function isTrustStatusIdentifier(value) {
|
|
13053
|
-
if (typeof value !== "string" || value.trim().length === 0 || value.length > TRUST_STATUS_MAX_IDENTIFIER_LENGTH) {
|
|
13054
|
-
return false;
|
|
13055
|
-
}
|
|
13056
|
-
for (const character of value) {
|
|
13057
|
-
const codePoint = character.codePointAt(0);
|
|
13058
|
-
if (codePoint !== void 0 && (codePoint < 32 || codePoint === 127)) return false;
|
|
13059
|
-
}
|
|
13060
|
-
return true;
|
|
13061
|
-
}
|
|
13062
|
-
function compareArtifactReferences(left, right) {
|
|
13063
|
-
const leftKey = `${left.kind}\0${left.id}\0${left.digest?.value ?? ""}`;
|
|
13064
|
-
const rightKey = `${right.kind}\0${right.id}\0${right.digest?.value ?? ""}`;
|
|
13065
|
-
return leftKey < rightKey ? -1 : leftKey > rightKey ? 1 : 0;
|
|
13066
|
-
}
|
|
13067
|
-
function normalizeArtifactReference(value, path2) {
|
|
13068
|
-
if (!isRecord10(value)) throw new Error(`${path2} must be an object`);
|
|
13069
|
-
if (!hasExactKeys(value, value.digest === void 0 ? ["kind", "id"] : ["kind", "id", "digest"])) {
|
|
13070
|
-
throw new Error(`${path2} has unknown or missing fields`);
|
|
13071
|
-
}
|
|
13072
|
-
if (typeof value.kind !== "string" || !ARTIFACT_KINDS.has(value.kind)) {
|
|
13073
|
-
throw new Error(`${path2}.kind is invalid`);
|
|
13074
|
-
}
|
|
13075
|
-
if (!isTrustStatusIdentifier(value.id)) throw new Error(`${path2}.id is invalid`);
|
|
13076
|
-
const reference = { kind: value.kind, id: value.id };
|
|
13077
|
-
if (value.digest !== void 0) {
|
|
13078
|
-
if (!isRecord10(value.digest) || !hasExactKeys(value.digest, ["algorithm", "value"]) || value.digest.algorithm !== "sha256" || typeof value.digest.value !== "string" || !/^[a-f0-9]{64}$/u.test(value.digest.value)) {
|
|
13079
|
-
throw new Error(`${path2}.digest is invalid`);
|
|
13080
|
-
}
|
|
13081
|
-
reference.digest = { algorithm: "sha256", value: value.digest.value };
|
|
13082
|
-
}
|
|
13083
|
-
return reference;
|
|
13084
|
-
}
|
|
13085
|
-
function normalizeAttributedStatus(axis, value) {
|
|
13086
|
-
if (!hasExactKeys(value, ["state", "source", "authority", "artifacts"])) {
|
|
13087
|
-
throw new Error(`${axis} has unknown or missing fields`);
|
|
13088
|
-
}
|
|
13089
|
-
if (!isRecord10(value.source) || !hasExactKeys(value.source, ["kind", "id"])) {
|
|
13090
|
-
throw new Error(`${axis}.source is invalid`);
|
|
13091
|
-
}
|
|
13092
|
-
if (typeof value.source.kind !== "string" || !SOURCE_KINDS.has(value.source.kind) || !AXIS_SOURCES[axis].has(value.source.kind) || !isTrustStatusIdentifier(value.source.id)) {
|
|
13093
|
-
throw new Error(`${axis}.source is invalid`);
|
|
13094
|
-
}
|
|
13095
|
-
if (!isRecord10(value.authority) || !hasExactKeys(value.authority, ["kind", "id"])) {
|
|
13096
|
-
throw new Error(`${axis}.authority is invalid`);
|
|
13097
|
-
}
|
|
13098
|
-
if (typeof value.authority.kind !== "string" || !AUTHORITY_KINDS.has(value.authority.kind) || !SOURCE_AUTHORITIES[value.source.kind].has(
|
|
13099
|
-
value.authority.kind
|
|
13100
|
-
) || !isTrustStatusIdentifier(value.authority.id)) {
|
|
13101
|
-
throw new Error(`${axis}.authority is invalid`);
|
|
13102
|
-
}
|
|
13103
|
-
if (value.source.kind === "compatibility" && value.state !== "unknown" && value.state !== "not_applicable") {
|
|
13104
|
-
throw new Error(`${axis} compatibility source cannot establish ${value.state}`);
|
|
13105
|
-
}
|
|
13106
|
-
if (!Array.isArray(value.artifacts) || value.artifacts.length > TRUST_STATUS_MAX_ARTIFACT_REFERENCES) {
|
|
13107
|
-
throw new Error(`${axis}.artifacts exceeds the bounded reference list`);
|
|
13108
|
-
}
|
|
13109
|
-
const artifacts = value.artifacts.map(
|
|
13110
|
-
(entry, index) => normalizeArtifactReference(entry, `${axis}.artifacts[${index}]`)
|
|
13111
|
-
);
|
|
13112
|
-
artifacts.sort(compareArtifactReferences);
|
|
13113
|
-
for (let index = 1; index < artifacts.length; index += 1) {
|
|
13114
|
-
if (compareArtifactReferences(
|
|
13115
|
-
artifacts[index - 1],
|
|
13116
|
-
artifacts[index]
|
|
13117
|
-
) === 0) {
|
|
13118
|
-
throw new Error(`${axis}.artifacts contains a duplicate reference`);
|
|
13119
|
-
}
|
|
13120
|
-
}
|
|
13121
|
-
return {
|
|
13122
|
-
state: value.state,
|
|
13123
|
-
source: { kind: value.source.kind, id: value.source.id },
|
|
13124
|
-
authority: { kind: value.authority.kind, id: value.authority.id },
|
|
13125
|
-
artifacts
|
|
13126
|
-
};
|
|
13127
|
-
}
|
|
13128
|
-
function normalizeAxis(axis, value) {
|
|
13129
|
-
if (!isRecord10(value) || typeof value.state !== "string" || !AXIS_STATES[axis].has(value.state)) {
|
|
13130
|
-
throw new Error(`${axis}.state is invalid`);
|
|
13131
|
-
}
|
|
13132
|
-
if (value.state === "absent") {
|
|
13133
|
-
if (!hasExactKeys(value, ["state", "reason"]) || typeof value.reason !== "string" || !ABSENCE_REASONS.has(value.reason)) {
|
|
13134
|
-
throw new Error(`${axis} absent state is invalid`);
|
|
13135
|
-
}
|
|
13136
|
-
return { state: "absent", reason: value.reason };
|
|
13137
|
-
}
|
|
13138
|
-
return normalizeAttributedStatus(axis, value);
|
|
13139
|
-
}
|
|
13140
|
-
function normalizeTrustStatus(value) {
|
|
13141
|
-
if (!isRecord10(value) || !hasExactKeys(value, ["version", ...TRUST_STATUS_AXES])) {
|
|
13142
|
-
throw new Error("trust status has unknown or missing fields");
|
|
13143
|
-
}
|
|
13144
|
-
if (value.version !== TRUST_STATUS_VERSION) throw new Error("trust status version is invalid");
|
|
13145
|
-
return {
|
|
13146
|
-
version: TRUST_STATUS_VERSION,
|
|
13147
|
-
artifactIntegrity: normalizeAxis("artifactIntegrity", value.artifactIntegrity),
|
|
13148
|
-
validationGrounding: normalizeAxis("validationGrounding", value.validationGrounding),
|
|
13149
|
-
independentReview: normalizeAxis("independentReview", value.independentReview),
|
|
13150
|
-
contextProvenance: normalizeAxis("contextProvenance", value.contextProvenance),
|
|
13151
|
-
autonomyEnforcement: normalizeAxis("autonomyEnforcement", value.autonomyEnforcement),
|
|
13152
|
-
completionEvidence: normalizeAxis("completionEvidence", value.completionEvidence)
|
|
13153
|
-
};
|
|
13154
|
-
}
|
|
13155
|
-
function absentTrustStatus(reason) {
|
|
13156
|
-
return { state: "absent", reason };
|
|
13157
|
-
}
|
|
13158
|
-
function composeTrustStatus(...projections) {
|
|
13159
|
-
const axes = {
|
|
13160
|
-
artifactIntegrity: absentTrustStatus("not_recorded"),
|
|
13161
|
-
validationGrounding: absentTrustStatus("not_recorded"),
|
|
13162
|
-
independentReview: absentTrustStatus("not_recorded"),
|
|
13163
|
-
contextProvenance: absentTrustStatus("not_recorded"),
|
|
13164
|
-
autonomyEnforcement: absentTrustStatus("not_recorded"),
|
|
13165
|
-
completionEvidence: absentTrustStatus("not_recorded")
|
|
13166
|
-
};
|
|
13167
|
-
for (const projection of projections) {
|
|
13168
|
-
if (projection.artifactIntegrity !== void 0) axes.artifactIntegrity = projection.artifactIntegrity;
|
|
13169
|
-
if (projection.validationGrounding !== void 0) axes.validationGrounding = projection.validationGrounding;
|
|
13170
|
-
if (projection.independentReview !== void 0) axes.independentReview = projection.independentReview;
|
|
13171
|
-
if (projection.contextProvenance !== void 0) axes.contextProvenance = projection.contextProvenance;
|
|
13172
|
-
if (projection.autonomyEnforcement !== void 0) axes.autonomyEnforcement = projection.autonomyEnforcement;
|
|
13173
|
-
if (projection.completionEvidence !== void 0) axes.completionEvidence = projection.completionEvidence;
|
|
13174
|
-
}
|
|
13175
|
-
return normalizeTrustStatus({ version: TRUST_STATUS_VERSION, ...axes });
|
|
13176
|
-
}
|
|
13177
|
-
function sha256Reference(kind, id, digest) {
|
|
13178
|
-
const reference = { kind, id };
|
|
13179
|
-
if (digest !== void 0 && /^[a-f0-9]{64}$/u.test(digest)) {
|
|
13180
|
-
reference.digest = { algorithm: "sha256", value: digest };
|
|
13181
|
-
}
|
|
13182
|
-
return reference;
|
|
13183
|
-
}
|
|
13184
|
-
function receiptReference(receipt) {
|
|
13185
|
-
return sha256Reference("run_receipt", receipt.runId, receipt.integrity?.digest);
|
|
13186
|
-
}
|
|
13187
|
-
function attributed(state, source, authority, artifacts) {
|
|
13188
|
-
return { state, source, authority, artifacts: [...artifacts].sort(compareArtifactReferences) };
|
|
13189
|
-
}
|
|
13190
|
-
function receiptSource(receipt) {
|
|
13191
|
-
return { kind: "run_receipt", id: receipt.runId };
|
|
13192
|
-
}
|
|
13193
|
-
function compatibilitySource(receipt, field) {
|
|
13194
|
-
return { kind: "compatibility", id: `run_receipt:${receipt.runId}:${field}` };
|
|
13195
|
-
}
|
|
13196
|
-
var DISPATCH_AUTHORITY = { kind: "clio", id: "dispatch" };
|
|
13197
|
-
var COMPATIBILITY_AUTHORITY = { kind: "unknown", id: "historical-persisted-format" };
|
|
13198
|
-
function adaptReceiptIntegrityStatus(receipt, verification) {
|
|
13199
|
-
if (receipt === null || receipt === void 0) return absentTrustStatus("artifact_missing");
|
|
13200
|
-
const artifacts = [receiptReference(receipt)];
|
|
13201
|
-
if (verification === void 0 || verification.ok && receipt.integrity === void 0) {
|
|
13202
|
-
return attributed(
|
|
13203
|
-
"unknown",
|
|
13204
|
-
{
|
|
13205
|
-
kind: "compatibility",
|
|
13206
|
-
id: `run_receipt:${receipt.runId}:${receipt.integrity === void 0 ? "integrity-missing" : "integrity-unchecked"}`
|
|
13207
|
-
},
|
|
13208
|
-
COMPATIBILITY_AUTHORITY,
|
|
13209
|
-
artifacts
|
|
13210
|
-
);
|
|
13211
|
-
}
|
|
13212
|
-
return attributed(
|
|
13213
|
-
verification.ok ? "verified" : "failed",
|
|
13214
|
-
{ kind: "receipt_integrity_verification", id: receipt.runId },
|
|
13215
|
-
{ kind: "clio", id: "receipt-integrity" },
|
|
13216
|
-
artifacts
|
|
13217
|
-
);
|
|
13218
|
-
}
|
|
13219
|
-
function validationArtifacts(receipt) {
|
|
13220
|
-
const artifacts = [receiptReference(receipt)];
|
|
13221
|
-
for (const fact of receipt.quality?.typedValidations ?? []) {
|
|
13222
|
-
artifacts.push(sha256Reference("validation_result", fact.sourceId, fact.validatorDigest));
|
|
13223
|
-
}
|
|
13224
|
-
const resultContract = receipt.quality?.resultContract;
|
|
13225
|
-
if (resultContract !== null && resultContract !== void 0) {
|
|
13226
|
-
artifacts.push(sha256Reference("validation_result", resultContract.sourceId, resultContract.validatorDigest));
|
|
13227
|
-
}
|
|
13228
|
-
return uniqueBoundedReferences(artifacts);
|
|
13229
|
-
}
|
|
13230
|
-
function qualityHasFailure(quality) {
|
|
13231
|
-
if (quality === void 0) return false;
|
|
13232
|
-
if (quality.typedValidations.some((fact) => !fact.passed)) return true;
|
|
13233
|
-
return quality.resultContract?.conformance === "fail" || quality.resultContract?.quality === "fail";
|
|
13234
|
-
}
|
|
13235
|
-
function qualityHasValidation(quality) {
|
|
13236
|
-
if (quality === void 0) return false;
|
|
13237
|
-
if (quality.typedValidations.some((fact) => fact.passed)) return true;
|
|
13238
|
-
return quality.resultContract?.quality === "pass";
|
|
13239
|
-
}
|
|
13240
|
-
function verificationStatus(verification, receipt, artifacts) {
|
|
13241
|
-
if (verification.state === "verified") {
|
|
13242
|
-
return attributed("validated", receiptSource(receipt), { kind: "validator", id: verification.basis }, artifacts);
|
|
13243
|
-
}
|
|
13244
|
-
if (verification.state === "unverified") return absentTrustStatus("not_observed");
|
|
13245
|
-
if (verification.state === "not_applicable") {
|
|
13246
|
-
return attributed("not_applicable", receiptSource(receipt), DISPATCH_AUTHORITY, artifacts);
|
|
13247
|
-
}
|
|
13248
|
-
return attributed(
|
|
13249
|
-
"unknown",
|
|
13250
|
-
receiptSource(receipt),
|
|
13251
|
-
verification.basis === "acp-external-unobserved" ? { kind: "external_system", id: "acp-delegation" } : COMPATIBILITY_AUTHORITY,
|
|
13252
|
-
artifacts
|
|
13253
|
-
);
|
|
13254
|
-
}
|
|
13255
|
-
function adaptRunReceiptValidationStatus(receipt) {
|
|
13256
|
-
if (receipt === null || receipt === void 0) return absentTrustStatus("artifact_missing");
|
|
13257
|
-
const artifacts = validationArtifacts(receipt);
|
|
13258
|
-
if (receipt.hostVerification?.status === "rejected") {
|
|
13259
|
-
return attributed("failed", receiptSource(receipt), { kind: "validator", id: "host-verification" }, artifacts);
|
|
13260
|
-
}
|
|
13261
|
-
if (receipt.hostVerification?.status === "verified") {
|
|
13262
|
-
return attributed("validated", receiptSource(receipt), { kind: "validator", id: "host-verification" }, artifacts);
|
|
13263
|
-
}
|
|
13264
|
-
if (qualityHasFailure(receipt.quality)) {
|
|
13265
|
-
return attributed("failed", receiptSource(receipt), { kind: "validator", id: "receipt-quality" }, artifacts);
|
|
13266
|
-
}
|
|
13267
|
-
if ((receipt.validationGrounding?.ungrounded.length ?? 0) > 0 || receipt.validationGrounding !== void 0 && receipt.validationGrounding.claimed > receipt.validationGrounding.grounded) {
|
|
13268
|
-
return attributed("ungrounded", receiptSource(receipt), { kind: "validator", id: "command-grounding" }, artifacts);
|
|
13269
|
-
}
|
|
13270
|
-
if (qualityHasValidation(receipt.quality)) {
|
|
13271
|
-
return attributed("validated", receiptSource(receipt), { kind: "validator", id: "receipt-quality" }, artifacts);
|
|
13272
|
-
}
|
|
13273
|
-
if (receipt.verification !== void 0) {
|
|
13274
|
-
return verificationStatus(receipt.verification, receipt, artifacts);
|
|
13275
|
-
}
|
|
13276
|
-
return attributed("unknown", compatibilitySource(receipt, "verification"), COMPATIBILITY_AUTHORITY, artifacts);
|
|
13277
|
-
}
|
|
13278
|
-
function validBriefing(briefing) {
|
|
13279
|
-
return Number.isSafeInteger(briefing.bytes) && briefing.bytes >= 0 && /^[a-f0-9]{64}$/u.test(briefing.contentHash);
|
|
13280
|
-
}
|
|
13281
|
-
function validBoundedProjectContext(context) {
|
|
13282
|
-
return context.tier === "bounded" && Number.isSafeInteger(context.chars) && (context.chars ?? -1) >= 0 && typeof context.contentHash === "string" && /^[a-f0-9]{64}$/u.test(context.contentHash);
|
|
13283
|
-
}
|
|
13284
|
-
function contextArtifacts(receipt) {
|
|
13285
|
-
const artifacts = [receiptReference(receipt)];
|
|
13286
|
-
if (receipt.briefing !== void 0 && validBriefing(receipt.briefing)) {
|
|
13287
|
-
artifacts.push(sha256Reference("briefing", `${receipt.runId}:briefing`, receipt.briefing.contentHash));
|
|
13288
|
-
}
|
|
13289
|
-
if (receipt.projectContext?.tier === "bounded" && validBoundedProjectContext(receipt.projectContext)) {
|
|
13290
|
-
artifacts.push(
|
|
13291
|
-
sha256Reference("project_context", `${receipt.runId}:project-context`, receipt.projectContext.contentHash)
|
|
13292
|
-
);
|
|
13293
|
-
}
|
|
13294
|
-
return uniqueBoundedReferences(artifacts);
|
|
13295
|
-
}
|
|
13296
|
-
function adaptRunReceiptContextStatus(receipt) {
|
|
13297
|
-
if (receipt === null || receipt === void 0) return absentTrustStatus("artifact_missing");
|
|
13298
|
-
const artifacts = contextArtifacts(receipt);
|
|
13299
|
-
const source = receiptSource(receipt);
|
|
13300
|
-
const briefingInvalid = receipt.briefing !== void 0 && !validBriefing(receipt.briefing);
|
|
13301
|
-
if (briefingInvalid) return attributed("invalid", source, DISPATCH_AUTHORITY, artifacts);
|
|
13302
|
-
const context = receipt.projectContext;
|
|
13303
|
-
if (context === void 0) {
|
|
13304
|
-
if (receipt.briefing !== void 0) return attributed("recorded", source, DISPATCH_AUTHORITY, artifacts);
|
|
13305
|
-
return attributed("unknown", compatibilitySource(receipt, "projectContext"), COMPATIBILITY_AUTHORITY, artifacts);
|
|
13306
|
-
}
|
|
13307
|
-
if (context.tier === "none") {
|
|
13308
|
-
if (context.chars !== void 0 || context.contentHash !== void 0 || context.sections !== void 0) {
|
|
13309
|
-
return attributed("invalid", source, DISPATCH_AUTHORITY, artifacts);
|
|
13310
|
-
}
|
|
13311
|
-
return receipt.briefing === void 0 ? attributed("not_applicable", source, DISPATCH_AUTHORITY, artifacts) : attributed("recorded", source, DISPATCH_AUTHORITY, artifacts);
|
|
13312
|
-
}
|
|
13313
|
-
return attributed(validBoundedProjectContext(context) ? "recorded" : "invalid", source, DISPATCH_AUTHORITY, artifacts);
|
|
13314
|
-
}
|
|
13315
|
-
function adaptRunReceiptAutonomyStatus(receipt) {
|
|
13316
|
-
if (receipt === null || receipt === void 0) return absentTrustStatus("artifact_missing");
|
|
13317
|
-
const enforcement = receipt.autonomyEnforcement;
|
|
13318
|
-
const artifacts = [receiptReference(receipt)];
|
|
13319
|
-
if (enforcement === void 0) {
|
|
13320
|
-
return attributed("unknown", compatibilitySource(receipt, "autonomyEnforcement"), COMPATIBILITY_AUTHORITY, artifacts);
|
|
13321
|
-
}
|
|
13322
|
-
artifacts.push({ kind: "autonomy_policy", id: `${receipt.runId}:${enforcement.autonomy}` });
|
|
13323
|
-
const authority = enforcement.grade === "mediated" ? { kind: "clio", id: "safety-autonomy" } : { kind: "runtime", id: enforcement.externalMode ?? "external-runtime" };
|
|
13324
|
-
const state = enforcement.dangerousBypass === true || enforcement.grade === "bypassed" ? "bypassed" : enforcement.grade === "approximated" ? "approximated" : "enforced";
|
|
13325
|
-
return attributed(state, receiptSource(receipt), authority, artifacts);
|
|
13326
|
-
}
|
|
13327
|
-
function receiptClaimsAreAuthenticated(receipt, integrity) {
|
|
13328
|
-
return receipt?.integrity !== void 0 && integrity?.ok === true;
|
|
13329
|
-
}
|
|
13330
|
-
function unauthenticatedReceiptProjection(receipt) {
|
|
13331
|
-
if (receipt === null || receipt === void 0) {
|
|
13332
|
-
return {
|
|
13333
|
-
validationGrounding: absentTrustStatus("artifact_missing"),
|
|
13334
|
-
contextProvenance: absentTrustStatus("artifact_missing"),
|
|
13335
|
-
autonomyEnforcement: absentTrustStatus("artifact_missing")
|
|
13336
|
-
};
|
|
13337
|
-
}
|
|
13338
|
-
if (receipt.integrity === void 0) {
|
|
13339
|
-
const artifacts = [receiptReference(receipt)];
|
|
13340
|
-
return {
|
|
13341
|
-
validationGrounding: attributed(
|
|
13342
|
-
"unknown",
|
|
13343
|
-
compatibilitySource(receipt, "canonical-projection"),
|
|
13344
|
-
COMPATIBILITY_AUTHORITY,
|
|
13345
|
-
artifacts
|
|
13346
|
-
),
|
|
13347
|
-
contextProvenance: attributed(
|
|
13348
|
-
"unknown",
|
|
13349
|
-
compatibilitySource(receipt, "canonical-projection"),
|
|
13350
|
-
COMPATIBILITY_AUTHORITY,
|
|
13351
|
-
artifacts
|
|
13352
|
-
),
|
|
13353
|
-
autonomyEnforcement: attributed(
|
|
13354
|
-
"unknown",
|
|
13355
|
-
compatibilitySource(receipt, "canonical-projection"),
|
|
13356
|
-
COMPATIBILITY_AUTHORITY,
|
|
13357
|
-
artifacts
|
|
13358
|
-
)
|
|
13359
|
-
};
|
|
13360
|
-
}
|
|
13361
|
-
return {
|
|
13362
|
-
validationGrounding: absentTrustStatus("not_observed"),
|
|
13363
|
-
contextProvenance: absentTrustStatus("not_observed"),
|
|
13364
|
-
autonomyEnforcement: absentTrustStatus("not_observed")
|
|
13365
|
-
};
|
|
13366
|
-
}
|
|
13367
|
-
function adaptRunReceiptTrustStatus(receipt, options = {}) {
|
|
13368
|
-
const authenticated2 = receiptClaimsAreAuthenticated(receipt, options.integrity);
|
|
13369
|
-
const receiptProjection = authenticated2 ? {
|
|
13370
|
-
validationGrounding: adaptRunReceiptValidationStatus(receipt),
|
|
13371
|
-
contextProvenance: adaptRunReceiptContextStatus(receipt),
|
|
13372
|
-
autonomyEnforcement: adaptRunReceiptAutonomyStatus(receipt)
|
|
13373
|
-
} : unauthenticatedReceiptProjection(receipt);
|
|
13374
|
-
return composeTrustStatus({
|
|
13375
|
-
artifactIntegrity: adaptReceiptIntegrityStatus(receipt, options.integrity),
|
|
13376
|
-
...receiptProjection,
|
|
13377
|
-
independentReview: absentTrustStatus(receipt === null || receipt === void 0 ? "artifact_missing" : "not_recorded"),
|
|
13378
|
-
completionEvidence: absentTrustStatus(
|
|
13379
|
-
receipt === null || receipt === void 0 ? "artifact_missing" : "not_recorded"
|
|
13380
|
-
)
|
|
13381
|
-
});
|
|
13382
|
-
}
|
|
13383
|
-
function inspectRunReceiptTrustStatus(receipt, envelope) {
|
|
13384
|
-
let integrity;
|
|
13385
|
-
if (receipt === null || receipt === void 0) {
|
|
13386
|
-
integrity = { ok: false, reason: "receipt unavailable" };
|
|
13387
|
-
} else if (envelope === null || envelope === void 0) {
|
|
13388
|
-
integrity = { ok: false, reason: "run ledger envelope unavailable" };
|
|
13389
|
-
} else {
|
|
13390
|
-
try {
|
|
13391
|
-
integrity = verifyReceiptIntegrity(receipt, envelope);
|
|
13392
|
-
} catch (error) {
|
|
13393
|
-
integrity = {
|
|
13394
|
-
ok: false,
|
|
13395
|
-
reason: `receipt invalid: ${error instanceof Error ? error.message : String(error)}`
|
|
13396
|
-
};
|
|
13397
|
-
}
|
|
13398
|
-
}
|
|
13399
|
-
return {
|
|
13400
|
-
integrity,
|
|
13401
|
-
status: adaptRunReceiptTrustStatus(receipt, { integrity })
|
|
13402
|
-
};
|
|
13403
|
-
}
|
|
13404
|
-
function gateReference(artifact) {
|
|
13405
|
-
return sha256Reference("gate_decision", artifact.id, artifact.integrity.digest);
|
|
13406
|
-
}
|
|
13407
|
-
function gateAuthority(artifact) {
|
|
13408
|
-
if (artifact.outcome === "operator-confirmed") return { kind: "operator", id: "gate-confirmation" };
|
|
13409
|
-
if (artifact.outcome === "full-auto-applied") return { kind: "clio", id: "full-auto-gate-policy" };
|
|
13410
|
-
return { kind: "reviewer", id: artifact.decider?.runId ?? "unavailable-decider" };
|
|
13411
|
-
}
|
|
13412
|
-
function adaptGateDecisionReviewStatus(artifact, subjectRunId, verification) {
|
|
13413
|
-
if (artifact === null || artifact === void 0) return absentTrustStatus("artifact_missing");
|
|
13414
|
-
const source = { kind: "gate_decision", id: artifact.id };
|
|
13415
|
-
const artifacts = [gateReference(artifact)];
|
|
13416
|
-
const authority = gateAuthority(artifact);
|
|
13417
|
-
if (!artifact.subjects.some((subject) => subject.runId === subjectRunId)) return absentTrustStatus("not_recorded");
|
|
13418
|
-
if (verification === void 0 || !verification.ok) {
|
|
13419
|
-
return attributed(
|
|
13420
|
-
"unknown",
|
|
13421
|
-
source,
|
|
13422
|
-
verification === void 0 ? COMPATIBILITY_AUTHORITY : { kind: "unknown", id: "unauthenticated-gate-artifact" },
|
|
13423
|
-
artifacts
|
|
13424
|
-
);
|
|
13425
|
-
}
|
|
13426
|
-
if (artifact.decider === void 0 || artifact.correlation === void 0) {
|
|
13427
|
-
if (artifact.outcome === "operator-confirmed" || artifact.outcome === "full-auto-applied") {
|
|
13428
|
-
return attributed("not_applicable", source, authority, artifacts);
|
|
13429
|
-
}
|
|
13430
|
-
return attributed("inconclusive", source, authority, artifacts);
|
|
13431
|
-
}
|
|
13432
|
-
if (!artifact.correlation.independent) return attributed("not_independent", source, authority, artifacts);
|
|
13433
|
-
if (artifact.outcome === "pass") return attributed("passed", source, authority, artifacts);
|
|
13434
|
-
if (artifact.outcome === "fail") return attributed("failed", source, authority, artifacts);
|
|
13435
|
-
if (artifact.outcome === "winner") {
|
|
13436
|
-
return attributed(
|
|
13437
|
-
artifact.winner?.subject.runId === subjectRunId ? "passed" : "failed",
|
|
13438
|
-
source,
|
|
13439
|
-
authority,
|
|
13440
|
-
artifacts
|
|
13441
|
-
);
|
|
13442
|
-
}
|
|
13443
|
-
return attributed("inconclusive", source, authority, artifacts);
|
|
13444
|
-
}
|
|
13445
|
-
function adaptGroundedEvidenceValidationStatus(input) {
|
|
13446
|
-
const observed = (input.artifacts ?? []).filter((artifact) => !SELF_REPORTED_ARTIFACT_KINDS.has(artifact.kind));
|
|
13447
|
-
if (observed.length === 0) return absentTrustStatus("not_observed");
|
|
13448
|
-
return attributed(
|
|
13449
|
-
"validated",
|
|
13450
|
-
{ kind: "evidence_bundle", id: `${input.evidenceId}:${input.runId}` },
|
|
13451
|
-
{ kind: "clio", id: "evidence-grounding" },
|
|
13452
|
-
uniqueBoundedReferences([{ kind: "evidence_bundle", id: input.evidenceId }, ...observed])
|
|
13453
|
-
);
|
|
13454
|
-
}
|
|
13455
|
-
function adaptFinishContractCompletionStatus(assessment, options = {}) {
|
|
13456
|
-
const artifacts = uniqueBoundedReferences(
|
|
13457
|
-
options.artifacts ?? assessment.evidence.map((evidence, index) => ({
|
|
13458
|
-
kind: evidence.turnId === void 0 ? "finish_contract_evidence" : "session_entry",
|
|
13459
|
-
id: evidence.turnId ?? `${evidence.kind}:${index + 1}`
|
|
13460
|
-
}))
|
|
13461
|
-
);
|
|
13462
|
-
const source = { kind: "finish_contract", id: options.sourceId ?? assessment.reason };
|
|
13463
|
-
const authority = { kind: "clio", id: "finish-contract" };
|
|
13464
|
-
if (assessment.reason === "no_mutation") return attributed("not_applicable", source, authority, artifacts);
|
|
13465
|
-
if (assessment.reason === "validation_evidence") return attributed("evidenced", source, authority, artifacts);
|
|
13466
|
-
if (assessment.reason === "explicit_limitation") return attributed("limited", source, authority, artifacts);
|
|
13467
|
-
return attributed("incomplete", source, authority, artifacts);
|
|
13468
|
-
}
|
|
13469
|
-
function uniqueBoundedReferences(references) {
|
|
13470
|
-
const sorted = [...references].sort(compareArtifactReferences);
|
|
13471
|
-
const unique = sorted.filter(
|
|
13472
|
-
(reference, index) => index === 0 || compareArtifactReferences(sorted[index - 1], reference) !== 0
|
|
13473
|
-
);
|
|
13474
|
-
return unique.slice(0, TRUST_STATUS_MAX_ARTIFACT_REFERENCES);
|
|
13475
|
-
}
|
|
13476
|
-
|
|
13477
13420
|
// src/domains/evidence/types.ts
|
|
13478
13421
|
init_esm_shims();
|
|
13479
13422
|
var EVIDENCE_VERSION = 1;
|
|
@@ -13499,7 +13442,6 @@ function buildEvidenceTrustStatusFile(input) {
|
|
|
13499
13442
|
evidenceId: input.evidenceId,
|
|
13500
13443
|
source,
|
|
13501
13444
|
gateDecisions: input.gateDecisions,
|
|
13502
|
-
auditRows: input.auditRows,
|
|
13503
13445
|
validationEvidence: input.validationEvidence?.get(source.envelope.id) ?? []
|
|
13504
13446
|
})
|
|
13505
13447
|
}))
|
|
@@ -13507,7 +13449,6 @@ function buildEvidenceTrustStatusFile(input) {
|
|
|
13507
13449
|
}
|
|
13508
13450
|
function composeEvidenceRunTrustStatus(input) {
|
|
13509
13451
|
const inspection = inspectRunReceiptTrustStatus(input.source.receipt, input.source.envelope);
|
|
13510
|
-
const receiptRejected = inspection.status.artifactIntegrity.state === "failed";
|
|
13511
13452
|
let status = inspection.status;
|
|
13512
13453
|
const grounded = input.validationEvidence.filter((artifact) => isTrustStatusIdentifier(artifact.id));
|
|
13513
13454
|
if (grounded.length > 0 && (status.validationGrounding.state === "absent" || status.validationGrounding.state === "unknown")) {
|
|
@@ -13532,21 +13473,6 @@ function composeEvidenceRunTrustStatus(input) {
|
|
|
13532
13473
|
independentReview: adaptGateDecisionReviewStatus(gate, input.source.envelope.id, verification)
|
|
13533
13474
|
});
|
|
13534
13475
|
}
|
|
13535
|
-
const finish = latestFinishContractForRun(input.auditRows, input.source.envelope.id);
|
|
13536
|
-
if (finish !== null) {
|
|
13537
|
-
const completion = adaptFinishContractCompletionStatus(finish.assessment, {
|
|
13538
|
-
sourceId: finish.sourceId,
|
|
13539
|
-
artifacts: finish.artifacts
|
|
13540
|
-
});
|
|
13541
|
-
status = composeTrustStatus(status, {
|
|
13542
|
-
completionEvidence: receiptRejected && completion.state === "evidenced" ? {
|
|
13543
|
-
state: "unknown",
|
|
13544
|
-
source: { kind: "finish_contract", id: finish.sourceId },
|
|
13545
|
-
authority: { kind: "clio", id: "finish-contract" },
|
|
13546
|
-
artifacts: finish.artifacts
|
|
13547
|
-
} : completion
|
|
13548
|
-
});
|
|
13549
|
-
}
|
|
13550
13476
|
return status;
|
|
13551
13477
|
}
|
|
13552
13478
|
function latestGateDecisionForRun(decisions, runId) {
|
|
@@ -13554,55 +13480,6 @@ function latestGateDecisionForRun(decisions, runId) {
|
|
|
13554
13480
|
(left, right) => compareCodepoints(left.createdAt, right.createdAt) || left.cycle - right.cycle || compareCodepoints(left.id, right.id)
|
|
13555
13481
|
).at(-1) ?? null;
|
|
13556
13482
|
}
|
|
13557
|
-
function latestFinishContractForRun(rows, runId) {
|
|
13558
|
-
const candidates = rows.filter((row) => row.auditKind === "completion_contract" && row.runId === runId && row.confidence === "exact").flatMap((row) => {
|
|
13559
|
-
const assessment = finishContractAssessmentFromAudit(row.row);
|
|
13560
|
-
if (assessment === null) return [];
|
|
13561
|
-
const correlationId = readOptionalString(row.row.correlationId) ?? `${runId}:completion-contract`;
|
|
13562
|
-
if (!isTrustStatusIdentifier(correlationId)) return [];
|
|
13563
|
-
const turnId = readOptionalString(row.row.turnId);
|
|
13564
|
-
const artifacts = [
|
|
13565
|
-
{ kind: "finish_contract_evidence", id: correlationId },
|
|
13566
|
-
...turnId === null || !isTrustStatusIdentifier(turnId) ? [] : [{ kind: "session_entry", id: turnId }]
|
|
13567
|
-
];
|
|
13568
|
-
return [{ sourceId: correlationId, assessment, artifacts, timestamp: row.ts ?? "" }];
|
|
13569
|
-
}).sort(
|
|
13570
|
-
(left, right) => compareCodepoints(left.timestamp, right.timestamp) || compareCodepoints(left.sourceId, right.sourceId)
|
|
13571
|
-
);
|
|
13572
|
-
const latest2 = candidates.at(-1);
|
|
13573
|
-
return latest2 === void 0 ? null : { sourceId: latest2.sourceId, assessment: latest2.assessment, artifacts: latest2.artifacts };
|
|
13574
|
-
}
|
|
13575
|
-
function finishContractAssessmentFromAudit(row) {
|
|
13576
|
-
const reason = readOptionalString(row.reason);
|
|
13577
|
-
const decision = readOptionalString(row.decision);
|
|
13578
|
-
const mutatedPaths = Array.isArray(row.mutatedPaths) ? row.mutatedPaths.filter((entry) => typeof entry === "string") : [];
|
|
13579
|
-
const turnId = readOptionalString(row.turnId);
|
|
13580
|
-
const evidenceKinds = Array.isArray(row.evidenceKinds) ? row.evidenceKinds.filter(isFinishContractEvidenceKind) : [];
|
|
13581
|
-
const evidence = evidenceKinds.map((kind) => ({
|
|
13582
|
-
kind,
|
|
13583
|
-
summary: "recorded by the finish contract",
|
|
13584
|
-
...turnId === null ? {} : { turnId }
|
|
13585
|
-
}));
|
|
13586
|
-
if (decision === "ok" && reason === "no_mutation") {
|
|
13587
|
-
return { kind: "ok", reason, evidence: [], mutatedPaths };
|
|
13588
|
-
}
|
|
13589
|
-
if (decision === "ok" && reason === "validation_evidence") {
|
|
13590
|
-
return { kind: "ok", reason, evidence, mutatedPaths };
|
|
13591
|
-
}
|
|
13592
|
-
if (decision === "ok" && reason === "explicit_limitation") {
|
|
13593
|
-
return { kind: "ok", reason, evidence: [], mutatedPaths };
|
|
13594
|
-
}
|
|
13595
|
-
if (decision === "engage" && reason === "unvalidated_mutation") {
|
|
13596
|
-
return { kind: "engage", reason, message: "finish contract engaged", evidence: [], mutatedPaths };
|
|
13597
|
-
}
|
|
13598
|
-
return null;
|
|
13599
|
-
}
|
|
13600
|
-
function isFinishContractEvidenceKind(value) {
|
|
13601
|
-
return value === "validation_command" || value === "protected_artifact" || value === "dispatch_receipt";
|
|
13602
|
-
}
|
|
13603
|
-
function readOptionalString(value) {
|
|
13604
|
-
return typeof value === "string" && value.trim().length > 0 ? value : null;
|
|
13605
|
-
}
|
|
13606
13483
|
|
|
13607
13484
|
// src/domains/evidence/store.ts
|
|
13608
13485
|
init_esm_shims();
|
|
@@ -13676,7 +13553,7 @@ async function loadEvidenceTrustStatus(dataDir, evidenceId) {
|
|
|
13676
13553
|
}
|
|
13677
13554
|
const source = `${evidenceId}/trust-status.json`;
|
|
13678
13555
|
const parsed = parseJson(raw, source);
|
|
13679
|
-
if (!
|
|
13556
|
+
if (!isRecord10(parsed)) throw new Error(`${source}: expected object`);
|
|
13680
13557
|
if (parsed.version !== 1) throw new Error(`${source}: expected version 1`);
|
|
13681
13558
|
if (readString(parsed, source, "evidenceId") !== evidenceId) {
|
|
13682
13559
|
throw new Error(`${source}.evidenceId: expected ${evidenceId}`);
|
|
@@ -13689,7 +13566,7 @@ async function loadEvidenceTrustStatus(dataDir, evidenceId) {
|
|
|
13689
13566
|
projection: "canonical",
|
|
13690
13567
|
runs: parsed.runs.map((entry, index) => {
|
|
13691
13568
|
const entrySource = `${source}.runs[${index}]`;
|
|
13692
|
-
if (!
|
|
13569
|
+
if (!isRecord10(entry)) throw new Error(`${entrySource}: expected object`);
|
|
13693
13570
|
return {
|
|
13694
13571
|
runId: readString(entry, entrySource, "runId"),
|
|
13695
13572
|
status: normalizeTrustStatus(entry.status)
|
|
@@ -13707,10 +13584,10 @@ async function loadEvidenceRunProvenance(dataDir, evidenceId) {
|
|
|
13707
13584
|
throw error;
|
|
13708
13585
|
}
|
|
13709
13586
|
const parsed = parseJson(raw, `${evidenceId}/receipt.json`);
|
|
13710
|
-
if (!
|
|
13587
|
+
if (!isRecord10(parsed) || !Array.isArray(parsed.receipts)) return [];
|
|
13711
13588
|
const out = [];
|
|
13712
13589
|
for (const entry of parsed.receipts) {
|
|
13713
|
-
if (!
|
|
13590
|
+
if (!isRecord10(entry) || typeof entry.runId !== "string") continue;
|
|
13714
13591
|
const view = runProvenanceFromUnknown(entry);
|
|
13715
13592
|
if (hasRunProvenance(view)) out.push({ runId: entry.runId, view });
|
|
13716
13593
|
}
|
|
@@ -13735,7 +13612,7 @@ async function listEvidenceOverviews(dataDir) {
|
|
|
13735
13612
|
return overviews;
|
|
13736
13613
|
}
|
|
13737
13614
|
function parseOverview(value, source) {
|
|
13738
|
-
if (!
|
|
13615
|
+
if (!isRecord10(value)) throw new Error(`${source}: expected object`);
|
|
13739
13616
|
if (value.version !== 1) throw new Error(`${source}: expected version 1`);
|
|
13740
13617
|
const evidenceId = readString(value, source, "evidenceId");
|
|
13741
13618
|
const sourceValue = readSource(value.source, `${source}.source`);
|
|
@@ -13776,13 +13653,13 @@ function parseOverview(value, source) {
|
|
|
13776
13653
|
};
|
|
13777
13654
|
}
|
|
13778
13655
|
function parseFindingsFile(value, source) {
|
|
13779
|
-
if (!
|
|
13656
|
+
if (!isRecord10(value)) throw new Error(`${source}: expected object`);
|
|
13780
13657
|
if (value.version !== 1) throw new Error(`${source}: expected version 1`);
|
|
13781
13658
|
if (!Array.isArray(value.findings)) throw new Error(`${source}.findings: expected array`);
|
|
13782
13659
|
return value.findings.map((entry, index) => parseFinding(entry, `${source}.findings[${index}]`));
|
|
13783
13660
|
}
|
|
13784
13661
|
function parseFinding(value, source) {
|
|
13785
|
-
if (!
|
|
13662
|
+
if (!isRecord10(value)) throw new Error(`${source}: expected object`);
|
|
13786
13663
|
const severity = readString(value, source, "severity");
|
|
13787
13664
|
if (severity !== "info" && severity !== "warn") throw new Error(`${source}.severity: expected info or warn`);
|
|
13788
13665
|
const tag = readString(value, source, "tag");
|
|
@@ -13795,14 +13672,14 @@ function parseFinding(value, source) {
|
|
|
13795
13672
|
};
|
|
13796
13673
|
}
|
|
13797
13674
|
function readSource(value, source) {
|
|
13798
|
-
if (!
|
|
13675
|
+
if (!isRecord10(value)) throw new Error(`${source}: expected object`);
|
|
13799
13676
|
if (value.kind === "run") return { kind: "run", runId: readString(value, source, "runId") };
|
|
13800
13677
|
if (value.kind === "session") return { kind: "session", sessionId: readString(value, source, "sessionId") };
|
|
13801
13678
|
if (value.kind === "eval") return { kind: "eval", evalId: readString(value, source, "evalId") };
|
|
13802
13679
|
throw new Error(`${source}.kind: expected run, session, or eval`);
|
|
13803
13680
|
}
|
|
13804
13681
|
function readTotals(value, source) {
|
|
13805
|
-
if (!
|
|
13682
|
+
if (!isRecord10(value)) throw new Error(`${source}: expected object`);
|
|
13806
13683
|
return {
|
|
13807
13684
|
runs: readNumber(value, source, "runs"),
|
|
13808
13685
|
receipts: readNumber(value, source, "receipts"),
|
|
@@ -13860,7 +13737,7 @@ function parseJson(raw, source) {
|
|
|
13860
13737
|
throw new Error(`${source}: invalid JSON: ${message}`);
|
|
13861
13738
|
}
|
|
13862
13739
|
}
|
|
13863
|
-
function
|
|
13740
|
+
function isRecord10(value) {
|
|
13864
13741
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
13865
13742
|
}
|
|
13866
13743
|
function findingsFile(evidenceId, findings) {
|
|
@@ -13915,7 +13792,6 @@ async function buildEvidence(options) {
|
|
|
13915
13792
|
evidenceId,
|
|
13916
13793
|
runSources,
|
|
13917
13794
|
gateDecisions: gateDecisions.decisions,
|
|
13918
|
-
auditRows: auditLinks.rows,
|
|
13919
13795
|
validationEvidence
|
|
13920
13796
|
});
|
|
13921
13797
|
const findings = buildFindings(runSources, trustStatusRaw, sessionLinks, auditLinks, protectedArtifactsRaw);
|
|
@@ -13946,7 +13822,10 @@ async function buildEvidence(options) {
|
|
|
13946
13822
|
redactedToolEvents,
|
|
13947
13823
|
protectedArtifacts
|
|
13948
13824
|
);
|
|
13949
|
-
const transcript = redactSecretsText(
|
|
13825
|
+
const transcript = redactSecretsText(
|
|
13826
|
+
renderTranscript(overview, redactedRunSources, sessionLinks, trustStatusRaw),
|
|
13827
|
+
tally
|
|
13828
|
+
);
|
|
13950
13829
|
const finalOverview = { ...overview, redactionCount: tally.count };
|
|
13951
13830
|
await writeEvidenceFiles(
|
|
13952
13831
|
directory,
|
|
@@ -14019,8 +13898,9 @@ function buildFindings(runSources, trustStatus, sessionLinks, auditLinks, protec
|
|
|
14019
13898
|
const status = trustByRun.get(source.envelope.id);
|
|
14020
13899
|
if (status === void 0) throw new Error(`canonical trust status missing for run ${source.envelope.id}`);
|
|
14021
13900
|
if (source.receiptError !== null) {
|
|
14022
|
-
const
|
|
14023
|
-
|
|
13901
|
+
const retired = retiredIntegrityVersionOf(status.artifactIntegrity) !== null;
|
|
13902
|
+
const tag = retired ? "receipt-retired" : source.receiptIntegrityFailed ? "receipt-integrity" : "unknown";
|
|
13903
|
+
findings.push(finding(findings.length, retired ? "info" : "warn", tag, source.envelope.id, source.receiptError));
|
|
14024
13904
|
}
|
|
14025
13905
|
if (isSuccessfulRun(source) && (status.validationGrounding.state === "absent" || status.validationGrounding.state === "unknown")) {
|
|
14026
13906
|
findings.push(
|
|
@@ -14081,6 +13961,7 @@ function buildFindings(runSources, trustStatus, sessionLinks, auditLinks, protec
|
|
|
14081
13961
|
)
|
|
14082
13962
|
);
|
|
14083
13963
|
}
|
|
13964
|
+
findings.push(...axisFindings(findings.length, source, status));
|
|
14084
13965
|
if (source.envelope.status === "stale" || source.envelope.status === "dead") {
|
|
14085
13966
|
findings.push(
|
|
14086
13967
|
finding(findings.length, "warn", "timeout", source.envelope.id, `run status ${source.envelope.status}`)
|
|
@@ -14231,17 +14112,17 @@ function validationToolCallCandidate(entry, linked, runSources) {
|
|
|
14231
14112
|
}
|
|
14232
14113
|
function validationToolCallSummary(toolName, args) {
|
|
14233
14114
|
const parsed = parseMaybeJson(args);
|
|
14234
|
-
const argRecord =
|
|
14115
|
+
const argRecord = isRecord11(parsed) ? parsed : null;
|
|
14235
14116
|
if (toolName === "bash") {
|
|
14236
|
-
const command =
|
|
14117
|
+
const command = readOptionalString(argRecord?.command);
|
|
14237
14118
|
if (command === null) return null;
|
|
14238
14119
|
const detected = detectValidationCommand(command);
|
|
14239
14120
|
return detected.kind === "validation" ? detected.matched : null;
|
|
14240
14121
|
}
|
|
14241
14122
|
if (toolName === "verify") {
|
|
14242
|
-
const check =
|
|
14123
|
+
const check = readOptionalString(argRecord?.check);
|
|
14243
14124
|
if (check === "frontend") {
|
|
14244
|
-
const target =
|
|
14125
|
+
const target = readOptionalString(argRecord?.path) ?? "artifact";
|
|
14245
14126
|
return `verify frontend ${target}`;
|
|
14246
14127
|
}
|
|
14247
14128
|
if (check === null) return null;
|
|
@@ -14253,8 +14134,8 @@ function validationToolCallSummary(toolName, args) {
|
|
|
14253
14134
|
}
|
|
14254
14135
|
function isSuccessfulSessionToolResult(result) {
|
|
14255
14136
|
if (result.isError) return false;
|
|
14256
|
-
const obj =
|
|
14257
|
-
const details =
|
|
14137
|
+
const obj = isRecord11(result.result) ? result.result : null;
|
|
14138
|
+
const details = isRecord11(obj?.details) ? obj.details : null;
|
|
14258
14139
|
return details?.kind !== "error";
|
|
14259
14140
|
}
|
|
14260
14141
|
function finding(index, severity, tag, runId, message) {
|
|
@@ -14271,7 +14152,7 @@ async function writeEvidenceFiles(directory, overview, runSources, findings, ses
|
|
|
14271
14152
|
await writeJson(join17(directory, "overview.json"), overview);
|
|
14272
14153
|
await writeFile(
|
|
14273
14154
|
join17(directory, "transcript.md"),
|
|
14274
|
-
transcript ?? renderTranscript(overview, runSources, sessionLinks),
|
|
14155
|
+
transcript ?? renderTranscript(overview, runSources, sessionLinks, trustStatus),
|
|
14275
14156
|
"utf8"
|
|
14276
14157
|
);
|
|
14277
14158
|
await writeJsonl(join17(directory, "trace.raw.jsonl"), rawTraceRows(runSources));
|
|
@@ -14283,7 +14164,7 @@ async function writeEvidenceFiles(directory, overview, runSources, findings, ses
|
|
|
14283
14164
|
await writeJson(join17(directory, "trust-status.json"), trustStatus);
|
|
14284
14165
|
await writeJson(join17(directory, "protected-artifacts.json"), protectedArtifacts);
|
|
14285
14166
|
await writeJson(join17(directory, "findings.json"), findingsFile(overview.evidenceId, [...findings]));
|
|
14286
|
-
await writeFile(join17(directory, "findings.md"),
|
|
14167
|
+
await writeFile(join17(directory, "findings.md"), renderEvidenceFindingsMarkdown(findings, trustStatus), "utf8");
|
|
14287
14168
|
}
|
|
14288
14169
|
function rawTraceRows(runSources) {
|
|
14289
14170
|
const rows = [];
|
|
@@ -14300,7 +14181,8 @@ function cleanedTraceRows(runSources, findings, toolEventRows) {
|
|
|
14300
14181
|
const rows = [];
|
|
14301
14182
|
for (const source of runSources) {
|
|
14302
14183
|
const envelope = source.envelope;
|
|
14303
|
-
const
|
|
14184
|
+
const receipt = authenticatedReceipt(source);
|
|
14185
|
+
const provenance = receipt === null ? {} : extractRunProvenance(receipt);
|
|
14304
14186
|
rows.push({
|
|
14305
14187
|
kind: "run",
|
|
14306
14188
|
runId: envelope.id,
|
|
@@ -14426,13 +14308,13 @@ function attributionWindows(ledger, runSources, sessionIds) {
|
|
|
14426
14308
|
}
|
|
14427
14309
|
const linkedSessions = new Set(sessionIds);
|
|
14428
14310
|
for (const row of ledger.rows) {
|
|
14429
|
-
if (!
|
|
14430
|
-
const id =
|
|
14431
|
-
const startedAt =
|
|
14432
|
-
const sessionId =
|
|
14311
|
+
if (!isRecord11(row)) continue;
|
|
14312
|
+
const id = readOptionalString(row.id);
|
|
14313
|
+
const startedAt = readOptionalString(row.startedAt);
|
|
14314
|
+
const sessionId = readOptionalString(row.sessionId);
|
|
14433
14315
|
if (id === null || startedAt === null || sessionId === null) continue;
|
|
14434
14316
|
if (windows.has(id) || !linkedSessions.has(sessionId)) continue;
|
|
14435
|
-
windows.set(id, { runId: id, startedAt, endedAt:
|
|
14317
|
+
windows.set(id, { runId: id, startedAt, endedAt: readOptionalString(row.endedAt) });
|
|
14436
14318
|
}
|
|
14437
14319
|
return [...windows.values()].sort((left, right) => compareCodepoints(left.runId, right.runId));
|
|
14438
14320
|
}
|
|
@@ -14547,16 +14429,16 @@ function extractSessionToolCall(entry, linked) {
|
|
|
14547
14429
|
const payload = payloadObject(entry.payload);
|
|
14548
14430
|
const block = firstContentBlock(entry.payload, "toolCall");
|
|
14549
14431
|
const fn = payloadObject(payload?.function);
|
|
14550
|
-
const id =
|
|
14551
|
-
const tool =
|
|
14432
|
+
const id = readOptionalString(payload?.id) ?? readOptionalString(payload?.toolCallId) ?? readOptionalString(payload?.tool_call_id) ?? readOptionalString(block?.id) ?? entry.turnId;
|
|
14433
|
+
const tool = readOptionalString(payload?.name) ?? readOptionalString(payload?.toolName) ?? readOptionalString(payload?.tool) ?? readOptionalString(fn?.name) ?? readOptionalString(block?.name) ?? "tool";
|
|
14552
14434
|
const args = payload?.arguments ?? payload?.args ?? payload?.input ?? parseMaybeJson(fn?.arguments) ?? block?.arguments ?? block?.args ?? void 0;
|
|
14553
14435
|
return { id, tool, args, timestamp: entry.timestamp, link: linked.link, sessionId: linked.sessionId };
|
|
14554
14436
|
}
|
|
14555
14437
|
function extractSessionToolResult(entry, linked) {
|
|
14556
14438
|
const payload = payloadObject(entry.payload);
|
|
14557
14439
|
const contentText = extractTextFromPayload(entry.payload);
|
|
14558
|
-
const id =
|
|
14559
|
-
const tool =
|
|
14440
|
+
const id = readOptionalString(payload?.toolCallId) ?? readOptionalString(payload?.tool_call_id) ?? readOptionalString(payload?.id) ?? null;
|
|
14441
|
+
const tool = readOptionalString(payload?.toolName) ?? readOptionalString(payload?.name) ?? readOptionalString(payload?.tool) ?? "tool";
|
|
14560
14442
|
const result = payload?.result ?? payload?.output ?? payload?.out ?? payload?.content ?? (contentText.length > 0 ? contentText : entry.payload);
|
|
14561
14443
|
return {
|
|
14562
14444
|
id,
|
|
@@ -14583,12 +14465,12 @@ async function linkAuditRows(stateDir, source, runSources, sessionLinks) {
|
|
|
14583
14465
|
runSources.map((item) => [item.envelope.id, item.envelope.sessionId ?? item.receipt?.sessionId ?? null])
|
|
14584
14466
|
);
|
|
14585
14467
|
for (const audit of auditRows.rows) {
|
|
14586
|
-
const directRunId =
|
|
14468
|
+
const directRunId = readOptionalString(audit.row.runId);
|
|
14587
14469
|
if (directRunId !== null && runIds.has(directRunId)) {
|
|
14588
14470
|
rows.push(
|
|
14589
14471
|
auditLinkedRow(audit, {
|
|
14590
14472
|
runId: directRunId,
|
|
14591
|
-
sessionId:
|
|
14473
|
+
sessionId: readOptionalString(audit.row.sessionId) ?? runSessionIds.get(directRunId) ?? null,
|
|
14592
14474
|
linkKind: "run-id",
|
|
14593
14475
|
confidence: "exact",
|
|
14594
14476
|
reasons: ["audit runId matched run ledger"]
|
|
@@ -14596,7 +14478,7 @@ async function linkAuditRows(stateDir, source, runSources, sessionLinks) {
|
|
|
14596
14478
|
);
|
|
14597
14479
|
continue;
|
|
14598
14480
|
}
|
|
14599
|
-
const directSessionId =
|
|
14481
|
+
const directSessionId = readOptionalString(audit.row.sessionId);
|
|
14600
14482
|
if (directSessionId !== null && sessionIds.has(directSessionId)) {
|
|
14601
14483
|
rows.push(
|
|
14602
14484
|
auditLinkedRow(audit, {
|
|
@@ -14631,7 +14513,7 @@ function auditLinkedRow(audit, fields) {
|
|
|
14631
14513
|
}
|
|
14632
14514
|
function bestEffortAuditLink(audit, source, runSources, sessionIds) {
|
|
14633
14515
|
if (audit.auditKind !== "tool_call") return null;
|
|
14634
|
-
const tool =
|
|
14516
|
+
const tool = readOptionalString(audit.row.tool);
|
|
14635
14517
|
if (tool === null || audit.ts === null) return null;
|
|
14636
14518
|
const candidates = runSources.filter((item) => {
|
|
14637
14519
|
if (!timestampInRunWindow(audit.ts ?? "", item.envelope)) return false;
|
|
@@ -14695,9 +14577,9 @@ function auditToolEvents(rows) {
|
|
|
14695
14577
|
const events = [];
|
|
14696
14578
|
for (const row of rows) {
|
|
14697
14579
|
if (row.auditKind !== "tool_call") continue;
|
|
14698
|
-
const tool =
|
|
14580
|
+
const tool = readOptionalString(row.row.tool);
|
|
14699
14581
|
if (tool === null) continue;
|
|
14700
|
-
const decision =
|
|
14582
|
+
const decision = readOptionalString(row.row.decision);
|
|
14701
14583
|
if (decision === "classified") continue;
|
|
14702
14584
|
const event = {
|
|
14703
14585
|
source: "audit-row",
|
|
@@ -14714,7 +14596,7 @@ function auditToolEvents(rows) {
|
|
|
14714
14596
|
};
|
|
14715
14597
|
if (row.ts !== null) event.timestamp = row.ts;
|
|
14716
14598
|
if (decision !== null) event.decision = decision;
|
|
14717
|
-
const actionClass =
|
|
14599
|
+
const actionClass = readOptionalString(row.row.actionClass);
|
|
14718
14600
|
if (actionClass !== null) event.actionClass = actionClass;
|
|
14719
14601
|
events.push(event);
|
|
14720
14602
|
}
|
|
@@ -14725,8 +14607,8 @@ function compareAuditLinkedRows(a, b) {
|
|
|
14725
14607
|
if (byTs !== 0) return byTs;
|
|
14726
14608
|
const byKind = compareCodepoints(a.auditKind, b.auditKind);
|
|
14727
14609
|
if (byKind !== 0) return byKind;
|
|
14728
|
-
const aCorrelation =
|
|
14729
|
-
const bCorrelation =
|
|
14610
|
+
const aCorrelation = readOptionalString(a.row.correlationId) ?? "";
|
|
14611
|
+
const bCorrelation = readOptionalString(b.row.correlationId) ?? "";
|
|
14730
14612
|
if (aCorrelation !== bCorrelation) return compareCodepoints(aCorrelation, bCorrelation);
|
|
14731
14613
|
return compareCodepoints(JSON.stringify(a.row), JSON.stringify(b.row));
|
|
14732
14614
|
}
|
|
@@ -14767,7 +14649,8 @@ function protectedArtifactsFile(sessionLinks) {
|
|
|
14767
14649
|
function compareProtectedArtifactEvents(left, right) {
|
|
14768
14650
|
return compareCodepoints(left.timestamp, right.timestamp) || compareCodepoints(left.sessionId, right.sessionId) || compareCodepoints(left.turnId, right.turnId) || compareCodepoints(left.artifact.path, right.artifact.path);
|
|
14769
14651
|
}
|
|
14770
|
-
function renderTranscript(overview, runSources, sessionLinks) {
|
|
14652
|
+
function renderTranscript(overview, runSources, sessionLinks, trustStatus) {
|
|
14653
|
+
const trustByRun = new Map(trustStatus.runs.map((entry) => [entry.runId, entry.status]));
|
|
14771
14654
|
const lines = [
|
|
14772
14655
|
`# Evidence ${overview.evidenceId}`,
|
|
14773
14656
|
"",
|
|
@@ -14784,7 +14667,8 @@ function renderTranscript(overview, runSources, sessionLinks) {
|
|
|
14784
14667
|
);
|
|
14785
14668
|
lines.push(` task: ${truncateText(envelope.task, MAX_TASK_CHARS)}`);
|
|
14786
14669
|
if (source.receipt !== null) {
|
|
14787
|
-
|
|
14670
|
+
const status = trustByRun.get(envelope.id);
|
|
14671
|
+
for (const line of provenanceTranscriptLines(extractRunProvenance(source.receipt), status)) {
|
|
14788
14672
|
lines.push(` ${line}`);
|
|
14789
14673
|
}
|
|
14790
14674
|
}
|
|
@@ -14926,16 +14810,36 @@ function renderSessionTranscriptEntry(linked) {
|
|
|
14926
14810
|
const _exhaustive = entry;
|
|
14927
14811
|
return [`${prefix} ${String(_exhaustive)}`];
|
|
14928
14812
|
}
|
|
14929
|
-
function
|
|
14930
|
-
|
|
14931
|
-
const
|
|
14932
|
-
|
|
14933
|
-
|
|
14934
|
-
|
|
14813
|
+
function axisFindings(offset, source, status) {
|
|
14814
|
+
const out = [];
|
|
14815
|
+
const runId = source.envelope.id;
|
|
14816
|
+
const next = (severity, tag, message) => {
|
|
14817
|
+
out.push(finding(offset + out.length, severity, tag, runId, message));
|
|
14818
|
+
};
|
|
14819
|
+
const review = status.independentReview.state;
|
|
14820
|
+
if (review === "failed") {
|
|
14821
|
+
next("warn", "independent-review", "independent review failed for this run");
|
|
14822
|
+
} else if (review === "not_independent") {
|
|
14823
|
+
next("warn", "independent-review", "review was not independent of the run it judged");
|
|
14824
|
+
} else if (review === "inconclusive") {
|
|
14825
|
+
next("info", "independent-review", "independent review was inconclusive");
|
|
14826
|
+
} else if (isSuccessfulRun(source) && (review === "absent" || review === "unknown")) {
|
|
14827
|
+
next("info", "independent-review", "run was not independently reviewed; its result rests on its own receipt");
|
|
14828
|
+
}
|
|
14829
|
+
if (status.contextProvenance.state === "invalid") {
|
|
14830
|
+
next("warn", "context-provenance", "context provenance record is contradictory; see trust-status.json");
|
|
14831
|
+
}
|
|
14832
|
+
const completion = status.completionEvidence.state;
|
|
14833
|
+
if (completion === "incomplete") {
|
|
14834
|
+
next(
|
|
14835
|
+
"warn",
|
|
14836
|
+
"completion-evidence",
|
|
14837
|
+
"run mutated the workspace and finished without validation evidence at the completion boundary"
|
|
14838
|
+
);
|
|
14839
|
+
} else if (completion === "limited") {
|
|
14840
|
+
next("info", "completion-evidence", "run finished with an explicit limitation instead of validation evidence");
|
|
14935
14841
|
}
|
|
14936
|
-
|
|
14937
|
-
return `${lines.join("\n")}
|
|
14938
|
-
`;
|
|
14842
|
+
return out;
|
|
14939
14843
|
}
|
|
14940
14844
|
async function readRunLedger(stateDir) {
|
|
14941
14845
|
const target = join17(stateDir, "runs.json");
|
|
@@ -14953,7 +14857,7 @@ async function readRunLedger(stateDir) {
|
|
|
14953
14857
|
}
|
|
14954
14858
|
function selectRunEnvelopes(ledger, source) {
|
|
14955
14859
|
return ledger.rows.flatMap((entry, index) => {
|
|
14956
|
-
if (!
|
|
14860
|
+
if (!isRecord11(entry)) return [];
|
|
14957
14861
|
const selected = source.kind === "run" ? entry.id === source.runId : entry.sessionId === source.sessionId;
|
|
14958
14862
|
return selected ? [parseRunEnvelope(entry, `${ledger.path}[${index}]`)] : [];
|
|
14959
14863
|
});
|
|
@@ -14983,6 +14887,7 @@ async function readReceipt(stateDir, envelope) {
|
|
|
14983
14887
|
}
|
|
14984
14888
|
const integrity = inspectRunReceiptTrustStatus(receipt, envelope).integrity;
|
|
14985
14889
|
if (!integrity.ok) {
|
|
14890
|
+
if (integrity.retired !== void 0) return { receipt, error: integrity.reason, integrityFailed: false };
|
|
14986
14891
|
return { receipt, error: `receipt integrity: ${integrity.reason}`, integrityFailed: true };
|
|
14987
14892
|
}
|
|
14988
14893
|
return { receipt, error: null, integrityFailed: false };
|
|
@@ -14993,7 +14898,7 @@ function readExecutionRole(value, source) {
|
|
|
14993
14898
|
return role;
|
|
14994
14899
|
}
|
|
14995
14900
|
function parseRunEnvelope(value, source) {
|
|
14996
|
-
if (!
|
|
14901
|
+
if (!isRecord11(value)) throw new Error(`${source}: expected object`);
|
|
14997
14902
|
const reasoningTokenCount = readOptionalNumber2(value, source, "reasoningTokenCount");
|
|
14998
14903
|
return {
|
|
14999
14904
|
...value,
|
|
@@ -15020,11 +14925,11 @@ function parseRunEnvelope(value, source) {
|
|
|
15020
14925
|
};
|
|
15021
14926
|
}
|
|
15022
14927
|
function parseRunReceipt(value, source) {
|
|
15023
|
-
if (!
|
|
14928
|
+
if (!isRecord11(value)) throw new Error(`${source}: expected object`);
|
|
15024
14929
|
const integrity = value.integrity;
|
|
15025
|
-
if (!
|
|
14930
|
+
if (!isRecord11(integrity)) throw new Error(`${source}.integrity: expected object`);
|
|
15026
14931
|
const reasoningTokenCount = readOptionalNumber2(value, source, "reasoningTokenCount");
|
|
15027
|
-
const failureMessage =
|
|
14932
|
+
const failureMessage = readOptionalString(value.failureMessage);
|
|
15028
14933
|
return {
|
|
15029
14934
|
...value,
|
|
15030
14935
|
runId: readString2(value, source, "runId"),
|
|
@@ -15062,7 +14967,7 @@ function readToolStats(record, source, field) {
|
|
|
15062
14967
|
if (!Array.isArray(value)) throw new Error(`${source}.${field}: expected array`);
|
|
15063
14968
|
return value.map((entry, index) => {
|
|
15064
14969
|
const itemSource = `${source}.${field}[${index}]`;
|
|
15065
|
-
if (!
|
|
14970
|
+
if (!isRecord11(entry)) throw new Error(`${itemSource}: expected object`);
|
|
15066
14971
|
return {
|
|
15067
14972
|
tool: readString2(entry, itemSource, "tool"),
|
|
15068
14973
|
count: readNumber2(entry, itemSource, "count"),
|
|
@@ -15116,7 +15021,7 @@ function readNullableNumber(record, source, field) {
|
|
|
15116
15021
|
throw new Error(`${source}.${field}: expected number or null`);
|
|
15117
15022
|
return value;
|
|
15118
15023
|
}
|
|
15119
|
-
function
|
|
15024
|
+
function readOptionalString(value) {
|
|
15120
15025
|
return typeof value === "string" && value.length > 0 ? value : null;
|
|
15121
15026
|
}
|
|
15122
15027
|
function parseJson2(raw, source) {
|
|
@@ -15127,11 +15032,11 @@ function parseJson2(raw, source) {
|
|
|
15127
15032
|
throw new Error(`${source}: invalid JSON: ${message}`);
|
|
15128
15033
|
}
|
|
15129
15034
|
}
|
|
15130
|
-
function
|
|
15035
|
+
function isRecord11(value) {
|
|
15131
15036
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
15132
15037
|
}
|
|
15133
15038
|
function payloadObject(payload) {
|
|
15134
|
-
return
|
|
15039
|
+
return isRecord11(payload) ? payload : null;
|
|
15135
15040
|
}
|
|
15136
15041
|
function parseMaybeJson(value) {
|
|
15137
15042
|
if (typeof value !== "string") return value;
|
|
@@ -15148,7 +15053,7 @@ function firstContentBlock(payload, type) {
|
|
|
15148
15053
|
const content = obj?.content;
|
|
15149
15054
|
if (!Array.isArray(content)) return null;
|
|
15150
15055
|
for (const block of content) {
|
|
15151
|
-
if (!
|
|
15056
|
+
if (!isRecord11(block)) continue;
|
|
15152
15057
|
if (block.type === type) return block;
|
|
15153
15058
|
}
|
|
15154
15059
|
return null;
|
|
@@ -15161,7 +15066,7 @@ function extractTextFromPayload(payload) {
|
|
|
15161
15066
|
if (Array.isArray(obj.content)) {
|
|
15162
15067
|
const parts = [];
|
|
15163
15068
|
for (const block of obj.content) {
|
|
15164
|
-
if (!
|
|
15069
|
+
if (!isRecord11(block)) continue;
|
|
15165
15070
|
if (block.type === "text" && typeof block.text === "string") parts.push(block.text);
|
|
15166
15071
|
}
|
|
15167
15072
|
return parts.join("\n");
|
|
@@ -15258,9 +15163,6 @@ init_esm_shims();
|
|
|
15258
15163
|
// src/domains/eval/report.ts
|
|
15259
15164
|
init_esm_shims();
|
|
15260
15165
|
|
|
15261
|
-
// src/domains/eval/run-compare.ts
|
|
15262
|
-
init_esm_shims();
|
|
15263
|
-
|
|
15264
15166
|
// src/domains/eval/runner.ts
|
|
15265
15167
|
init_esm_shims();
|
|
15266
15168
|
function summarizeEvalResults(records) {
|
|
@@ -15329,8 +15231,7 @@ async function buildEvalEvidence(options) {
|
|
|
15329
15231
|
const trustStatus = buildEvidenceTrustStatusFile({
|
|
15330
15232
|
evidenceId,
|
|
15331
15233
|
runSources: linkedRuns.runSources,
|
|
15332
|
-
gateDecisions: gateDecisions.decisions
|
|
15333
|
-
auditRows: linkedRuns.auditRows
|
|
15234
|
+
gateDecisions: gateDecisions.decisions
|
|
15334
15235
|
});
|
|
15335
15236
|
await writeEvalEvidenceFiles(
|
|
15336
15237
|
directory,
|
|
@@ -15464,7 +15365,7 @@ async function writeEvalEvidenceFiles(directory, artifact, overview, findings, t
|
|
|
15464
15365
|
await writeJson2(join18(directory, "protected-artifacts.json"), emptyProtected);
|
|
15465
15366
|
await writeJson2(join18(directory, "eval-result.json"), redactedArtifact);
|
|
15466
15367
|
await writeJson2(join18(directory, "findings.json"), findingsFile(overview.evidenceId, [...findings]));
|
|
15467
|
-
await writeFile2(join18(directory, "findings.md"),
|
|
15368
|
+
await writeFile2(join18(directory, "findings.md"), renderEvidenceFindingsMarkdown(findings, trustStatus), "utf8");
|
|
15468
15369
|
}
|
|
15469
15370
|
function rawEvalTraceRows(artifact) {
|
|
15470
15371
|
return artifact.results.map((result) => ({
|
|
@@ -15554,16 +15455,6 @@ function renderEvalTranscript(artifact, overview) {
|
|
|
15554
15455
|
return `${lines.join("\n")}
|
|
15555
15456
|
`;
|
|
15556
15457
|
}
|
|
15557
|
-
function renderFindings2(findings) {
|
|
15558
|
-
if (findings.length === 0) return "No findings.\n";
|
|
15559
|
-
const lines = ["# Findings", ""];
|
|
15560
|
-
for (const finding2 of findings) {
|
|
15561
|
-
lines.push(`- ${finding2.id} [${finding2.severity}] ${finding2.tag}: ${finding2.message}`);
|
|
15562
|
-
}
|
|
15563
|
-
lines.push("");
|
|
15564
|
-
return `${lines.join("\n")}
|
|
15565
|
-
`;
|
|
15566
|
-
}
|
|
15567
15458
|
async function writeJson2(path2, value) {
|
|
15568
15459
|
await writeFile2(path2, `${JSON.stringify(value, null, 2)}
|
|
15569
15460
|
`, "utf8");
|
|
@@ -15617,7 +15508,7 @@ async function readRunLedger2(stateDir) {
|
|
|
15617
15508
|
try {
|
|
15618
15509
|
const raw = await readFile3(join18(stateDir, "runs.json"), "utf8");
|
|
15619
15510
|
const parsed = JSON.parse(raw);
|
|
15620
|
-
return Array.isArray(parsed) ? parsed.filter(
|
|
15511
|
+
return Array.isArray(parsed) ? parsed.filter(isRecord12) : [];
|
|
15621
15512
|
} catch {
|
|
15622
15513
|
return [];
|
|
15623
15514
|
}
|
|
@@ -15629,7 +15520,7 @@ async function readReceiptForRun(stateDir, envelope) {
|
|
|
15629
15520
|
const path2 = envelope.receiptPath ?? join18(stateDir, "receipts", `${envelope.id}.json`);
|
|
15630
15521
|
try {
|
|
15631
15522
|
const parsed = JSON.parse(await readFile3(path2, "utf8"));
|
|
15632
|
-
return
|
|
15523
|
+
return isRecord12(parsed) ? parsed : null;
|
|
15633
15524
|
} catch {
|
|
15634
15525
|
return null;
|
|
15635
15526
|
}
|
|
@@ -15644,7 +15535,7 @@ async function countSessionEntries(stateDir, sessionIds) {
|
|
|
15644
15535
|
count += raw.split("\n").filter((line) => line.trim().length > 0).filter((line) => {
|
|
15645
15536
|
try {
|
|
15646
15537
|
const parsed = JSON.parse(line);
|
|
15647
|
-
return
|
|
15538
|
+
return isRecord12(parsed) && parsed.type !== "session";
|
|
15648
15539
|
} catch {
|
|
15649
15540
|
return false;
|
|
15650
15541
|
}
|
|
@@ -15693,7 +15584,7 @@ async function linkedEvalAuditRows(stateDir, runIds, artifact) {
|
|
|
15693
15584
|
} catch {
|
|
15694
15585
|
continue;
|
|
15695
15586
|
}
|
|
15696
|
-
if (!
|
|
15587
|
+
if (!isRecord12(parsed)) continue;
|
|
15697
15588
|
const directRunId = typeof parsed.runId === "string" ? parsed.runId : null;
|
|
15698
15589
|
if (directRunId !== null && runIds.has(directRunId)) {
|
|
15699
15590
|
rows.push(evalAuditRow(parsed, directRunId, "run-id", "exact", ["audit runId matched nested eval run"]));
|
|
@@ -15764,7 +15655,7 @@ function sanitizeEvidenceId2(value) {
|
|
|
15764
15655
|
const sanitized = value.replace(/[^A-Za-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
15765
15656
|
return sanitized.length === 0 ? "unknown" : sanitized;
|
|
15766
15657
|
}
|
|
15767
|
-
function
|
|
15658
|
+
function isRecord12(value) {
|
|
15768
15659
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
15769
15660
|
}
|
|
15770
15661
|
|
|
@@ -15775,30 +15666,30 @@ init_esm_shims();
|
|
|
15775
15666
|
function lower(value) {
|
|
15776
15667
|
return (value ?? "").toLowerCase();
|
|
15777
15668
|
}
|
|
15778
|
-
function
|
|
15669
|
+
function canonicalJson3(value) {
|
|
15779
15670
|
if (value === null) return "null";
|
|
15780
15671
|
if (typeof value === "string" || typeof value === "boolean") return JSON.stringify(value);
|
|
15781
15672
|
if (typeof value === "number") {
|
|
15782
15673
|
if (!Number.isFinite(value)) throw new Error("response schema digest requires finite numbers");
|
|
15783
15674
|
return JSON.stringify(value);
|
|
15784
15675
|
}
|
|
15785
|
-
if (Array.isArray(value)) return `[${value.map(
|
|
15676
|
+
if (Array.isArray(value)) return `[${value.map(canonicalJson3).join(",")}]`;
|
|
15786
15677
|
if (typeof value === "object") {
|
|
15787
15678
|
const record = value;
|
|
15788
15679
|
return `{${Object.keys(record).sort().map((key) => {
|
|
15789
15680
|
if (record[key] === void 0) throw new Error("response schema digest cannot contain undefined");
|
|
15790
|
-
return `${JSON.stringify(key)}:${
|
|
15681
|
+
return `${JSON.stringify(key)}:${canonicalJson3(record[key])}`;
|
|
15791
15682
|
}).join(",")}}`;
|
|
15792
15683
|
}
|
|
15793
15684
|
throw new Error(`response schema digest cannot represent ${typeof value}`);
|
|
15794
15685
|
}
|
|
15795
15686
|
function canonicalResponseSchemaDigest(schema) {
|
|
15796
|
-
return
|
|
15687
|
+
return createHash11("sha256").update(canonicalJson3(schema), "utf8").digest("hex");
|
|
15797
15688
|
}
|
|
15798
15689
|
function typedValidationFactsFromToolStats(toolStats) {
|
|
15799
15690
|
return toolStats.filter((stat) => stat.tool === "verify" && stat.count > 0).map((stat) => ({
|
|
15800
15691
|
sourceId: "tool:verify",
|
|
15801
|
-
validatorDigest:
|
|
15692
|
+
validatorDigest: createHash11("sha256").update(canonicalJson3(stat), "utf8").digest("hex"),
|
|
15802
15693
|
passed: stat.ok === stat.count && stat.errors === 0 && stat.blocked === 0
|
|
15803
15694
|
}));
|
|
15804
15695
|
}
|
|
@@ -15925,17 +15816,17 @@ export {
|
|
|
15925
15816
|
ACP_MAX_RAW_RECORD_BYTES,
|
|
15926
15817
|
ACP_MAX_CHUNK_BYTES,
|
|
15927
15818
|
ACP_MAX_TOOL_CALL_ID_BYTES,
|
|
15928
|
-
sha256,
|
|
15929
|
-
canonicalJson2 as canonicalJson,
|
|
15930
15819
|
compile,
|
|
15931
15820
|
compileWorker,
|
|
15932
15821
|
WORKER_OUTPUT_MAX_BYTES,
|
|
15933
15822
|
durableAssistantTextFromEvent,
|
|
15934
15823
|
setCapacityDraining,
|
|
15935
15824
|
capacityDrain,
|
|
15825
|
+
capacityLeaseUsage,
|
|
15936
15826
|
openAgentLedger,
|
|
15937
15827
|
renderAgentLedgerBoard,
|
|
15938
15828
|
closeAgentLedger,
|
|
15829
|
+
renderDispatchReviewerTask,
|
|
15939
15830
|
createRunReceiptQuality,
|
|
15940
15831
|
UNVERIFIABLE_RECEIPT_VERIFICATION,
|
|
15941
15832
|
decideReviewGate,
|
|
@@ -15959,8 +15850,6 @@ export {
|
|
|
15959
15850
|
extractRunProvenance,
|
|
15960
15851
|
provenanceTranscriptLines,
|
|
15961
15852
|
provenanceCompactSuffix,
|
|
15962
|
-
adaptRunReceiptTrustStatus,
|
|
15963
|
-
inspectRunReceiptTrustStatus,
|
|
15964
15853
|
FAILURE_CAUSE_TAGS,
|
|
15965
15854
|
evidenceDirectory,
|
|
15966
15855
|
EvidenceNotFoundError,
|
|
@@ -15971,4 +15860,4 @@ export {
|
|
|
15971
15860
|
summarizeEvalResults,
|
|
15972
15861
|
buildEvalEvidence
|
|
15973
15862
|
};
|
|
15974
|
-
//# sourceMappingURL=chunk-
|
|
15863
|
+
//# sourceMappingURL=chunk-TEO2TLVN.js.map
|