@iowarp/clio-coder 0.3.4 → 0.3.7
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 +65 -2
- package/CONTRIBUTING.md +6 -6
- package/README.md +16 -5
- package/dist/{acp-S5R4RR5B.js → acp-SK4MD6MM.js} +11 -11
- package/dist/{agents-P6DMMVZY.js → agents-2FN2K6ME.js} +33 -26
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-2XCZLPKS.js → auth-QIYZWM5I.js} +15 -15
- package/dist/{chunk-EKMEHE4H.js → chunk-33YXPOE3.js} +2 -3
- package/dist/{chunk-VAWWTKDP.js → chunk-3HAPLH5M.js} +11 -11
- package/dist/{chunk-YCWGATWI.js → chunk-465YSENW.js} +3 -3
- package/dist/{chunk-4OC57DA6.js → chunk-4DGYLA73.js} +53 -2
- package/dist/{chunk-UZHIZC5S.js → chunk-4DWFMQDR.js} +61 -76
- package/dist/{chunk-ZWMF7253.js → chunk-5C3AQNDW.js} +328 -9
- package/dist/{chunk-22NAGB7X.js → chunk-5C77SEEY.js} +5 -94
- package/dist/{chunk-WPQLXFOZ.js → chunk-5FR74PWO.js} +3 -2
- package/dist/{chunk-35MKKU5R.js → chunk-5UJ6ECTS.js} +18 -10
- package/dist/{chunk-BRXQQJFP.js → chunk-6M7VS3J3.js} +571 -50
- package/dist/{chunk-QQK64KLB.js → chunk-6TUKSZVF.js} +141 -23
- package/dist/{chunk-N4CZJQRK.js → chunk-AB4XIIVB.js} +8 -6
- package/dist/{chunk-KRPY7NTG.js → chunk-BMWK7ZIZ.js} +14 -20
- package/dist/{chunk-4BPJXDWC.js → chunk-C4JBQ5SR.js} +30 -14
- package/dist/{chunk-ZYKPLLNQ.js → chunk-CEYBNUGC.js} +821 -83
- package/dist/{chunk-VEZEGCGW.js → chunk-D4MDIG46.js} +20 -18
- package/dist/chunk-DJNLUABN.js +843 -0
- package/dist/{chunk-BP4OYD6A.js → chunk-DMD2AGVS.js} +21 -2
- package/dist/{chunk-KOHPCX4K.js → chunk-DOOEX22V.js} +2 -2
- package/dist/chunk-DQA7QLMD.js +123 -0
- package/dist/chunk-DR52UMZW.js +21 -0
- package/dist/{chunk-3HZ5RWN2.js → chunk-EBEFWSGL.js} +9 -7
- package/dist/{chunk-EDRHSCIE.js → chunk-EELBMBT6.js} +128 -13
- package/dist/{chunk-HV5X7OR2.js → chunk-EOOQZZDE.js} +16 -14
- package/dist/{chunk-WR67VIZY.js → chunk-FOT2FX5J.js} +63 -5
- package/dist/{chunk-BPGS2WCQ.js → chunk-GEYXPTRF.js} +2 -1
- package/dist/{chunk-FYYLNIL5.js → chunk-GH5622CP.js} +2 -2
- package/dist/{chunk-BEY543CS.js → chunk-GOXNB3AO.js} +5 -2
- package/dist/chunk-GWS3VEIW.js +195 -0
- package/dist/{chunk-G4BMMOKF.js → chunk-HVDIIIQW.js} +2 -2
- package/dist/chunk-HWUFFB6L.js +83 -0
- package/dist/{chunk-X6COSD2O.js → chunk-J7PIKKWC.js} +8 -436
- package/dist/{chunk-NILBFAPG.js → chunk-JNXPYBB4.js} +2 -2
- package/dist/{chunk-4VP4KH3K.js → chunk-JRIO5UD2.js} +4 -4
- package/dist/{chunk-K6WL7QZT.js → chunk-JTSEDYVQ.js} +7 -7
- package/dist/{chunk-QKMUKYO7.js → chunk-KCMKRQX4.js} +236 -84
- package/dist/chunk-KZ2H5X4G.js +1026 -0
- package/dist/{chunk-A2GZF7DC.js → chunk-LADCF22A.js} +13 -13
- package/dist/chunk-LCGCVYZ4.js +57 -0
- package/dist/chunk-M4AKACEO.js +382 -0
- package/dist/{chunk-POHLU5DW.js → chunk-M6L6IDJG.js} +3 -3
- package/dist/{chunk-4JUF2NNX.js → chunk-MXI6J5JF.js} +7 -7
- package/dist/{chunk-X4RCMKVQ.js → chunk-NDINPTJ4.js} +2 -2
- package/dist/{chunk-TTNYS3EA.js → chunk-OB5HIGJY.js} +1 -1
- package/dist/{chunk-7RXG6QRZ.js → chunk-OBMAI2DP.js} +61 -840
- package/dist/{chunk-5M54SPOL.js → chunk-ODFEOB4F.js} +161 -5
- package/dist/chunk-PD3MESLB.js +242 -0
- package/dist/{chunk-ED4KHGC3.js → chunk-PPAMZ32Z.js} +9 -2
- package/dist/{chunk-VMNQ6OZA.js → chunk-QCTRSGHQ.js} +963 -786
- package/dist/chunk-RVG5JXAL.js +41 -0
- package/dist/{chunk-RD5U66HV.js → chunk-SROCI7ZU.js} +7 -7
- package/dist/{chunk-MFFY33HR.js → chunk-THKY7CD7.js} +466 -205
- package/dist/{chunk-34475P3I.js → chunk-TSHXZTOQ.js} +5 -4
- package/dist/{chunk-PCZJO5TI.js → chunk-UFQ3F4FW.js} +13 -178
- package/dist/{chunk-AD2SYQYC.js → chunk-UHXRNZ2J.js} +121 -3
- package/dist/chunk-UND3GU2L.js +103 -0
- package/dist/{chunk-QQL5RT5M.js → chunk-UUANF5CR.js} +2323 -2114
- package/dist/{chunk-VJWL6YS5.js → chunk-UUVG37B4.js} +2 -2
- package/dist/chunk-UVDSQ6LW.js +472 -0
- package/dist/{chunk-QWU7ZBO7.js → chunk-VQNODYQ4.js} +215 -56
- package/dist/chunk-VREKEFLL.js +37 -0
- package/dist/{chunk-2TZWSW76.js → chunk-WHGPSPT5.js} +2 -2
- package/dist/{chunk-TW3WDMVS.js → chunk-WHJYKASB.js} +2 -2
- package/dist/{chunk-MEQ45TQ4.js → chunk-WJHBC77E.js} +21 -7
- package/dist/{chunk-HXG4IURW.js → chunk-X2KV5FXT.js} +2 -2
- package/dist/{chunk-YHZX5GEU.js → chunk-XAKHZX5N.js} +2 -2
- package/dist/{chunk-2LZI5CAG.js → chunk-XEGB6BCN.js} +228 -36
- package/dist/{chunk-E25LMLRW.js → chunk-YD734TPH.js} +2 -2
- package/dist/{verifiers-4UUM6TEE.js → chunk-YTYFXUI3.js} +121 -372
- package/dist/{chunk-3JLKSKD7.js → chunk-ZGH7FGS5.js} +17 -7
- package/dist/{chunk-VSNATDE6.js → chunk-ZZMN5OM4.js} +2 -2
- package/dist/cli/index.js +34 -32
- package/dist/{clio-J5JIOIDS.js → clio-WBVQEBKO.js} +7 -7
- package/dist/{code-nav-AXCXSBHX.js → code-nav-FGGFIE7L.js} +7 -7
- package/dist/codewiki/build-worker.js +4 -4
- package/dist/{components-KELWS457.js → components-F7OEATSO.js} +5 -5
- package/dist/{config-OEBMIN2U.js → config-TRBL3RCF.js} +48 -41
- package/dist/{configure-PUQOSIXQ.js → configure-OLCVPHNM.js} +17 -17
- package/dist/{context-URSXPBCK.js → context-MJIJ6GOX.js} +12 -12
- package/dist/{context-EKDCKUUZ.js → context-WFPKQSM6.js} +26 -9
- package/dist/{context-MGSE4Z2T.js → context-XEWE3MOJ.js} +44 -37
- package/dist/{context-clear-KDAJRNUK.js → context-clear-KNOS2JPB.js} +44 -37
- package/dist/{context-index-BZ4UYMTC.js → context-index-SSR5ECNE.js} +3 -3
- package/dist/{context-working-set-SBKMPPI2.js → context-working-set-EUXAZI6N.js} +14 -13
- package/dist/{dispatch-runner-MSWN72NK.js → dispatch-runner-B7MTOVKL.js} +321 -60
- package/dist/{docs-2C2LTVT2.js → docs-FLJTIDSE.js} +5 -5
- package/dist/{doctor-7BSE27PJ.js → doctor-RN4YKO2X.js} +15 -15
- package/dist/{eval-IZGDOO4H.js → eval-RUBJVSNQ.js} +52 -236
- package/dist/{evidence-SR7WXB5B.js → evidence-JZNBUOQZ.js} +39 -33
- package/dist/{evolve-K7VE2CBX.js → evolve-FJVC4KKI.js} +39 -33
- package/dist/{extensions-QVDOHDGJ.js → extensions-IQL36S7K.js} +5 -5
- package/dist/{fleet-7XMJNQNF.js → fleet-BDKYJFCP.js} +243 -370
- package/dist/fleet-commands-ZFIWZSB3.js +70 -0
- package/dist/fleet-graph-Y6HPXIVF.js +125 -0
- package/dist/fleet-new-RDVJLHHH.js +48 -0
- package/dist/{fleet-preflight-AQNAH644.js → fleet-preflight-BHSNPBMH.js} +2 -2
- package/dist/fleet-validate-BIYREGIK.js +79 -0
- package/dist/{init-JGNPAYXT.js → init-LQUB5COQ.js} +57 -48
- package/dist/library-NJAHIGG4.js +217 -0
- package/dist/memory-OG6HOYKM.js +472 -0
- package/dist/{models-ZMMLFJNN.js → models-5ZG5XY7J.js} +23 -22
- package/dist/{monitor-2F3T5KHP.js → monitor-TJ7AMTGB.js} +69 -35
- package/dist/{orchestrator-ORHT43JB.js → orchestrator-WZYB54DM.js} +4868 -1189
- package/dist/{paths-UXLN5YYZ.js → paths-XUC7GS6E.js} +5 -5
- package/dist/{reset-NXGTYNUO.js → reset-PXQT45IY.js} +8 -8
- package/dist/{run-RF4WJGMT.js → run-FQ74YF62.js} +82 -62
- package/dist/{share-UT3W6E4M.js → share-FW7SVCL3.js} +34 -10
- package/dist/{skills-PSACKC5Q.js → skills-7E7IRB3R.js} +25 -9
- package/dist/{skills-eval-WJSI55RZ.js → skills-eval-LI75W6OK.js} +43 -35
- package/dist/{targets-PIIRAOYS.js → targets-4CIFKCTW.js} +27 -24
- package/dist/{terminal-lease-ULWXWNVY.js → terminal-lease-WUZY7ZV5.js} +5 -4
- package/dist/{uninstall-FZCQCDKC.js → uninstall-7FV7IP4E.js} +5 -5
- package/dist/{upgrade-346TZ6AV.js → upgrade-K2HVIVMQ.js} +21 -20
- package/dist/{usage-6KKXR32N.js → usage-GTZELZQX.js} +159 -59
- package/dist/verifiers-RLAHT27O.js +336 -0
- package/dist/{verify-X5HDROLA.js → verify-BX3BRKH5.js} +7 -6
- package/dist/{wiki-generate-7STOCIFZ.js → wiki-generate-ASIFASCN.js} +58 -48
- package/dist/worker/entry.js +98 -84
- package/dist/{workspace-G4ZWUIPR.js → workspace-ZJ6BFM3Q.js} +4 -4
- package/docs/README.md +4 -3
- package/docs/acp.md +1 -1
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +2 -2
- package/docs/artifact-placement.md +1 -2
- package/docs/artifact-versions.md +10 -6
- package/docs/built-in-agents.md +26 -2
- package/docs/capacity-and-scheduling.md +1 -1
- package/docs/commands-and-modes.md +90 -8
- package/docs/configuration-and-targets.md +90 -2
- package/docs/context-engine.md +4 -2
- package/docs/context-working-set.md +4 -4
- package/docs/development-pipeline.md +1 -1
- package/docs/dispatch-architecture-rationale.md +1 -1
- package/docs/documentation-coverage.md +4 -4
- package/docs/documentation-guide.md +4 -4
- package/docs/eval-runner.md +1 -1
- package/docs/evals-internal.md +4 -45
- package/docs/evidence-and-memory.md +70 -10
- package/docs/evolution.md +1 -1
- package/docs/exit-codes-and-output.md +4 -1
- package/docs/extensions-and-sharing.md +6 -2
- package/docs/fleet-demo-runbook.md +2 -2
- package/docs/fleet-dispatch.md +224 -11
- package/docs/git-commit-provenance.md +2 -2
- package/docs/glossary.md +1 -1
- package/docs/installation-and-lifecycle.md +2 -2
- package/docs/middleware-and-components.md +20 -2
- package/docs/model-catalog.md +1 -1
- package/docs/observability.md +55 -8
- package/docs/proactive-memory.md +26 -16
- package/docs/prompt-envelope-and-tools.md +4 -2
- package/docs/provider-adapter-cookbook.md +1 -1
- package/docs/release-cut-checklist.md +83 -65
- package/docs/resource-library.md +59 -0
- package/docs/safety-model.md +29 -7
- package/docs/scientific-validation.md +3 -3
- package/docs/session-lifecycle.md +37 -1
- package/docs/skills-marketplace.md +16 -3
- package/docs/tool-usage.md +14 -7
- package/docs/trace-store.md +1 -1
- package/docs/troubleshooting.md +1 -1
- package/docs/tui-design.md +38 -4
- package/docs/worker-dispatch-mechanics.md +3 -3
- package/package.json +7 -4
- package/src/cli/agents.ts +2 -3
- package/src/cli/argv.ts +14 -1
- package/src/cli/fleet-commands.ts +37 -0
- package/src/cli/fleet-graph.ts +102 -0
- package/src/cli/fleet-new.ts +36 -0
- package/src/cli/fleet-preflight.ts +121 -0
- package/src/cli/fleet-validate.ts +30 -0
- package/src/cli/fleet.ts +188 -335
- package/src/cli/index.ts +4 -2
- package/src/cli/library.ts +190 -0
- package/src/cli/memory.ts +272 -10
- package/src/cli/modes/json-stream.ts +2 -2
- package/src/cli/modes/print.ts +12 -1
- package/src/cli/run.ts +22 -2
- package/src/cli/share.ts +13 -1
- package/src/cli/targets.ts +12 -3
- package/src/cli/usage.ts +160 -20
- package/src/core/bus-events.ts +7 -0
- package/src/core/commit-attribution.ts +4 -4
- package/src/core/config.ts +130 -0
- package/src/core/defaults.ts +81 -0
- package/src/core/response-model-id.ts +134 -0
- package/src/core/toml.ts +62 -0
- package/src/core/workspace-files.ts +0 -1
- package/src/domains/agents/builtins/architect.md +2 -1
- package/src/domains/agents/builtins/oracle.md +33 -0
- package/src/domains/agents/catalog.ts +18 -5
- package/src/domains/agents/fleet-contract.ts +278 -16
- package/src/domains/agents/index.ts +14 -0
- package/src/domains/agents/recipe.ts +54 -14
- package/src/domains/agents/result-contract.ts +242 -5
- package/src/domains/config/classify.ts +4 -0
- package/src/domains/context/bootstrap.ts +36 -27
- package/src/domains/context/project-metadata.ts +19 -63
- package/src/domains/context/prompt-context.ts +8 -0
- package/src/domains/context/working-set/policies/index.ts +3 -4
- package/src/domains/dispatch/active-route-planner.ts +14 -0
- package/src/domains/dispatch/backoff.ts +2 -1
- package/src/domains/dispatch/budget-envelope.ts +396 -0
- package/src/domains/dispatch/capability-match.ts +1 -0
- package/src/domains/dispatch/checkout-writer-lease.ts +175 -0
- package/src/domains/dispatch/contract.ts +36 -0
- package/src/domains/dispatch/delegation-plan.ts +167 -0
- package/src/domains/dispatch/execution-plan.ts +76 -5
- package/src/domains/dispatch/execution-role.ts +3 -1
- package/src/domains/dispatch/execution-scheduler.ts +183 -67
- package/src/domains/dispatch/extension.ts +339 -36
- package/src/domains/dispatch/fleet-gate.ts +14 -0
- package/src/domains/dispatch/fleet-plan.ts +63 -3
- package/src/domains/dispatch/fleet-run.ts +737 -0
- package/src/domains/dispatch/gate-role-prompts.ts +9 -0
- package/src/domains/dispatch/host-verification.ts +178 -0
- package/src/domains/dispatch/index.ts +38 -0
- package/src/domains/dispatch/intent.ts +159 -0
- package/src/domains/dispatch/orphan-recovery.ts +1 -0
- package/src/domains/dispatch/receipt-integrity.ts +12 -4
- package/src/domains/dispatch/state.ts +37 -3
- package/src/domains/dispatch/types.ts +61 -9
- package/src/domains/dispatch/validation.ts +80 -6
- package/src/domains/dispatch/worker-spawn.ts +14 -3
- package/src/domains/eval/metrics/evidence.ts +0 -116
- package/src/domains/eval/metrics/invariants.ts +1 -1
- package/src/domains/eval/runners/clio-run.ts +1 -10
- package/src/domains/eval/runners/external-command.ts +2 -29
- package/src/domains/eval/schema/suite.ts +0 -7
- package/src/domains/eval/suites/run.ts +1 -7
- package/src/domains/evidence/trust-status.ts +10 -1
- package/src/domains/memory/index.ts +22 -0
- package/src/domains/memory/operations.ts +58 -1
- package/src/domains/memory/promotion.ts +281 -0
- package/src/domains/memory/prompt-section.ts +25 -5
- package/src/domains/memory/proposal.ts +51 -7
- package/src/domains/memory/task-bank.ts +3 -2
- package/src/domains/memory/task-memory-handoff.ts +181 -24
- package/src/domains/memory/task-memory-policy.ts +3 -1
- package/src/domains/memory/types.ts +37 -0
- package/src/domains/memory/validate.ts +178 -0
- package/src/domains/middleware/index.ts +15 -0
- package/src/domains/middleware/memory-intervention.ts +35 -25
- package/src/domains/middleware/runtime.ts +6 -0
- package/src/domains/middleware/skills-reminder.ts +19 -4
- package/src/domains/middleware/stalled-turn.ts +43 -1
- package/src/domains/middleware/types.ts +10 -0
- package/src/domains/middleware/watchdog.ts +281 -0
- package/src/domains/observability/contract.ts +9 -2
- package/src/domains/observability/cost.ts +31 -4
- package/src/domains/observability/extension.ts +2 -2
- package/src/domains/observability/index.ts +10 -0
- package/src/domains/observability/out-of-turn-usage.ts +223 -0
- package/src/domains/providers/index.ts +3 -0
- package/src/domains/providers/model-discovery.ts +9 -0
- package/src/domains/providers/runtime-resolution.ts +38 -1
- package/src/domains/providers/runtimes/common/probe-helpers.ts +97 -16
- package/src/domains/providers/types/context-window-slots.ts +18 -0
- package/src/domains/providers/types/runtime-descriptor.ts +3 -1
- package/src/domains/resources/index.ts +20 -0
- package/src/domains/resources/library.ts +326 -0
- package/src/domains/resources/skills/marketplace.ts +37 -12
- package/src/domains/safety/call-target.ts +211 -14
- package/src/domains/safety/decision-presentation.ts +268 -0
- package/src/domains/safety/redaction.ts +73 -0
- package/src/domains/session/context-ledger.ts +10 -1
- package/src/domains/session/decision-board.ts +4 -0
- package/src/domains/session/entries.ts +3 -0
- package/src/domains/session/handoff.ts +629 -0
- package/src/domains/session/history.ts +68 -19
- package/src/domains/session/usage.ts +24 -7
- package/src/domains/share/archive.ts +67 -2
- package/src/engine/acp/event-mapper.ts +7 -0
- package/src/engine/acp/server.ts +29 -2
- package/src/engine/apis/lmstudio.ts +25 -4
- package/src/engine/apis/openai-completions.ts +147 -22
- package/src/engine/claude/sdk-runtime.ts +8 -2
- package/src/engine/claude/tool-safety.ts +13 -0
- package/src/engine/loop-guard.ts +27 -3
- package/src/engine/worker-events.ts +4 -3
- package/src/engine/worker-runtime.ts +59 -54
- package/src/entry/orchestrator.ts +55 -1
- package/src/interactive/bus-notices.ts +26 -0
- package/src/interactive/chat-loop-messages.ts +22 -0
- package/src/interactive/chat-loop.ts +248 -1
- package/src/interactive/chat-renderer.ts +41 -3
- package/src/interactive/clio-editor.ts +44 -7
- package/src/interactive/context-overlay.ts +43 -5
- package/src/interactive/cost-overlay.ts +70 -11
- package/src/interactive/council-dispatch.ts +30 -0
- package/src/interactive/council-grid.ts +213 -0
- package/src/interactive/council.ts +99 -0
- package/src/interactive/dispatch-board.ts +471 -50
- package/src/interactive/fleet-run-preview.ts +307 -0
- package/src/interactive/footer/notifications.ts +219 -0
- package/src/interactive/footer/widgets.ts +13 -0
- package/src/interactive/handoff-round.ts +56 -0
- package/src/interactive/interactive-application.ts +49 -2
- package/src/interactive/interactive-event-projection.ts +9 -1
- package/src/interactive/interactive-input-runtime.ts +11 -1
- package/src/interactive/interactive-presentation.ts +11 -1
- package/src/interactive/interactive-slash-runtime.ts +52 -2
- package/src/interactive/interactive-subscriptions.ts +14 -2
- package/src/interactive/memory-overlay.ts +89 -4
- package/src/interactive/oracle.ts +179 -0
- package/src/interactive/overlay-ask-user-lifecycle.ts +7 -1
- package/src/interactive/overlay-frame.ts +5 -2
- package/src/interactive/overlay-general-openers.ts +230 -2
- package/src/interactive/overlay-key-routing.ts +58 -2
- package/src/interactive/overlay-lifecycle.ts +52 -5
- package/src/interactive/overlay-permission-lifecycle.ts +33 -8
- package/src/interactive/overlay-resource-openers.ts +11 -3
- package/src/interactive/overlay-session-lifecycle.ts +234 -2
- package/src/interactive/overlay-transitions.ts +11 -0
- package/src/interactive/overlays/ask-user.ts +74 -30
- package/src/interactive/overlays/decisions.ts +3 -1
- package/src/interactive/overlays/fleet-run-approval.ts +208 -0
- package/src/interactive/overlays/handoff-review.ts +185 -0
- package/src/interactive/overlays/library-install-confirm.ts +151 -0
- package/src/interactive/overlays/list-overlay.ts +168 -2
- package/src/interactive/overlays/settings.ts +101 -4
- package/src/interactive/overlays/side-question.ts +139 -0
- package/src/interactive/overlays/skills-hub.ts +401 -15
- package/src/interactive/permission-hint.ts +35 -0
- package/src/interactive/permission-overlay.ts +95 -45
- package/src/interactive/renderers/tool-execution.ts +19 -49
- package/src/interactive/session-last-turn.ts +8 -1
- package/src/interactive/session-usage-reseed.ts +36 -10
- package/src/interactive/side-question.ts +171 -0
- package/src/interactive/slash-commands.ts +434 -7
- package/src/interactive/slash-spec.ts +19 -6
- package/src/interactive/status/summary.ts +5 -0
- package/src/interactive/status/types.ts +5 -0
- package/src/interactive/terminal-lease.ts +1 -0
- package/src/interactive/theme/tokens.ts +30 -0
- package/src/interactive/turn-context.ts +96 -23
- package/src/interactive/turn-middleware.ts +16 -1
- package/src/interactive/turn-runtime.ts +37 -8
- package/src/interactive/turn-state.ts +3 -0
- package/src/interactive/watchdog-run.ts +75 -0
- package/src/interactive/worker-progress.ts +440 -0
- package/src/interactive/worker-share.ts +56 -1
- package/src/interactive/worker-stream.ts +58 -110
- package/src/tools/agent-tools.ts +28 -3
- package/src/tools/ask-user.ts +21 -1
- package/src/tools/bootstrap.ts +3 -0
- package/src/tools/compete-worktrees.ts +13 -79
- package/src/tools/context/index.ts +2 -2
- package/src/tools/dispatch-admission.ts +242 -8
- package/src/tools/dispatch-arguments.ts +65 -1
- package/src/tools/dispatch-event-text.ts +19 -0
- package/src/tools/dispatch-plan.ts +136 -6
- package/src/tools/dispatch-runner.ts +319 -13
- package/src/tools/dispatch-types.ts +20 -1
- package/src/tools/dispatch.ts +96 -3
- package/src/tools/monitor.ts +31 -0
- package/src/tools/profiles.ts +18 -4
- package/src/tools/registry.ts +15 -5
- package/src/tools/result-disposition.ts +156 -0
- package/src/tools/result-shaping.ts +59 -1
- package/src/tools/task-worktree.ts +238 -0
- package/src/tools/verify/authoring.ts +116 -55
- package/src/tools/verify/scripts.ts +62 -0
- package/src/tools/worker-evidence.ts +21 -1
- package/src/worker/spec-contract.ts +44 -3
- package/dist/chunk-EFADSJET.js +0 -18
- package/dist/chunk-HC4CLZ2Y.js +0 -68
- package/dist/memory-4ALKDJ4Q.js +0 -246
- package/src/domains/eval/metrics/chaos-stream.ts +0 -93
|
@@ -6,12 +6,15 @@
|
|
|
6
6
|
* are pure data: no class methods, no engine refs.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
import type { ResponseModelIdObservation } from "../../core/response-model-id.js";
|
|
9
10
|
import type { SkillActivation } from "../../core/skill-activation.js";
|
|
10
11
|
import type { ToolProfileName } from "../../tools/profiles.js";
|
|
11
12
|
import type { AgentAudience } from "../agents/spec.js";
|
|
12
13
|
import type { EvidenceTag } from "../evidence/index.js";
|
|
13
14
|
import type { CostProvenance, RuntimeTargetSnapshot } from "../providers/index.js";
|
|
15
|
+
import type { RunToolBudgetEnvelope } from "./budget-envelope.js";
|
|
14
16
|
import type { ExecutionRole, GateTopologyRole } from "./execution-role.js";
|
|
17
|
+
import type { DispatchIntent } from "./intent.js";
|
|
15
18
|
import type { RouteDecisionV1 } from "./route-decision.js";
|
|
16
19
|
import type { RoutingIntent } from "./routing-intent.js";
|
|
17
20
|
|
|
@@ -39,7 +42,8 @@ export type RunOutcomeCode =
|
|
|
39
42
|
| "worker_tool_call_cap_exhausted"
|
|
40
43
|
| "loop_guard_tools_disabled_exhausted"
|
|
41
44
|
| "result_contract_exhausted"
|
|
42
|
-
| "worker_final_output_missing"
|
|
45
|
+
| "worker_final_output_missing"
|
|
46
|
+
| "host_verification_rejected";
|
|
43
47
|
|
|
44
48
|
export function isRunOutcomeCode(value: unknown): value is RunOutcomeCode {
|
|
45
49
|
return (
|
|
@@ -47,7 +51,8 @@ export function isRunOutcomeCode(value: unknown): value is RunOutcomeCode {
|
|
|
47
51
|
value === "worker_tool_call_cap_exhausted" ||
|
|
48
52
|
value === "loop_guard_tools_disabled_exhausted" ||
|
|
49
53
|
value === "result_contract_exhausted" ||
|
|
50
|
-
value === "worker_final_output_missing"
|
|
54
|
+
value === "worker_final_output_missing" ||
|
|
55
|
+
value === "host_verification_rejected"
|
|
51
56
|
);
|
|
52
57
|
}
|
|
53
58
|
|
|
@@ -236,6 +241,13 @@ export interface RunGateProvenance {
|
|
|
236
241
|
verdict?: "pass" | "fail" | "revise";
|
|
237
242
|
}
|
|
238
243
|
|
|
244
|
+
export interface RunCouncilProvenance {
|
|
245
|
+
group: string;
|
|
246
|
+
label: string;
|
|
247
|
+
color?: string;
|
|
248
|
+
round: number;
|
|
249
|
+
}
|
|
250
|
+
|
|
239
251
|
/**
|
|
240
252
|
* Plan-approval provenance for multi-task, compete, or remote dispatch.
|
|
241
253
|
* `approval: "operator"` records that a supervised autonomy level parked the
|
|
@@ -246,7 +258,7 @@ export interface RunGateProvenance {
|
|
|
246
258
|
*/
|
|
247
259
|
export interface RunPlanProvenance {
|
|
248
260
|
hash: string;
|
|
249
|
-
topology: "parallel" | "sequential" | "pipeline" | "review" | "compete" | "detached" | "fleet";
|
|
261
|
+
topology: "parallel" | "sequential" | "pipeline" | "review" | "compete" | "council" | "detached" | "fleet";
|
|
250
262
|
taskCount: number;
|
|
251
263
|
approval: "operator" | "full-auto";
|
|
252
264
|
source: null | {
|
|
@@ -309,7 +321,7 @@ export interface RunPhaseDurations {
|
|
|
309
321
|
* bumping one without the other is a compile error.
|
|
310
322
|
*/
|
|
311
323
|
export interface RunReceiptIntegrity {
|
|
312
|
-
version:
|
|
324
|
+
version: 19;
|
|
313
325
|
algorithm: "sha256";
|
|
314
326
|
digest: string;
|
|
315
327
|
}
|
|
@@ -418,6 +430,8 @@ export interface RunEnvelope {
|
|
|
418
430
|
agentAudience?: AgentAudience;
|
|
419
431
|
requestOrigin?: DispatchRequestOrigin;
|
|
420
432
|
task: string;
|
|
433
|
+
/** Immutable recipe policy, invocation request, effective phase, and admission reasons. */
|
|
434
|
+
budget?: RunToolBudgetEnvelope;
|
|
421
435
|
/** Present only when a bounded parent briefing was sent as dynamic task data. */
|
|
422
436
|
briefing?: RunBriefingProvenance;
|
|
423
437
|
/** Sent steering provenance in stable per-run sequence order; prose is never persisted. */
|
|
@@ -445,6 +459,7 @@ export interface RunEnvelope {
|
|
|
445
459
|
pipeline?: RunPipelineProvenance;
|
|
446
460
|
/** Review/compete gate provenance; present only on runs of a gated dispatch. */
|
|
447
461
|
gate?: RunGateProvenance;
|
|
462
|
+
council?: RunCouncilProvenance;
|
|
448
463
|
/** Plan-approval provenance; present only on runs of an approval-gated plan. */
|
|
449
464
|
plan?: RunPlanProvenance;
|
|
450
465
|
/** Ad-hoc specialist provenance; present only when a persona override composed the stable prompt. */
|
|
@@ -615,9 +630,10 @@ export interface RunReceiptReproducibility {
|
|
|
615
630
|
}
|
|
616
631
|
|
|
617
632
|
export interface RunReceiptUpstreamResponse {
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
633
|
+
requestedModelId: string | null;
|
|
634
|
+
responseModelIdObservation: ResponseModelIdObservation;
|
|
635
|
+
differingResponseModelId: string | null;
|
|
636
|
+
providerResponseId: string | null;
|
|
621
637
|
}
|
|
622
638
|
|
|
623
639
|
/**
|
|
@@ -669,6 +685,25 @@ export interface RunReceiptVerification {
|
|
|
669
685
|
| "receipt-unavailable";
|
|
670
686
|
}
|
|
671
687
|
|
|
688
|
+
export interface RunHostVerificationCheck {
|
|
689
|
+
check: string;
|
|
690
|
+
argv: string[];
|
|
691
|
+
cwd: string;
|
|
692
|
+
exitCode: number;
|
|
693
|
+
durationMs: number;
|
|
694
|
+
memo: boolean;
|
|
695
|
+
outputTail: string;
|
|
696
|
+
artifactPath?: string;
|
|
697
|
+
/** Original evidence owner on a memo hit. */
|
|
698
|
+
evidenceRunId?: string;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
export interface RunHostVerification {
|
|
702
|
+
status: "verified" | "rejected" | "skipped";
|
|
703
|
+
reason?: string;
|
|
704
|
+
checks: RunHostVerificationCheck[];
|
|
705
|
+
}
|
|
706
|
+
|
|
672
707
|
export interface RunReceipt {
|
|
673
708
|
runId: string;
|
|
674
709
|
agentId: string;
|
|
@@ -677,6 +712,10 @@ export interface RunReceipt {
|
|
|
677
712
|
agentAudience?: AgentAudience;
|
|
678
713
|
requestOrigin?: DispatchRequestOrigin;
|
|
679
714
|
task: string;
|
|
715
|
+
/** Normalized dispatch intent admitted before worker execution. */
|
|
716
|
+
intent?: DispatchIntent;
|
|
717
|
+
/** Integrity-sealed recipe policy, invocation request, effective phase, and admission reasons. */
|
|
718
|
+
budget?: RunToolBudgetEnvelope;
|
|
680
719
|
/** Proof of briefing content without copying its prose into the receipt. */
|
|
681
720
|
briefing?: RunBriefingProvenance;
|
|
682
721
|
/** Sent steering provenance in stable per-run sequence order; prose is never persisted. */
|
|
@@ -707,8 +746,11 @@ export interface RunReceipt {
|
|
|
707
746
|
pipeline?: RunPipelineProvenance;
|
|
708
747
|
/** Review/compete gate provenance; present only on runs of a gated dispatch. */
|
|
709
748
|
gate?: RunGateProvenance;
|
|
749
|
+
council?: RunCouncilProvenance;
|
|
710
750
|
/** Plan-approval provenance; present only on runs of an approval-gated plan. */
|
|
711
751
|
plan?: RunPlanProvenance;
|
|
752
|
+
/** Version 5 fleet gate artifact authored by this run. */
|
|
753
|
+
fleetGate?: { path: string; pathHash: string };
|
|
712
754
|
/** Ad-hoc specialist provenance; present only when a persona override composed the stable prompt. */
|
|
713
755
|
personaOverride?: RunPersonaOverride;
|
|
714
756
|
/** Effective project-context tier for this run; absent on receipts written before this field landed. */
|
|
@@ -757,6 +799,17 @@ export interface RunReceipt {
|
|
|
757
799
|
toolActivity?: ToolActivitySummary;
|
|
758
800
|
/** Integrity-sealed evidence confidence. Sealed on every receipt. */
|
|
759
801
|
verification: RunReceiptVerification;
|
|
802
|
+
/** Orchestrator-executed declared checks. Worker self-report never populates this field. */
|
|
803
|
+
hostVerification?: RunHostVerification;
|
|
804
|
+
/** Isolated writer checkout and its collect-time application result. */
|
|
805
|
+
worktree?: {
|
|
806
|
+
path: string;
|
|
807
|
+
branch: string;
|
|
808
|
+
diffHash: string;
|
|
809
|
+
apply: "merge" | "preserve";
|
|
810
|
+
applied: boolean;
|
|
811
|
+
reason?: string;
|
|
812
|
+
};
|
|
760
813
|
/** Required normalized routing request, sealed without task or prompt data. */
|
|
761
814
|
routingIntent: RoutingIntent;
|
|
762
815
|
/** Required routing-quality facts known at receipt finalization. */
|
|
@@ -779,8 +832,7 @@ export interface RunReceipt {
|
|
|
779
832
|
* What this run contributed to its dispatch's agent ledger. Optional and
|
|
780
833
|
* absent unless the run had a ledger, following validationGrounding and
|
|
781
834
|
* capabilityMismatch: receiptDigestFields skips undefined, so a receipt
|
|
782
|
-
* without one
|
|
783
|
-
* RUN_RECEIPT_INTEGRITY_VERSION stays where it is.
|
|
835
|
+
* without one omits the field from canonical serialization.
|
|
784
836
|
*/
|
|
785
837
|
ledgerContribution?: RunLedgerContribution;
|
|
786
838
|
/**
|
|
@@ -11,6 +11,7 @@ import { cloneValidatedResponseSchema } from "../../core/response-schema.js";
|
|
|
11
11
|
import { isToolProfileName, type ToolProfileName } from "../../tools/profiles.js";
|
|
12
12
|
import type { AgentProduct } from "../agents/spec.js";
|
|
13
13
|
import { type AutonomyLevel, isAutonomyLevel } from "../safety/autonomy.js";
|
|
14
|
+
import { cloneDispatchBudgetRequest, type DispatchBudgetRequest } from "./budget-envelope.js";
|
|
14
15
|
import {
|
|
15
16
|
EXECUTION_HANDOFF_MAX_ITEMS,
|
|
16
17
|
EXECUTION_HANDOFF_MAX_TEXT_BYTES,
|
|
@@ -18,6 +19,7 @@ import {
|
|
|
18
19
|
} from "./execution-handoff.js";
|
|
19
20
|
import { isExecutionRole } from "./execution-role.js";
|
|
20
21
|
import { COMPETE_STANCES, type CompeteStance } from "./gate-role-prompts.js";
|
|
22
|
+
import { type DispatchIntent, isDispatchIntent } from "./intent.js";
|
|
21
23
|
import { isRoutingIntent, type RoutingIntent } from "./routing-intent.js";
|
|
22
24
|
import type {
|
|
23
25
|
DispatchRequestOrigin,
|
|
@@ -76,6 +78,8 @@ export interface JobSpec {
|
|
|
76
78
|
target?: string;
|
|
77
79
|
model?: string;
|
|
78
80
|
thinkingLevel?: JobThinkingLevel;
|
|
81
|
+
/** Invocation phase and optional preauthorized retry or revision ceiling. */
|
|
82
|
+
budget?: DispatchBudgetRequest;
|
|
79
83
|
/**
|
|
80
84
|
* What this run delivers, which decides what its reserve window admits.
|
|
81
85
|
* "orientation" adds `code_nav` to the delivery tools kept live inside the
|
|
@@ -118,6 +122,10 @@ export interface JobSpec {
|
|
|
118
122
|
*/
|
|
119
123
|
denyTools?: ReadonlyArray<string>;
|
|
120
124
|
cwd?: string;
|
|
125
|
+
/** Run this writer in an isolated git worktree. */
|
|
126
|
+
worktree?: true;
|
|
127
|
+
/** How a successful isolated writer is applied to its parent checkout. */
|
|
128
|
+
apply?: "merge" | "preserve";
|
|
121
129
|
memorySection?: string;
|
|
122
130
|
noSkills?: boolean;
|
|
123
131
|
skillPaths?: ReadonlyArray<string>;
|
|
@@ -131,6 +139,8 @@ export interface JobSpec {
|
|
|
131
139
|
* per-tool calls (subprocess).
|
|
132
140
|
*/
|
|
133
141
|
writeRoots?: ReadonlyArray<string>;
|
|
142
|
+
/** Normalized model-declared path, output, and host verification intent. */
|
|
143
|
+
intent?: DispatchIntent;
|
|
134
144
|
requestOrigin?: DispatchRequestOrigin;
|
|
135
145
|
/**
|
|
136
146
|
* Threaded output from the previous pipeline step. Set only by the dispatch
|
|
@@ -156,6 +166,8 @@ export interface JobSpec {
|
|
|
156
166
|
autonomy?: AutonomyLevel;
|
|
157
167
|
/** Review/compete gate provenance sealed into the run's receipt. */
|
|
158
168
|
gate?: RunGateProvenance;
|
|
169
|
+
/** Council grouping projected to receipts and fleet surfaces. */
|
|
170
|
+
council?: { group: string; label: string; color?: string; round: number };
|
|
159
171
|
/** Plan-approval provenance sealed into the run's receipt. */
|
|
160
172
|
plan?: RunPlanProvenance;
|
|
161
173
|
/**
|
|
@@ -180,6 +192,7 @@ const KNOWN_KEYS = new Set([
|
|
|
180
192
|
"target",
|
|
181
193
|
"model",
|
|
182
194
|
"thinkingLevel",
|
|
195
|
+
"budget",
|
|
183
196
|
"node",
|
|
184
197
|
"routingIntent",
|
|
185
198
|
"failover",
|
|
@@ -191,18 +204,22 @@ const KNOWN_KEYS = new Set([
|
|
|
191
204
|
"toolProfile",
|
|
192
205
|
"denyTools",
|
|
193
206
|
"cwd",
|
|
207
|
+
"worktree",
|
|
208
|
+
"apply",
|
|
194
209
|
"memorySection",
|
|
195
210
|
"noSkills",
|
|
196
211
|
"skillPaths",
|
|
197
212
|
"trustProjectCompatRoots",
|
|
198
213
|
"responseSchema",
|
|
199
214
|
"writeRoots",
|
|
215
|
+
"intent",
|
|
200
216
|
"requestOrigin",
|
|
201
217
|
"pipelineInput",
|
|
202
218
|
"predecessorHandoffs",
|
|
203
219
|
"lineage",
|
|
204
220
|
"autonomy",
|
|
205
221
|
"gate",
|
|
222
|
+
"council",
|
|
206
223
|
"plan",
|
|
207
224
|
"competeStance",
|
|
208
225
|
]);
|
|
@@ -378,6 +395,15 @@ export function validateJobSpec(spec: unknown): Validated {
|
|
|
378
395
|
}
|
|
379
396
|
}
|
|
380
397
|
|
|
398
|
+
let budget: DispatchBudgetRequest | undefined;
|
|
399
|
+
if ("budget" in spec && spec.budget !== undefined) {
|
|
400
|
+
try {
|
|
401
|
+
budget = cloneDispatchBudgetRequest(spec.budget);
|
|
402
|
+
} catch (error) {
|
|
403
|
+
errors.push(error instanceof Error ? error.message : String(error));
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
381
407
|
if ("requiredCapabilities" in spec && spec.requiredCapabilities !== undefined) {
|
|
382
408
|
if (!Array.isArray(spec.requiredCapabilities) || spec.requiredCapabilities.some((c) => typeof c !== "string")) {
|
|
383
409
|
errors.push("requiredCapabilities must be a string[]");
|
|
@@ -386,7 +412,7 @@ export function validateJobSpec(spec: unknown): Validated {
|
|
|
386
412
|
|
|
387
413
|
if ("toolProfile" in spec && spec.toolProfile !== undefined) {
|
|
388
414
|
if (typeof spec.toolProfile !== "string" || !isToolProfileName(spec.toolProfile)) {
|
|
389
|
-
errors.push("toolProfile must be one of: minimal-local|science-local|full-agent");
|
|
415
|
+
errors.push("toolProfile must be one of: minimal-local|science-local|full-agent|council-read-only");
|
|
390
416
|
}
|
|
391
417
|
}
|
|
392
418
|
|
|
@@ -401,6 +427,13 @@ export function validateJobSpec(spec: unknown): Validated {
|
|
|
401
427
|
errors.push("cwd must be a non-empty string");
|
|
402
428
|
}
|
|
403
429
|
}
|
|
430
|
+
if ("worktree" in spec && spec.worktree !== undefined && spec.worktree !== true) {
|
|
431
|
+
errors.push("worktree must be true when present");
|
|
432
|
+
}
|
|
433
|
+
if ("apply" in spec && spec.apply !== undefined && spec.apply !== "merge" && spec.apply !== "preserve") {
|
|
434
|
+
errors.push("apply must be merge or preserve");
|
|
435
|
+
}
|
|
436
|
+
if (spec.apply !== undefined && spec.worktree !== true) errors.push("apply requires worktree: true");
|
|
404
437
|
|
|
405
438
|
if ("memorySection" in spec && spec.memorySection !== undefined) {
|
|
406
439
|
if (typeof spec.memorySection !== "string") {
|
|
@@ -444,6 +477,15 @@ export function validateJobSpec(spec: unknown): Validated {
|
|
|
444
477
|
errors.push("writeRoots must be a non-empty array of non-empty strings");
|
|
445
478
|
}
|
|
446
479
|
}
|
|
480
|
+
if ("intent" in spec && spec.intent !== undefined && !isDispatchIntent(spec.intent)) {
|
|
481
|
+
errors.push("intent must be a normalized dispatch intent");
|
|
482
|
+
}
|
|
483
|
+
if (isDispatchIntent(spec.intent) && spec.intent.writeRoots.length > 0 && Array.isArray(spec.writeRoots)) {
|
|
484
|
+
const jobCwd = typeof spec.cwd === "string" && spec.cwd.length > 0 ? spec.cwd : process.cwd();
|
|
485
|
+
const legacy = [...new Set(spec.writeRoots.map((root) => path.resolve(jobCwd, String(root))))].sort();
|
|
486
|
+
const declared = [...new Set(spec.intent.writeRoots.map((root) => path.resolve(jobCwd, root)))].sort();
|
|
487
|
+
if (JSON.stringify(legacy) !== JSON.stringify(declared)) errors.push("intent_write_roots_contradiction");
|
|
488
|
+
}
|
|
447
489
|
|
|
448
490
|
if ("requestOrigin" in spec && spec.requestOrigin !== undefined) {
|
|
449
491
|
if (typeof spec.requestOrigin !== "string" || !VALID_REQUEST_ORIGINS.has(spec.requestOrigin)) {
|
|
@@ -530,24 +572,32 @@ export function validateJobSpec(spec: unknown): Validated {
|
|
|
530
572
|
out.reroutes = spec.reroutes.map((hop) => ({ ...hop }));
|
|
531
573
|
}
|
|
532
574
|
if (typeof spec.thinkingLevel === "string") out.thinkingLevel = spec.thinkingLevel as JobThinkingLevel;
|
|
575
|
+
if (budget !== undefined) out.budget = budget;
|
|
533
576
|
if (Array.isArray(spec.requiredCapabilities)) {
|
|
534
577
|
out.requiredCapabilities = spec.requiredCapabilities.map((c) => String(c));
|
|
535
578
|
}
|
|
536
579
|
if (typeof spec.toolProfile === "string" && isToolProfileName(spec.toolProfile)) out.toolProfile = spec.toolProfile;
|
|
537
580
|
if (Array.isArray(spec.denyTools)) out.denyTools = spec.denyTools.map((tool) => String(tool));
|
|
538
581
|
if (typeof spec.cwd === "string") out.cwd = spec.cwd;
|
|
582
|
+
if (spec.worktree === true) out.worktree = true;
|
|
583
|
+
if (spec.apply === "merge" || spec.apply === "preserve") out.apply = spec.apply;
|
|
539
584
|
if (typeof spec.memorySection === "string") out.memorySection = spec.memorySection;
|
|
540
585
|
if (typeof spec.noSkills === "boolean") out.noSkills = spec.noSkills;
|
|
541
586
|
if (Array.isArray(spec.skillPaths)) out.skillPaths = spec.skillPaths.map((p) => String(p));
|
|
542
587
|
if (typeof spec.trustProjectCompatRoots === "boolean") out.trustProjectCompatRoots = spec.trustProjectCompatRoots;
|
|
543
588
|
if (responseSchema) out.responseSchema = responseSchema;
|
|
544
|
-
if (
|
|
589
|
+
if (isDispatchIntent(spec.intent)) out.intent = structuredClone(spec.intent);
|
|
590
|
+
const effectiveWriteRoots =
|
|
545
591
|
Array.isArray(spec.writeRoots) &&
|
|
546
592
|
spec.writeRoots.length > 0 &&
|
|
547
593
|
spec.writeRoots.every((root) => typeof root === "string" && root.length > 0)
|
|
548
|
-
|
|
594
|
+
? spec.writeRoots
|
|
595
|
+
: isDispatchIntent(spec.intent) && spec.intent.writeRoots.length > 0
|
|
596
|
+
? spec.intent.writeRoots
|
|
597
|
+
: undefined;
|
|
598
|
+
if (effectiveWriteRoots !== undefined) {
|
|
549
599
|
const jobCwd = typeof spec.cwd === "string" && spec.cwd.length > 0 ? spec.cwd : process.cwd();
|
|
550
|
-
out.writeRoots =
|
|
600
|
+
out.writeRoots = effectiveWriteRoots.map((root) => path.resolve(jobCwd, String(root)));
|
|
551
601
|
}
|
|
552
602
|
if (typeof spec.requestOrigin === "string" && VALID_REQUEST_ORIGINS.has(spec.requestOrigin)) {
|
|
553
603
|
out.requestOrigin = spec.requestOrigin as DispatchRequestOrigin;
|
|
@@ -558,6 +608,7 @@ export function validateJobSpec(spec: unknown): Validated {
|
|
|
558
608
|
if (isValidLineage(spec.lineage)) out.lineage = spec.lineage;
|
|
559
609
|
if (isAutonomyLevel(spec.autonomy)) out.autonomy = spec.autonomy;
|
|
560
610
|
if (isValidGate(spec.gate)) out.gate = cloneGate(spec.gate);
|
|
611
|
+
if (isValidCouncil(spec.council)) out.council = { ...spec.council };
|
|
561
612
|
if (typeof spec.competeStance === "string" && VALID_COMPETE_STANCES.has(spec.competeStance)) {
|
|
562
613
|
out.competeStance = spec.competeStance as CompeteStance;
|
|
563
614
|
}
|
|
@@ -640,9 +691,18 @@ function isValidProtectedArtifactRemap(value: unknown): value is ProtectedArtifa
|
|
|
640
691
|
);
|
|
641
692
|
}
|
|
642
693
|
|
|
643
|
-
const VALID_GATE_ROLES = new Set(["builder", "reviewer", "candidate", "judge"]);
|
|
694
|
+
const VALID_GATE_ROLES = new Set(["builder", "reviewer", "candidate", "judge", "member", "synthesis"]);
|
|
644
695
|
const VALID_GATE_VERDICTS = new Set(["pass", "fail", "revise"]);
|
|
645
|
-
const VALID_PLAN_TOPOLOGIES = new Set([
|
|
696
|
+
const VALID_PLAN_TOPOLOGIES = new Set([
|
|
697
|
+
"parallel",
|
|
698
|
+
"sequential",
|
|
699
|
+
"pipeline",
|
|
700
|
+
"review",
|
|
701
|
+
"compete",
|
|
702
|
+
"council",
|
|
703
|
+
"detached",
|
|
704
|
+
"fleet",
|
|
705
|
+
]);
|
|
646
706
|
const VALID_PLAN_APPROVALS = new Set(["operator", "full-auto"]);
|
|
647
707
|
|
|
648
708
|
function isValidGate(value: unknown): value is RunGateProvenance {
|
|
@@ -674,6 +734,20 @@ function cloneGate(gate: RunGateProvenance): RunGateProvenance {
|
|
|
674
734
|
};
|
|
675
735
|
}
|
|
676
736
|
|
|
737
|
+
function isValidCouncil(value: unknown): value is NonNullable<JobSpec["council"]> {
|
|
738
|
+
return (
|
|
739
|
+
isPlainObject(value) &&
|
|
740
|
+
typeof value.group === "string" &&
|
|
741
|
+
value.group.length > 0 &&
|
|
742
|
+
typeof value.label === "string" &&
|
|
743
|
+
value.label.length > 0 &&
|
|
744
|
+
(value.color === undefined || typeof value.color === "string") &&
|
|
745
|
+
typeof value.round === "number" &&
|
|
746
|
+
Number.isInteger(value.round) &&
|
|
747
|
+
value.round >= 1
|
|
748
|
+
);
|
|
749
|
+
}
|
|
750
|
+
|
|
677
751
|
function isValidPlan(value: unknown): value is RunPlanProvenance {
|
|
678
752
|
if (!isPlainObject(value)) return false;
|
|
679
753
|
if (typeof value.hash !== "string" || value.hash.length === 0) return false;
|
|
@@ -133,6 +133,16 @@ export interface WorkerProcessOptions {
|
|
|
133
133
|
approvedIdentity?: ApprovedWorkerIdentity;
|
|
134
134
|
/** How long bulk output may precede the announce before the peer is refused. */
|
|
135
135
|
attestationGraceMs?: number;
|
|
136
|
+
/**
|
|
137
|
+
* Clock behind the heartbeat stamp, defaulting to `Date.now`. The stamp stays
|
|
138
|
+
* a wall-clock instant in production because the ledger, the receipt, and the
|
|
139
|
+
* evidence record all serialize it as ISO-8601 for an operator to read. That
|
|
140
|
+
* leaves a test with no honest way to assert the stamp advanced: comparing
|
|
141
|
+
* two wall-clock reads taken either side of an interval orders them backward
|
|
142
|
+
* on any host that resyncs its clock in between. A test injects the steppable
|
|
143
|
+
* clock from tests/harness/clock.ts here and asserts on that instead.
|
|
144
|
+
*/
|
|
145
|
+
now?: () => number;
|
|
136
146
|
}
|
|
137
147
|
|
|
138
148
|
/**
|
|
@@ -181,6 +191,7 @@ export function spawnWorkerProcess(
|
|
|
181
191
|
): SpawnedWorker {
|
|
182
192
|
const shutdownGraceMs = opts?.shutdownGraceMs ?? DEFAULT_SHUTDOWN_GRACE_MS;
|
|
183
193
|
const attestationGraceMs = opts?.attestationGraceMs ?? DEFAULT_ATTESTATION_GRACE_MS;
|
|
194
|
+
const now = opts?.now ?? Date.now;
|
|
184
195
|
const approved = opts?.approvedIdentity ?? approvedIdentityForSpec(spec);
|
|
185
196
|
|
|
186
197
|
const child: ChildProcess = spawn(command, [...args], {
|
|
@@ -193,7 +204,7 @@ export function spawnWorkerProcess(
|
|
|
193
204
|
});
|
|
194
205
|
const pid = child.pid ?? null;
|
|
195
206
|
|
|
196
|
-
const heartbeatAt = { current:
|
|
207
|
+
const heartbeatAt = { current: now() };
|
|
197
208
|
|
|
198
209
|
const queue = createBoundedEventQueue();
|
|
199
210
|
const waiters: Array<(r: IteratorResult<unknown>) => void> = [];
|
|
@@ -222,7 +233,7 @@ export function spawnWorkerProcess(
|
|
|
222
233
|
}
|
|
223
234
|
|
|
224
235
|
function push(value: unknown): void {
|
|
225
|
-
heartbeatAt.current =
|
|
236
|
+
heartbeatAt.current = now();
|
|
226
237
|
const w = waiters.shift();
|
|
227
238
|
if (w) {
|
|
228
239
|
w({ value, done: false });
|
|
@@ -367,7 +378,7 @@ export function spawnWorkerProcess(
|
|
|
367
378
|
if (!announceAccepted) failAttestation(`Invalid worker attestation: ${frame.reason}`);
|
|
368
379
|
return;
|
|
369
380
|
}
|
|
370
|
-
heartbeatAt.current =
|
|
381
|
+
heartbeatAt.current = now();
|
|
371
382
|
if (frame.value.kind === "announce") {
|
|
372
383
|
if (announceAccepted || announceFailed) return;
|
|
373
384
|
const verdict = verifyWorkerAttestation(frame.value.attestation, approved);
|
|
@@ -64,119 +64,3 @@ export function evidenceMetricsFromReceipt(receipt: RunReceipt): Record<string,
|
|
|
64
64
|
...(typeof receipt.costUsd === "number" && Number.isFinite(receipt.costUsd) ? { "cost.usd": receipt.costUsd } : {}),
|
|
65
65
|
};
|
|
66
66
|
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Count terminal dispatch tool calls in a `clio-coder run --json` stream: the
|
|
70
|
-
* decomposition checkpoint. Mirrors the dedup rules of the tool-call metric
|
|
71
|
-
* fold (canonical clio finishes win over pi execution ends when both exist).
|
|
72
|
-
* An absent or eventless stream counts zero.
|
|
73
|
-
*/
|
|
74
|
-
export function dispatchCountFromJsonl(stdout: string): number {
|
|
75
|
-
let executionEnds = 0;
|
|
76
|
-
let canonicalFinishes = 0;
|
|
77
|
-
const seenExecutionEnds = new Set<string>();
|
|
78
|
-
const seenCanonicalFinishes = new Set<string>();
|
|
79
|
-
let sawCanonicalFinishEvent = false;
|
|
80
|
-
for (const event of jsonlEvents(stdout)) {
|
|
81
|
-
if (event.type === "tool_execution_end") {
|
|
82
|
-
if (stringField(event, "toolName") !== "dispatch") continue;
|
|
83
|
-
const callId = stringField(event, "toolCallId");
|
|
84
|
-
if (callId !== undefined) {
|
|
85
|
-
if (seenExecutionEnds.has(callId)) continue;
|
|
86
|
-
seenExecutionEnds.add(callId);
|
|
87
|
-
}
|
|
88
|
-
executionEnds += 1;
|
|
89
|
-
continue;
|
|
90
|
-
}
|
|
91
|
-
if (event.type !== "clio_tool_finish" || !isRecord(event.payload)) continue;
|
|
92
|
-
sawCanonicalFinishEvent = true;
|
|
93
|
-
if (stringField(event.payload, "tool") !== "dispatch") continue;
|
|
94
|
-
const callId = stringField(event.payload, "toolCallId") ?? stringField(event, "toolCallId");
|
|
95
|
-
if (callId !== undefined) {
|
|
96
|
-
if (seenCanonicalFinishes.has(callId)) continue;
|
|
97
|
-
seenCanonicalFinishes.add(callId);
|
|
98
|
-
}
|
|
99
|
-
canonicalFinishes += 1;
|
|
100
|
-
}
|
|
101
|
-
return sawCanonicalFinishEvent ? canonicalFinishes : executionEnds;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/** Count model-authored dispatch calls whose normalized task set includes Scout. */
|
|
105
|
-
export function scoutDispatchCountFromJsonl(stdout: string): number {
|
|
106
|
-
const seen = new Set<string>();
|
|
107
|
-
let count = 0;
|
|
108
|
-
for (const event of jsonlEvents(stdout)) {
|
|
109
|
-
if (event.type !== "tool_execution_start" || stringField(event, "toolName") !== "dispatch") continue;
|
|
110
|
-
if (!isRecord(event.args) || !dispatchArgsIncludeAgent(event.args, "scout")) continue;
|
|
111
|
-
const callId = stringField(event, "toolCallId");
|
|
112
|
-
if (callId !== undefined) {
|
|
113
|
-
if (seen.has(callId)) continue;
|
|
114
|
-
seen.add(callId);
|
|
115
|
-
}
|
|
116
|
-
count += 1;
|
|
117
|
-
}
|
|
118
|
-
return count;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function dispatchArgsIncludeAgent(args: Record<string, unknown>, expectedAgent: string): boolean {
|
|
122
|
-
const sharedAgent = stringField(args, "agent") ?? stringField(args, "agent_id") ?? stringField(args, "agentId");
|
|
123
|
-
let tasks: unknown = args.tasks;
|
|
124
|
-
if (typeof tasks === "string") {
|
|
125
|
-
const trimmed = tasks.trim();
|
|
126
|
-
if (trimmed.startsWith("[") || trimmed.startsWith("{")) {
|
|
127
|
-
try {
|
|
128
|
-
tasks = JSON.parse(trimmed) as unknown;
|
|
129
|
-
} catch {
|
|
130
|
-
// A plain task string keeps using the shared agent below.
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
const taskList: unknown[] = Array.isArray(tasks) ? tasks : tasks === undefined ? [{ task: args.task }] : [tasks];
|
|
135
|
-
return taskList.some((task: unknown) => {
|
|
136
|
-
if (typeof task === "string") return sharedAgent?.toLowerCase() === expectedAgent;
|
|
137
|
-
if (!isRecord(task)) return false;
|
|
138
|
-
const agent =
|
|
139
|
-
stringField(task, "agent") ?? stringField(task, "agent_id") ?? stringField(task, "agentId") ?? sharedAgent;
|
|
140
|
-
return agent?.toLowerCase() === expectedAgent;
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Stale-wiki behavioral checkpoint: true when the stream shows a live source
|
|
146
|
-
* read (read/grep start) AFTER a `code_nav mode=wiki` start, i.e. the model
|
|
147
|
-
* did not answer from the wiki alone. Absent either half → false.
|
|
148
|
-
*/
|
|
149
|
-
export function wikiStaleAcknowledgedFromJsonl(stdout: string): boolean {
|
|
150
|
-
let sawWikiLookup = false;
|
|
151
|
-
for (const event of jsonlEvents(stdout)) {
|
|
152
|
-
if (event.type !== "tool_execution_start") continue;
|
|
153
|
-
const toolName = stringField(event, "toolName");
|
|
154
|
-
if (toolName === "code_nav" && isRecord(event.args) && event.args.mode === "wiki") {
|
|
155
|
-
sawWikiLookup = true;
|
|
156
|
-
continue;
|
|
157
|
-
}
|
|
158
|
-
if (sawWikiLookup && (toolName === "read" || toolName === "grep")) return true;
|
|
159
|
-
}
|
|
160
|
-
return false;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
function* jsonlEvents(stdout: string): Generator<Record<string, unknown>> {
|
|
164
|
-
for (const line of stdout.split(/\r?\n/)) {
|
|
165
|
-
if (line.trim().length === 0) continue;
|
|
166
|
-
try {
|
|
167
|
-
const parsed: unknown = JSON.parse(line);
|
|
168
|
-
if (isRecord(parsed)) yield parsed;
|
|
169
|
-
} catch {
|
|
170
|
-
// Non-JSON noise (including the pretty receipt tail) is not an event.
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
function stringField(record: Record<string, unknown>, field: string): string | undefined {
|
|
176
|
-
const value = record[field];
|
|
177
|
-
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
181
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
182
|
-
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Invariant metrics: the promises Clio makes about its own machinery, read
|
|
3
3
|
* from the journal one eval item left behind.
|
|
4
4
|
*
|
|
5
|
-
* These invert what a
|
|
5
|
+
* These invert what a task outcome measures. A weak model that never solved the
|
|
6
6
|
* task leaves every one of them intact; a strong model that solved it leaves
|
|
7
7
|
* them broken the moment Clio failed to seal, to agree with itself, or to
|
|
8
8
|
* write a receipt its own ledger can authenticate. The task outcome and the
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import { shellQuote } from "../../../core/shell-quote.js";
|
|
2
|
-
import {
|
|
3
|
-
dispatchCountFromJsonl,
|
|
4
|
-
evidenceMetricsFromReceipt,
|
|
5
|
-
receiptFromRunJsonStdout,
|
|
6
|
-
scoutDispatchCountFromJsonl,
|
|
7
|
-
wikiStaleAcknowledgedFromJsonl,
|
|
8
|
-
} from "../metrics/evidence.js";
|
|
2
|
+
import { evidenceMetricsFromReceipt, receiptFromRunJsonStdout } from "../metrics/evidence.js";
|
|
9
3
|
import { streamInvariantMetrics } from "../metrics/invariants.js";
|
|
10
4
|
import { tokenMetricEntries } from "../metrics/token-stream.js";
|
|
11
5
|
import type { EvalRunnerV2, EvalSuiteTargetV2 } from "../schema/suite.js";
|
|
@@ -58,9 +52,6 @@ export async function runClioRunRunner(
|
|
|
58
52
|
"tools.failed": tools.failed,
|
|
59
53
|
"tools.blocked": tools.blocked,
|
|
60
54
|
"verifier.exitCode": result.exitCode,
|
|
61
|
-
"dispatch.count": dispatchCountFromJsonl(toolMetricStream),
|
|
62
|
-
"dispatch.scoutCount": scoutDispatchCountFromJsonl(toolMetricStream),
|
|
63
|
-
"wiki.staleAcknowledged": wikiStaleAcknowledgedFromJsonl(toolMetricStream),
|
|
64
55
|
...(receipt === null ? {} : evidenceMetricsFromReceipt(receipt)),
|
|
65
56
|
...(receipt === null
|
|
66
57
|
? {}
|