@iowarp/clio-coder 0.3.6 → 0.3.8
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 +59 -0
- package/README.md +22 -6
- package/dist/{acp-2BEHC4DL.js → acp-U67UHUK2.js} +14 -14
- package/dist/{agents-LNNFTM53.js → agents-YU6SGALZ.js} +42 -35
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-KXXFI2VS.js → auth-5ZPJOIVG.js} +32 -24
- package/dist/builtins-C6JMZVV6.js +17 -0
- package/dist/{chunk-E25LMLRW.js → chunk-26LEYJZH.js} +2 -2
- package/dist/{chunk-TSHXZTOQ.js → chunk-2HEJ2F35.js} +5 -5
- package/dist/{chunk-PBTHKCPN.js → chunk-2HFZQUHL.js} +7 -7
- package/dist/{chunk-FO5ZOVUY.js → chunk-3BINW3FP.js} +5 -5
- package/dist/{chunk-4OC57DA6.js → chunk-4DGYLA73.js} +53 -2
- package/dist/{chunk-CKXWIANG.js → chunk-4SPRNWDE.js} +18 -16
- package/dist/{chunk-E2ER4LJF.js → chunk-5C3AQNDW.js} +25 -1
- package/dist/{chunk-XF5N4U5A.js → chunk-5DHKRSMQ.js} +9 -8
- package/dist/{chunk-43AOLP7E.js → chunk-5FR74PWO.js} +2 -1
- package/dist/{chunk-EKY57CSP.js → chunk-5H3GB5BO.js} +68 -772
- package/dist/{chunk-6XXKFVSN.js → chunk-5Q2VVUKB.js} +4 -4
- package/dist/{chunk-DJVECN66.js → chunk-7RFXX52T.js} +295 -3705
- package/dist/{chunk-ZXF4XRKW.js → chunk-7RGZWPB6.js} +158 -8
- package/dist/{chunk-FYYLNIL5.js → chunk-A2NJGIB3.js} +2 -2
- package/dist/{chunk-XXQNGV4M.js → chunk-A3WNZD3P.js} +548 -72
- package/dist/{chunk-VEZEGCGW.js → chunk-B5CSFE7B.js} +23 -21
- package/dist/{chunk-2SFS6XQE.js → chunk-DGSYXYMX.js} +3 -2
- package/dist/chunk-DR52UMZW.js +21 -0
- package/dist/{chunk-ZWLZP4ZT.js → chunk-DYIM5TJT.js} +98 -12
- package/dist/{chunk-QKMUKYO7.js → chunk-E77JEWSD.js} +270 -125
- package/dist/{chunk-LYF7OHWH.js → chunk-EMYUUSFG.js} +12 -467
- package/dist/{chunk-4VP4KH3K.js → chunk-EQ63NRB7.js} +8 -8
- package/dist/chunk-FBVTI2TJ.js +518 -0
- package/dist/{chunk-R46L2BIR.js → chunk-FHJEP5SW.js} +19 -25
- package/dist/{chunk-WR67VIZY.js → chunk-GN57SG4G.js} +66 -8
- package/dist/{chunk-RD5U66HV.js → chunk-GPIEI3LY.js} +9 -9
- package/dist/{chunk-PCZJO5TI.js → chunk-GU2UIAFZ.js} +13 -178
- package/dist/chunk-GWS3VEIW.js +195 -0
- package/dist/chunk-H7IXIC72.js +103 -0
- package/dist/{chunk-3BPUFZDL.js → chunk-HLE42MG7.js} +3 -3
- package/dist/{chunk-24I7BN55.js → chunk-IFBNV6H6.js} +3 -3
- package/dist/{chunk-QNQHSOLF.js → chunk-IGWKHNIQ.js} +114 -55
- package/dist/chunk-IIZWH4XA.js +172 -0
- package/dist/{chunk-AD2SYQYC.js → chunk-IJ7RPIYJ.js} +124 -6
- package/dist/chunk-J3YUBZWY.js +382 -0
- package/dist/{chunk-5JGRAMKL.js → chunk-JOZYP4GM.js} +8 -6
- package/dist/{chunk-OH3TOQTB.js → chunk-K4XHGFR5.js} +751 -15
- package/dist/{chunk-EYPA3EGJ.js → chunk-KTYTFRMB.js} +178 -14
- package/dist/chunk-LU7P4LHA.js +33 -0
- package/dist/chunk-ME6CCNFO.js +108 -0
- package/dist/chunk-MXKJU4JB.js +1100 -0
- package/dist/{chunk-RY3LY4J5.js → chunk-N22QMJKY.js} +21 -18
- package/dist/chunk-NMPKI6XL.js +3006 -0
- package/dist/chunk-NUGM5KR6.js +165 -0
- package/dist/{chunk-22NAGB7X.js → chunk-P43ETTHK.js} +5 -94
- package/dist/{chunk-NILBFAPG.js → chunk-PMDBGQSJ.js} +2 -2
- package/dist/chunk-PT7HYKEM.js +165 -0
- package/dist/chunk-RVG5JXAL.js +41 -0
- package/dist/{chunk-GEYXPTRF.js → chunk-RWSI4YD7.js} +2 -2
- package/dist/{chunk-4BPJXDWC.js → chunk-TANS5ZJS.js} +35 -19
- package/dist/{verifiers-NCBTHHN2.js → chunk-TB5666IT.js} +67 -324
- package/dist/{chunk-QM3F2GKX.js → chunk-TLQJPP24.js} +7927 -8088
- package/dist/{chunk-G7MUEIGA.js → chunk-TT36MB5S.js} +2 -1
- package/dist/chunk-TTHACPOM.js +961 -0
- package/dist/{chunk-6US73PDB.js → chunk-TYPGUK6W.js} +7 -7
- package/dist/{chunk-MFFY33HR.js → chunk-U6MBIEMB.js} +554 -209
- package/dist/chunk-VAWNZU7Z.js +242 -0
- package/dist/{chunk-IR4CFBFN.js → chunk-VCBR6CU7.js} +12 -12
- package/dist/{chunk-WHJYKASB.js → chunk-VHN4MY6O.js} +2 -2
- package/dist/{chunk-XYDYPRZI.js → chunk-VWZOAB7K.js} +10 -10
- package/dist/{chunk-ZRGEBJ4T.js → chunk-WLFILSD5.js} +48 -48
- package/dist/{chunk-K7T3E2SR.js → chunk-WNIJTQQK.js} +12 -11
- package/dist/{chunk-CYQKWTG3.js → chunk-WSB3FPX7.js} +68 -20
- package/dist/{chunk-KHSFENX2.js → chunk-WWCZ5F23.js} +116 -14
- package/dist/{chunk-XE2VEJHX.js → chunk-WXY7KU3G.js} +2 -2
- package/dist/{chunk-PPAMZ32Z.js → chunk-XK56QHLX.js} +6 -1
- package/dist/{chunk-KOHPCX4K.js → chunk-XWSF374K.js} +5 -5
- package/dist/{chunk-CJUB2JJ2.js → chunk-YS5VLNH5.js} +10 -10
- package/dist/{chunk-ZZMN5OM4.js → chunk-ZNLWCMVZ.js} +2 -2
- package/dist/{chunk-WHGPSPT5.js → chunk-ZVJ5BLO2.js} +2 -2
- package/dist/cli/index.js +33 -31
- package/dist/{clio-M2KGYUFZ.js → clio-QVTYJ57A.js} +10 -10
- package/dist/{code-nav-GQNL7XA6.js → code-nav-FGGFIE7L.js} +5 -5
- package/dist/codewiki/build-worker.js +4 -4
- package/dist/{components-5TTYYX6G.js → components-ZFA3SAER.js} +9 -9
- package/dist/{config-XUUYQIWO.js → config-LW5IJFQN.js} +65 -55
- package/dist/{configure-IHJ7YOMV.js → configure-7XIZCOU4.js} +29 -24
- package/dist/{context-75MIWW3U.js → context-L3WL3X7K.js} +54 -43
- package/dist/{context-ZQ7SIFJV.js → context-N52ZA626.js} +30 -14
- package/dist/{context-74JLXAWD.js → context-Y6Y7QPR6.js} +12 -12
- package/dist/{context-clear-GYKWNUML.js → context-clear-MBQRLSDQ.js} +54 -43
- package/dist/{context-index-SSR5ECNE.js → context-index-HVMFQHK3.js} +5 -5
- package/dist/{context-working-set-UX5KEP4J.js → context-working-set-GS6DSO7F.js} +18 -18
- package/dist/{dispatch-runner-GIJBHNFL.js → dispatch-runner-22ZCNOM3.js} +367 -79
- package/dist/{docs-6FZSCG5B.js → docs-7LQ23DLM.js} +9 -9
- package/dist/{doctor-SVJ5BZCW.js → doctor-M7YEDGAE.js} +27 -23
- package/dist/{eval-CG6LLBLD.js → eval-BEC2WHDA.js} +73 -20
- package/dist/{evidence-ZYFIEN42.js → evidence-REJUMSKM.js} +70 -59
- package/dist/{evolve-QGEXEMDW.js → evolve-PY5ZBA5K.js} +50 -39
- package/dist/{extensions-ADGNCJJD.js → extensions-HVKU65YU.js} +7 -7
- package/dist/{fleet-S5R4ZOQY.js → fleet-7WZEWRFA.js} +236 -377
- package/dist/fleet-commands-UVHWM76J.js +70 -0
- package/dist/fleet-graph-6ULH7PES.js +125 -0
- package/dist/fleet-new-RDVJLHHH.js +48 -0
- package/dist/{fleet-preflight-BHSNPBMH.js → fleet-preflight-J53T6CCE.js} +5 -5
- package/dist/fleet-validate-72PC4SLA.js +79 -0
- package/dist/{init-5DRU55YR.js → init-OG3TPGQG.js} +69 -57
- package/dist/library-CNTMPLRF.js +217 -0
- package/dist/{memory-7YKKR6UC.js → memory-6IS7F275.js} +52 -41
- package/dist/{models-ZPOLRU2C.js → models-ENRJDA5W.js} +37 -31
- package/dist/{monitor-US5F5YGZ.js → monitor-XLDVO7TN.js} +79 -42
- package/dist/{orchestrator-E2AL4T5N.js → orchestrator-6KSPYRHA.js} +4126 -762
- package/dist/{paths-E7KYAQWE.js → paths-DBXMZMDU.js} +6 -6
- package/dist/registry-LG64LTF4.js +11 -0
- package/dist/{reset-KZ652EK6.js → reset-RZ4ER727.js} +12 -12
- package/dist/{run-SRNBKDWD.js → run-Y2CNK5RU.js} +89 -76
- package/dist/{share-CGZE33UP.js → share-A55GYP6Z.js} +37 -13
- package/dist/{skills-S2X4DLY5.js → skills-ALC5J6AT.js} +29 -13
- package/dist/{skills-eval-W2GGIC4R.js → skills-eval-JPBEBYQU.js} +60 -48
- package/dist/support-MIETYA5E.js +38 -0
- package/dist/{targets-54SWINWB.js → targets-VGNXIR3S.js} +46 -36
- package/dist/{terminal-lease-SAIF2OGY.js → terminal-lease-WOBR64YA.js} +4 -4
- package/dist/{uninstall-BVLWXKBT.js → uninstall-ZJF5H5ZN.js} +9 -9
- package/dist/{upgrade-JKAR27XC.js → upgrade-FUSUAGHR.js} +31 -28
- package/dist/{usage-MSAWCLX4.js → usage-N4MKVHKD.js} +140 -68
- package/dist/verifiers-YAWOJ3H2.js +336 -0
- package/dist/{verify-X5HDROLA.js → verify-LTDHYBGY.js} +10 -9
- package/dist/{wiki-generate-GUSOQ6ZP.js → wiki-generate-6M7GHTBJ.js} +75 -62
- package/dist/worker/entry.js +67 -57
- package/docs/README.md +3 -2
- package/docs/acp.md +1 -1
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +2 -2
- package/docs/artifact-versions.md +11 -6
- package/docs/built-in-agents.md +26 -2
- package/docs/capacity-and-scheduling.md +1 -1
- package/docs/commands-and-modes.md +83 -3
- package/docs/configuration-and-targets.md +86 -4
- package/docs/context-engine.md +1 -1
- package/docs/development-pipeline.md +1 -1
- package/docs/dispatch-architecture-rationale.md +1 -1
- package/docs/documentation-coverage.md +3 -3
- package/docs/documentation-guide.md +3 -3
- package/docs/eval-runner.md +1 -1
- package/docs/evals-internal.md +1 -1
- package/docs/evidence-and-memory.md +74 -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 +228 -16
- package/docs/git-commit-provenance.md +2 -2
- package/docs/glossary.md +22 -2
- package/docs/installation-and-lifecycle.md +2 -2
- package/docs/middleware-and-components.md +2 -1
- package/docs/model-catalog.md +1 -1
- package/docs/observability.md +56 -9
- package/docs/proactive-memory.md +1 -1
- 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 +2 -2
- 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 +1 -1
- package/docs/worker-dispatch-mechanics.md +3 -3
- package/package.json +1 -2
- package/src/cli/argv.ts +5 -0
- package/src/cli/configure.ts +107 -23
- package/src/cli/doctor.ts +5 -1
- package/src/cli/evidence.ts +30 -25
- 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 +111 -0
- package/src/cli/fleet-validate.ts +30 -0
- package/src/cli/fleet.ts +173 -335
- package/src/cli/index.ts +3 -1
- package/src/cli/library.ts +190 -0
- package/src/cli/share.ts +13 -1
- package/src/cli/shared.ts +1 -0
- package/src/cli/targets.ts +4 -1
- package/src/cli/usage.ts +111 -19
- package/src/cli/validate-model.ts +60 -5
- package/src/core/bus-events.ts +29 -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/path-boundary.ts +100 -0
- package/src/domains/agents/builtins/architect.md +1 -0
- package/src/domains/agents/builtins/oracle.md +33 -0
- package/src/domains/agents/catalog.ts +13 -1
- package/src/domains/agents/extension.ts +2 -11
- package/src/domains/agents/fleet-contract.ts +304 -24
- package/src/domains/agents/index.ts +14 -0
- package/src/domains/agents/recipe.ts +7 -1
- package/src/domains/agents/registry.ts +73 -5
- package/src/domains/agents/result-contract.ts +360 -15
- package/src/domains/agents/write-boundary.ts +15 -50
- package/src/domains/config/classify.ts +4 -0
- package/src/domains/context/project-rules.ts +51 -1
- package/src/domains/dispatch/active-route-planner.ts +14 -0
- package/src/domains/dispatch/assignment-reconcile.ts +22 -5
- package/src/domains/dispatch/assignment-store.ts +151 -14
- package/src/domains/dispatch/backoff.ts +2 -1
- 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 +48 -0
- package/src/domains/dispatch/delegation-plan.ts +164 -0
- package/src/domains/dispatch/execution-plan.ts +76 -5
- package/src/domains/dispatch/execution-role.ts +12 -2
- package/src/domains/dispatch/execution-scheduler.ts +183 -67
- package/src/domains/dispatch/extension.ts +412 -74
- 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 +791 -0
- package/src/domains/dispatch/gate-role-prompts.ts +47 -0
- package/src/domains/dispatch/host-verification.ts +178 -0
- package/src/domains/dispatch/index.ts +41 -1
- package/src/domains/dispatch/intent-requirements.ts +40 -0
- package/src/domains/dispatch/intent.ts +235 -0
- package/src/domains/dispatch/path-scope.ts +370 -0
- package/src/domains/dispatch/receipt-integrity.ts +9 -4
- package/src/domains/dispatch/state.ts +36 -3
- package/src/domains/dispatch/types.ts +64 -12
- package/src/domains/dispatch/validation.ts +69 -6
- package/src/domains/dispatch/write-boundary-enforcer.ts +45 -0
- package/src/domains/dispatch/write-boundary.ts +201 -22
- package/src/domains/eval/metrics/evidence.ts +79 -2
- package/src/domains/eval/runners/clio-run.ts +12 -2
- package/src/domains/evidence/build.ts +69 -11
- package/src/domains/evidence/index.ts +21 -0
- package/src/domains/evidence/provenance.ts +46 -11
- package/src/domains/evidence/trust-projection.ts +274 -0
- package/src/domains/evidence/trust-status.ts +155 -18
- package/src/domains/evidence/types.ts +4 -0
- package/src/domains/extensions/discovery.ts +88 -1
- package/src/domains/extensions/resources.ts +20 -8
- package/src/domains/extensions/state.ts +6 -2
- package/src/domains/extensions/types.ts +4 -1
- package/src/domains/lifecycle/doctor.ts +140 -1
- package/src/domains/middleware/index.ts +15 -0
- package/src/domains/middleware/watchdog.ts +281 -0
- package/src/domains/observability/contract.ts +3 -1
- package/src/domains/observability/cost.ts +12 -1
- 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/prompts/contract.ts +3 -5
- package/src/domains/providers/extension.ts +30 -2
- package/src/domains/resources/common-loader.ts +3 -0
- package/src/domains/resources/index.ts +20 -0
- package/src/domains/resources/library.ts +326 -0
- package/src/domains/resources/prompts/loader.ts +119 -14
- package/src/domains/resources/skills/marketplace.ts +37 -12
- package/src/domains/safety/policy-engine.ts +5 -5
- package/src/domains/safety/run-effects.ts +64 -1
- package/src/domains/safety/scope.ts +7 -12
- package/src/domains/session/handoff.ts +629 -0
- package/src/domains/share/archive.ts +67 -2
- package/src/engine/acp/server.ts +4 -1
- package/src/engine/prompt-templates.ts +18 -1
- package/src/engine/worker-runtime.ts +6 -3
- package/src/entry/orchestrator.ts +37 -0
- package/src/interactive/bus-notices.ts +26 -0
- package/src/interactive/chat-loop.ts +235 -1
- package/src/interactive/chat-renderer.ts +22 -0
- package/src/interactive/cost-overlay.ts +31 -3
- 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 +311 -17
- package/src/interactive/fleet-run-preview.ts +307 -0
- package/src/interactive/footer/notifications.ts +219 -0
- package/src/interactive/handoff-round.ts +56 -0
- package/src/interactive/interactive-application.ts +43 -1
- package/src/interactive/interactive-event-projection.ts +23 -1
- package/src/interactive/interactive-slash-runtime.ts +52 -2
- package/src/interactive/interactive-subscriptions.ts +14 -2
- package/src/interactive/oracle.ts +179 -0
- package/src/interactive/overlay-ask-user-lifecycle.ts +6 -0
- package/src/interactive/overlay-general-openers.ts +190 -1
- package/src/interactive/overlay-key-routing.ts +17 -1
- package/src/interactive/overlay-lifecycle.ts +41 -1
- package/src/interactive/overlay-permission-lifecycle.ts +10 -0
- package/src/interactive/overlay-resource-openers.ts +11 -3
- package/src/interactive/overlay-session-lifecycle.ts +234 -2
- 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 +221 -30
- package/src/interactive/overlays/side-question.ts +139 -0
- package/src/interactive/overlays/skills-hub.ts +401 -15
- package/src/interactive/side-question.ts +171 -0
- package/src/interactive/slash-commands.ts +439 -7
- package/src/interactive/slash-spec.ts +19 -6
- package/src/interactive/theme/tokens.ts +30 -0
- package/src/interactive/turn-middleware.ts +15 -1
- package/src/interactive/view/artifacts.ts +42 -9
- package/src/interactive/view/view-overlay.ts +15 -3
- package/src/interactive/watchdog-run.ts +75 -0
- package/src/interactive/worker-receipts.ts +14 -2
- package/src/interactive/worker-share.ts +56 -1
- package/src/interactive/worker-stream.ts +15 -0
- package/src/tools/bootstrap.ts +3 -0
- package/src/tools/compete-worktrees.ts +13 -79
- package/src/tools/dispatch-admission.ts +251 -18
- package/src/tools/dispatch-arguments.ts +84 -1
- package/src/tools/dispatch-plan.ts +165 -6
- package/src/tools/dispatch-runner.ts +364 -23
- package/src/tools/dispatch-types.ts +20 -1
- package/src/tools/dispatch.ts +72 -2
- package/src/tools/monitor.ts +29 -0
- package/src/tools/profiles.ts +18 -4
- package/src/tools/task-worktree.ts +238 -0
- package/src/tools/verify/authoring.ts +61 -1
- package/src/tools/verify/scripts.ts +62 -0
- package/src/tools/worker-evidence.ts +21 -14
- package/src/worker/spec-contract.ts +3 -1
- package/dist/chunk-HC4CLZ2Y.js +0 -68
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { pathBoundaryCovers } from "../../core/path-boundary.js";
|
|
3
|
+
import { normalizeWriteBoundary } from "../agents/write-boundary.js";
|
|
4
|
+
|
|
5
|
+
export type DelegationTaskMode = "sequential" | "parallel";
|
|
6
|
+
|
|
7
|
+
export interface DelegationPlanTask {
|
|
8
|
+
id: string;
|
|
9
|
+
agent: string;
|
|
10
|
+
description: string;
|
|
11
|
+
depends_on: ReadonlyArray<string>;
|
|
12
|
+
writes: ReadonlyArray<string>;
|
|
13
|
+
mode?: DelegationTaskMode;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface DelegationPlan {
|
|
17
|
+
tasks: ReadonlyArray<DelegationPlanTask>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type DelegationPlanReason =
|
|
21
|
+
| "delegation_plan_malformed"
|
|
22
|
+
| "delegation_plan_over_max_tasks"
|
|
23
|
+
| "delegation_plan_duplicate_id"
|
|
24
|
+
| "delegation_plan_roster_violation"
|
|
25
|
+
| "delegation_plan_dependency_unknown"
|
|
26
|
+
| "delegation_plan_dependency_cycle"
|
|
27
|
+
| "delegation_plan_writes_outside_boundary";
|
|
28
|
+
|
|
29
|
+
export type DelegationPlanValidation =
|
|
30
|
+
| { ok: true; plan: DelegationPlan; hash: string }
|
|
31
|
+
| { ok: false; reason: DelegationPlanReason; detail: string };
|
|
32
|
+
|
|
33
|
+
export interface ValidateDelegationPlanInput {
|
|
34
|
+
value: unknown;
|
|
35
|
+
roster: ReadonlyArray<string>;
|
|
36
|
+
maxTasks: number;
|
|
37
|
+
writes: ReadonlyArray<string>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const DELEGATION_PROPOSAL_BRIEFING_MAX_BYTES = 12_000;
|
|
41
|
+
|
|
42
|
+
export function buildDelegationProposalBriefing(proposals: ReadonlyArray<{ agent: string; output: string }>): string {
|
|
43
|
+
const value = proposals.map((proposal) => `PROPOSAL ${proposal.agent}\n${proposal.output}`).join("\n\n");
|
|
44
|
+
if (Buffer.byteLength(value, "utf8") <= DELEGATION_PROPOSAL_BRIEFING_MAX_BYTES) return value;
|
|
45
|
+
const suffix = "\n[truncated]";
|
|
46
|
+
const source = Buffer.from(value, "utf8");
|
|
47
|
+
let end = DELEGATION_PROPOSAL_BRIEFING_MAX_BYTES - Buffer.byteLength(suffix, "utf8");
|
|
48
|
+
while (end > 0) {
|
|
49
|
+
const byte = source[end];
|
|
50
|
+
if (byte === undefined || (byte & 0xc0) !== 0x80) break;
|
|
51
|
+
end -= 1;
|
|
52
|
+
}
|
|
53
|
+
return `${source.subarray(0, end).toString("utf8")}${suffix}`;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const ID_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/u;
|
|
57
|
+
|
|
58
|
+
function malformed(detail: string): DelegationPlanValidation {
|
|
59
|
+
return { ok: false, reason: "delegation_plan_malformed", detail };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function validateDelegationPlan(input: ValidateDelegationPlanInput): DelegationPlanValidation {
|
|
63
|
+
if (input.value === null || typeof input.value !== "object" || Array.isArray(input.value)) {
|
|
64
|
+
return malformed("delegation plan must be an object");
|
|
65
|
+
}
|
|
66
|
+
const record = input.value as Record<string, unknown>;
|
|
67
|
+
if (Object.keys(record).some((key) => key !== "tasks") || !Array.isArray(record.tasks)) {
|
|
68
|
+
return malformed("delegation plan must carry only tasks[]");
|
|
69
|
+
}
|
|
70
|
+
if (record.tasks.length === 0) return malformed("delegation plan must carry at least one task");
|
|
71
|
+
if (record.tasks.length > input.maxTasks) {
|
|
72
|
+
return {
|
|
73
|
+
ok: false,
|
|
74
|
+
reason: "delegation_plan_over_max_tasks",
|
|
75
|
+
detail: `delegation plan returned ${record.tasks.length} tasks, above maxTasks ${input.maxTasks}`,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const roster = new Set(input.roster);
|
|
79
|
+
const ids = new Set<string>();
|
|
80
|
+
const tasks: DelegationPlanTask[] = [];
|
|
81
|
+
for (const raw of record.tasks) {
|
|
82
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return malformed("every task must be an object");
|
|
83
|
+
const task = raw as Record<string, unknown>;
|
|
84
|
+
if (
|
|
85
|
+
Object.keys(task).some((key) => !["id", "agent", "description", "depends_on", "writes", "mode"].includes(key)) ||
|
|
86
|
+
typeof task.id !== "string" ||
|
|
87
|
+
!ID_RE.test(task.id) ||
|
|
88
|
+
typeof task.agent !== "string" ||
|
|
89
|
+
task.agent.length === 0 ||
|
|
90
|
+
typeof task.description !== "string" ||
|
|
91
|
+
task.description.trim().length === 0 ||
|
|
92
|
+
!Array.isArray(task.depends_on) ||
|
|
93
|
+
task.depends_on.some((value) => typeof value !== "string" || value.length === 0) ||
|
|
94
|
+
!Array.isArray(task.writes) ||
|
|
95
|
+
task.writes.some((value) => typeof value !== "string" || value.length === 0) ||
|
|
96
|
+
(task.mode !== undefined && task.mode !== "sequential" && task.mode !== "parallel")
|
|
97
|
+
) {
|
|
98
|
+
return malformed("each task requires id, agent, description, depends_on[], writes[], and an optional valid mode");
|
|
99
|
+
}
|
|
100
|
+
if (ids.has(task.id)) {
|
|
101
|
+
return { ok: false, reason: "delegation_plan_duplicate_id", detail: `duplicate task id '${task.id}'` };
|
|
102
|
+
}
|
|
103
|
+
if (!roster.has(task.agent)) {
|
|
104
|
+
return {
|
|
105
|
+
ok: false,
|
|
106
|
+
reason: "delegation_plan_roster_violation",
|
|
107
|
+
detail: `task '${task.id}' names agent '${task.agent}' outside the roster`,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
let writes: ReadonlyArray<string>;
|
|
111
|
+
try {
|
|
112
|
+
writes = normalizeWriteBoundary(task.writes as string[]);
|
|
113
|
+
} catch (error) {
|
|
114
|
+
return malformed(`task '${task.id}' has invalid writes: ${error instanceof Error ? error.message : String(error)}`);
|
|
115
|
+
}
|
|
116
|
+
const outside = writes.find((path) => !pathBoundaryCovers(input.writes, path));
|
|
117
|
+
if (outside !== undefined) {
|
|
118
|
+
return {
|
|
119
|
+
ok: false,
|
|
120
|
+
reason: "delegation_plan_writes_outside_boundary",
|
|
121
|
+
detail: `task '${task.id}' writes '${outside}' outside the plan step boundary`,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
ids.add(task.id);
|
|
125
|
+
tasks.push({
|
|
126
|
+
id: task.id,
|
|
127
|
+
agent: task.agent,
|
|
128
|
+
description: task.description,
|
|
129
|
+
depends_on: [...(task.depends_on as string[])],
|
|
130
|
+
writes,
|
|
131
|
+
...(task.mode !== undefined ? { mode: task.mode as DelegationTaskMode } : {}),
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
for (const task of tasks) {
|
|
135
|
+
const unknown = task.depends_on.find((dependency) => !ids.has(dependency));
|
|
136
|
+
if (unknown !== undefined) {
|
|
137
|
+
return {
|
|
138
|
+
ok: false,
|
|
139
|
+
reason: "delegation_plan_dependency_unknown",
|
|
140
|
+
detail: `task '${task.id}' depends on unknown task '${unknown}'`,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
const remaining = new Set(ids);
|
|
145
|
+
const completed = new Set<string>();
|
|
146
|
+
while (remaining.size > 0) {
|
|
147
|
+
const ready = tasks.filter(
|
|
148
|
+
(task) => remaining.has(task.id) && task.depends_on.every((dependency) => completed.has(dependency)),
|
|
149
|
+
);
|
|
150
|
+
if (ready.length === 0) {
|
|
151
|
+
return {
|
|
152
|
+
ok: false,
|
|
153
|
+
reason: "delegation_plan_dependency_cycle",
|
|
154
|
+
detail: `delegation plan dependency cycle includes ${[...remaining].sort().join(", ")}`,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
for (const task of ready) {
|
|
158
|
+
remaining.delete(task.id);
|
|
159
|
+
completed.add(task.id);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const plan = { tasks } satisfies DelegationPlan;
|
|
163
|
+
return { ok: true, plan, hash: createHash("sha256").update(JSON.stringify(plan)).digest("hex") };
|
|
164
|
+
}
|
|
@@ -3,7 +3,7 @@ import type { ResultContract } from "../agents/result-contract.js";
|
|
|
3
3
|
import type { AgentAutomationAuthority } from "../agents/spec.js";
|
|
4
4
|
import type { ExecutionRole } from "./execution-role.js";
|
|
5
5
|
|
|
6
|
-
export type ExecutionPlanTopology = "parallel" | "sequential" | "pipeline" | "review" | "compete" | "fleet";
|
|
6
|
+
export type ExecutionPlanTopology = "parallel" | "sequential" | "pipeline" | "review" | "compete" | "council" | "fleet";
|
|
7
7
|
export type ExecutionPlanScope = "readonly" | "workspace";
|
|
8
8
|
export type ExecutionPlanFailurePolicy = "stop" | "continue";
|
|
9
9
|
|
|
@@ -56,6 +56,19 @@ export interface ExecutionPlanAgentStep {
|
|
|
56
56
|
* contract declares no boundary at all and is therefore not enforced.
|
|
57
57
|
*/
|
|
58
58
|
writes?: ReadonlyArray<string>;
|
|
59
|
+
/** Exact per-step route defaults from a version 5 fleet contract. */
|
|
60
|
+
target?: string;
|
|
61
|
+
profile?: string;
|
|
62
|
+
/** Version 5 gate authoring and baseline execution facts. */
|
|
63
|
+
gate?: { path: string; commandId: string };
|
|
64
|
+
/** Version 5 dynamic planning facts. */
|
|
65
|
+
plan?: {
|
|
66
|
+
roster: ReadonlyArray<string>;
|
|
67
|
+
maxTasks: number;
|
|
68
|
+
proposals: boolean;
|
|
69
|
+
};
|
|
70
|
+
/** The plan step that admitted this dynamically authored task. */
|
|
71
|
+
planParentId?: string;
|
|
59
72
|
}
|
|
60
73
|
|
|
61
74
|
/**
|
|
@@ -85,6 +98,8 @@ export interface ExecutionPlanCodeStep {
|
|
|
85
98
|
commitFrom?: ReadonlyArray<string>;
|
|
86
99
|
/** Declared write boundary; see `ExecutionPlanAgentStep.writes`. */
|
|
87
100
|
writes?: ReadonlyArray<string>;
|
|
101
|
+
/** A gate check executes a declared gate file through this command. */
|
|
102
|
+
gate?: { gateId: string; path: string };
|
|
88
103
|
}
|
|
89
104
|
|
|
90
105
|
export type ExecutionPlanStep = ExecutionPlanAgentStep | ExecutionPlanCodeStep;
|
|
@@ -106,6 +121,8 @@ export interface ExecutionPlan {
|
|
|
106
121
|
topology: ExecutionPlanTopology;
|
|
107
122
|
rootTask: string;
|
|
108
123
|
maxWorkers: number;
|
|
124
|
+
/** Serialize writer admission when set. The only supported value in this cut is one. */
|
|
125
|
+
writers?: 1;
|
|
109
126
|
onFailure: ExecutionPlanFailurePolicy;
|
|
110
127
|
steps: ReadonlyArray<ExecutionPlanStep>;
|
|
111
128
|
loops: ReadonlyArray<ExecutionPlanLoop>;
|
|
@@ -240,6 +257,7 @@ function checkLoops(steps: ReadonlyArray<ExecutionPlanStep>, loops: ReadonlyArra
|
|
|
240
257
|
function checkWriteBoundaryWaves(
|
|
241
258
|
steps: ReadonlyArray<ExecutionPlanStep>,
|
|
242
259
|
waves: ReadonlyArray<ReadonlyArray<string>>,
|
|
260
|
+
writerLimit?: 1,
|
|
243
261
|
): void {
|
|
244
262
|
const byId = new Map(steps.map((step) => [step.id, step]));
|
|
245
263
|
for (const [index, wave] of waves.entries()) {
|
|
@@ -250,7 +268,7 @@ function checkWriteBoundaryWaves(
|
|
|
250
268
|
const declared = members.filter((step) => step.writes !== undefined);
|
|
251
269
|
if (declared.length === 0) continue;
|
|
252
270
|
const undeclared = members.filter((step) => step.writes === undefined);
|
|
253
|
-
if (undeclared.length > 0) {
|
|
271
|
+
if (undeclared.length > 0 && writerLimit !== 1) {
|
|
254
272
|
throw new Error(
|
|
255
273
|
`execution plan: wave ${index} mixes boundary-enforced steps (${declared
|
|
256
274
|
.map((step) => step.id)
|
|
@@ -260,7 +278,7 @@ function checkWriteBoundaryWaves(
|
|
|
260
278
|
);
|
|
261
279
|
}
|
|
262
280
|
const writers = declared.filter((step) => (step.writes?.length ?? 0) > 0);
|
|
263
|
-
if (writers.length > 1) {
|
|
281
|
+
if (writers.length > 1 && writerLimit !== 1) {
|
|
264
282
|
throw new Error(
|
|
265
283
|
`execution plan: wave ${index} schedules ${writers.length} steps that may write (${writers
|
|
266
284
|
.map((step) => step.id)
|
|
@@ -273,6 +291,9 @@ function checkWriteBoundaryWaves(
|
|
|
273
291
|
}
|
|
274
292
|
|
|
275
293
|
export function compileExecutionPlan(input: ExecutionPlanInput): ExecutionPlan {
|
|
294
|
+
if (input.writers !== undefined && input.writers !== 1) {
|
|
295
|
+
throw new Error("execution plan: writers must be 1 when present");
|
|
296
|
+
}
|
|
276
297
|
const steps = canonicalSteps(input.steps);
|
|
277
298
|
const loops = (input.loops ?? []).map((loop) => ({
|
|
278
299
|
...loop,
|
|
@@ -281,12 +302,13 @@ export function compileExecutionPlan(input: ExecutionPlanInput): ExecutionPlan {
|
|
|
281
302
|
}));
|
|
282
303
|
checkLoops(steps, loops);
|
|
283
304
|
const waves = executionPlanWaves(steps, input.maxWorkers);
|
|
284
|
-
checkWriteBoundaryWaves(steps, waves);
|
|
305
|
+
checkWriteBoundaryWaves(steps, waves, input.writers);
|
|
285
306
|
const canonical = {
|
|
286
307
|
version: 4 as const,
|
|
287
308
|
topology: input.topology,
|
|
288
309
|
rootTask: input.rootTask,
|
|
289
310
|
maxWorkers: input.maxWorkers,
|
|
311
|
+
...(input.writers === 1 ? { writers: 1 as const } : {}),
|
|
290
312
|
onFailure: input.onFailure,
|
|
291
313
|
steps,
|
|
292
314
|
loops,
|
|
@@ -309,6 +331,55 @@ export function executionPlanAncestors(plan: ExecutionPlan, stepId: string): Rea
|
|
|
309
331
|
return ancestors;
|
|
310
332
|
}
|
|
311
333
|
|
|
334
|
+
/** Recompile a plan with coordinator-validated dynamic agent tasks. */
|
|
335
|
+
export function spliceExecutionPlan(
|
|
336
|
+
plan: ExecutionPlan,
|
|
337
|
+
parentId: string,
|
|
338
|
+
tasks: ReadonlyArray<{
|
|
339
|
+
id: string;
|
|
340
|
+
agentId: string;
|
|
341
|
+
task: string;
|
|
342
|
+
dependencies: ReadonlyArray<string>;
|
|
343
|
+
writes: ReadonlyArray<string>;
|
|
344
|
+
target?: string;
|
|
345
|
+
profile?: string;
|
|
346
|
+
requestedAuthority: AgentAutomationAuthority;
|
|
347
|
+
approvedAuthority: AgentAutomationAuthority | null;
|
|
348
|
+
expectedResultContract: ResultContract["kind"];
|
|
349
|
+
executionRole: ExecutionRole;
|
|
350
|
+
}>,
|
|
351
|
+
): ExecutionPlan {
|
|
352
|
+
const parent = plan.steps.find((step) => step.id === parentId);
|
|
353
|
+
if (parent?.kind !== "agent" || parent.plan === undefined) {
|
|
354
|
+
throw new Error(`execution plan: '${parentId}' is not a plan step`);
|
|
355
|
+
}
|
|
356
|
+
const inserted: ExecutionPlanStepInput[] = tasks.map((task) => ({
|
|
357
|
+
kind: "agent",
|
|
358
|
+
id: task.id,
|
|
359
|
+
agentId: task.agentId,
|
|
360
|
+
executionRole: task.executionRole,
|
|
361
|
+
scope: task.writes.length > 0 ? "workspace" : "readonly",
|
|
362
|
+
expectedResultContract: task.expectedResultContract,
|
|
363
|
+
requestedAuthority: task.requestedAuthority,
|
|
364
|
+
approvedAuthority: task.approvedAuthority,
|
|
365
|
+
dependencies: [parentId, ...task.dependencies],
|
|
366
|
+
task: task.task,
|
|
367
|
+
writes: [...task.writes],
|
|
368
|
+
...(task.target !== undefined ? { target: task.target } : {}),
|
|
369
|
+
...(task.profile !== undefined ? { profile: task.profile } : {}),
|
|
370
|
+
planParentId: parentId,
|
|
371
|
+
}));
|
|
372
|
+
return compileExecutionPlan({
|
|
373
|
+
topology: plan.topology,
|
|
374
|
+
rootTask: plan.rootTask,
|
|
375
|
+
maxWorkers: plan.maxWorkers,
|
|
376
|
+
...(plan.writers === 1 ? { writers: 1 as const } : {}),
|
|
377
|
+
onFailure: plan.onFailure,
|
|
378
|
+
steps: [...plan.steps, ...inserted],
|
|
379
|
+
loops: plan.loops,
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
|
|
312
383
|
/** A linear step declares no dependencies; the compiler chains them by position. */
|
|
313
384
|
export type ExecutionPlanLinearStepInput =
|
|
314
385
|
| (Omit<ExecutionPlanAgentStep, "kind" | "dependencies"> & { kind?: "agent" })
|
|
@@ -317,7 +388,7 @@ export type ExecutionPlanLinearStepInput =
|
|
|
317
388
|
export function compileLinearExecutionPlan(
|
|
318
389
|
input: Omit<ExecutionPlanInput, "steps"> & { steps: ReadonlyArray<ExecutionPlanLinearStepInput> },
|
|
319
390
|
): ExecutionPlan {
|
|
320
|
-
const parallel = input.topology === "parallel" || input.topology === "compete";
|
|
391
|
+
const parallel = input.topology === "parallel" || input.topology === "compete" || input.topology === "council";
|
|
321
392
|
return compileExecutionPlan({
|
|
322
393
|
...input,
|
|
323
394
|
steps: input.steps.map((step, index): ExecutionPlanStepInput => {
|
|
@@ -47,7 +47,7 @@ export function isExecutionRole(value: unknown): value is ExecutionRole {
|
|
|
47
47
|
* statistics belong to: every compete candidate occupies a distinct `candidate`
|
|
48
48
|
* position but they are all ordinary `builder` routes.
|
|
49
49
|
*/
|
|
50
|
-
export type GateTopologyRole = "builder" | "reviewer" | "candidate" | "judge";
|
|
50
|
+
export type GateTopologyRole = "builder" | "reviewer" | "candidate" | "judge" | "member" | "synthesis";
|
|
51
51
|
|
|
52
52
|
/**
|
|
53
53
|
* Facts the role is derived from. `capabilityClass` and `resultContractKind`
|
|
@@ -86,6 +86,8 @@ export function deriveExecutionRole(input: ExecutionRoleInput): ExecutionRole {
|
|
|
86
86
|
if (input.attempt > 0) return "recovery";
|
|
87
87
|
if (input.gateRole === "reviewer") return "reviewer";
|
|
88
88
|
if (input.gateRole === "judge") return "judge";
|
|
89
|
+
if (input.gateRole === "synthesis") return "judge";
|
|
90
|
+
if (input.gateRole === "member") return "researcher";
|
|
89
91
|
if (input.gateRole === "builder" || input.gateRole === "candidate") return "builder";
|
|
90
92
|
if (input.resultContractKind === "verifier-report") return "verifier";
|
|
91
93
|
if (input.capabilityClass === "read-only") return "researcher";
|
|
@@ -170,9 +172,17 @@ export function gateDeciderAgentId(requested: string | undefined): string {
|
|
|
170
172
|
* the slot. The gate validates that answer and fails closed on a malformed one,
|
|
171
173
|
* so also enforcing an inapplicable recipe postcondition would fail the run
|
|
172
174
|
* before its verdict could be read.
|
|
175
|
+
*
|
|
176
|
+
* `synthesis` is the third decider and belongs here for the same reason.
|
|
177
|
+
* {@link deriveExecutionRole} already resolves it to the `judge` role, and
|
|
178
|
+
* `isBoundedGateRolePrompt` admits it only under the council judge prompt,
|
|
179
|
+
* which asks for `{"verdict","text"}`. A council seats the read-only
|
|
180
|
+
* `researcher` by default, whose recipe declares `research-report`, so leaving
|
|
181
|
+
* the recipe postcondition on the slot sealed a contract failure on every
|
|
182
|
+
* correct synthesis and burned the configured retries reproducing it.
|
|
173
183
|
*/
|
|
174
184
|
export function appliesRecipeResultContract(gateRole: GateTopologyRole | undefined): boolean {
|
|
175
|
-
return gateRole !== "reviewer" && gateRole !== "judge";
|
|
185
|
+
return gateRole !== "reviewer" && gateRole !== "judge" && gateRole !== "synthesis";
|
|
176
186
|
}
|
|
177
187
|
|
|
178
188
|
/** The route dimensions a gate correlation is measured across. */
|