@iowarp/clio-coder 0.3.8 → 0.4.0
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 +102 -0
- package/NOTICE +33 -0
- package/README.md +12 -3
- package/dist/{acp-U67UHUK2.js → acp-G5WJBNCT.js} +13 -12
- package/dist/{agents-YU6SGALZ.js → agents-FMV2Q5G4.js} +41 -36
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-5ZPJOIVG.js → auth-3IDSJEIK.js} +18 -18
- package/dist/{builtins-C6JMZVV6.js → builtins-XCZWXSC7.js} +5 -5
- package/dist/{chunk-IFBNV6H6.js → chunk-2ANTL7MR.js} +3 -3
- package/dist/{chunk-5FR74PWO.js → chunk-2JDWVJND.js} +2 -2
- package/dist/{chunk-XWSF374K.js → chunk-2OQE55CK.js} +3 -3
- package/dist/{chunk-5H3GB5BO.js → chunk-32KWKNSF.js} +8 -384
- package/dist/{chunk-KTYTFRMB.js → chunk-36EJLSQQ.js} +34 -36
- package/dist/{chunk-FHJEP5SW.js → chunk-3BT2XMV4.js} +19 -13
- package/dist/chunk-3DPEIQKN.js +113 -0
- package/dist/{chunk-GU2UIAFZ.js → chunk-3URVFKWK.js} +7 -7
- package/dist/{chunk-WEH5XRJQ.js → chunk-3XML7CDN.js} +3 -3
- package/dist/chunk-42FMPA75.js +101 -0
- package/dist/{chunk-A2NJGIB3.js → chunk-5LXZXPKX.js} +2 -2
- package/dist/{chunk-VCBR6CU7.js → chunk-5PSMVOLM.js} +2 -2
- package/dist/{chunk-NMPKI6XL.js → chunk-6DB53AJS.js} +203 -25
- package/dist/{chunk-3BINW3FP.js → chunk-76ONBSIA.js} +2 -2
- package/dist/{chunk-26LEYJZH.js → chunk-7MCTRUCE.js} +2 -2
- package/dist/{chunk-TYPGUK6W.js → chunk-AB44T6BB.js} +111 -5
- package/dist/{chunk-K4XHGFR5.js → chunk-B7OBL7PK.js} +317 -721
- package/dist/{chunk-B5CSFE7B.js → chunk-BBVJUZHB.js} +2 -2
- package/dist/{chunk-EQ63NRB7.js → chunk-BBVYXMFO.js} +2 -2
- package/dist/{chunk-ZVJ5BLO2.js → chunk-BKFJHQCA.js} +154 -16
- package/dist/chunk-BKFM6EJV.js +462 -0
- package/dist/chunk-BMS5RKQY.js +27 -0
- package/dist/{chunk-ZNLWCMVZ.js → chunk-BPKCPIL7.js} +2 -2
- package/dist/{chunk-TLQJPP24.js → chunk-BUMFYQFY.js} +1394 -1349
- package/dist/{chunk-BNAZZHFG.js → chunk-BYP5D4HI.js} +1 -1
- package/dist/chunk-C2LTL2W6.js +2447 -0
- package/dist/{chunk-ME6CCNFO.js → chunk-CODPRO7Q.js} +8 -8
- package/dist/{chunk-E77JEWSD.js → chunk-CTJ4RNAA.js} +7 -37
- package/dist/{chunk-ODFEOB4F.js → chunk-CY6FY24N.js} +26 -8
- package/dist/{chunk-7RFXX52T.js → chunk-DQITNCXG.js} +642 -172
- package/dist/{chunk-TTHACPOM.js → chunk-DYJP44XW.js} +578 -117
- package/dist/{chunk-2HFZQUHL.js → chunk-F4CKPOEQ.js} +18 -8
- package/dist/{chunk-DGSYXYMX.js → chunk-FEFIFZTL.js} +3 -3
- package/dist/{chunk-GWS3VEIW.js → chunk-FWDFM5ZU.js} +24 -3
- package/dist/{chunk-MV3K5QF2.js → chunk-GCSMB2KY.js} +2 -2
- package/dist/chunk-GKF55TAZ.js +391 -0
- package/dist/{chunk-VWZOAB7K.js → chunk-GR5G2PVF.js} +9 -8
- package/dist/{chunk-4DGYLA73.js → chunk-GXNLGKAB.js} +80 -9
- package/dist/chunk-HHV2GANA.js +88 -0
- package/dist/{chunk-IIZWH4XA.js → chunk-HI63TFOG.js} +5 -4
- package/dist/{chunk-WLFILSD5.js → chunk-HJJTYUHX.js} +113 -83
- package/dist/{chunk-TT36MB5S.js → chunk-HLW2MRKE.js} +3 -1
- package/dist/{chunk-PMDBGQSJ.js → chunk-HWHKMHUA.js} +7 -7
- package/dist/chunk-HZHHCK24.js +1631 -0
- package/dist/{chunk-WSB3FPX7.js → chunk-I5VEOC6I.js} +39 -143
- package/dist/chunk-IBEBSCYA.js +564 -0
- package/dist/chunk-IQ7KR472.js +362 -0
- package/dist/{chunk-A3WNZD3P.js → chunk-J4W7KFM7.js} +949 -972
- package/dist/{chunk-TB5666IT.js → chunk-JDG2WCRO.js} +5 -5
- package/dist/{chunk-N22QMJKY.js → chunk-K5C3NCBD.js} +4 -4
- package/dist/{chunk-CGKSTWHD.js → chunk-K6BSR66V.js} +2 -1
- package/dist/{chunk-5C3AQNDW.js → chunk-KFZI4NIL.js} +216 -38
- package/dist/chunk-KMVISBZR.js +132 -0
- package/dist/{chunk-WXY7KU3G.js → chunk-LDQ2ZF2M.js} +2 -2
- package/dist/{chunk-XN3L4EYL.js → chunk-LQ3DZAMX.js} +3 -3
- package/dist/{chunk-U6MBIEMB.js → chunk-LY4S7GJC.js} +173 -144
- package/dist/{chunk-4SPRNWDE.js → chunk-MLKNTWH2.js} +19 -19
- package/dist/{chunk-MVVUPGPW.js → chunk-MXHC5QYU.js} +6 -6
- package/dist/chunk-NEKRRTYW.js +56 -0
- package/dist/{chunk-SPULKLCF.js → chunk-NHCZP4K7.js} +3 -3
- package/dist/chunk-NHLBIGRH.js +1506 -0
- package/dist/chunk-NQQH3YT7.js +302 -0
- package/dist/chunk-NYS75XW5.js +15 -0
- package/dist/{chunk-GN57SG4G.js → chunk-O4XIVISU.js} +10 -8
- package/dist/{chunk-EMYUUSFG.js → chunk-O6TL7WWY.js} +6 -6
- package/dist/chunk-OQBA45DZ.js +97 -0
- package/dist/{chunk-LU7P4LHA.js → chunk-P3FOHJT4.js} +2 -2
- package/dist/chunk-PMZCIOCJ.js +25 -0
- package/dist/{chunk-I4HZDVNP.js → chunk-PQEFIJ36.js} +2 -2
- package/dist/{chunk-J3YUBZWY.js → chunk-QBJA7R7N.js} +62 -6
- package/dist/chunk-QDC3K2U3.js +262 -0
- package/dist/{chunk-2HEJ2F35.js → chunk-QLFS5GO2.js} +22 -10
- package/dist/{chunk-7RGZWPB6.js → chunk-QLL7ILRG.js} +95 -32
- package/dist/{chunk-YS5VLNH5.js → chunk-QREDIESB.js} +6 -6
- package/dist/chunk-QSNYB6ZV.js +195 -0
- package/dist/{chunk-GOXNB3AO.js → chunk-RAPCMZL4.js} +75 -4
- package/dist/chunk-RKKLTLYB.js +45 -0
- package/dist/{chunk-P43ETTHK.js → chunk-SJ5ZKQ4S.js} +2 -2
- package/dist/{chunk-GPIEI3LY.js → chunk-SP2RXXYO.js} +6 -54
- package/dist/chunk-SUCTJL45.js +45 -0
- package/dist/{chunk-DYIM5TJT.js → chunk-SUW5DORT.js} +263 -7
- package/dist/chunk-T56WDKA5.js +183 -0
- package/dist/chunk-TVHHYFHE.js +255 -0
- package/dist/{chunk-FJ3H4MN5.js → chunk-TZ3SGWZZ.js} +3 -3
- package/dist/{chunk-MXKJU4JB.js → chunk-U77AMWDL.js} +91 -10
- package/dist/{chunk-5DHKRSMQ.js → chunk-ULC6OTWO.js} +11 -7
- package/dist/{chunk-RWSI4YD7.js → chunk-UM7N4G5A.js} +33 -12
- package/dist/{chunk-FCSXB6T2.js → chunk-UOSL25KY.js} +14 -2
- package/dist/{chunk-IGWKHNIQ.js → chunk-UXMFQ54G.js} +44 -37
- package/dist/{chunk-HFSBBKSQ.js → chunk-V5DHCITQ.js} +171 -3
- package/dist/{chunk-5WIGXA4T.js → chunk-VAZSBTKF.js} +111 -4
- package/dist/{chunk-VHN4MY6O.js → chunk-VEO4AP2K.js} +2 -2
- package/dist/{chunk-IJ7RPIYJ.js → chunk-VFA6GDY5.js} +65 -4
- package/dist/{chunk-PT7HYKEM.js → chunk-VO2LKSTM.js} +2 -2
- package/dist/chunk-VO67MWHC.js +75 -0
- package/dist/{chunk-XK56QHLX.js → chunk-VPKWYKEY.js} +19 -5
- package/dist/{chunk-TANS5ZJS.js → chunk-VYMXRQI6.js} +36 -22
- package/dist/{chunk-WWCZ5F23.js → chunk-W5VSYASO.js} +77 -16
- package/dist/{chunk-WNIJTQQK.js → chunk-WZR7K7ZX.js} +72 -116
- package/dist/{chunk-5Q2VVUKB.js → chunk-X3YGUTOB.js} +4 -4
- package/dist/chunk-X75E3D2N.js +686 -0
- package/dist/{chunk-VAWNZU7Z.js → chunk-YDFRH54B.js} +4 -4
- package/dist/chunk-YJX4SHTD.js +40 -0
- package/dist/{chunk-ZI647VB5.js → chunk-YPI3QQCF.js} +2 -2
- package/dist/chunk-Z2RR6MAK.js +127 -0
- package/dist/{chunk-FBVTI2TJ.js → chunk-Z4TXYIEG.js} +12 -131
- package/dist/cli/index.js +47 -36
- package/dist/{clio-QVTYJ57A.js → clio-2JXHBBY5.js} +7 -7
- package/dist/{code-nav-FGGFIE7L.js → code-nav-3YYRMYNF.js} +8 -8
- package/dist/{compile-cache-CVJMMODC.js → compile-cache-7FPE6PS3.js} +3 -3
- package/dist/{components-ZFA3SAER.js → components-RYZV4JGP.js} +5 -5
- package/dist/{config-LW5IJFQN.js → config-QZPCMYSO.js} +99 -63
- package/dist/{configure-7XIZCOU4.js → configure-TEGEBYCA.js} +23 -22
- package/dist/{context-Y6Y7QPR6.js → context-AV7OEZ4D.js} +12 -12
- package/dist/{context-L3WL3X7K.js → context-E6H5RNMC.js} +56 -47
- package/dist/{context-N52ZA626.js → context-GSXUE4CT.js} +29 -27
- package/dist/{context-clear-MBQRLSDQ.js → context-clear-SHIBYK6T.js} +55 -46
- package/dist/{context-index-HVMFQHK3.js → context-index-HNG3MOME.js} +2 -2
- package/dist/{context-working-set-GS6DSO7F.js → context-working-set-5ZGKPGZQ.js} +13 -13
- package/dist/{dispatch-runner-22ZCNOM3.js → dispatch-runner-EFMJT4LD.js} +93 -64
- package/dist/{docs-7LQ23DLM.js → docs-23KQS3XK.js} +5 -5
- package/dist/doctor-QOA5FNY5.js +313 -0
- package/dist/{eval-BEC2WHDA.js → eval-TFBYQH4H.js} +2032 -156
- package/dist/eval-inventory-SXH7PDKX.js +316 -0
- package/dist/{evidence-REJUMSKM.js → evidence-ERGESKGN.js} +203 -48
- package/dist/{evolve-PY5ZBA5K.js → evolve-VDXTSYCJ.js} +52 -43
- package/dist/{extensions-HVKU65YU.js → extensions-7BGBHN57.js} +13 -7
- package/dist/{fleet-7WZEWRFA.js → fleet-2RRVDF2V.js} +228 -108
- package/dist/{fleet-commands-UVHWM76J.js → fleet-commands-VJ726XIA.js} +11 -11
- package/dist/fleet-decisions-EPAPM3XJ.js +157 -0
- package/dist/{fleet-graph-6ULH7PES.js → fleet-graph-JF5QOATM.js} +18 -15
- package/dist/fleet-inspect-VLY4S7QM.js +442 -0
- package/dist/{fleet-preflight-J53T6CCE.js → fleet-preflight-AIZUEJOY.js} +5 -5
- package/dist/{fleet-validate-72PC4SLA.js → fleet-validate-AJRPDMDV.js} +22 -19
- package/dist/fleet-verify-JFEL2L3H.js +175 -0
- package/dist/fleet-view-ZCON35AG.js +102 -0
- package/dist/{init-OG3TPGQG.js → init-DN2WWLFE.js} +72 -62
- package/dist/install-XGLBQY5E.js +13 -0
- package/dist/interop-OZBKXAYL.js +114 -0
- package/dist/{library-CNTMPLRF.js → library-YWZG7IMW.js} +21 -18
- package/dist/{memory-6IS7F275.js → memory-I4C4HMLW.js} +54 -45
- package/dist/{models-ENRJDA5W.js → models-CEYXJBO6.js} +33 -30
- package/dist/{monitor-XLDVO7TN.js → monitor-NZ6GCI3P.js} +59 -52
- package/dist/{orchestrator-6KSPYRHA.js → orchestrator-GCGQ4N5I.js} +7827 -7328
- package/dist/panes-HMABYVO4.js +58 -0
- package/dist/panes-KY6W3V2E.js +103 -0
- package/dist/{paths-DBXMZMDU.js → paths-II4K7DNR.js} +5 -5
- package/dist/{reset-RZ4ER727.js → reset-DQ6FGCSH.js} +13 -11
- package/dist/resources-BB3MVJMD.js +111 -0
- package/dist/{run-Y2CNK5RU.js → run-H2GQDUER.js} +119 -87
- package/dist/{share-A55GYP6Z.js → share-GTJN6A5O.js} +20 -17
- package/dist/{skills-ALC5J6AT.js → skills-L55TEW6R.js} +33 -24
- package/dist/{skills-eval-JPBEBYQU.js → skills-eval-XVXPH2JI.js} +67 -56
- package/dist/skills-inventory-S4MXPJFV.js +126 -0
- package/dist/slash-commands-ZSGASKJC.js +77 -0
- package/dist/{steer-GGWFUJUD.js → steer-RZGSCY4R.js} +4 -4
- package/dist/{support-MIETYA5E.js → support-PKEUNNQL.js} +6 -6
- package/dist/{targets-VGNXIR3S.js → targets-NCPZ644J.js} +68 -40
- package/dist/{terminal-lease-WOBR64YA.js → terminal-lease-44SV3YCN.js} +6 -4
- package/dist/tools-DAF3DI3C.js +27 -0
- package/dist/{trace-PNCASAXC.js → trace-FYVW2MQA.js} +207 -10
- package/dist/tui-primitives-2AKXQNZK.js +13 -0
- package/dist/{uninstall-ZJF5H5ZN.js → uninstall-DW2PNOIC.js} +5 -5
- package/dist/{upgrade-FUSUAGHR.js → upgrade-3XPP6OQL.js} +27 -24
- package/dist/{usage-N4MKVHKD.js → usage-3NLHGTU2.js} +114 -62
- package/dist/{verifiers-YAWOJ3H2.js → verifiers-SSQONKRT.js} +172 -13
- package/dist/{verify-LTDHYBGY.js → verify-3U6J7FZI.js} +10 -10
- package/dist/{web-fetch-2YHJ3KTG.js → web-fetch-S7RR6GZ7.js} +3 -3
- package/dist/{wiki-generate-6M7GHTBJ.js → wiki-generate-CEHYGPGQ.js} +75 -65
- package/dist/with-panes-MKB46MPQ.js +782 -0
- package/dist/worker/entry.js +106 -75
- package/docs/README.md +3 -2
- package/docs/acp.md +24 -3
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +2 -2
- package/docs/artifact-versions.md +9 -1
- package/docs/built-in-agents.md +1 -1
- package/docs/capacity-and-scheduling.md +62 -3
- package/docs/commands-and-modes.md +31 -2
- package/docs/configuration-and-targets.md +69 -12
- package/docs/context-engine.md +63 -4
- package/docs/development-pipeline.md +19 -0
- package/docs/dispatch-typed-intent.md +385 -0
- package/docs/documentation-coverage.md +5 -5
- package/docs/documentation-guide.md +1 -1
- package/docs/environment-variables.md +3 -0
- package/docs/eval-runner.md +262 -11
- package/docs/evals-internal.md +72 -2
- package/docs/evidence-and-memory.md +12 -11
- package/docs/evolution.md +1 -1
- package/docs/exit-codes-and-output.md +1 -1
- package/docs/extensions-and-sharing.md +27 -1
- package/docs/fleet-dispatch.md +25 -4
- package/docs/installation-and-lifecycle.md +15 -2
- package/docs/middleware-and-components.md +1 -1
- package/docs/model-catalog.md +10 -1
- package/docs/observability.md +55 -4
- package/docs/proactive-memory.md +127 -14
- package/docs/prompt-envelope-and-tools.md +19 -1
- package/docs/provider-adapter-cookbook.md +1 -1
- package/docs/release-cut-checklist.md +19 -3
- package/docs/safety-model.md +2 -2
- package/docs/scientific-validation.md +3 -3
- package/docs/session-lifecycle.md +1 -1
- package/docs/skills-marketplace.md +1 -1
- package/docs/tool-usage.md +18 -8
- package/docs/trace-store.md +1 -1
- package/docs/troubleshooting.md +88 -1
- package/docs/tui-design.md +1 -1
- package/docs/worker-dispatch-mechanics.md +1 -1
- package/package.json +5 -2
- package/src/cli/acp.ts +6 -2
- package/src/cli/agents.ts +1 -1
- package/src/cli/argv.ts +25 -0
- package/src/cli/config-inspect.ts +33 -6
- package/src/cli/config.ts +1 -1
- package/src/cli/configure.ts +23 -21
- package/src/cli/doctor-panes.ts +124 -0
- package/src/cli/doctor-state-size.ts +82 -0
- package/src/cli/doctor-toolchain.ts +57 -0
- package/src/cli/doctor.ts +22 -1
- package/src/cli/eval-inventory.ts +436 -0
- package/src/cli/eval.ts +93 -16
- package/src/cli/evidence-detail.ts +88 -0
- package/src/cli/evidence-inventory.ts +183 -0
- package/src/cli/evidence.ts +30 -5
- package/src/cli/extensions.ts +5 -1
- package/src/cli/fleet-decisions.ts +69 -0
- package/src/cli/fleet-inspect.ts +334 -0
- package/src/cli/fleet-verify.ts +133 -0
- package/src/cli/fleet-view.ts +810 -0
- package/src/cli/fleet.ts +179 -39
- package/src/cli/index.ts +14 -2
- package/src/cli/interop-inspect.ts +128 -0
- package/src/cli/interop.ts +34 -0
- package/src/cli/panes.ts +35 -0
- package/src/cli/reset.ts +5 -2
- package/src/cli/run.ts +58 -0
- package/src/cli/skills-inventory.ts +185 -0
- package/src/cli/skills.ts +16 -13
- package/src/cli/targets.ts +44 -13
- package/src/cli/tools.ts +321 -0
- package/src/cli/trace-inspect.ts +252 -0
- package/src/cli/trace.ts +85 -5
- package/src/cli/usage.ts +63 -14
- package/src/cli/verifiers-inspect.ts +347 -0
- package/src/cli/verifiers.ts +9 -0
- package/src/core/bus-events.ts +33 -1
- package/src/core/cache-telemetry.ts +42 -0
- package/src/core/config.ts +67 -0
- package/src/core/defaults.ts +124 -8
- package/src/core/endpoint-key.ts +27 -0
- package/src/core/residency-target-key.ts +25 -0
- package/src/core/response-schema.ts +80 -6
- package/src/core/theme-token-hex.ts +43 -0
- package/src/core/tool-names.ts +2 -1
- package/src/core/xdg.ts +1 -1
- package/src/domains/agents/fleets/build-review.md +0 -3
- package/src/domains/agents/fleets/build-test.md +0 -3
- package/src/domains/agents/result-contract-filesystem.ts +32 -0
- package/src/domains/agents/result-contract.ts +164 -35
- package/src/domains/config/classify.ts +6 -0
- package/src/domains/context/codewiki/coordinator.ts +12 -4
- package/src/domains/dispatch/admission-error.ts +9 -0
- package/src/domains/dispatch/admission.ts +52 -14
- package/src/domains/dispatch/capacity-lease.ts +118 -9
- package/src/domains/dispatch/contract.ts +11 -0
- package/src/domains/dispatch/council-topology.ts +398 -0
- package/src/domains/dispatch/execution-plan.ts +44 -4
- package/src/domains/dispatch/extension.ts +378 -82
- package/src/domains/dispatch/fleet-node-prompt.ts +62 -0
- package/src/domains/dispatch/fleet-plan.ts +7 -2
- package/src/domains/dispatch/fleet-run.ts +87 -4
- package/src/domains/dispatch/gate-decisions.ts +11 -1
- package/src/domains/dispatch/gate-role-prompts.ts +9 -0
- package/src/domains/dispatch/gate-topology.ts +289 -0
- package/src/domains/dispatch/heartbeat.ts +32 -8
- package/src/domains/dispatch/index.ts +22 -0
- package/src/domains/dispatch/intent-compatibility.ts +330 -0
- package/src/domains/dispatch/intent.ts +85 -1
- package/src/domains/dispatch/orphan-recovery.ts +5 -0
- package/src/domains/dispatch/reservation-store.ts +139 -11
- package/src/domains/dispatch/run-event-journal-bridge.ts +149 -0
- package/src/domains/dispatch/run-event-journal.ts +598 -0
- package/src/domains/dispatch/state.ts +49 -1
- package/src/domains/dispatch/types.ts +13 -0
- package/src/domains/dispatch/validation.ts +33 -8
- package/src/domains/dispatch/worker-spawn.ts +25 -11
- package/src/domains/dispatch/write-boundary-enforcer.ts +20 -3
- package/src/domains/dispatch/write-boundary.ts +62 -1
- 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 +342 -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/inventory.ts +113 -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/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 +127 -0
- 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 +105 -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 +2 -13
- package/src/domains/evidence/eval.ts +2 -12
- package/src/domains/evidence/findings-markdown.ts +33 -0
- package/src/domains/evidence/run-trust.ts +7 -113
- package/src/domains/evidence/store.ts +6 -0
- package/src/domains/evidence/trust-projection.ts +2 -2
- package/src/domains/extensions/compatibility.ts +285 -0
- package/src/domains/extensions/discovery.ts +38 -3
- package/src/domains/extensions/resources.ts +1 -1
- package/src/domains/extensions/state.ts +12 -3
- package/src/domains/extensions/types.ts +2 -0
- package/src/domains/lifecycle/doctor.ts +69 -1
- package/src/domains/memory/index.ts +14 -1
- package/src/domains/memory/task-bank-promotion.ts +64 -0
- package/src/domains/memory/task-memory-policy.ts +82 -17
- 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 +3 -0
- package/src/domains/middleware/index.ts +1 -0
- package/src/domains/middleware/memory-intervention.ts +97 -21
- package/src/domains/middleware/memory-step-endpoint.ts +71 -0
- package/src/domains/mux/contract.ts +434 -0
- package/src/domains/mux/detect.ts +158 -0
- package/src/domains/mux/extension.ts +47 -0
- package/src/domains/mux/index.ts +96 -0
- package/src/domains/mux/manifest.ts +6 -0
- package/src/domains/mux/operations.ts +164 -0
- package/src/domains/mux/pane-registry.ts +90 -0
- package/src/domains/mux/protocol.ts +49 -0
- package/src/domains/mux/socket-client.ts +816 -0
- package/src/domains/mux/types.ts +222 -0
- package/src/domains/mux/viewer-command.ts +59 -0
- package/src/domains/mux/yazi/assets/init.lua +2 -0
- package/src/domains/mux/yazi/assets/plugins/git.yazi/LICENSE +21 -0
- package/src/domains/mux/yazi/assets/plugins/git.yazi/README.md +78 -0
- package/src/domains/mux/yazi/assets/plugins/git.yazi/main.lua +255 -0
- package/src/domains/mux/yazi/assets/plugins/git.yazi/types.lua +12 -0
- package/src/domains/mux/yazi/assets/yazi.toml +17 -0
- package/src/domains/mux/yazi/event-stream.ts +180 -0
- package/src/domains/mux/yazi/profile.ts +299 -0
- package/src/domains/mux/yazi/session.ts +228 -0
- package/src/domains/mux/yazi/theme.ts +30 -0
- package/src/domains/observability/background-memory-usage.ts +140 -0
- package/src/domains/observability/cost.ts +22 -1
- package/src/domains/observability/index.ts +9 -0
- package/src/domains/observability/out-of-turn-usage.ts +51 -2
- package/src/domains/observability/trace-store.ts +234 -2
- package/src/domains/prompts/compiler.ts +100 -13
- package/src/domains/providers/endpoint-capacity.ts +228 -0
- package/src/domains/providers/endpoint-slots-store.ts +189 -0
- package/src/domains/providers/extension.ts +20 -3
- package/src/domains/providers/index.ts +32 -0
- package/src/domains/providers/model-runtime-capabilities.ts +32 -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/boot-manifest.ts +1 -0
- package/src/domains/providers/runtimes/builtins.ts +2 -0
- 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/runtimes/protocol/litellm.ts +375 -0
- package/src/domains/providers/support.ts +1 -0
- package/src/domains/providers/target-model-cache.ts +124 -0
- package/src/domains/providers/types/capability-flags.ts +2 -0
- package/src/domains/providers/types/target-descriptor.ts +2 -0
- package/src/domains/resources/index.ts +3 -0
- package/src/domains/resources/prompts/loader.ts +95 -33
- package/src/domains/resources/skills/loader.ts +33 -0
- package/src/domains/safety/action-classifier.ts +6 -0
- package/src/domains/safety/call-target.ts +52 -0
- package/src/domains/safety/run-effects.ts +35 -4
- 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/domains/toolchain/archive.ts +175 -0
- package/src/domains/toolchain/contract.ts +28 -0
- package/src/domains/toolchain/extension.ts +47 -0
- package/src/domains/toolchain/index.ts +39 -0
- package/src/domains/toolchain/install.ts +327 -0
- package/src/domains/toolchain/manifest.ts +8 -0
- package/src/domains/toolchain/paths.ts +34 -0
- package/src/domains/toolchain/registry.ts +265 -0
- package/src/domains/toolchain/remove.ts +218 -0
- package/src/domains/toolchain/resolve.ts +182 -0
- package/src/domains/toolchain/types.ts +113 -0
- package/src/domains/toolchain/version.ts +88 -0
- package/src/engine/acp/adapter.ts +18 -3
- package/src/engine/acp/server.ts +413 -70
- package/src/engine/acp/types.ts +19 -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/claude/sdk-module.ts +98 -0
- package/src/engine/claude/sdk-runtime.ts +19 -11
- package/src/engine/provider-payload.ts +29 -1
- package/src/engine/tui-primitives.ts +21 -0
- package/src/engine/tui.ts +1 -0
- package/src/engine/worker-runtime.ts +2 -13
- package/src/entry/boot-options.ts +2 -0
- package/src/entry/orchestrator.ts +279 -35
- package/src/entry/panes-activation.ts +31 -0
- package/src/entry/with-panes.ts +20 -0
- 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 +41 -10
- package/src/interactive/cost-overlay.ts +66 -6
- package/src/interactive/council-grid.ts +1 -3
- package/src/interactive/council.ts +11 -0
- package/src/interactive/dispatch-board.ts +102 -20
- package/src/interactive/fleet-run-preview.ts +41 -15
- package/src/interactive/handoff-round.ts +41 -2
- package/src/interactive/interactive-application.ts +177 -7
- package/src/interactive/interactive-input-runtime.ts +15 -0
- package/src/interactive/interactive-presentation.ts +4 -0
- package/src/interactive/interactive-shell.ts +20 -17
- package/src/interactive/interactive-slash-runtime.ts +63 -10
- package/src/interactive/memory-overlay.ts +9 -0
- package/src/interactive/modal-marker.ts +170 -0
- package/src/interactive/mutation-preview.ts +295 -0
- package/src/interactive/mux-bridge.ts +214 -0
- package/src/interactive/overlay-frame.ts +58 -2
- package/src/interactive/overlay-general-openers.ts +17 -0
- package/src/interactive/overlay-key-routing.ts +52 -3
- package/src/interactive/overlay-lifecycle.ts +56 -7
- package/src/interactive/overlay-model-selectors.ts +40 -3
- package/src/interactive/overlay-permission-lifecycle.ts +112 -24
- package/src/interactive/overlay-session-lifecycle.ts +73 -9
- package/src/interactive/overlay-transitions.ts +18 -4
- package/src/interactive/overlays/agents.ts +1 -0
- package/src/interactive/overlays/ask-user.ts +227 -49
- package/src/interactive/overlays/auth-dialog.ts +1 -0
- package/src/interactive/overlays/context-reset.ts +1 -0
- package/src/interactive/overlays/cwd-fallback.ts +1 -0
- package/src/interactive/overlays/decisions.ts +11 -11
- package/src/interactive/overlays/extensions.ts +1 -0
- package/src/interactive/overlays/fleet-run-approval.ts +1 -0
- package/src/interactive/overlays/handoff-review.ts +1 -0
- package/src/interactive/overlays/help-reference.ts +6 -0
- package/src/interactive/overlays/interop.ts +1 -0
- package/src/interactive/overlays/library-install-confirm.ts +1 -0
- package/src/interactive/overlays/library-tabs.ts +28 -0
- package/src/interactive/overlays/list-overlay.ts +10 -1
- package/src/interactive/overlays/message-picker.ts +1 -0
- package/src/interactive/overlays/model-scope.ts +86 -0
- package/src/interactive/overlays/model-selector.ts +1 -0
- package/src/interactive/overlays/prompts.ts +12 -1
- package/src/interactive/overlays/session-selector.ts +1 -0
- package/src/interactive/overlays/settings-sections.ts +30 -0
- package/src/interactive/overlays/settings.ts +614 -45
- package/src/interactive/overlays/side-question.ts +1 -0
- package/src/interactive/overlays/skills-hub.ts +3 -11
- package/src/interactive/overlays/tree-selector.ts +1 -0
- package/src/interactive/pane-policy.ts +46 -0
- package/src/interactive/panes-runtime.ts +292 -0
- 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/compaction-summary.ts +29 -0
- package/src/interactive/renderers/tool-execution.ts +4 -0
- package/src/interactive/renderers/worker-entry.ts +122 -14
- package/src/interactive/side-question.ts +58 -1
- package/src/interactive/slash-commands.ts +251 -15
- 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/tasks-overlay.ts +1 -0
- package/src/interactive/terminal-lease.ts +2 -0
- package/src/interactive/theme/tokens.ts +3 -14
- package/src/interactive/turn-context.ts +346 -33
- 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 +109 -1
- package/src/interactive/view/view-overlay.ts +29 -3
- package/src/interactive/watch-pane.ts +152 -0
- package/src/interactive/worker-progress.ts +7 -1
- package/src/interactive/worker-receipts.ts +19 -1
- package/src/interactive/worker-stream.ts +5 -0
- package/src/interactive/yazi-bridge.ts +444 -0
- package/src/tools/ask-user.ts +43 -2
- package/src/tools/bootstrap.ts +26 -2
- package/src/tools/builtin-tool-catalog.ts +15 -0
- package/src/tools/compete-worktrees.ts +83 -2
- package/src/tools/core-bootstrap.ts +2 -1
- package/src/tools/dispatch-admission.ts +14 -3
- package/src/tools/dispatch-arguments.ts +20 -20
- package/src/tools/dispatch-plan.ts +17 -9
- package/src/tools/dispatch-run-events.ts +134 -19
- package/src/tools/dispatch-runner.ts +29 -7
- package/src/tools/dispatch-scout.ts +1 -1
- package/src/tools/dispatch-types.ts +15 -3
- package/src/tools/dispatch.ts +1 -1
- package/src/tools/executables.ts +17 -14
- package/src/tools/observation.ts +54 -4
- package/src/tools/panes-surface.ts +38 -0
- package/src/tools/panes.ts +112 -0
- package/src/tools/policy.ts +10 -1
- package/src/tools/presentation.ts +1 -0
- package/src/tools/registry.ts +16 -0
- package/dist/chunk-AOCYTWAV.js +0 -449
- package/dist/chunk-HLE42MG7.js +0 -37
- package/dist/chunk-HWUFFB6L.js +0 -83
- package/dist/chunk-JOZYP4GM.js +0 -279
- package/dist/doctor-M7YEDGAE.js +0 -91
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
} from "node:fs";
|
|
35
35
|
import { hostname } from "node:os";
|
|
36
36
|
import { join, relative, resolve } from "node:path";
|
|
37
|
-
import type { RunKind } from "../domains/dispatch/types.js";
|
|
37
|
+
import type { RunGateWorktreeProvenance, RunKind } from "../domains/dispatch/types.js";
|
|
38
38
|
import {
|
|
39
39
|
commitWorktreePath,
|
|
40
40
|
isCanonicalWorktreePathInside,
|
|
@@ -47,6 +47,24 @@ export interface CandidateWorktree {
|
|
|
47
47
|
index: number;
|
|
48
48
|
branch: string;
|
|
49
49
|
path: string;
|
|
50
|
+
provenance?: RunGateWorktreeProvenance;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Narrow mux surface used by compete; the native functions remain usable alone. */
|
|
54
|
+
export interface CompeteMuxWorktrees {
|
|
55
|
+
available(): boolean;
|
|
56
|
+
worktreeCreate(request: {
|
|
57
|
+
cwd: string;
|
|
58
|
+
branch: string;
|
|
59
|
+
base: string;
|
|
60
|
+
path: string;
|
|
61
|
+
label: string;
|
|
62
|
+
focus: boolean;
|
|
63
|
+
}): Promise<{
|
|
64
|
+
workspaceId: string;
|
|
65
|
+
worktree: { path: string; branch: string | null };
|
|
66
|
+
} | null>;
|
|
67
|
+
worktreeRemove(workspaceId: string, options?: { force?: boolean }): Promise<boolean>;
|
|
50
68
|
}
|
|
51
69
|
|
|
52
70
|
export type CompeteGroupState = "active" | "cleanup-ready" | "winner-preserved";
|
|
@@ -546,6 +564,52 @@ export function createCandidateWorktree(
|
|
|
546
564
|
return { index, branch, path };
|
|
547
565
|
}
|
|
548
566
|
|
|
567
|
+
/**
|
|
568
|
+
* Prefer herdr's worktree lifecycle while preserving Git as the recovery
|
|
569
|
+
* authority. A failed or vanished mux is deliberately indistinguishable from
|
|
570
|
+
* no mux to the caller except for the receipt provenance returned here.
|
|
571
|
+
*/
|
|
572
|
+
export async function createCandidateWorktreeMapped(
|
|
573
|
+
ownership: CompeteGroupOwnership,
|
|
574
|
+
index: number,
|
|
575
|
+
baseline: string,
|
|
576
|
+
mux?: CompeteMuxWorktrees,
|
|
577
|
+
): Promise<CandidateWorktree> {
|
|
578
|
+
assertOwnership(ownership);
|
|
579
|
+
const branch = competeBranch(ownership.group, index);
|
|
580
|
+
const path = join(ownership.directory, `candidate-${index}`);
|
|
581
|
+
if (!isCanonicalPathInside(ownership.directory, path)) {
|
|
582
|
+
throw new Error(`candidate ${index} path escapes compete group ${ownership.group}`);
|
|
583
|
+
}
|
|
584
|
+
let fallback: RunGateWorktreeProvenance["fallback"] = "mux-unavailable";
|
|
585
|
+
if (mux?.available()) {
|
|
586
|
+
const created = await mux
|
|
587
|
+
.worktreeCreate({
|
|
588
|
+
cwd: ownership.root,
|
|
589
|
+
branch,
|
|
590
|
+
base: baseline,
|
|
591
|
+
path,
|
|
592
|
+
label: `clio compete ${ownership.group} candidate ${index}`,
|
|
593
|
+
focus: false,
|
|
594
|
+
})
|
|
595
|
+
.catch(() => null);
|
|
596
|
+
if (created !== null) {
|
|
597
|
+
if (resolve(created.worktree.path) !== resolve(path) || created.worktree.branch !== branch) {
|
|
598
|
+
throw new Error(`herdr created candidate ${index} at an unexpected path or branch`);
|
|
599
|
+
}
|
|
600
|
+
return {
|
|
601
|
+
index,
|
|
602
|
+
branch,
|
|
603
|
+
path,
|
|
604
|
+
provenance: { backend: "herdr", path, branch, workspaceId: created.workspaceId },
|
|
605
|
+
};
|
|
606
|
+
}
|
|
607
|
+
fallback = "mux-operation-failed";
|
|
608
|
+
}
|
|
609
|
+
const native = createCandidateWorktree(ownership, index, baseline);
|
|
610
|
+
return { ...native, provenance: { backend: "native", path, branch, fallback } };
|
|
611
|
+
}
|
|
612
|
+
|
|
549
613
|
/**
|
|
550
614
|
* Seal a candidate's work as one commit on its branch. Returns false when the
|
|
551
615
|
* builder changed nothing (an empty candidate is a legitimate ranking fact).
|
|
@@ -605,7 +669,7 @@ function removeRegisteredWorktree(root: string, path: string): void {
|
|
|
605
669
|
}
|
|
606
670
|
}
|
|
607
671
|
|
|
608
|
-
|
|
672
|
+
function removeCandidateWorktree(
|
|
609
673
|
ownership: CompeteGroupOwnership,
|
|
610
674
|
worktree: CandidateWorktree,
|
|
611
675
|
deleteBranch: boolean,
|
|
@@ -633,6 +697,23 @@ export function removeCandidateWorktree(
|
|
|
633
697
|
}
|
|
634
698
|
}
|
|
635
699
|
|
|
700
|
+
/** Remove through herdr when it owns the workspace, then verify with Git. */
|
|
701
|
+
export async function removeCandidateWorktreeMapped(
|
|
702
|
+
ownership: CompeteGroupOwnership,
|
|
703
|
+
worktree: CandidateWorktree,
|
|
704
|
+
deleteBranch: boolean,
|
|
705
|
+
mux?: CompeteMuxWorktrees,
|
|
706
|
+
): Promise<void> {
|
|
707
|
+
const workspaceId = worktree.provenance?.backend === "herdr" ? worktree.provenance.workspaceId : undefined;
|
|
708
|
+
if (workspaceId && mux?.available()) {
|
|
709
|
+
await mux.worktreeRemove(workspaceId, { force: true }).catch(() => false);
|
|
710
|
+
}
|
|
711
|
+
// This is both the native fallback after mux loss and the postcondition check
|
|
712
|
+
// after a successful RPC. It prunes an already-removed path harmlessly and
|
|
713
|
+
// removes the candidate branch, which worktree.remove does not promise to do.
|
|
714
|
+
removeCandidateWorktree(ownership, worktree, deleteBranch);
|
|
715
|
+
}
|
|
716
|
+
|
|
636
717
|
/**
|
|
637
718
|
* Merge the winning candidate branch into the current branch. Fast-forward
|
|
638
719
|
* is impossible by construction (the candidate branched from HEAD and HEAD
|
|
@@ -184,6 +184,7 @@ export function assertRegisteredBuiltinTools(
|
|
|
184
184
|
registry: ToolRegistry,
|
|
185
185
|
registration: CoreToolRegistration,
|
|
186
186
|
includeDispatchTools: boolean,
|
|
187
|
+
includePanesTools = false,
|
|
187
188
|
): void {
|
|
188
|
-
assertBuiltinToolPolicy(registry.listAll(), { ...registration, includeDispatchTools });
|
|
189
|
+
assertBuiltinToolPolicy(registry.listAll(), { ...registration, includeDispatchTools, includePanesTools });
|
|
189
190
|
}
|
|
@@ -4,11 +4,13 @@ import type { ExecutionPlan } from "../domains/dispatch/execution-plan.js";
|
|
|
4
4
|
import { gateDeciderAgentId } from "../domains/dispatch/execution-role.js";
|
|
5
5
|
import {
|
|
6
6
|
COUNCIL_JUDGE_PROMPT,
|
|
7
|
+
COUNCIL_MAX_MEMBERS,
|
|
8
|
+
COUNCIL_MIN_MEMBERS,
|
|
7
9
|
JUDGE_GATE_PROMPT,
|
|
8
10
|
REVIEWER_GATE_PROMPT,
|
|
9
11
|
renderCouncilVoteMemberTask,
|
|
10
12
|
} from "../domains/dispatch/gate-role-prompts.js";
|
|
11
|
-
import { normalizeDispatchIntent } from "../domains/dispatch/intent.js";
|
|
13
|
+
import { narrowDispatchIntentToReadOnly, normalizeDispatchIntent } from "../domains/dispatch/intent.js";
|
|
12
14
|
import { renderDispatchReviewerTask } from "../domains/dispatch/intent-requirements.js";
|
|
13
15
|
import { approvedRouteCandidates } from "../domains/dispatch/route-approval.js";
|
|
14
16
|
import { defaultRoutingIntent } from "../domains/dispatch/routing-intent.js";
|
|
@@ -109,7 +111,9 @@ function councilSettingsFromArgs(
|
|
|
109
111
|
members.push({ label, target, ...(model ? { model } : {}), ...(thinking ? { thinking } : {}) });
|
|
110
112
|
}
|
|
111
113
|
}
|
|
112
|
-
if (members.length <
|
|
114
|
+
if (members.length < COUNCIL_MIN_MEMBERS || members.length > COUNCIL_MAX_MEMBERS) {
|
|
115
|
+
return { ok: false, message: "council_members_out_of_range" };
|
|
116
|
+
}
|
|
113
117
|
const labels = new Set<string>();
|
|
114
118
|
for (const member of members) {
|
|
115
119
|
if (labels.has(member.label)) return { ok: false, message: `council_member_label_duplicate: ${member.label}` };
|
|
@@ -389,7 +393,9 @@ export function createDispatchAdmissionController(deps: DispatchToolDeps): Dispa
|
|
|
389
393
|
};
|
|
390
394
|
});
|
|
391
395
|
const reservation = deps.dispatch.reservations.prepare({
|
|
392
|
-
|
|
396
|
+
// A council keeps its own name so a capacity denial can say that its
|
|
397
|
+
// width has a floor. A fleet's waves are already parallel by shape.
|
|
398
|
+
topology: artifact.topology === "fleet" ? "parallel" : artifact.topology,
|
|
393
399
|
tasks,
|
|
394
400
|
});
|
|
395
401
|
try {
|
|
@@ -638,6 +644,11 @@ export function createDispatchAdmissionController(deps: DispatchToolDeps): Dispa
|
|
|
638
644
|
executionRole: "researcher",
|
|
639
645
|
autonomy: "read-only",
|
|
640
646
|
toolProfile: "council-read-only",
|
|
647
|
+
// A member inherits the caller's declared scope but never its
|
|
648
|
+
// write authority: the same trees arrive as read roots, so the
|
|
649
|
+
// declaration stays enforceable against a read-only run instead of
|
|
650
|
+
// claiming a write scope nothing can grant.
|
|
651
|
+
...(base.intent === undefined ? {} : { intent: narrowDispatchIntentToReadOnly(base.intent) }),
|
|
641
652
|
// The runner reuses this composed task from the resolved plan, so
|
|
642
653
|
// the approval artifact the plan hash binds shows the operator the
|
|
643
654
|
// exact ballot the member is asked to cast.
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
/** Pure model-argument parsing; every returned DispatchRequest has a concrete agent id. */
|
|
2
2
|
|
|
3
|
-
import { pathBoundaryCovers } from "../core/path-boundary.js";
|
|
4
3
|
import type { AgentAutomationAuthority } from "../domains/agents/spec.js";
|
|
5
4
|
import { type AgentTaskType, classifyAgentTask } from "../domains/dispatch/agent-candidates.js";
|
|
6
5
|
import { cloneDispatchBudgetRequest } from "../domains/dispatch/budget-envelope.js";
|
|
7
6
|
import type { DispatchRequest } from "../domains/dispatch/contract.js";
|
|
8
7
|
import { type AgentRoleFactsResolver, requestExecutionRole } from "../domains/dispatch/execution-role.js";
|
|
9
8
|
import type { DispatchIntent } from "../domains/dispatch/intent.js";
|
|
9
|
+
import {
|
|
10
|
+
classifyDispatchIntentCompatibility,
|
|
11
|
+
dispatchIntentRefusals,
|
|
12
|
+
dispatchIntentScopeWidening,
|
|
13
|
+
} from "../domains/dispatch/intent-compatibility.js";
|
|
10
14
|
import { parseRoutingIntent } from "../domains/dispatch/routing-intent.js";
|
|
11
15
|
import { DISPATCH_BRIEFING_MAX_BYTES, type JobThinkingLevel } from "../domains/dispatch/validation.js";
|
|
12
16
|
import { isToolProfileName, TOOL_PROFILE_NAMES } from "./profiles.js";
|
|
@@ -197,10 +201,17 @@ function dispatchRequestFromArgs(
|
|
|
197
201
|
? args.writeRoots.filter((entry): entry is string => typeof entry === "string")
|
|
198
202
|
: undefined;
|
|
199
203
|
if (legacy !== undefined) {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
+
// Asked through the same rule the job-spec validator asks, so the two
|
|
205
|
+
// cannot disagree about the same pair. A raw string comparison here
|
|
206
|
+
// would refuse './src/tools' against 'src/tools', which name one tree.
|
|
207
|
+
const refusal = dispatchIntentRefusals(
|
|
208
|
+
classifyDispatchIntentCompatibility({
|
|
209
|
+
intent: resolved.intent,
|
|
210
|
+
writeRoots: legacy,
|
|
211
|
+
...(cwd !== undefined ? { cwd } : {}),
|
|
212
|
+
}),
|
|
213
|
+
).find((entry) => entry.code === "intent_write_roots_contradiction");
|
|
214
|
+
if (refusal !== undefined) return { ok: false, message: refusal.message };
|
|
204
215
|
request.writeRoots = legacy;
|
|
205
216
|
} else {
|
|
206
217
|
request.writeRoots = resolved.intent.writeRoots;
|
|
@@ -273,21 +284,10 @@ export function dispatchRequestsFromArgs(
|
|
|
273
284
|
}
|
|
274
285
|
const ceiling = options.resolveIntent(sharedIntent, parsed.request.cwd);
|
|
275
286
|
if (!ceiling.ok) return { ok: false, message: `dispatch: task ${index + 1}: ${ceiling.message}` };
|
|
276
|
-
const
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
};
|
|
281
|
-
for (const field of ["readRoots", "writeRoots", "relevantPaths"] as const) {
|
|
282
|
-
const outside = parsed.request.intent?.[field].find(
|
|
283
|
-
(candidate) => !pathBoundaryCovers(pathCeilings[field], candidate),
|
|
284
|
-
);
|
|
285
|
-
if (outside !== undefined) {
|
|
286
|
-
return {
|
|
287
|
-
ok: false,
|
|
288
|
-
message: `dispatch: task ${index + 1}: intent_scope_widening: ${field} entry '${outside}' is outside the top-level intent ceiling`,
|
|
289
|
-
};
|
|
290
|
-
}
|
|
287
|
+
const widening =
|
|
288
|
+
parsed.request.intent === undefined ? null : dispatchIntentScopeWidening(ceiling.intent, parsed.request.intent);
|
|
289
|
+
if (widening !== null) {
|
|
290
|
+
return { ok: false, message: `dispatch: task ${index + 1}: ${widening.message}` };
|
|
291
291
|
}
|
|
292
292
|
}
|
|
293
293
|
requests.push(parsed.request);
|
|
@@ -236,15 +236,19 @@ function str(value: unknown): string | undefined {
|
|
|
236
236
|
return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
|
|
237
237
|
}
|
|
238
238
|
|
|
239
|
-
/** Keep terminal control bytes and line breaks out of approval artifacts. */
|
|
240
|
-
function safeField(value: string): string {
|
|
239
|
+
/** Keep terminal control bytes and line breaks out of approval artifacts without losing their identity. */
|
|
240
|
+
function safeField(value: string, bindChangedValue = true): string {
|
|
241
241
|
let result = "";
|
|
242
242
|
for (const character of value) {
|
|
243
243
|
const code = character.codePointAt(0) ?? 0;
|
|
244
244
|
result += code < 32 || (code >= 127 && code <= 159) ? "?" : character;
|
|
245
|
-
if (result.length >= 256)
|
|
245
|
+
if (result.length >= 256) {
|
|
246
|
+
result = `${result.slice(0, 255)}…`;
|
|
247
|
+
break;
|
|
248
|
+
}
|
|
246
249
|
}
|
|
247
|
-
return result;
|
|
250
|
+
if (!bindChangedValue || result === value) return result;
|
|
251
|
+
return `${result}{sha256=${createHash("sha256").update(value, "utf8").digest("hex")}}`;
|
|
248
252
|
}
|
|
249
253
|
|
|
250
254
|
function renderLegacyPathScope(task: DispatchPlanTaskView): string[] {
|
|
@@ -393,7 +397,7 @@ function renderPlanText(
|
|
|
393
397
|
? ""
|
|
394
398
|
: ` posture=${routing.posture} maxCostUsd=${routing.maxCostUsd ?? "none"} deadlineMs=${routing.deadlineMs ?? "none"} minimumQuality=${routing.minimumQuality ?? "none"} locality=${routing.locality}`;
|
|
395
399
|
lines.push(
|
|
396
|
-
` ${index + 1}.${role} agent=${safeField(task.agent)}${target}${model}${node}${failover}${routingText} task=${JSON.stringify(safeField(task.task))}`,
|
|
400
|
+
` ${index + 1}.${role} agent=${safeField(task.agent)}${target}${model}${node}${failover}${routingText} task_bytes=${Buffer.byteLength(task.task, "utf8")} task_sha256=${createHash("sha256").update(task.task, "utf8").digest("hex")} task_preview=${JSON.stringify(safeField(task.task, false))}`,
|
|
397
401
|
);
|
|
398
402
|
if (task.council !== undefined) {
|
|
399
403
|
lines.push(
|
|
@@ -420,25 +424,29 @@ function renderPlanText(
|
|
|
420
424
|
}
|
|
421
425
|
if (task.agentSelection !== null) {
|
|
422
426
|
lines.push(
|
|
423
|
-
` agent-selection=auto baseline=${safeField(task.agentSelection.baselineAgentId)} authority=${task.agentSelection.approvedAuthorities.map(safeField).join(",")} basis=${task.agentSelection.authorityBasis}`,
|
|
427
|
+
` agent-selection=auto baseline=${safeField(task.agentSelection.baselineAgentId)} authority=${task.agentSelection.approvedAuthorities.map((authority) => safeField(authority)).join(",")} basis=${task.agentSelection.authorityBasis}`,
|
|
424
428
|
);
|
|
425
429
|
}
|
|
426
430
|
if (task.stepId !== null) {
|
|
427
431
|
lines.push(
|
|
428
|
-
` step=${safeField(task.stepId)} wave=${task.wave ?? "?"} role=${task.executionRole} dependencies=${task.dependencies.map(safeField).join(",") || "none"} result=${task.expectedResultContract ?? "none"} authority=${task.authorityGrant?.requested ?? "none"} basis=${task.authorityGrant?.basis ?? "none"}`,
|
|
432
|
+
` step=${safeField(task.stepId)} wave=${task.wave ?? "?"} role=${task.executionRole} dependencies=${task.dependencies.map((dependency) => safeField(dependency)).join(",") || "none"} result=${task.expectedResultContract ?? "none"} authority=${task.authorityGrant?.requested ?? "none"} basis=${task.authorityGrant?.basis ?? "none"}`,
|
|
429
433
|
);
|
|
430
434
|
const agentReasons = task.agentDecision?.agentSelection.evaluations
|
|
431
435
|
.filter((evaluation) => evaluation.rejections.length > 0)
|
|
432
436
|
.slice(0, 8)
|
|
433
437
|
.map(
|
|
434
|
-
(evaluation) =>
|
|
438
|
+
(evaluation) =>
|
|
439
|
+
`${safeField(evaluation.agentId)}:${evaluation.rejections
|
|
440
|
+
.slice(0, 4)
|
|
441
|
+
.map((rejection) => safeField(rejection))
|
|
442
|
+
.join(",")}`,
|
|
435
443
|
);
|
|
436
444
|
if (agentReasons !== undefined && agentReasons.length > 0)
|
|
437
445
|
lines.push(` agent-exclusions=${agentReasons.join(";")}`);
|
|
438
446
|
}
|
|
439
447
|
if (task.briefing !== undefined) {
|
|
440
448
|
lines.push(
|
|
441
|
-
` briefing_bytes=${Buffer.byteLength(task.briefing, "utf8")} briefing_sha256=${createHash("sha256").update(task.briefing, "utf8").digest("hex")} briefing_preview=${JSON.stringify(safeField(task.briefing))}`,
|
|
449
|
+
` briefing_bytes=${Buffer.byteLength(task.briefing, "utf8")} briefing_sha256=${createHash("sha256").update(task.briefing, "utf8").digest("hex")} briefing_preview=${JSON.stringify(safeField(task.briefing, false))}`,
|
|
442
450
|
);
|
|
443
451
|
}
|
|
444
452
|
if (task.intent !== undefined) {
|
|
@@ -2,6 +2,7 @@ import { BusChannels } from "../core/bus-events.js";
|
|
|
2
2
|
import type { SafeEventBus } from "../core/event-bus.js";
|
|
3
3
|
import type { DispatchContract } from "../domains/dispatch/contract.js";
|
|
4
4
|
import { durableAssistantTextFromEvent } from "../domains/dispatch/event-pump.js";
|
|
5
|
+
import { defaultRunEventJournal, type RunEventJournalSink } from "../domains/dispatch/run-event-journal.js";
|
|
5
6
|
import type { RunReceipt } from "../domains/dispatch/types.js";
|
|
6
7
|
import { assistantTextFromEvent } from "./dispatch-event-text.js";
|
|
7
8
|
import { truncateUtf8 } from "./truncate-utf8.js";
|
|
@@ -77,10 +78,95 @@ function eventDetail(event: unknown): string | undefined {
|
|
|
77
78
|
return undefined;
|
|
78
79
|
}
|
|
79
80
|
|
|
80
|
-
|
|
81
|
+
/**
|
|
82
|
+
* Project one worker/ACP event into the display tail, or null when the event is
|
|
83
|
+
* not tail-visible. Heartbeats and streaming `message_update` increments are
|
|
84
|
+
* noise on a transcript: the tail keeps message boundaries, not deltas.
|
|
85
|
+
*
|
|
86
|
+
* The durable journal writes exactly this projection, so a transcript read back
|
|
87
|
+
* by `clio-coder fleet view` and the monitor's live peek cannot disagree about
|
|
88
|
+
* what a run did. Both the registry below and the domain-owned journal bridge
|
|
89
|
+
* (src/domains/dispatch/run-event-journal-bridge.ts) call it.
|
|
90
|
+
*/
|
|
91
|
+
export function runTailEntryFromEvent(event: unknown, at: string = new Date().toISOString()): RunTailEntry | null {
|
|
92
|
+
const type = isRecord(event) && typeof event.type === "string" ? event.type : "unknown";
|
|
93
|
+
if (type === "heartbeat" || type === "message_update") return null;
|
|
94
|
+
const entry: RunTailEntry = { at, type };
|
|
95
|
+
const detail = eventDetail(event);
|
|
96
|
+
if (detail !== undefined) entry.detail = detail;
|
|
97
|
+
return entry;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export interface DispatchRunEventRegistryOptions {
|
|
101
|
+
/**
|
|
102
|
+
* Durable tee for the display tail. Omitted takes the process-wide default
|
|
103
|
+
* journal (settings-gated by `panes.journal`); `null` turns it off for this
|
|
104
|
+
* registry. This is the one wiring choke point: every registry in the
|
|
105
|
+
* process is built by this factory, so the sink attaches here rather than at
|
|
106
|
+
* each of the three construction sites that call it.
|
|
107
|
+
*/
|
|
108
|
+
journal?: RunEventJournalSink | null;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** Outcome recorded for a run whose completion rejected before a receipt existed. */
|
|
112
|
+
const REGISTRY_FAILURE_OUTCOME = "failed";
|
|
113
|
+
/** Outcome recorded when a receipt settled without a readable outcome field. */
|
|
114
|
+
const REGISTRY_UNKNOWN_OUTCOME = "unknown";
|
|
115
|
+
|
|
116
|
+
function errorText(error: unknown): string {
|
|
117
|
+
return error instanceof Error ? error.message : String(error);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function createDispatchRunEventRegistry(
|
|
121
|
+
options: DispatchRunEventRegistryOptions = {},
|
|
122
|
+
): DispatchRunEventRegistry {
|
|
81
123
|
const runTails = new Map<string, RunTailState>();
|
|
82
124
|
const activeRuns = new Set<string>();
|
|
83
125
|
const activeBatches = new Set<string>();
|
|
126
|
+
const journal: RunEventJournalSink | null = options.journal === undefined ? defaultRunEventJournal() : options.journal;
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Seal one logical run in the journal. `logicalRunId` is the id an operator
|
|
130
|
+
* asked about; a retried run's receipt carries the terminal attempt's id
|
|
131
|
+
* instead, and that only ever appears as a field on the line.
|
|
132
|
+
*/
|
|
133
|
+
const journalSeal = (logicalRunId: string, receipt: RunReceipt): void => {
|
|
134
|
+
if (journal === null || !isRecord(receipt)) return;
|
|
135
|
+
// Every field is read defensively. The journal sits on the completion path
|
|
136
|
+
// of every dispatch, and a receipt that is missing a block it is typed to
|
|
137
|
+
// have (a stubbed contract, a truncated read) must degrade the transcript,
|
|
138
|
+
// never reject the completion the caller is awaiting.
|
|
139
|
+
const digest = receipt.integrity?.digest;
|
|
140
|
+
const outcome = typeof receipt.outcome === "string" ? receipt.outcome : REGISTRY_UNKNOWN_OUTCOME;
|
|
141
|
+
journal.receipt(logicalRunId, {
|
|
142
|
+
outcome,
|
|
143
|
+
exitCode: typeof receipt.exitCode === "number" ? receipt.exitCode : null,
|
|
144
|
+
...(typeof digest === "string" ? { digest } : {}),
|
|
145
|
+
...(receipt.runId !== logicalRunId ? { attemptRunId: receipt.runId } : {}),
|
|
146
|
+
});
|
|
147
|
+
journal.terminal(logicalRunId, outcome, receipt.outcomeDetail ?? undefined);
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Seal a batch's journals. `assignmentIds` are the logical work ids in
|
|
152
|
+
* admission order and `dispatchBatch` resolves one receipt per request, so
|
|
153
|
+
* equal lengths pair by index. Anything else pairs by the receipt's own run
|
|
154
|
+
* id and leaves unmatched assignments without a terminal line rather than
|
|
155
|
+
* inventing an outcome for them.
|
|
156
|
+
*/
|
|
157
|
+
const sealBatchJournals = (assignmentIds: ReadonlyArray<string>, receipts: ReadonlyArray<RunReceipt>): void => {
|
|
158
|
+
if (journal === null || !Array.isArray(receipts)) return;
|
|
159
|
+
if (assignmentIds.length === receipts.length) {
|
|
160
|
+
for (const [index, runId] of assignmentIds.entries()) {
|
|
161
|
+
const receipt = receipts[index];
|
|
162
|
+
if (receipt !== undefined) journalSeal(runId, receipt);
|
|
163
|
+
}
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
for (const receipt of receipts) {
|
|
167
|
+
if (receipt != null && typeof receipt.runId === "string") journalSeal(receipt.runId, receipt);
|
|
168
|
+
}
|
|
169
|
+
};
|
|
84
170
|
|
|
85
171
|
const pruneRunTails = (): void => {
|
|
86
172
|
while (runTails.size > RUN_TAIL_RUN_LIMIT) {
|
|
@@ -97,19 +183,20 @@ export function createDispatchRunEventRegistry(): DispatchRunEventRegistry {
|
|
|
97
183
|
};
|
|
98
184
|
|
|
99
185
|
const recordRunEvent = (runId: string, agentId: string, event: unknown): void => {
|
|
100
|
-
const
|
|
101
|
-
if (
|
|
186
|
+
const entry = runTailEntryFromEvent(event);
|
|
187
|
+
if (entry === null) return;
|
|
102
188
|
const state = runTails.get(runId) ?? { agentId, entries: [], lastSeenAt: Date.now() };
|
|
103
189
|
state.lastSeenAt = Date.now();
|
|
104
|
-
const entry: RunTailEntry = { at: new Date().toISOString(), type };
|
|
105
|
-
const detail = eventDetail(event);
|
|
106
|
-
if (detail !== undefined) entry.detail = detail;
|
|
107
190
|
state.entries.push(entry);
|
|
108
191
|
if (state.entries.length > RUN_TAIL_ENTRY_LIMIT) {
|
|
109
192
|
state.entries.splice(0, state.entries.length - RUN_TAIL_ENTRY_LIMIT);
|
|
110
193
|
}
|
|
111
194
|
runTails.set(runId, state);
|
|
112
195
|
pruneRunTails();
|
|
196
|
+
// The journal is a tee of exactly this projection, appended after the
|
|
197
|
+
// in-memory tail is already updated so a sink that degrades cannot change
|
|
198
|
+
// what `eventTail` returns.
|
|
199
|
+
journal?.append(runId, entry);
|
|
113
200
|
};
|
|
114
201
|
|
|
115
202
|
const drainSingle = async (
|
|
@@ -172,6 +259,7 @@ export function createDispatchRunEventRegistry(): DispatchRunEventRegistry {
|
|
|
172
259
|
throw new Error(`dispatch event registry: run '${handle.runId}' is already registered`);
|
|
173
260
|
}
|
|
174
261
|
activeRuns.add(handle.runId);
|
|
262
|
+
journal?.open(handle.runId, agentId);
|
|
175
263
|
const summaryPromise = drainSingle(handle.runId, agentId, handle.events, bus);
|
|
176
264
|
const completion = Promise.allSettled([summaryPromise, handle.finalPromise]).then(
|
|
177
265
|
([summaryResult, receiptResult]) => {
|
|
@@ -180,12 +268,24 @@ export function createDispatchRunEventRegistry(): DispatchRunEventRegistry {
|
|
|
180
268
|
return { receipt: receiptResult.value, summary: summaryResult.value };
|
|
181
269
|
},
|
|
182
270
|
);
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
.
|
|
271
|
+
// One subscription, not a `.then().finally()` chain. Chaining pushes the
|
|
272
|
+
// tail release a microtask later than it used to land, and a caller that
|
|
273
|
+
// awaits `completion` and then reads `eventTail` observes the run as
|
|
274
|
+
// still active. Journal and release settle together in this handler.
|
|
275
|
+
const releaseSingle = (): void => {
|
|
276
|
+
activeRuns.delete(handle.runId);
|
|
277
|
+
pruneRunTails();
|
|
278
|
+
};
|
|
279
|
+
void completion.then(
|
|
280
|
+
({ receipt }) => {
|
|
281
|
+
journalSeal(handle.runId, receipt);
|
|
282
|
+
releaseSingle();
|
|
283
|
+
},
|
|
284
|
+
(error: unknown) => {
|
|
285
|
+
journal?.terminal(handle.runId, REGISTRY_FAILURE_OUTCOME, errorText(error));
|
|
286
|
+
releaseSingle();
|
|
287
|
+
},
|
|
288
|
+
);
|
|
189
289
|
return { runId: handle.runId, completion };
|
|
190
290
|
},
|
|
191
291
|
registerBatch(handle, agentIds, bus) {
|
|
@@ -204,6 +304,9 @@ export function createDispatchRunEventRegistry(): DispatchRunEventRegistry {
|
|
|
204
304
|
}
|
|
205
305
|
activeBatches.add(handle.batchId);
|
|
206
306
|
for (const runId of handle.assignmentIds) activeRuns.add(runId);
|
|
307
|
+
for (const [index, runId] of handle.assignmentIds.entries()) {
|
|
308
|
+
journal?.open(runId, agentIds[index] ?? "unknown");
|
|
309
|
+
}
|
|
207
310
|
const completion = Promise.allSettled([drainBatch(handle.batchId, handle.events, bus), handle.finalPromise]).then(
|
|
208
311
|
([summariesResult, receiptsResult]) => {
|
|
209
312
|
if (summariesResult.status === "rejected") throw summariesResult.reason;
|
|
@@ -211,13 +314,25 @@ export function createDispatchRunEventRegistry(): DispatchRunEventRegistry {
|
|
|
211
314
|
return { receipts: receiptsResult.value, summaries: summariesResult.value };
|
|
212
315
|
},
|
|
213
316
|
);
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
317
|
+
// Single subscription for the same reason as registerSingle above.
|
|
318
|
+
const releaseBatch = (): void => {
|
|
319
|
+
activeBatches.delete(handle.batchId);
|
|
320
|
+
for (const runId of handle.assignmentIds) activeRuns.delete(runId);
|
|
321
|
+
pruneRunTails();
|
|
322
|
+
};
|
|
323
|
+
void completion.then(
|
|
324
|
+
({ receipts }) => {
|
|
325
|
+
sealBatchJournals(handle.assignmentIds, receipts);
|
|
326
|
+
releaseBatch();
|
|
327
|
+
},
|
|
328
|
+
(error: unknown) => {
|
|
329
|
+
const detail = errorText(error);
|
|
330
|
+
for (const runId of handle.assignmentIds) {
|
|
331
|
+
journal?.terminal(runId, REGISTRY_FAILURE_OUTCOME, detail);
|
|
332
|
+
}
|
|
333
|
+
releaseBatch();
|
|
334
|
+
},
|
|
335
|
+
);
|
|
221
336
|
for (const [index, runId] of handle.assignmentIds.entries()) {
|
|
222
337
|
if (!runTails.has(runId)) {
|
|
223
338
|
runTails.set(runId, {
|
|
@@ -40,6 +40,7 @@ import {
|
|
|
40
40
|
REVIEWER_GATE_PROMPT,
|
|
41
41
|
renderCouncilVoteMemberTask,
|
|
42
42
|
} from "../domains/dispatch/gate-role-prompts.js";
|
|
43
|
+
import { narrowDispatchIntentToReadOnly } from "../domains/dispatch/intent.js";
|
|
43
44
|
import { renderDispatchReviewerTask } from "../domains/dispatch/intent-requirements.js";
|
|
44
45
|
import { UNVERIFIABLE_RECEIPT_VERIFICATION } from "../domains/dispatch/receipt-findings.js";
|
|
45
46
|
import { type ReceiptIntegrityResult, verifyReceiptIntegrity } from "../domains/dispatch/receipt-integrity.js";
|
|
@@ -56,7 +57,7 @@ import {
|
|
|
56
57
|
claimCompeteGroup,
|
|
57
58
|
cleanupCompeteGroup,
|
|
58
59
|
commitCandidateWork,
|
|
59
|
-
|
|
60
|
+
createCandidateWorktreeMapped,
|
|
60
61
|
isGitRepository,
|
|
61
62
|
loadCompeteGroup,
|
|
62
63
|
markCompeteGroupCleanupReady,
|
|
@@ -65,7 +66,7 @@ import {
|
|
|
65
66
|
protectedPathsChangedByCompeteBranch,
|
|
66
67
|
recoverCleanupReadyCompeteGroups,
|
|
67
68
|
registerCompeteGroupRun,
|
|
68
|
-
|
|
69
|
+
removeCandidateWorktreeMapped,
|
|
69
70
|
settleCompeteGroupRun,
|
|
70
71
|
settleRecoveredCompeteDecision,
|
|
71
72
|
} from "./compete-worktrees.js";
|
|
@@ -1255,10 +1256,14 @@ async function runCompete(
|
|
|
1255
1256
|
// every branch and worktree created below is covered by finalization.
|
|
1256
1257
|
ownership = claimCompeteGroup(requestedRoot, group);
|
|
1257
1258
|
const root = ownership.root;
|
|
1258
|
-
const createCandidate = deps.competeWorktrees?.createCandidate ?? createCandidateWorktree;
|
|
1259
1259
|
for (let index = 1; index <= compete.candidates; index += 1) {
|
|
1260
1260
|
throwIfStopped();
|
|
1261
|
-
|
|
1261
|
+
const customCreate = deps.competeWorktrees?.createCandidate;
|
|
1262
|
+
worktrees.push(
|
|
1263
|
+
await (customCreate
|
|
1264
|
+
? customCreate(ownership, index, "HEAD")
|
|
1265
|
+
: createCandidateWorktreeMapped(ownership, index, "HEAD", deps.competeWorktrees?.mux)),
|
|
1266
|
+
);
|
|
1262
1267
|
}
|
|
1263
1268
|
|
|
1264
1269
|
if (timeoutMs !== undefined) {
|
|
@@ -1287,7 +1292,12 @@ async function runCompete(
|
|
|
1287
1292
|
executionRole: "builder",
|
|
1288
1293
|
cwd: worktree.path,
|
|
1289
1294
|
protectedArtifactRemap: { sourceRoot: root, workerRoot: worktree.path },
|
|
1290
|
-
gate: {
|
|
1295
|
+
gate: {
|
|
1296
|
+
role: "candidate",
|
|
1297
|
+
group,
|
|
1298
|
+
cycle: worktree.index,
|
|
1299
|
+
...(worktree.provenance ? { worktree: worktree.provenance } : {}),
|
|
1300
|
+
},
|
|
1291
1301
|
ledger,
|
|
1292
1302
|
competeStance: COMPETE_STANCES[(worktree.index - 1) % COMPETE_STANCES.length] as CompeteStance,
|
|
1293
1303
|
};
|
|
@@ -1523,7 +1533,7 @@ async function runCompete(
|
|
|
1523
1533
|
for (const worktree of worktrees) {
|
|
1524
1534
|
if (worktree.index === winnerAtFinalization.index) continue;
|
|
1525
1535
|
try {
|
|
1526
|
-
|
|
1536
|
+
await removeCandidateWorktreeMapped(ownership, worktree, true, deps.competeWorktrees?.mux);
|
|
1527
1537
|
} catch (err) {
|
|
1528
1538
|
finalizationErrors.push(err);
|
|
1529
1539
|
}
|
|
@@ -1540,8 +1550,13 @@ async function runCompete(
|
|
|
1540
1550
|
finalizationErrors.push(err);
|
|
1541
1551
|
}
|
|
1542
1552
|
try {
|
|
1553
|
+
if (deps.competeWorktrees?.mux) {
|
|
1554
|
+
for (const worktree of worktrees) {
|
|
1555
|
+
await removeCandidateWorktreeMapped(ownership, worktree, true, deps.competeWorktrees.mux);
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1543
1558
|
const cleanupGroup = deps.competeWorktrees?.cleanupGroup ?? cleanupCompeteGroup;
|
|
1544
|
-
cleanupGroup(ownership);
|
|
1559
|
+
await cleanupGroup(ownership);
|
|
1545
1560
|
} catch (err) {
|
|
1546
1561
|
finalizationErrors.push(err);
|
|
1547
1562
|
}
|
|
@@ -1885,6 +1900,13 @@ async function runCouncil(
|
|
|
1885
1900
|
executionRole: "researcher",
|
|
1886
1901
|
autonomy: "read-only",
|
|
1887
1902
|
toolProfile: "council-read-only",
|
|
1903
|
+
// Admission already demoted the caller's declared write roots to
|
|
1904
|
+
// read roots for every planned member, and the resolved-plan pin
|
|
1905
|
+
// below carries that narrowed intent in. Repeat it here so the
|
|
1906
|
+
// no-plan fallback path lands on the same request: a member spread
|
|
1907
|
+
// from `base` would otherwise inherit a write scope its read-only
|
|
1908
|
+
// autonomy cannot grant, and the two paths would disagree.
|
|
1909
|
+
...(base.intent === undefined ? {} : { intent: narrowDispatchIntentToReadOnly(base.intent) }),
|
|
1888
1910
|
// A vote is a majority over the members' verdict fields, so a vote
|
|
1889
1911
|
// council asks each member for one and seals the ballot it asked
|
|
1890
1912
|
// for. The seated recipe is untouched: the ask is a task suffix and
|
|
@@ -256,7 +256,7 @@ export async function runScoutContinuationPlan<T, S>(input: {
|
|
|
256
256
|
};
|
|
257
257
|
},
|
|
258
258
|
cancel: (assignmentId) => input.dispatch.abort(assignmentId),
|
|
259
|
-
release: (ownerId) => input.dispatch.reservations?.
|
|
259
|
+
release: (ownerId) => input.dispatch.reservations?.release(ownerId),
|
|
260
260
|
releaseUnconsumed: (ownerId) => input.dispatch.reservations?.rollbackUnconsumed(ownerId),
|
|
261
261
|
},
|
|
262
262
|
input.signal,
|
|
@@ -3,7 +3,13 @@ import type { AgentSpec } from "../domains/agents/spec.js";
|
|
|
3
3
|
import type { DispatchContract, DispatchRequest } from "../domains/dispatch/contract.js";
|
|
4
4
|
import type { AgentRoleFactsResolver } from "../domains/dispatch/execution-role.js";
|
|
5
5
|
import type { AutonomyLevel } from "../domains/safety/autonomy.js";
|
|
6
|
-
import type {
|
|
6
|
+
import type {
|
|
7
|
+
CandidateWorktree,
|
|
8
|
+
CompeteGroupOwnership,
|
|
9
|
+
CompeteMuxWorktrees,
|
|
10
|
+
cleanupCompeteGroup,
|
|
11
|
+
mergeWinnerBranch,
|
|
12
|
+
} from "./compete-worktrees.js";
|
|
7
13
|
import type { DispatchBackgroundRegistry } from "./dispatch-background.js";
|
|
8
14
|
import type { DispatchPlanView, ResolvedDispatchPlanArtifact } from "./dispatch-plan.js";
|
|
9
15
|
import type { DispatchRunEventRegistry } from "./dispatch-run-events.js";
|
|
@@ -83,9 +89,15 @@ export interface DispatchToolDeps {
|
|
|
83
89
|
background?: DispatchBackgroundRegistry;
|
|
84
90
|
/** Optional compete storage overrides for alternate backends and deterministic fault tests. */
|
|
85
91
|
competeWorktrees?: {
|
|
86
|
-
createCandidate?:
|
|
87
|
-
|
|
92
|
+
createCandidate?: (
|
|
93
|
+
ownership: CompeteGroupOwnership,
|
|
94
|
+
index: number,
|
|
95
|
+
baseline: string,
|
|
96
|
+
) => CandidateWorktree | Promise<CandidateWorktree>;
|
|
97
|
+
cleanupGroup?: (...args: Parameters<typeof cleanupCompeteGroup>) => void | Promise<void>;
|
|
88
98
|
mergeWinner?: typeof mergeWinnerBranch;
|
|
99
|
+
/** Optional herdr route; every operation retains native Git fallback. */
|
|
100
|
+
mux?: CompeteMuxWorktrees;
|
|
89
101
|
};
|
|
90
102
|
getAgentCatalog?: () => string;
|
|
91
103
|
getAgentSpecs: () => ReadonlyArray<AgentSpec>;
|