@iowarp/clio-coder 0.3.4 → 0.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +65 -2
- package/CONTRIBUTING.md +6 -6
- package/README.md +16 -5
- package/dist/{acp-S5R4RR5B.js → acp-SK4MD6MM.js} +11 -11
- package/dist/{agents-P6DMMVZY.js → agents-2FN2K6ME.js} +33 -26
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-2XCZLPKS.js → auth-QIYZWM5I.js} +15 -15
- package/dist/{chunk-EKMEHE4H.js → chunk-33YXPOE3.js} +2 -3
- package/dist/{chunk-VAWWTKDP.js → chunk-3HAPLH5M.js} +11 -11
- package/dist/{chunk-YCWGATWI.js → chunk-465YSENW.js} +3 -3
- package/dist/{chunk-4OC57DA6.js → chunk-4DGYLA73.js} +53 -2
- package/dist/{chunk-UZHIZC5S.js → chunk-4DWFMQDR.js} +61 -76
- package/dist/{chunk-ZWMF7253.js → chunk-5C3AQNDW.js} +328 -9
- package/dist/{chunk-22NAGB7X.js → chunk-5C77SEEY.js} +5 -94
- package/dist/{chunk-WPQLXFOZ.js → chunk-5FR74PWO.js} +3 -2
- package/dist/{chunk-35MKKU5R.js → chunk-5UJ6ECTS.js} +18 -10
- package/dist/{chunk-BRXQQJFP.js → chunk-6M7VS3J3.js} +571 -50
- package/dist/{chunk-QQK64KLB.js → chunk-6TUKSZVF.js} +141 -23
- package/dist/{chunk-N4CZJQRK.js → chunk-AB4XIIVB.js} +8 -6
- package/dist/{chunk-KRPY7NTG.js → chunk-BMWK7ZIZ.js} +14 -20
- package/dist/{chunk-4BPJXDWC.js → chunk-C4JBQ5SR.js} +30 -14
- package/dist/{chunk-ZYKPLLNQ.js → chunk-CEYBNUGC.js} +821 -83
- package/dist/{chunk-VEZEGCGW.js → chunk-D4MDIG46.js} +20 -18
- package/dist/chunk-DJNLUABN.js +843 -0
- package/dist/{chunk-BP4OYD6A.js → chunk-DMD2AGVS.js} +21 -2
- package/dist/{chunk-KOHPCX4K.js → chunk-DOOEX22V.js} +2 -2
- package/dist/chunk-DQA7QLMD.js +123 -0
- package/dist/chunk-DR52UMZW.js +21 -0
- package/dist/{chunk-3HZ5RWN2.js → chunk-EBEFWSGL.js} +9 -7
- package/dist/{chunk-EDRHSCIE.js → chunk-EELBMBT6.js} +128 -13
- package/dist/{chunk-HV5X7OR2.js → chunk-EOOQZZDE.js} +16 -14
- package/dist/{chunk-WR67VIZY.js → chunk-FOT2FX5J.js} +63 -5
- package/dist/{chunk-BPGS2WCQ.js → chunk-GEYXPTRF.js} +2 -1
- package/dist/{chunk-FYYLNIL5.js → chunk-GH5622CP.js} +2 -2
- package/dist/{chunk-BEY543CS.js → chunk-GOXNB3AO.js} +5 -2
- package/dist/chunk-GWS3VEIW.js +195 -0
- package/dist/{chunk-G4BMMOKF.js → chunk-HVDIIIQW.js} +2 -2
- package/dist/chunk-HWUFFB6L.js +83 -0
- package/dist/{chunk-X6COSD2O.js → chunk-J7PIKKWC.js} +8 -436
- package/dist/{chunk-NILBFAPG.js → chunk-JNXPYBB4.js} +2 -2
- package/dist/{chunk-4VP4KH3K.js → chunk-JRIO5UD2.js} +4 -4
- package/dist/{chunk-K6WL7QZT.js → chunk-JTSEDYVQ.js} +7 -7
- package/dist/{chunk-QKMUKYO7.js → chunk-KCMKRQX4.js} +236 -84
- package/dist/chunk-KZ2H5X4G.js +1026 -0
- package/dist/{chunk-A2GZF7DC.js → chunk-LADCF22A.js} +13 -13
- package/dist/chunk-LCGCVYZ4.js +57 -0
- package/dist/chunk-M4AKACEO.js +382 -0
- package/dist/{chunk-POHLU5DW.js → chunk-M6L6IDJG.js} +3 -3
- package/dist/{chunk-4JUF2NNX.js → chunk-MXI6J5JF.js} +7 -7
- package/dist/{chunk-X4RCMKVQ.js → chunk-NDINPTJ4.js} +2 -2
- package/dist/{chunk-TTNYS3EA.js → chunk-OB5HIGJY.js} +1 -1
- package/dist/{chunk-7RXG6QRZ.js → chunk-OBMAI2DP.js} +61 -840
- package/dist/{chunk-5M54SPOL.js → chunk-ODFEOB4F.js} +161 -5
- package/dist/chunk-PD3MESLB.js +242 -0
- package/dist/{chunk-ED4KHGC3.js → chunk-PPAMZ32Z.js} +9 -2
- package/dist/{chunk-VMNQ6OZA.js → chunk-QCTRSGHQ.js} +963 -786
- package/dist/chunk-RVG5JXAL.js +41 -0
- package/dist/{chunk-RD5U66HV.js → chunk-SROCI7ZU.js} +7 -7
- package/dist/{chunk-MFFY33HR.js → chunk-THKY7CD7.js} +466 -205
- package/dist/{chunk-34475P3I.js → chunk-TSHXZTOQ.js} +5 -4
- package/dist/{chunk-PCZJO5TI.js → chunk-UFQ3F4FW.js} +13 -178
- package/dist/{chunk-AD2SYQYC.js → chunk-UHXRNZ2J.js} +121 -3
- package/dist/chunk-UND3GU2L.js +103 -0
- package/dist/{chunk-QQL5RT5M.js → chunk-UUANF5CR.js} +2323 -2114
- package/dist/{chunk-VJWL6YS5.js → chunk-UUVG37B4.js} +2 -2
- package/dist/chunk-UVDSQ6LW.js +472 -0
- package/dist/{chunk-QWU7ZBO7.js → chunk-VQNODYQ4.js} +215 -56
- package/dist/chunk-VREKEFLL.js +37 -0
- package/dist/{chunk-2TZWSW76.js → chunk-WHGPSPT5.js} +2 -2
- package/dist/{chunk-TW3WDMVS.js → chunk-WHJYKASB.js} +2 -2
- package/dist/{chunk-MEQ45TQ4.js → chunk-WJHBC77E.js} +21 -7
- package/dist/{chunk-HXG4IURW.js → chunk-X2KV5FXT.js} +2 -2
- package/dist/{chunk-YHZX5GEU.js → chunk-XAKHZX5N.js} +2 -2
- package/dist/{chunk-2LZI5CAG.js → chunk-XEGB6BCN.js} +228 -36
- package/dist/{chunk-E25LMLRW.js → chunk-YD734TPH.js} +2 -2
- package/dist/{verifiers-4UUM6TEE.js → chunk-YTYFXUI3.js} +121 -372
- package/dist/{chunk-3JLKSKD7.js → chunk-ZGH7FGS5.js} +17 -7
- package/dist/{chunk-VSNATDE6.js → chunk-ZZMN5OM4.js} +2 -2
- package/dist/cli/index.js +34 -32
- package/dist/{clio-J5JIOIDS.js → clio-WBVQEBKO.js} +7 -7
- package/dist/{code-nav-AXCXSBHX.js → code-nav-FGGFIE7L.js} +7 -7
- package/dist/codewiki/build-worker.js +4 -4
- package/dist/{components-KELWS457.js → components-F7OEATSO.js} +5 -5
- package/dist/{config-OEBMIN2U.js → config-TRBL3RCF.js} +48 -41
- package/dist/{configure-PUQOSIXQ.js → configure-OLCVPHNM.js} +17 -17
- package/dist/{context-URSXPBCK.js → context-MJIJ6GOX.js} +12 -12
- package/dist/{context-EKDCKUUZ.js → context-WFPKQSM6.js} +26 -9
- package/dist/{context-MGSE4Z2T.js → context-XEWE3MOJ.js} +44 -37
- package/dist/{context-clear-KDAJRNUK.js → context-clear-KNOS2JPB.js} +44 -37
- package/dist/{context-index-BZ4UYMTC.js → context-index-SSR5ECNE.js} +3 -3
- package/dist/{context-working-set-SBKMPPI2.js → context-working-set-EUXAZI6N.js} +14 -13
- package/dist/{dispatch-runner-MSWN72NK.js → dispatch-runner-B7MTOVKL.js} +321 -60
- package/dist/{docs-2C2LTVT2.js → docs-FLJTIDSE.js} +5 -5
- package/dist/{doctor-7BSE27PJ.js → doctor-RN4YKO2X.js} +15 -15
- package/dist/{eval-IZGDOO4H.js → eval-RUBJVSNQ.js} +52 -236
- package/dist/{evidence-SR7WXB5B.js → evidence-JZNBUOQZ.js} +39 -33
- package/dist/{evolve-K7VE2CBX.js → evolve-FJVC4KKI.js} +39 -33
- package/dist/{extensions-QVDOHDGJ.js → extensions-IQL36S7K.js} +5 -5
- package/dist/{fleet-7XMJNQNF.js → fleet-BDKYJFCP.js} +243 -370
- package/dist/fleet-commands-ZFIWZSB3.js +70 -0
- package/dist/fleet-graph-Y6HPXIVF.js +125 -0
- package/dist/fleet-new-RDVJLHHH.js +48 -0
- package/dist/{fleet-preflight-AQNAH644.js → fleet-preflight-BHSNPBMH.js} +2 -2
- package/dist/fleet-validate-BIYREGIK.js +79 -0
- package/dist/{init-JGNPAYXT.js → init-LQUB5COQ.js} +57 -48
- package/dist/library-NJAHIGG4.js +217 -0
- package/dist/memory-OG6HOYKM.js +472 -0
- package/dist/{models-ZMMLFJNN.js → models-5ZG5XY7J.js} +23 -22
- package/dist/{monitor-2F3T5KHP.js → monitor-TJ7AMTGB.js} +69 -35
- package/dist/{orchestrator-ORHT43JB.js → orchestrator-WZYB54DM.js} +4868 -1189
- package/dist/{paths-UXLN5YYZ.js → paths-XUC7GS6E.js} +5 -5
- package/dist/{reset-NXGTYNUO.js → reset-PXQT45IY.js} +8 -8
- package/dist/{run-RF4WJGMT.js → run-FQ74YF62.js} +82 -62
- package/dist/{share-UT3W6E4M.js → share-FW7SVCL3.js} +34 -10
- package/dist/{skills-PSACKC5Q.js → skills-7E7IRB3R.js} +25 -9
- package/dist/{skills-eval-WJSI55RZ.js → skills-eval-LI75W6OK.js} +43 -35
- package/dist/{targets-PIIRAOYS.js → targets-4CIFKCTW.js} +27 -24
- package/dist/{terminal-lease-ULWXWNVY.js → terminal-lease-WUZY7ZV5.js} +5 -4
- package/dist/{uninstall-FZCQCDKC.js → uninstall-7FV7IP4E.js} +5 -5
- package/dist/{upgrade-346TZ6AV.js → upgrade-K2HVIVMQ.js} +21 -20
- package/dist/{usage-6KKXR32N.js → usage-GTZELZQX.js} +159 -59
- package/dist/verifiers-RLAHT27O.js +336 -0
- package/dist/{verify-X5HDROLA.js → verify-BX3BRKH5.js} +7 -6
- package/dist/{wiki-generate-7STOCIFZ.js → wiki-generate-ASIFASCN.js} +58 -48
- package/dist/worker/entry.js +98 -84
- package/dist/{workspace-G4ZWUIPR.js → workspace-ZJ6BFM3Q.js} +4 -4
- package/docs/README.md +4 -3
- package/docs/acp.md +1 -1
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +2 -2
- package/docs/artifact-placement.md +1 -2
- package/docs/artifact-versions.md +10 -6
- package/docs/built-in-agents.md +26 -2
- package/docs/capacity-and-scheduling.md +1 -1
- package/docs/commands-and-modes.md +90 -8
- package/docs/configuration-and-targets.md +90 -2
- package/docs/context-engine.md +4 -2
- package/docs/context-working-set.md +4 -4
- package/docs/development-pipeline.md +1 -1
- package/docs/dispatch-architecture-rationale.md +1 -1
- package/docs/documentation-coverage.md +4 -4
- package/docs/documentation-guide.md +4 -4
- package/docs/eval-runner.md +1 -1
- package/docs/evals-internal.md +4 -45
- package/docs/evidence-and-memory.md +70 -10
- package/docs/evolution.md +1 -1
- package/docs/exit-codes-and-output.md +4 -1
- package/docs/extensions-and-sharing.md +6 -2
- package/docs/fleet-demo-runbook.md +2 -2
- package/docs/fleet-dispatch.md +224 -11
- package/docs/git-commit-provenance.md +2 -2
- package/docs/glossary.md +1 -1
- package/docs/installation-and-lifecycle.md +2 -2
- package/docs/middleware-and-components.md +20 -2
- package/docs/model-catalog.md +1 -1
- package/docs/observability.md +55 -8
- package/docs/proactive-memory.md +26 -16
- package/docs/prompt-envelope-and-tools.md +4 -2
- package/docs/provider-adapter-cookbook.md +1 -1
- package/docs/release-cut-checklist.md +83 -65
- package/docs/resource-library.md +59 -0
- package/docs/safety-model.md +29 -7
- package/docs/scientific-validation.md +3 -3
- package/docs/session-lifecycle.md +37 -1
- package/docs/skills-marketplace.md +16 -3
- package/docs/tool-usage.md +14 -7
- package/docs/trace-store.md +1 -1
- package/docs/troubleshooting.md +1 -1
- package/docs/tui-design.md +38 -4
- package/docs/worker-dispatch-mechanics.md +3 -3
- package/package.json +7 -4
- package/src/cli/agents.ts +2 -3
- package/src/cli/argv.ts +14 -1
- package/src/cli/fleet-commands.ts +37 -0
- package/src/cli/fleet-graph.ts +102 -0
- package/src/cli/fleet-new.ts +36 -0
- package/src/cli/fleet-preflight.ts +121 -0
- package/src/cli/fleet-validate.ts +30 -0
- package/src/cli/fleet.ts +188 -335
- package/src/cli/index.ts +4 -2
- package/src/cli/library.ts +190 -0
- package/src/cli/memory.ts +272 -10
- package/src/cli/modes/json-stream.ts +2 -2
- package/src/cli/modes/print.ts +12 -1
- package/src/cli/run.ts +22 -2
- package/src/cli/share.ts +13 -1
- package/src/cli/targets.ts +12 -3
- package/src/cli/usage.ts +160 -20
- package/src/core/bus-events.ts +7 -0
- package/src/core/commit-attribution.ts +4 -4
- package/src/core/config.ts +130 -0
- package/src/core/defaults.ts +81 -0
- package/src/core/response-model-id.ts +134 -0
- package/src/core/toml.ts +62 -0
- package/src/core/workspace-files.ts +0 -1
- package/src/domains/agents/builtins/architect.md +2 -1
- package/src/domains/agents/builtins/oracle.md +33 -0
- package/src/domains/agents/catalog.ts +18 -5
- package/src/domains/agents/fleet-contract.ts +278 -16
- package/src/domains/agents/index.ts +14 -0
- package/src/domains/agents/recipe.ts +54 -14
- package/src/domains/agents/result-contract.ts +242 -5
- package/src/domains/config/classify.ts +4 -0
- package/src/domains/context/bootstrap.ts +36 -27
- package/src/domains/context/project-metadata.ts +19 -63
- package/src/domains/context/prompt-context.ts +8 -0
- package/src/domains/context/working-set/policies/index.ts +3 -4
- package/src/domains/dispatch/active-route-planner.ts +14 -0
- package/src/domains/dispatch/backoff.ts +2 -1
- package/src/domains/dispatch/budget-envelope.ts +396 -0
- package/src/domains/dispatch/capability-match.ts +1 -0
- package/src/domains/dispatch/checkout-writer-lease.ts +175 -0
- package/src/domains/dispatch/contract.ts +36 -0
- package/src/domains/dispatch/delegation-plan.ts +167 -0
- package/src/domains/dispatch/execution-plan.ts +76 -5
- package/src/domains/dispatch/execution-role.ts +3 -1
- package/src/domains/dispatch/execution-scheduler.ts +183 -67
- package/src/domains/dispatch/extension.ts +339 -36
- package/src/domains/dispatch/fleet-gate.ts +14 -0
- package/src/domains/dispatch/fleet-plan.ts +63 -3
- package/src/domains/dispatch/fleet-run.ts +737 -0
- package/src/domains/dispatch/gate-role-prompts.ts +9 -0
- package/src/domains/dispatch/host-verification.ts +178 -0
- package/src/domains/dispatch/index.ts +38 -0
- package/src/domains/dispatch/intent.ts +159 -0
- package/src/domains/dispatch/orphan-recovery.ts +1 -0
- package/src/domains/dispatch/receipt-integrity.ts +12 -4
- package/src/domains/dispatch/state.ts +37 -3
- package/src/domains/dispatch/types.ts +61 -9
- package/src/domains/dispatch/validation.ts +80 -6
- package/src/domains/dispatch/worker-spawn.ts +14 -3
- package/src/domains/eval/metrics/evidence.ts +0 -116
- package/src/domains/eval/metrics/invariants.ts +1 -1
- package/src/domains/eval/runners/clio-run.ts +1 -10
- package/src/domains/eval/runners/external-command.ts +2 -29
- package/src/domains/eval/schema/suite.ts +0 -7
- package/src/domains/eval/suites/run.ts +1 -7
- package/src/domains/evidence/trust-status.ts +10 -1
- package/src/domains/memory/index.ts +22 -0
- package/src/domains/memory/operations.ts +58 -1
- package/src/domains/memory/promotion.ts +281 -0
- package/src/domains/memory/prompt-section.ts +25 -5
- package/src/domains/memory/proposal.ts +51 -7
- package/src/domains/memory/task-bank.ts +3 -2
- package/src/domains/memory/task-memory-handoff.ts +181 -24
- package/src/domains/memory/task-memory-policy.ts +3 -1
- package/src/domains/memory/types.ts +37 -0
- package/src/domains/memory/validate.ts +178 -0
- package/src/domains/middleware/index.ts +15 -0
- package/src/domains/middleware/memory-intervention.ts +35 -25
- package/src/domains/middleware/runtime.ts +6 -0
- package/src/domains/middleware/skills-reminder.ts +19 -4
- package/src/domains/middleware/stalled-turn.ts +43 -1
- package/src/domains/middleware/types.ts +10 -0
- package/src/domains/middleware/watchdog.ts +281 -0
- package/src/domains/observability/contract.ts +9 -2
- package/src/domains/observability/cost.ts +31 -4
- package/src/domains/observability/extension.ts +2 -2
- package/src/domains/observability/index.ts +10 -0
- package/src/domains/observability/out-of-turn-usage.ts +223 -0
- package/src/domains/providers/index.ts +3 -0
- package/src/domains/providers/model-discovery.ts +9 -0
- package/src/domains/providers/runtime-resolution.ts +38 -1
- package/src/domains/providers/runtimes/common/probe-helpers.ts +97 -16
- package/src/domains/providers/types/context-window-slots.ts +18 -0
- package/src/domains/providers/types/runtime-descriptor.ts +3 -1
- package/src/domains/resources/index.ts +20 -0
- package/src/domains/resources/library.ts +326 -0
- package/src/domains/resources/skills/marketplace.ts +37 -12
- package/src/domains/safety/call-target.ts +211 -14
- package/src/domains/safety/decision-presentation.ts +268 -0
- package/src/domains/safety/redaction.ts +73 -0
- package/src/domains/session/context-ledger.ts +10 -1
- package/src/domains/session/decision-board.ts +4 -0
- package/src/domains/session/entries.ts +3 -0
- package/src/domains/session/handoff.ts +629 -0
- package/src/domains/session/history.ts +68 -19
- package/src/domains/session/usage.ts +24 -7
- package/src/domains/share/archive.ts +67 -2
- package/src/engine/acp/event-mapper.ts +7 -0
- package/src/engine/acp/server.ts +29 -2
- package/src/engine/apis/lmstudio.ts +25 -4
- package/src/engine/apis/openai-completions.ts +147 -22
- package/src/engine/claude/sdk-runtime.ts +8 -2
- package/src/engine/claude/tool-safety.ts +13 -0
- package/src/engine/loop-guard.ts +27 -3
- package/src/engine/worker-events.ts +4 -3
- package/src/engine/worker-runtime.ts +59 -54
- package/src/entry/orchestrator.ts +55 -1
- package/src/interactive/bus-notices.ts +26 -0
- package/src/interactive/chat-loop-messages.ts +22 -0
- package/src/interactive/chat-loop.ts +248 -1
- package/src/interactive/chat-renderer.ts +41 -3
- package/src/interactive/clio-editor.ts +44 -7
- package/src/interactive/context-overlay.ts +43 -5
- package/src/interactive/cost-overlay.ts +70 -11
- package/src/interactive/council-dispatch.ts +30 -0
- package/src/interactive/council-grid.ts +213 -0
- package/src/interactive/council.ts +99 -0
- package/src/interactive/dispatch-board.ts +471 -50
- package/src/interactive/fleet-run-preview.ts +307 -0
- package/src/interactive/footer/notifications.ts +219 -0
- package/src/interactive/footer/widgets.ts +13 -0
- package/src/interactive/handoff-round.ts +56 -0
- package/src/interactive/interactive-application.ts +49 -2
- package/src/interactive/interactive-event-projection.ts +9 -1
- package/src/interactive/interactive-input-runtime.ts +11 -1
- package/src/interactive/interactive-presentation.ts +11 -1
- package/src/interactive/interactive-slash-runtime.ts +52 -2
- package/src/interactive/interactive-subscriptions.ts +14 -2
- package/src/interactive/memory-overlay.ts +89 -4
- package/src/interactive/oracle.ts +179 -0
- package/src/interactive/overlay-ask-user-lifecycle.ts +7 -1
- package/src/interactive/overlay-frame.ts +5 -2
- package/src/interactive/overlay-general-openers.ts +230 -2
- package/src/interactive/overlay-key-routing.ts +58 -2
- package/src/interactive/overlay-lifecycle.ts +52 -5
- package/src/interactive/overlay-permission-lifecycle.ts +33 -8
- package/src/interactive/overlay-resource-openers.ts +11 -3
- package/src/interactive/overlay-session-lifecycle.ts +234 -2
- package/src/interactive/overlay-transitions.ts +11 -0
- package/src/interactive/overlays/ask-user.ts +74 -30
- package/src/interactive/overlays/decisions.ts +3 -1
- package/src/interactive/overlays/fleet-run-approval.ts +208 -0
- package/src/interactive/overlays/handoff-review.ts +185 -0
- package/src/interactive/overlays/library-install-confirm.ts +151 -0
- package/src/interactive/overlays/list-overlay.ts +168 -2
- package/src/interactive/overlays/settings.ts +101 -4
- package/src/interactive/overlays/side-question.ts +139 -0
- package/src/interactive/overlays/skills-hub.ts +401 -15
- package/src/interactive/permission-hint.ts +35 -0
- package/src/interactive/permission-overlay.ts +95 -45
- package/src/interactive/renderers/tool-execution.ts +19 -49
- package/src/interactive/session-last-turn.ts +8 -1
- package/src/interactive/session-usage-reseed.ts +36 -10
- package/src/interactive/side-question.ts +171 -0
- package/src/interactive/slash-commands.ts +434 -7
- package/src/interactive/slash-spec.ts +19 -6
- package/src/interactive/status/summary.ts +5 -0
- package/src/interactive/status/types.ts +5 -0
- package/src/interactive/terminal-lease.ts +1 -0
- package/src/interactive/theme/tokens.ts +30 -0
- package/src/interactive/turn-context.ts +96 -23
- package/src/interactive/turn-middleware.ts +16 -1
- package/src/interactive/turn-runtime.ts +37 -8
- package/src/interactive/turn-state.ts +3 -0
- package/src/interactive/watchdog-run.ts +75 -0
- package/src/interactive/worker-progress.ts +440 -0
- package/src/interactive/worker-share.ts +56 -1
- package/src/interactive/worker-stream.ts +58 -110
- package/src/tools/agent-tools.ts +28 -3
- package/src/tools/ask-user.ts +21 -1
- package/src/tools/bootstrap.ts +3 -0
- package/src/tools/compete-worktrees.ts +13 -79
- package/src/tools/context/index.ts +2 -2
- package/src/tools/dispatch-admission.ts +242 -8
- package/src/tools/dispatch-arguments.ts +65 -1
- package/src/tools/dispatch-event-text.ts +19 -0
- package/src/tools/dispatch-plan.ts +136 -6
- package/src/tools/dispatch-runner.ts +319 -13
- package/src/tools/dispatch-types.ts +20 -1
- package/src/tools/dispatch.ts +96 -3
- package/src/tools/monitor.ts +31 -0
- package/src/tools/profiles.ts +18 -4
- package/src/tools/registry.ts +15 -5
- package/src/tools/result-disposition.ts +156 -0
- package/src/tools/result-shaping.ts +59 -1
- package/src/tools/task-worktree.ts +238 -0
- package/src/tools/verify/authoring.ts +116 -55
- package/src/tools/verify/scripts.ts +62 -0
- package/src/tools/worker-evidence.ts +21 -1
- package/src/worker/spec-contract.ts +44 -3
- package/dist/chunk-EFADSJET.js +0 -18
- package/dist/chunk-HC4CLZ2Y.js +0 -68
- package/dist/memory-4ALKDJ4Q.js +0 -246
- package/src/domains/eval/metrics/chaos-stream.ts +0 -93
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { createRequire as __clioCreateRequire } from "node:module"; const require = __clioCreateRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
|
-
|
|
3
|
+
loadProjectVerifierCatalog
|
|
4
|
+
} from "./chunk-GH5622CP.js";
|
|
5
|
+
import {
|
|
4
6
|
classify
|
|
5
7
|
} from "./chunk-AOCYTWAV.js";
|
|
6
8
|
import {
|
|
@@ -12,9 +14,6 @@ import {
|
|
|
12
14
|
tokenizeShellLike,
|
|
13
15
|
toolMutationPaths
|
|
14
16
|
} from "./chunk-MV3K5QF2.js";
|
|
15
|
-
import {
|
|
16
|
-
loadProjectVerifierCatalog
|
|
17
|
-
} from "./chunk-FYYLNIL5.js";
|
|
18
17
|
import {
|
|
19
18
|
isProjectVerifierCheckId,
|
|
20
19
|
isVerificationScriptName
|
|
@@ -42,701 +41,6 @@ import {
|
|
|
42
41
|
init_esm_shims
|
|
43
42
|
} from "./chunk-3R73A4XB.js";
|
|
44
43
|
|
|
45
|
-
// src/domains/agents/result-contract.ts
|
|
46
|
-
init_esm_shims();
|
|
47
|
-
import { createHash } from "node:crypto";
|
|
48
|
-
import path from "node:path";
|
|
49
|
-
|
|
50
|
-
// src/core/json-payload.ts
|
|
51
|
-
init_esm_shims();
|
|
52
|
-
function jsonPayloadCandidates(text) {
|
|
53
|
-
const trimmed = text.trim();
|
|
54
|
-
const candidates = [trimmed];
|
|
55
|
-
const fenced = /```[A-Za-z0-9_-]*\s*\n?([\s\S]*?)```/.exec(trimmed)?.[1]?.trim();
|
|
56
|
-
if (fenced !== void 0 && fenced.length > 0) candidates.push(fenced);
|
|
57
|
-
const start = trimmed.indexOf("{");
|
|
58
|
-
const end = trimmed.lastIndexOf("}");
|
|
59
|
-
if (start >= 0 && end > start) candidates.push(trimmed.slice(start, end + 1));
|
|
60
|
-
return candidates;
|
|
61
|
-
}
|
|
62
|
-
function parseJsonObjectPayload(text) {
|
|
63
|
-
let parsedSomething = false;
|
|
64
|
-
for (const candidate of jsonPayloadCandidates(text)) {
|
|
65
|
-
let value;
|
|
66
|
-
try {
|
|
67
|
-
value = JSON.parse(candidate);
|
|
68
|
-
} catch {
|
|
69
|
-
continue;
|
|
70
|
-
}
|
|
71
|
-
parsedSomething = true;
|
|
72
|
-
if (value === null || typeof value !== "object" || Array.isArray(value)) continue;
|
|
73
|
-
return { ok: true, value };
|
|
74
|
-
}
|
|
75
|
-
return { ok: false, reason: parsedSomething ? "not-object" : "not-json" };
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// src/domains/agents/result-contract.ts
|
|
79
|
-
function canonical(value) {
|
|
80
|
-
if (value === null) return "null";
|
|
81
|
-
if (typeof value === "string" || typeof value === "boolean") return JSON.stringify(value);
|
|
82
|
-
if (typeof value === "number") {
|
|
83
|
-
if (!Number.isFinite(value)) throw new Error("result contract cannot digest non-finite numbers");
|
|
84
|
-
return JSON.stringify(value);
|
|
85
|
-
}
|
|
86
|
-
if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
|
|
87
|
-
if (typeof value === "object") {
|
|
88
|
-
const record = value;
|
|
89
|
-
return `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${canonical(record[key])}`).join(",")}}`;
|
|
90
|
-
}
|
|
91
|
-
throw new Error(`result contract cannot digest ${typeof value}`);
|
|
92
|
-
}
|
|
93
|
-
function digest(value) {
|
|
94
|
-
return createHash("sha256").update(canonical(value), "utf8").digest("hex");
|
|
95
|
-
}
|
|
96
|
-
function resultContractDigest(contract) {
|
|
97
|
-
return digest(contract);
|
|
98
|
-
}
|
|
99
|
-
function resultContractSourceId(contract) {
|
|
100
|
-
return `agent-result-contract:${contract.kind}:${resultContractDigest(contract)}`;
|
|
101
|
-
}
|
|
102
|
-
function failure(contract, quality, reason) {
|
|
103
|
-
return {
|
|
104
|
-
conformance: "fail",
|
|
105
|
-
quality,
|
|
106
|
-
sourceId: resultContractSourceId(contract),
|
|
107
|
-
validatorDigest: digest({ contract, reason }),
|
|
108
|
-
reason
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
function success(contract, quality, value, extra = {}) {
|
|
112
|
-
return {
|
|
113
|
-
conformance: "pass",
|
|
114
|
-
quality,
|
|
115
|
-
sourceId: resultContractSourceId(contract),
|
|
116
|
-
validatorDigest: digest({ contract, value }),
|
|
117
|
-
...extra
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
function parseJson(output) {
|
|
121
|
-
if (output === null || output.trim().length === 0) return { ok: false, reason: "missing final result" };
|
|
122
|
-
const parsed = parseJsonObjectPayload(output);
|
|
123
|
-
if (parsed.ok) return parsed;
|
|
124
|
-
return {
|
|
125
|
-
ok: false,
|
|
126
|
-
reason: parsed.reason === "not-object" ? "result must be a JSON object" : "result must be valid JSON"
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
function hasOnlyKeys(value, keys) {
|
|
130
|
-
const allowed = new Set(keys);
|
|
131
|
-
return Object.keys(value).every((key) => allowed.has(key));
|
|
132
|
-
}
|
|
133
|
-
function string(value) {
|
|
134
|
-
return typeof value === "string" && value.trim().length > 0;
|
|
135
|
-
}
|
|
136
|
-
function parseFindings(value) {
|
|
137
|
-
if (!Array.isArray(value)) return null;
|
|
138
|
-
const findings = [];
|
|
139
|
-
for (const entry of value) {
|
|
140
|
-
if (entry === null || typeof entry !== "object" || Array.isArray(entry)) return null;
|
|
141
|
-
const finding = entry;
|
|
142
|
-
const line = finding.line;
|
|
143
|
-
if (!hasOnlyKeys(finding, ["claim", "path", "line"]) || !string(finding.claim) || !string(finding.path) || typeof line !== "number" || !Number.isSafeInteger(line) || line < 1) {
|
|
144
|
-
return null;
|
|
145
|
-
}
|
|
146
|
-
findings.push({ claim: finding.claim, path: finding.path, line });
|
|
147
|
-
}
|
|
148
|
-
return findings;
|
|
149
|
-
}
|
|
150
|
-
var RESULT_CONTRACT_KINDS = [
|
|
151
|
-
"architect-plan",
|
|
152
|
-
"scout-report",
|
|
153
|
-
"verifier-report",
|
|
154
|
-
"debugger-report",
|
|
155
|
-
"research-report",
|
|
156
|
-
"mutation-report",
|
|
157
|
-
"provenance-report",
|
|
158
|
-
"external-delegation"
|
|
159
|
-
];
|
|
160
|
-
function parseSubtasks(value) {
|
|
161
|
-
if (!Array.isArray(value) || value.length > 4) return null;
|
|
162
|
-
const subtasks = [];
|
|
163
|
-
const ids = /* @__PURE__ */ new Set();
|
|
164
|
-
for (const entry of value) {
|
|
165
|
-
if (entry === null || typeof entry !== "object" || Array.isArray(entry)) return null;
|
|
166
|
-
const subtask = entry;
|
|
167
|
-
if (!hasOnlyKeys(subtask, ["id", "task", "dependencies", "expectedResultContract", "requestedAuthority"]) || !string(subtask.id) || !/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/u.test(subtask.id) || ids.has(subtask.id) || !string(subtask.task) || Buffer.byteLength(subtask.task, "utf8") > 4096 || !Array.isArray(subtask.dependencies) || subtask.dependencies.length > 4 || subtask.dependencies.some((dependency) => !string(dependency)) || new Set(subtask.dependencies).size !== subtask.dependencies.length || !RESULT_CONTRACT_KINDS.includes(subtask.expectedResultContract) || !AGENT_AUTOMATION_AUTHORITIES.includes(subtask.requestedAuthority)) {
|
|
168
|
-
return null;
|
|
169
|
-
}
|
|
170
|
-
ids.add(subtask.id);
|
|
171
|
-
subtasks.push({
|
|
172
|
-
id: subtask.id,
|
|
173
|
-
task: subtask.task,
|
|
174
|
-
dependencies: [...subtask.dependencies],
|
|
175
|
-
expectedResultContract: subtask.expectedResultContract,
|
|
176
|
-
requestedAuthority: subtask.requestedAuthority
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
for (const subtask of subtasks) {
|
|
180
|
-
if (subtask.dependencies.some((dependency) => dependency === subtask.id || !ids.has(dependency))) return null;
|
|
181
|
-
}
|
|
182
|
-
const remaining = new Set(ids);
|
|
183
|
-
const completed = /* @__PURE__ */ new Set();
|
|
184
|
-
while (remaining.size > 0) {
|
|
185
|
-
const ready = subtasks.filter(
|
|
186
|
-
(subtask) => remaining.has(subtask.id) && subtask.dependencies.every((dependency) => completed.has(dependency))
|
|
187
|
-
);
|
|
188
|
-
if (ready.length === 0) return null;
|
|
189
|
-
for (const subtask of ready) {
|
|
190
|
-
remaining.delete(subtask.id);
|
|
191
|
-
completed.add(subtask.id);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
return subtasks;
|
|
195
|
-
}
|
|
196
|
-
function isContextHandbookResult(value) {
|
|
197
|
-
if (!hasOnlyKeys(value, ["projectName", "identity", "conventions", "invariants", "sections"])) return false;
|
|
198
|
-
if (!string(value.projectName) || !string(value.identity)) return false;
|
|
199
|
-
if (!Array.isArray(value.conventions) || value.conventions.some((entry) => !string(entry))) return false;
|
|
200
|
-
if (!Array.isArray(value.invariants) || value.invariants.some((entry) => !string(entry))) return false;
|
|
201
|
-
if (!Array.isArray(value.sections)) return false;
|
|
202
|
-
return value.sections.every((entry) => {
|
|
203
|
-
if (entry === null || typeof entry !== "object" || Array.isArray(entry)) return false;
|
|
204
|
-
const section = entry;
|
|
205
|
-
return hasOnlyKeys(section, ["title", "body"]) && string(section.title) && string(section.body);
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
function validateContextHandbook(contract, output) {
|
|
209
|
-
const parsed = parseJson(output);
|
|
210
|
-
if (!parsed.ok) return failure(contract, "fail", parsed.reason);
|
|
211
|
-
if (!isContextHandbookResult(parsed.value)) {
|
|
212
|
-
return failure(
|
|
213
|
-
contract,
|
|
214
|
-
"fail",
|
|
215
|
-
"context handbook result must carry projectName, identity, conventions[], invariants[], and sections[{title, body}] and nothing else"
|
|
216
|
-
);
|
|
217
|
-
}
|
|
218
|
-
return success(contract, "unmeasured", parsed.value);
|
|
219
|
-
}
|
|
220
|
-
function salvageScoutClaims(value) {
|
|
221
|
-
const grounded = [];
|
|
222
|
-
const ungrounded = [];
|
|
223
|
-
if (!Array.isArray(value)) return { grounded, ungrounded };
|
|
224
|
-
for (const entry of value) {
|
|
225
|
-
if (entry === null || typeof entry !== "object" || Array.isArray(entry)) continue;
|
|
226
|
-
const finding = entry;
|
|
227
|
-
if (!string(finding.claim)) continue;
|
|
228
|
-
const line = finding.line;
|
|
229
|
-
if (string(finding.path) && typeof line === "number" && Number.isSafeInteger(line) && line >= 1) {
|
|
230
|
-
grounded.push({ claim: finding.claim, path: finding.path, line });
|
|
231
|
-
continue;
|
|
232
|
-
}
|
|
233
|
-
ungrounded.push(finding.claim);
|
|
234
|
-
}
|
|
235
|
-
return { grounded, ungrounded };
|
|
236
|
-
}
|
|
237
|
-
function degradedScout(contract, value, reason) {
|
|
238
|
-
const salvaged = salvageScoutClaims(value.findings);
|
|
239
|
-
if (salvaged.grounded.length === 0 && salvaged.ungrounded.length === 0) return null;
|
|
240
|
-
const degradedReason = `${reason} (accepted as a degraded reconnaissance result; findings are leads, not validation evidence)`;
|
|
241
|
-
const scout = {
|
|
242
|
-
findings: salvaged.grounded,
|
|
243
|
-
citations: salvaged.grounded.map(({ path: citedPath, line }) => ({ path: citedPath, line })),
|
|
244
|
-
needsSplit: false,
|
|
245
|
-
proposedSubtasks: [],
|
|
246
|
-
ungroundedClaims: salvaged.ungrounded,
|
|
247
|
-
degradedReason
|
|
248
|
-
};
|
|
249
|
-
return success(contract, "unmeasured", scout, { scout, reason: degradedReason });
|
|
250
|
-
}
|
|
251
|
-
function validateScout(contract, output) {
|
|
252
|
-
const parsed = parseJson(output);
|
|
253
|
-
if (!parsed.ok) return failure(contract, "fail", parsed.reason);
|
|
254
|
-
const value = parsed.value;
|
|
255
|
-
const degrade = (reason) => degradedScout(contract, value, reason) ?? failure(contract, "fail", reason);
|
|
256
|
-
if (!hasOnlyKeys(value, ["findings", "needsSplit", "proposedSubtasks"])) {
|
|
257
|
-
return degrade("Scout result has unknown fields");
|
|
258
|
-
}
|
|
259
|
-
const findings = parseFindings(value.findings);
|
|
260
|
-
const proposedSubtasks = parseSubtasks(value.proposedSubtasks);
|
|
261
|
-
if (findings === null || typeof value.needsSplit !== "boolean" || proposedSubtasks === null) {
|
|
262
|
-
return degrade(
|
|
263
|
-
"Scout result must carry findings as {claim, path, line} objects, needsSplit, and 0..4 typed proposed subtasks"
|
|
264
|
-
);
|
|
265
|
-
}
|
|
266
|
-
if (value.needsSplit !== proposedSubtasks.length > 0) {
|
|
267
|
-
return degrade("Scout needsSplit must agree with proposedSubtasks");
|
|
268
|
-
}
|
|
269
|
-
if (findings.length === 0 && !value.needsSplit) {
|
|
270
|
-
return degrade("Scout result must carry at least one cited finding, or set needsSplit");
|
|
271
|
-
}
|
|
272
|
-
if (value.needsSplit && findings.length > 0) {
|
|
273
|
-
return degrade("Scout split recommendations carry typed subtasks instead of findings");
|
|
274
|
-
}
|
|
275
|
-
const scout = {
|
|
276
|
-
findings,
|
|
277
|
-
citations: findings.map(({ path: citedPath, line }) => ({ path: citedPath, line })),
|
|
278
|
-
needsSplit: value.needsSplit,
|
|
279
|
-
proposedSubtasks
|
|
280
|
-
};
|
|
281
|
-
return success(contract, "pass", scout, { scout });
|
|
282
|
-
}
|
|
283
|
-
function parseChecks(value) {
|
|
284
|
-
if (!Array.isArray(value) || value.length === 0) return null;
|
|
285
|
-
const checks = [];
|
|
286
|
-
for (const entry of value) {
|
|
287
|
-
if (entry === null || typeof entry !== "object" || Array.isArray(entry)) return null;
|
|
288
|
-
const check = entry;
|
|
289
|
-
if (!hasOnlyKeys(check, ["name", "passed", "evidence"]) || !string(check.name) || typeof check.passed !== "boolean" || !string(check.evidence)) {
|
|
290
|
-
return null;
|
|
291
|
-
}
|
|
292
|
-
checks.push({ name: check.name, passed: check.passed, evidence: check.evidence });
|
|
293
|
-
}
|
|
294
|
-
return checks;
|
|
295
|
-
}
|
|
296
|
-
function validateScoutCitation(input, citation) {
|
|
297
|
-
const cwd = path.resolve(input.cwd);
|
|
298
|
-
const citedPath = path.resolve(cwd, citation.path);
|
|
299
|
-
const relative = path.relative(cwd, citedPath);
|
|
300
|
-
if (relative === "" || relative.startsWith(`..${path.sep}`) || relative === ".." || path.isAbsolute(relative)) {
|
|
301
|
-
return { ok: false, reason: `Scout citation path escapes the workspace: ${citation.path}` };
|
|
302
|
-
}
|
|
303
|
-
const content = input.filesystem.readFile(citedPath);
|
|
304
|
-
if (content === null) return { ok: false, reason: `Scout citation cannot be read: ${citation.path}` };
|
|
305
|
-
const lineCount = content.split(/\r\n|\r|\n/u).length;
|
|
306
|
-
if (citation.line > lineCount) {
|
|
307
|
-
return { ok: false, reason: `Scout citation is past end of file: ${citation.path}:${citation.line}` };
|
|
308
|
-
}
|
|
309
|
-
if (input.observedReadRanges !== void 0) {
|
|
310
|
-
const spans = input.observedReadRanges.get(citedPath) ?? [];
|
|
311
|
-
if (!spans.some(([start, end]) => citation.line >= start && citation.line <= end)) {
|
|
312
|
-
const observed = spans.length === 0 ? "this run never read that file" : `this run read only ${spans.map(([start, end]) => `${start}-${end}`).join(", ")}`;
|
|
313
|
-
return {
|
|
314
|
-
ok: false,
|
|
315
|
-
reason: `Scout citation is not grounded in a live read: ${citation.path}:${citation.line} (${observed})`
|
|
316
|
-
};
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
return {
|
|
320
|
-
ok: true,
|
|
321
|
-
evidence: { ...citation, contentDigest: createHash("sha256").update(content, "utf8").digest("hex") }
|
|
322
|
-
};
|
|
323
|
-
}
|
|
324
|
-
function validateScoutCitations(input, citations) {
|
|
325
|
-
const evidence = [];
|
|
326
|
-
for (const citation of citations) {
|
|
327
|
-
const checked = validateScoutCitation(input, citation);
|
|
328
|
-
if (!checked.ok) return checked;
|
|
329
|
-
evidence.push(checked.evidence);
|
|
330
|
-
}
|
|
331
|
-
return { ok: true, evidence };
|
|
332
|
-
}
|
|
333
|
-
function groundDegradedScout(contract, input, scout, degradedReason) {
|
|
334
|
-
const grounded = [];
|
|
335
|
-
const evidence = [];
|
|
336
|
-
const demoted = [];
|
|
337
|
-
for (const finding of scout.findings) {
|
|
338
|
-
const checked = validateScoutCitation(input, { path: finding.path, line: finding.line });
|
|
339
|
-
if (checked.ok) {
|
|
340
|
-
grounded.push(finding);
|
|
341
|
-
evidence.push(checked.evidence);
|
|
342
|
-
continue;
|
|
343
|
-
}
|
|
344
|
-
demoted.push(finding.claim);
|
|
345
|
-
}
|
|
346
|
-
const degraded = {
|
|
347
|
-
findings: grounded,
|
|
348
|
-
citations: grounded.map(({ path: citedPath, line }) => ({ path: citedPath, line })),
|
|
349
|
-
needsSplit: false,
|
|
350
|
-
proposedSubtasks: [],
|
|
351
|
-
ungroundedClaims: [...scout.ungroundedClaims ?? [], ...demoted],
|
|
352
|
-
degradedReason
|
|
353
|
-
};
|
|
354
|
-
return success(contract, "unmeasured", { scout: degraded, evidence }, { scout: degraded, reason: degradedReason });
|
|
355
|
-
}
|
|
356
|
-
function validateVerifier(contract, output) {
|
|
357
|
-
const parsed = parseJson(output);
|
|
358
|
-
if (!parsed.ok) return failure(contract, "fail", parsed.reason);
|
|
359
|
-
const value = parsed.value;
|
|
360
|
-
if (!hasOnlyKeys(value, ["verdict", "checks"]) || value.verdict !== "pass" && value.verdict !== "fail") {
|
|
361
|
-
return failure(contract, "fail", "Verifier result must carry pass or fail verdict and checks");
|
|
362
|
-
}
|
|
363
|
-
const checks = parseChecks(value.checks);
|
|
364
|
-
if (checks === null || value.verdict === "pass" !== checks.every((check) => check.passed)) {
|
|
365
|
-
return failure(contract, "fail", "Verifier verdict must agree with every typed check");
|
|
366
|
-
}
|
|
367
|
-
const verifier = { verdict: value.verdict, checks };
|
|
368
|
-
return success(contract, value.verdict, verifier, { verifier });
|
|
369
|
-
}
|
|
370
|
-
function parseVerifierResult(output) {
|
|
371
|
-
const validation = validateVerifier({ kind: "verifier-report" }, output);
|
|
372
|
-
return validation.verifier ?? null;
|
|
373
|
-
}
|
|
374
|
-
function validateCodeReport(contract, output) {
|
|
375
|
-
const parsed = parseJson(output);
|
|
376
|
-
if (!parsed.ok) return failure(contract, "unmeasured", parsed.reason);
|
|
377
|
-
const value = parsed.value;
|
|
378
|
-
if (!hasOnlyKeys(value, ["passed", "exitCode", "checks", "artifactPaths", "outputExcerpt"]) || typeof value.passed !== "boolean" || typeof value.exitCode !== "number" || !Number.isSafeInteger(value.exitCode) || typeof value.outputExcerpt !== "string" || !Array.isArray(value.artifactPaths) || value.artifactPaths.some((entry) => !string(entry))) {
|
|
379
|
-
return failure(
|
|
380
|
-
contract,
|
|
381
|
-
"unmeasured",
|
|
382
|
-
"Code result must carry passed, integer exitCode, checks, artifactPaths, and outputExcerpt"
|
|
383
|
-
);
|
|
384
|
-
}
|
|
385
|
-
const checks = parseChecks(value.checks);
|
|
386
|
-
if (checks === null) return failure(contract, "unmeasured", "Code result must carry typed checks");
|
|
387
|
-
if (value.passed !== (value.exitCode === 0) || value.passed !== checks.every((check) => check.passed)) {
|
|
388
|
-
return failure(contract, "unmeasured", "Code result passed must agree with its exit code and every check");
|
|
389
|
-
}
|
|
390
|
-
return success(contract, "unmeasured", value);
|
|
391
|
-
}
|
|
392
|
-
var RESULT_COMMIT_MESSAGE_MAX_BYTES = 1e3;
|
|
393
|
-
var AUTHORSHIP_FIELDS = ["commitMessage", "summary"];
|
|
394
|
-
function hasControlCharacters(value) {
|
|
395
|
-
for (const character of value) {
|
|
396
|
-
const code = character.codePointAt(0) ?? 0;
|
|
397
|
-
if (code === 127) return true;
|
|
398
|
-
if (code < 32 && character !== "\n" && character !== "\r" && character !== " ") return true;
|
|
399
|
-
}
|
|
400
|
-
return false;
|
|
401
|
-
}
|
|
402
|
-
function normalizeAuthored(value) {
|
|
403
|
-
return value.replace(/\r\n/gu, "\n").replace(/\r/gu, "\n").trim();
|
|
404
|
-
}
|
|
405
|
-
function validateAuthorship(value) {
|
|
406
|
-
for (const field of AUTHORSHIP_FIELDS) {
|
|
407
|
-
const raw = value[field];
|
|
408
|
-
if (raw === void 0 || raw === null) continue;
|
|
409
|
-
if (typeof raw !== "string") return `${field} must be a string when present`;
|
|
410
|
-
if (raw.trim().length === 0) continue;
|
|
411
|
-
if (Buffer.byteLength(raw, "utf8") > RESULT_COMMIT_MESSAGE_MAX_BYTES) {
|
|
412
|
-
return `${field} must be at most ${RESULT_COMMIT_MESSAGE_MAX_BYTES} bytes`;
|
|
413
|
-
}
|
|
414
|
-
if (hasControlCharacters(raw)) return `${field} must not contain control characters`;
|
|
415
|
-
}
|
|
416
|
-
return null;
|
|
417
|
-
}
|
|
418
|
-
function resultContractAuthorship(contract, output) {
|
|
419
|
-
const empty = { commitMessage: null, summary: null };
|
|
420
|
-
if (contract.kind !== "mutation-report" && contract.kind !== "architect-plan") return empty;
|
|
421
|
-
const parsed = parseJson(output);
|
|
422
|
-
if (!parsed.ok || validateAuthorship(parsed.value) !== null) return empty;
|
|
423
|
-
const read = (field) => {
|
|
424
|
-
const raw = parsed.value[field];
|
|
425
|
-
if (typeof raw !== "string") return null;
|
|
426
|
-
const normalized = normalizeAuthored(raw);
|
|
427
|
-
return normalized.length === 0 ? null : normalized;
|
|
428
|
-
};
|
|
429
|
-
return { commitMessage: read("commitMessage"), summary: read("summary") };
|
|
430
|
-
}
|
|
431
|
-
function validateDebugger(contract, output) {
|
|
432
|
-
const parsed = parseJson(output);
|
|
433
|
-
if (!parsed.ok) return failure(contract, "unmeasured", parsed.reason);
|
|
434
|
-
const value = parsed.value;
|
|
435
|
-
if (!hasOnlyKeys(value, ["diagnosis", "reproduction", "evidence"]) || !string(value.diagnosis) || value.reproduction !== "reproduced" && value.reproduction !== "not-reproduced" && value.reproduction !== "unknown" || !Array.isArray(value.evidence) || value.evidence.some((entry) => !string(entry))) {
|
|
436
|
-
return failure(
|
|
437
|
-
contract,
|
|
438
|
-
"unmeasured",
|
|
439
|
-
"Debugger result must carry diagnosis, reproduction status, and evidence without a verdict"
|
|
440
|
-
);
|
|
441
|
-
}
|
|
442
|
-
return success(contract, "unmeasured", value);
|
|
443
|
-
}
|
|
444
|
-
function validateResearch(contract, output, networkAllowed) {
|
|
445
|
-
const parsed = parseJson(output);
|
|
446
|
-
if (!parsed.ok) return failure(contract, "unmeasured", parsed.reason);
|
|
447
|
-
const value = parsed.value;
|
|
448
|
-
if (!hasOnlyKeys(value, ["source", "findings"]) || value.source !== "local" && value.source !== "external" || !Array.isArray(value.findings)) {
|
|
449
|
-
return failure(
|
|
450
|
-
contract,
|
|
451
|
-
"unmeasured",
|
|
452
|
-
"Research result must distinguish local or external sources and carry findings"
|
|
453
|
-
);
|
|
454
|
-
}
|
|
455
|
-
if (value.source === "external" && !networkAllowed) {
|
|
456
|
-
return failure(contract, "unmeasured", "external research requires an allowed network posture");
|
|
457
|
-
}
|
|
458
|
-
for (const finding of value.findings) {
|
|
459
|
-
if (finding === null || typeof finding !== "object" || Array.isArray(finding)) {
|
|
460
|
-
return failure(contract, "unmeasured", "Research findings must be objects");
|
|
461
|
-
}
|
|
462
|
-
const record = finding;
|
|
463
|
-
if (!hasOnlyKeys(record, ["claim", "evidence"]) || !string(record.claim) || !string(record.evidence)) {
|
|
464
|
-
return failure(contract, "unmeasured", "Research findings must carry claim and evidence");
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
return success(contract, "unmeasured", value);
|
|
468
|
-
}
|
|
469
|
-
function describeWriteSet(effects, cwd) {
|
|
470
|
-
if (effects.mutatedPaths.size === 0) return "this run wrote nothing";
|
|
471
|
-
const written = [...effects.mutatedPaths].map((target) => path.relative(cwd, target) || target).sort().slice(0, MUTATION_WRITE_SET_REASON_LIMIT);
|
|
472
|
-
const more = effects.mutatedPaths.size - written.length;
|
|
473
|
-
return `this run wrote ${written.join(", ")}${more > 0 ? ` (+${more} more)` : ""}`;
|
|
474
|
-
}
|
|
475
|
-
var MUTATION_WRITE_SET_REASON_LIMIT = 8;
|
|
476
|
-
function pathIsPresent(filesystem, target) {
|
|
477
|
-
if (filesystem.pathExists === void 0) return true;
|
|
478
|
-
return filesystem.pathExists(target);
|
|
479
|
-
}
|
|
480
|
-
var MUTATION_VALIDATION_EXAMPLE = '{"name":"npm test","passed":true,"evidence":"exit 0"}';
|
|
481
|
-
function mutationValidationsReason(value) {
|
|
482
|
-
const empty = Array.isArray(value) && value.length === 0;
|
|
483
|
-
if (empty) {
|
|
484
|
-
return `Mutation result must carry typed validation results: validations was empty. Emit one entry per check this run actually made, each shaped like ${MUTATION_VALIDATION_EXAMPLE}. A run that only read files still names the read and cites what it saw.`;
|
|
485
|
-
}
|
|
486
|
-
return `Mutation result must carry typed validation results: every validations entry is shaped like ${MUTATION_VALIDATION_EXAMPLE}, with a string name, a boolean passed, a string evidence, and no other keys.`;
|
|
487
|
-
}
|
|
488
|
-
function validateMutation(contract, input) {
|
|
489
|
-
const parsed = parseJson(input.output);
|
|
490
|
-
if (!parsed.ok) return failure(contract, "unmeasured", parsed.reason);
|
|
491
|
-
const value = parsed.value;
|
|
492
|
-
if (!hasOnlyKeys(value, ["mutatedPaths", "validations", "commitMessage", "summary"]) || !Array.isArray(value.mutatedPaths) || value.mutatedPaths.some((entry) => !string(entry))) {
|
|
493
|
-
return failure(contract, "unmeasured", "Mutation result must carry mutatedPaths and validations");
|
|
494
|
-
}
|
|
495
|
-
const authorship = validateAuthorship(value);
|
|
496
|
-
if (authorship !== null) return failure(contract, "unmeasured", authorship);
|
|
497
|
-
const validations = parseChecks(value.validations);
|
|
498
|
-
if (validations === null) return failure(contract, "unmeasured", mutationValidationsReason(value.validations));
|
|
499
|
-
const reportedFailure = !validations.every((check) => check.passed);
|
|
500
|
-
const effects = input.observedRunEffects;
|
|
501
|
-
if (effects === void 0) return success(contract, reportedFailure ? "fail" : "pass", value);
|
|
502
|
-
const cwd = path.resolve(input.cwd);
|
|
503
|
-
let unverifiedMutation = false;
|
|
504
|
-
for (const reported of value.mutatedPaths) {
|
|
505
|
-
const target = path.resolve(cwd, reported);
|
|
506
|
-
if (effects.mutatedPaths.has(target)) continue;
|
|
507
|
-
if (effects.failedMutationPaths.has(target)) {
|
|
508
|
-
return failure(
|
|
509
|
-
contract,
|
|
510
|
-
"unmeasured",
|
|
511
|
-
`Mutation result names a path whose only write this run attempted was refused: ${reported} (${describeWriteSet(effects, cwd)})`
|
|
512
|
-
);
|
|
513
|
-
}
|
|
514
|
-
if (pathIsPresent(input.filesystem, target)) {
|
|
515
|
-
unverifiedMutation = true;
|
|
516
|
-
continue;
|
|
517
|
-
}
|
|
518
|
-
return failure(
|
|
519
|
-
contract,
|
|
520
|
-
"unmeasured",
|
|
521
|
-
`Mutation result names a path this run never wrote and that does not exist: ${reported} (${describeWriteSet(effects, cwd)})`
|
|
522
|
-
);
|
|
523
|
-
}
|
|
524
|
-
if (reportedFailure) return success(contract, "fail", value);
|
|
525
|
-
const measured = !unverifiedMutation && effects.validationCommands.size > 0;
|
|
526
|
-
return success(contract, measured ? "pass" : "unmeasured", value);
|
|
527
|
-
}
|
|
528
|
-
function validateProvenance(contract, output) {
|
|
529
|
-
const parsed = parseJson(output);
|
|
530
|
-
if (!parsed.ok) return failure(contract, "unmeasured", parsed.reason);
|
|
531
|
-
const value = parsed.value;
|
|
532
|
-
if (!hasOnlyKeys(value, ["confirmedFacts", "missingEvidence", "nextInspections"]) || ![value.confirmedFacts, value.missingEvidence, value.nextInspections].every(
|
|
533
|
-
(entry) => Array.isArray(entry) && entry.every((item) => string(item))
|
|
534
|
-
)) {
|
|
535
|
-
return failure(
|
|
536
|
-
contract,
|
|
537
|
-
"unmeasured",
|
|
538
|
-
"Provenance result must carry confirmedFacts, missingEvidence, and nextInspections"
|
|
539
|
-
);
|
|
540
|
-
}
|
|
541
|
-
return success(contract, "unmeasured", value);
|
|
542
|
-
}
|
|
543
|
-
function validateArchitect(contract, input) {
|
|
544
|
-
const artifactPath = path.resolve(input.cwd, contract.path);
|
|
545
|
-
const content = input.filesystem.readFile(artifactPath);
|
|
546
|
-
if (content === null || content.trim().length === 0) {
|
|
547
|
-
return failure(contract, "unmeasured", `required plan artifact is missing or empty: ${contract.path}`);
|
|
548
|
-
}
|
|
549
|
-
return success(contract, "unmeasured", {
|
|
550
|
-
path: contract.path,
|
|
551
|
-
artifactDigest: createHash("sha256").update(content, "utf8").digest("hex")
|
|
552
|
-
});
|
|
553
|
-
}
|
|
554
|
-
function parseScoutResult(output) {
|
|
555
|
-
const validation = validateScout({ kind: "scout-report" }, output);
|
|
556
|
-
if (validation.conformance !== "pass" || validation.scout === void 0) return null;
|
|
557
|
-
return validation.scout.degradedReason === void 0 ? validation.scout : null;
|
|
558
|
-
}
|
|
559
|
-
function validateResultContract(input) {
|
|
560
|
-
switch (input.contract.kind) {
|
|
561
|
-
case "architect-plan":
|
|
562
|
-
return validateArchitect(input.contract, input);
|
|
563
|
-
case "scout-report": {
|
|
564
|
-
const validation = validateScout(input.contract, input.output);
|
|
565
|
-
if (validation.scout === void 0) return validation;
|
|
566
|
-
const degradedReason = validation.scout.degradedReason;
|
|
567
|
-
if (degradedReason !== void 0) {
|
|
568
|
-
return groundDegradedScout(input.contract, input, validation.scout, degradedReason);
|
|
569
|
-
}
|
|
570
|
-
const citations = validateScoutCitations(input, validation.scout.citations);
|
|
571
|
-
return citations.ok ? success(
|
|
572
|
-
input.contract,
|
|
573
|
-
"pass",
|
|
574
|
-
{ scout: validation.scout, evidence: citations.evidence },
|
|
575
|
-
{ scout: validation.scout }
|
|
576
|
-
) : failure(input.contract, "fail", citations.reason);
|
|
577
|
-
}
|
|
578
|
-
case "verifier-report":
|
|
579
|
-
return validateVerifier(input.contract, input.output);
|
|
580
|
-
case "debugger-report":
|
|
581
|
-
return validateDebugger(input.contract, input.output);
|
|
582
|
-
case "research-report":
|
|
583
|
-
return validateResearch(input.contract, input.output, input.networkAllowed);
|
|
584
|
-
case "mutation-report":
|
|
585
|
-
return validateMutation(input.contract, input);
|
|
586
|
-
case "provenance-report":
|
|
587
|
-
return validateProvenance(input.contract, input.output);
|
|
588
|
-
case "external-delegation":
|
|
589
|
-
return success(input.contract, "unmeasured", { external: true });
|
|
590
|
-
case "artifact-report":
|
|
591
|
-
return success(input.contract, "unmeasured", { artifact: true });
|
|
592
|
-
case "context-handbook":
|
|
593
|
-
return validateContextHandbook(input.contract, input.output);
|
|
594
|
-
case "code-report":
|
|
595
|
-
return validateCodeReport(input.contract, input.output);
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
function validateRecipeResult(input) {
|
|
599
|
-
if (input.contract === null) return null;
|
|
600
|
-
if (!input.reachedTerminalResult) {
|
|
601
|
-
return {
|
|
602
|
-
applicable: false,
|
|
603
|
-
fact: {
|
|
604
|
-
sourceId: resultContractSourceId(input.contract),
|
|
605
|
-
validatorDigest: digest({ contract: input.contract, reached: false }),
|
|
606
|
-
conformance: "not-reached",
|
|
607
|
-
quality: "unmeasured"
|
|
608
|
-
}
|
|
609
|
-
};
|
|
610
|
-
}
|
|
611
|
-
const validation = validateResultContract({
|
|
612
|
-
contract: input.contract,
|
|
613
|
-
output: input.output,
|
|
614
|
-
cwd: input.cwd,
|
|
615
|
-
networkAllowed: input.networkAllowed,
|
|
616
|
-
filesystem: input.filesystem,
|
|
617
|
-
...input.observedRunEffects !== void 0 ? { observedRunEffects: input.observedRunEffects } : {}
|
|
618
|
-
});
|
|
619
|
-
return {
|
|
620
|
-
applicable: true,
|
|
621
|
-
validation,
|
|
622
|
-
fact: {
|
|
623
|
-
sourceId: validation.sourceId,
|
|
624
|
-
validatorDigest: validation.validatorDigest,
|
|
625
|
-
conformance: validation.conformance,
|
|
626
|
-
quality: validation.quality
|
|
627
|
-
}
|
|
628
|
-
};
|
|
629
|
-
}
|
|
630
|
-
var RESULT_CONTRACT_REPAIR_LIMIT = 2;
|
|
631
|
-
var RESULT_CONTRACT_ANCHOR_LIMIT = 12;
|
|
632
|
-
function resultContractShape(contract) {
|
|
633
|
-
switch (contract.kind) {
|
|
634
|
-
case "architect-plan":
|
|
635
|
-
return `a plan artifact written to ${contract.path}, then optionally {"commitMessage":"...","summary":"..."} describing it`;
|
|
636
|
-
case "scout-report":
|
|
637
|
-
return '{"findings":[{"claim":"what you observed","path":"src/file.ts","line":1}],"needsSplit":false,"proposedSubtasks":[]} or {"findings":[],"needsSplit":true,"proposedSubtasks":[{"id":"inspect","task":"Inspect the boundary","dependencies":[],"expectedResultContract":"scout-report","requestedAuthority":"read-only"}]} or, if you cannot produce a citation you are sure of, at least {"findings":[{"claim":"what you observed"}]}, which is accepted as an ungrounded lead rather than losing the run';
|
|
638
|
-
case "verifier-report":
|
|
639
|
-
return '{"verdict":"pass","checks":[{"name":"npm run typecheck","passed":true,"evidence":"exit 0"}]}';
|
|
640
|
-
case "debugger-report":
|
|
641
|
-
return '{"diagnosis":"...","reproduction":"reproduced","evidence":["..."]}';
|
|
642
|
-
case "research-report":
|
|
643
|
-
return '{"source":"local","findings":[{"claim":"...","evidence":"..."}]}';
|
|
644
|
-
case "mutation-report":
|
|
645
|
-
return '{"mutatedPaths":["src/file.ts"],"validations":[{"name":"npm test","passed":true,"evidence":"exit 0"}],"commitMessage":"optional: the commit message for this change","summary":"optional: one line"}';
|
|
646
|
-
case "provenance-report":
|
|
647
|
-
return '{"confirmedFacts":["..."],"missingEvidence":["..."],"nextInspections":["..."]}';
|
|
648
|
-
case "external-delegation":
|
|
649
|
-
return "any final text";
|
|
650
|
-
case "artifact-report":
|
|
651
|
-
return "any final text; the artifact you wrote at the location the task named is the result";
|
|
652
|
-
case "context-handbook":
|
|
653
|
-
return '{"projectName":"string","identity":"one sentence","conventions":[],"invariants":[],"sections":[{"title":"Architecture","body":"markdown that cites `real/path.ts` tokens"}]}';
|
|
654
|
-
case "code-report":
|
|
655
|
-
return '{"passed":false,"exitCode":1,"checks":[{"name":"test","passed":false,"evidence":"exit 1"}],"artifactPaths":["/path/command.log"],"outputExcerpt":"..."}';
|
|
656
|
-
}
|
|
657
|
-
}
|
|
658
|
-
function resultContractRepairMessage(input) {
|
|
659
|
-
const last = input.attempt >= RESULT_CONTRACT_REPAIR_LIMIT;
|
|
660
|
-
const lines = [
|
|
661
|
-
last ? "FINAL RESULT REQUIRED IN THIS RESPONSE. Your previous response still did not satisfy this run's result contract." : "Your previous response did not satisfy this run's result contract.",
|
|
662
|
-
`Validator reason: ${input.reason}`,
|
|
663
|
-
"Tool use is over. Answer from the evidence you already gathered.",
|
|
664
|
-
`Emit exactly this shape and nothing else: ${resultContractShape(input.contract)}`,
|
|
665
|
-
"Do not add prose, code fences, or commentary around it. Do not describe work you intend to do next."
|
|
666
|
-
];
|
|
667
|
-
if (input.anchors.length > 0) {
|
|
668
|
-
lines.push(
|
|
669
|
-
"",
|
|
670
|
-
"Locations you read successfully in this run (use these exact path:line values):",
|
|
671
|
-
...input.anchors.slice(-RESULT_CONTRACT_ANCHOR_LIMIT).map((anchor) => `- ${anchor}`)
|
|
672
|
-
);
|
|
673
|
-
}
|
|
674
|
-
return lines.join("\n");
|
|
675
|
-
}
|
|
676
|
-
var RESULT_CONTRACT_REPAIR_TOOL = "result_contract";
|
|
677
|
-
function resultContractRepairMessages(input, origin) {
|
|
678
|
-
const id = `clio-result-contract-repair-${input.attempt}`;
|
|
679
|
-
const timestamp = Date.now();
|
|
680
|
-
return [
|
|
681
|
-
{
|
|
682
|
-
role: "assistant",
|
|
683
|
-
content: [{ type: "toolCall", id, name: RESULT_CONTRACT_REPAIR_TOOL, arguments: {} }],
|
|
684
|
-
stopReason: "toolUse",
|
|
685
|
-
usage: {
|
|
686
|
-
input: 0,
|
|
687
|
-
output: 0,
|
|
688
|
-
cacheRead: 0,
|
|
689
|
-
cacheWrite: 0,
|
|
690
|
-
totalTokens: 0,
|
|
691
|
-
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }
|
|
692
|
-
},
|
|
693
|
-
...origin,
|
|
694
|
-
timestamp
|
|
695
|
-
},
|
|
696
|
-
{
|
|
697
|
-
role: "toolResult",
|
|
698
|
-
toolCallId: id,
|
|
699
|
-
toolName: RESULT_CONTRACT_REPAIR_TOOL,
|
|
700
|
-
content: [{ type: "text", text: resultContractRepairMessage(input) }],
|
|
701
|
-
isError: true,
|
|
702
|
-
timestamp
|
|
703
|
-
}
|
|
704
|
-
];
|
|
705
|
-
}
|
|
706
|
-
function parseResultContract(value, sourcePath) {
|
|
707
|
-
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
708
|
-
throw new Error(`agent recipe: ${sourcePath}: resultContract must be an object`);
|
|
709
|
-
}
|
|
710
|
-
const record = value;
|
|
711
|
-
if (typeof record.kind !== "string") throw new Error(`agent recipe: ${sourcePath}: resultContract.kind is required`);
|
|
712
|
-
const keys = Object.keys(record);
|
|
713
|
-
const only = (...allowed) => keys.every((key) => allowed.includes(key));
|
|
714
|
-
if (record.kind === "architect-plan") {
|
|
715
|
-
if (!only("kind", "path") || !string(record.path)) {
|
|
716
|
-
throw new Error(`agent recipe: ${sourcePath}: architect-plan requires only non-empty path`);
|
|
717
|
-
}
|
|
718
|
-
if (path.isAbsolute(record.path) || record.path.split(/[\\/]/u).includes("..")) {
|
|
719
|
-
throw new Error(`agent recipe: ${sourcePath}: architect-plan path must be workspace-relative`);
|
|
720
|
-
}
|
|
721
|
-
return { kind: "architect-plan", path: record.path };
|
|
722
|
-
}
|
|
723
|
-
const kinds = [
|
|
724
|
-
"scout-report",
|
|
725
|
-
"verifier-report",
|
|
726
|
-
"debugger-report",
|
|
727
|
-
"research-report",
|
|
728
|
-
"mutation-report",
|
|
729
|
-
"provenance-report",
|
|
730
|
-
"external-delegation",
|
|
731
|
-
"artifact-report",
|
|
732
|
-
"context-handbook"
|
|
733
|
-
];
|
|
734
|
-
if (!kinds.includes(record.kind) || !only("kind")) {
|
|
735
|
-
throw new Error(`agent recipe: ${sourcePath}: resultContract.kind is unsupported or has unknown keys`);
|
|
736
|
-
}
|
|
737
|
-
return { kind: record.kind };
|
|
738
|
-
}
|
|
739
|
-
|
|
740
44
|
// src/domains/safety/finish-contract.ts
|
|
741
45
|
init_esm_shims();
|
|
742
46
|
var FINISH_CONTRACT_ADVISORY_MESSAGE = "[Clio Coder] finish-contract advisory: you changed files this turn without recording validation evidence or an explicit limitation. Run a verification command or state what could not be verified.";
|
|
@@ -786,7 +90,7 @@ function mutatingReceipts(recent) {
|
|
|
786
90
|
for (const entry of recent) {
|
|
787
91
|
const bashMutation = bashExecutionMutationPaths(entry);
|
|
788
92
|
if (bashMutation !== null) {
|
|
789
|
-
for (const
|
|
93
|
+
for (const path4 of bashMutation) pushPath(paths, seen, path4);
|
|
790
94
|
continue;
|
|
791
95
|
}
|
|
792
96
|
const call = mutatingToolCall(entry);
|
|
@@ -798,7 +102,7 @@ function mutatingReceipts(recent) {
|
|
|
798
102
|
if (resultId !== null) {
|
|
799
103
|
const candidate = mutationCalls.get(resultId);
|
|
800
104
|
if (candidate !== void 0) {
|
|
801
|
-
for (const
|
|
105
|
+
for (const path4 of candidate.paths) pushPath(paths, seen, path4);
|
|
802
106
|
}
|
|
803
107
|
}
|
|
804
108
|
}
|
|
@@ -833,10 +137,10 @@ function bashExecutionMutationPaths(entry) {
|
|
|
833
137
|
if (record.cancelled === true || record.exitCode !== 0) return null;
|
|
834
138
|
return [...extractCommandWriteTargets(record.command), ...extractCommandDeleteTargets(record.command)];
|
|
835
139
|
}
|
|
836
|
-
function pushPath(paths, seen,
|
|
837
|
-
if (
|
|
838
|
-
seen.add(
|
|
839
|
-
paths.push(
|
|
140
|
+
function pushPath(paths, seen, path4) {
|
|
141
|
+
if (path4.length === 0 || seen.has(path4)) return;
|
|
142
|
+
seen.add(path4);
|
|
143
|
+
paths.push(path4);
|
|
840
144
|
}
|
|
841
145
|
function collectValidationEvidence(recent) {
|
|
842
146
|
const evidence = [];
|
|
@@ -977,8 +281,8 @@ function typedValidationSummary(toolName, payload) {
|
|
|
977
281
|
if (toolName === "verify") {
|
|
978
282
|
const check = typeof args?.check === "string" ? args.check.trim() : "";
|
|
979
283
|
if (check === "frontend") {
|
|
980
|
-
const
|
|
981
|
-
return `verify frontend ${
|
|
284
|
+
const path4 = typeof args?.path === "string" && args.path.trim().length > 0 ? args.path.trim() : "artifact";
|
|
285
|
+
return `verify frontend ${path4}`;
|
|
982
286
|
}
|
|
983
287
|
if (isVerificationScriptName(check)) return `npm run ${check}`;
|
|
984
288
|
if (isProjectVerifierCheckId(check)) return `verify ${check}`;
|
|
@@ -1059,11 +363,11 @@ function protectedArtifactEvidence(entry) {
|
|
|
1059
363
|
const record = asRecord(entry);
|
|
1060
364
|
if (record?.kind !== "protectedArtifact" || record.action !== "protect") return null;
|
|
1061
365
|
const artifact = asRecord(record.artifact);
|
|
1062
|
-
const
|
|
1063
|
-
if (
|
|
366
|
+
const path4 = typeof artifact?.path === "string" && artifact.path.trim().length > 0 ? artifact.path.trim() : null;
|
|
367
|
+
if (path4 === null) return null;
|
|
1064
368
|
const evidence = {
|
|
1065
369
|
kind: "protected_artifact",
|
|
1066
|
-
summary: `protected artifact recorded: ${
|
|
370
|
+
summary: `protected artifact recorded: ${path4}`
|
|
1067
371
|
};
|
|
1068
372
|
const turnId = turnIdOf(entry);
|
|
1069
373
|
if (turnId !== null) evidence.turnId = turnId;
|
|
@@ -1104,91 +408,25 @@ function asRecord(value) {
|
|
|
1104
408
|
return value !== null && typeof value === "object" ? value : null;
|
|
1105
409
|
}
|
|
1106
410
|
|
|
1107
|
-
// src/domains/safety/autonomy.ts
|
|
1108
|
-
init_esm_shims();
|
|
1109
|
-
var AUTONOMY_LEVELS = ["read-only", "suggest", "auto-edit", "full-auto"];
|
|
1110
|
-
var DEFAULT_AUTONOMY_LEVEL = "auto-edit";
|
|
1111
|
-
function isAutonomyLevel(value) {
|
|
1112
|
-
return typeof value === "string" && AUTONOMY_LEVELS.includes(value);
|
|
1113
|
-
}
|
|
1114
|
-
var DEFAULT_AUTONOMY_EXPOSURE = "local";
|
|
1115
|
-
function mapAutonomy(level, actionClass, options = {}) {
|
|
1116
|
-
if (actionClass === "git_destructive") return "deny";
|
|
1117
|
-
if ((level === "auto-edit" || level === "suggest") && options.exposure === "outward") return "ask";
|
|
1118
|
-
if (actionClass === "read") return "allow";
|
|
1119
|
-
if (level === "read-only") return "deny";
|
|
1120
|
-
if (level === "suggest") return "ask";
|
|
1121
|
-
switch (actionClass) {
|
|
1122
|
-
case "write":
|
|
1123
|
-
return "allow";
|
|
1124
|
-
case "dispatch":
|
|
1125
|
-
if (options.dispatchPlanScale === true && level !== "full-auto") return "ask";
|
|
1126
|
-
return "allow";
|
|
1127
|
-
case "execute": {
|
|
1128
|
-
if (options.executeRecognized !== false) return "allow";
|
|
1129
|
-
return level === "full-auto" ? "allow" : "ask";
|
|
1130
|
-
}
|
|
1131
|
-
case "unknown":
|
|
1132
|
-
return "ask";
|
|
1133
|
-
default:
|
|
1134
|
-
return "ask";
|
|
1135
|
-
}
|
|
1136
|
-
}
|
|
1137
|
-
function autonomyDenyRejection(level, tool, actionClass) {
|
|
1138
|
-
return {
|
|
1139
|
-
short: `${tool} denied: autonomy level is ${level}`,
|
|
1140
|
-
detail: `Clio is at autonomy ${level}: ${actionClass} actions are denied without prompting. Describe the change you would make instead, so the operator can apply it or raise the autonomy level.`,
|
|
1141
|
-
hints: ["Propose the exact edit or command as text.", "The operator can change the level in /settings."]
|
|
1142
|
-
};
|
|
1143
|
-
}
|
|
1144
|
-
function autonomyAskRejection(level, tool, actionClass, exposure = DEFAULT_AUTONOMY_EXPOSURE) {
|
|
1145
|
-
if (exposure === "outward") {
|
|
1146
|
-
return {
|
|
1147
|
-
short: `${tool} needs approval: outward-facing gate at autonomy ${level}`,
|
|
1148
|
-
detail: `The call declared exposure=outward, so answering it publishes or sends something outside the workspace. Autonomy ${level} auto-answers local gates and parks outward-facing ones for the operator.`,
|
|
1149
|
-
hints: [
|
|
1150
|
-
"Approving resumes only this call.",
|
|
1151
|
-
"Autonomy full-auto answers outward gates too; the safety net still applies there."
|
|
1152
|
-
]
|
|
1153
|
-
};
|
|
1154
|
-
}
|
|
1155
|
-
return {
|
|
1156
|
-
short: `${tool} needs approval (${actionClass}) at autonomy ${level}`,
|
|
1157
|
-
detail: `Autonomy ${level} routes ${actionClass} actions through operator approval. The call is parked until the operator approves it once or cancels it.`,
|
|
1158
|
-
hints: [
|
|
1159
|
-
"Approving resumes only this call.",
|
|
1160
|
-
"Recognized commands can be added to .clio-coder/safety.yaml.",
|
|
1161
|
-
// The sanctioned pivots for a gated shell command: typed verification
|
|
1162
|
-
// and read-class observe tools run without approval at this level,
|
|
1163
|
-
// and models otherwise stall retrying denied bash for checks or
|
|
1164
|
-
// directory listings.
|
|
1165
|
-
...actionClass === "execute" ? [
|
|
1166
|
-
'A declared package or project-catalog check runs without approval through the verify tool: verify(check="<id>").',
|
|
1167
|
-
"Read-only inspection runs without approval through the ls, read, grep, and find tools."
|
|
1168
|
-
] : []
|
|
1169
|
-
]
|
|
1170
|
-
};
|
|
1171
|
-
}
|
|
1172
|
-
|
|
1173
411
|
// src/domains/safety/path-policy.ts
|
|
1174
412
|
init_esm_shims();
|
|
1175
413
|
import { homedir } from "node:os";
|
|
1176
|
-
import
|
|
414
|
+
import path from "node:path";
|
|
1177
415
|
var ORDERED_KINDS = ["zeroAccessPaths", "readOnlyPaths", "noWritePaths", "noDeletePaths"];
|
|
1178
416
|
function isSameOrDescendant(candidatePath, policyPath) {
|
|
1179
|
-
const candidate =
|
|
1180
|
-
const policy =
|
|
1181
|
-
const relative =
|
|
1182
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
417
|
+
const candidate = path.resolve(candidatePath);
|
|
418
|
+
const policy = path.resolve(policyPath);
|
|
419
|
+
const relative = path.relative(policy, candidate);
|
|
420
|
+
return relative === "" || !relative.startsWith("..") && !path.isAbsolute(relative);
|
|
1183
421
|
}
|
|
1184
422
|
function expandTilde(rawPath) {
|
|
1185
423
|
if (rawPath === "~") return homedir();
|
|
1186
|
-
if (rawPath.startsWith("~/")) return
|
|
424
|
+
if (rawPath.startsWith("~/")) return path.join(homedir(), rawPath.slice(2));
|
|
1187
425
|
return rawPath;
|
|
1188
426
|
}
|
|
1189
427
|
function normalizePolicyEntry(rawPath, root) {
|
|
1190
428
|
const expanded = expandTilde(rawPath.trim());
|
|
1191
|
-
const resolved =
|
|
429
|
+
const resolved = path.isAbsolute(expanded) ? path.resolve(expanded) : path.resolve(root, expanded);
|
|
1192
430
|
return canonicalizeExistingPath(resolved);
|
|
1193
431
|
}
|
|
1194
432
|
function blocksOperation(kind, operation) {
|
|
@@ -1197,7 +435,7 @@ function blocksOperation(kind, operation) {
|
|
|
1197
435
|
return operation === "delete";
|
|
1198
436
|
}
|
|
1199
437
|
function compilePathPolicy(input, root = process.cwd()) {
|
|
1200
|
-
const resolvedRoot = canonicalizeExistingPath(
|
|
438
|
+
const resolvedRoot = canonicalizeExistingPath(path.resolve(root));
|
|
1201
439
|
const entries = [];
|
|
1202
440
|
const diagnostics = [];
|
|
1203
441
|
for (const kind of ORDERED_KINDS) {
|
|
@@ -1221,10 +459,10 @@ function compilePathPolicy(input, root = process.cwd()) {
|
|
|
1221
459
|
}
|
|
1222
460
|
function evaluatePathPolicy(policy, operation, targetPath, cwd = policy.root) {
|
|
1223
461
|
const expanded = expandTilde(targetPath);
|
|
1224
|
-
const lexicalTarget =
|
|
462
|
+
const lexicalTarget = path.isAbsolute(expanded) ? path.resolve(expanded) : path.resolve(cwd, expanded);
|
|
1225
463
|
const resolvedTarget = canonicalizeExistingPath(lexicalTarget);
|
|
1226
464
|
const normalizedResolvedTarget = normalizeSeparators(resolvedTarget);
|
|
1227
|
-
const normalizedRelativeTarget = normalizeSeparators(
|
|
465
|
+
const normalizedRelativeTarget = normalizeSeparators(path.relative(policy.root, resolvedTarget));
|
|
1228
466
|
const normalizedRawTarget = normalizeSeparators(targetPath);
|
|
1229
467
|
for (const entry of policy.entries) {
|
|
1230
468
|
if (!blocksOperation(entry.kind, operation)) continue;
|
|
@@ -1248,9 +486,9 @@ function matchesEntry(entry, resolvedTarget, normalizedResolvedTarget, normalize
|
|
|
1248
486
|
function compilePathPattern(rawPath, root) {
|
|
1249
487
|
if (!rawPath.includes("*")) return null;
|
|
1250
488
|
const expanded = expandTilde(rawPath.trim());
|
|
1251
|
-
const source =
|
|
489
|
+
const source = path.isAbsolute(expanded) ? expanded : path.join(root, expanded);
|
|
1252
490
|
const normalized = normalizeSeparators(canonicalizePatternSource(source));
|
|
1253
|
-
const relative = normalizeSeparators(
|
|
491
|
+
const relative = normalizeSeparators(path.isAbsolute(expanded) ? expanded : expanded);
|
|
1254
492
|
const absolutePattern = segmentPattern(normalized);
|
|
1255
493
|
const relativePattern = segmentPattern(relative);
|
|
1256
494
|
return new RegExp(`(?:${absolutePattern})|(?:${relativePattern})`);
|
|
@@ -1259,24 +497,24 @@ function canonicalizePatternSource(patternPath) {
|
|
|
1259
497
|
const wildcardIndex = patternPath.indexOf("*");
|
|
1260
498
|
if (wildcardIndex === -1) return canonicalizeExistingPath(patternPath);
|
|
1261
499
|
const fixedPrefix = patternPath.slice(0, wildcardIndex);
|
|
1262
|
-
const separatorIndex = fixedPrefix.lastIndexOf(
|
|
500
|
+
const separatorIndex = fixedPrefix.lastIndexOf(path.sep);
|
|
1263
501
|
if (separatorIndex === -1) return patternPath;
|
|
1264
502
|
const prefix = patternPath.slice(0, separatorIndex + 1);
|
|
1265
503
|
const suffix = patternPath.slice(separatorIndex + 1);
|
|
1266
|
-
return
|
|
504
|
+
return path.join(canonicalizeExistingPath(prefix), suffix);
|
|
1267
505
|
}
|
|
1268
506
|
function segmentPattern(rawPath) {
|
|
1269
507
|
const escaped = rawPath.split("*").map((part) => part.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("[^/]*");
|
|
1270
508
|
return `(?:^|/)${escaped}(?:$|/)`;
|
|
1271
509
|
}
|
|
1272
510
|
function normalizeSeparators(value) {
|
|
1273
|
-
return value.split(
|
|
511
|
+
return value.split(path.sep).join("/");
|
|
1274
512
|
}
|
|
1275
513
|
|
|
1276
514
|
// src/domains/safety/policy-engine.ts
|
|
1277
515
|
init_esm_shims();
|
|
1278
|
-
import { createHash as
|
|
1279
|
-
import
|
|
516
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
517
|
+
import path3 from "node:path";
|
|
1280
518
|
|
|
1281
519
|
// src/domains/safety/default-path-policy.ts
|
|
1282
520
|
init_esm_shims();
|
|
@@ -1398,10 +636,10 @@ function mergePathPolicyInputs(base, override) {
|
|
|
1398
636
|
// src/domains/safety/project-policy.ts
|
|
1399
637
|
init_esm_shims();
|
|
1400
638
|
var import_yaml = __toESM(require_dist(), 1);
|
|
1401
|
-
import { createHash
|
|
639
|
+
import { createHash } from "node:crypto";
|
|
1402
640
|
import { existsSync, readFileSync } from "node:fs";
|
|
1403
|
-
import
|
|
1404
|
-
var POLICY_RELATIVE_PATH =
|
|
641
|
+
import path2 from "node:path";
|
|
642
|
+
var POLICY_RELATIVE_PATH = path2.join(".clio-coder", "safety.yaml");
|
|
1405
643
|
var ACTION_CLASSES = /* @__PURE__ */ new Set([
|
|
1406
644
|
"read",
|
|
1407
645
|
"write",
|
|
@@ -1430,11 +668,11 @@ var COMMAND_KEYS = /* @__PURE__ */ new Set([
|
|
|
1430
668
|
var ENV_KEYS = /* @__PURE__ */ new Set(["mode", "allow"]);
|
|
1431
669
|
var ID_RE = /^[a-zA-Z0-9][a-zA-Z0-9_.:-]*$/;
|
|
1432
670
|
function projectSafetyPolicyPath(cwd = process.cwd()) {
|
|
1433
|
-
let cursor =
|
|
671
|
+
let cursor = path2.resolve(cwd);
|
|
1434
672
|
while (true) {
|
|
1435
|
-
const candidate =
|
|
673
|
+
const candidate = path2.join(cursor, POLICY_RELATIVE_PATH);
|
|
1436
674
|
if (existsSync(candidate)) return candidate;
|
|
1437
|
-
const parent =
|
|
675
|
+
const parent = path2.dirname(cursor);
|
|
1438
676
|
if (parent === cursor) return null;
|
|
1439
677
|
cursor = parent;
|
|
1440
678
|
}
|
|
@@ -1542,12 +780,12 @@ function parsePathList(value, key, errors) {
|
|
|
1542
780
|
continue;
|
|
1543
781
|
}
|
|
1544
782
|
const trimmed = item.trim();
|
|
1545
|
-
if (
|
|
783
|
+
if (path2.isAbsolute(trimmed)) {
|
|
1546
784
|
errors.push(`${label} must be relative to the policy root`);
|
|
1547
785
|
continue;
|
|
1548
786
|
}
|
|
1549
|
-
const normalized =
|
|
1550
|
-
const segments = normalized.split(
|
|
787
|
+
const normalized = path2.normalize(trimmed);
|
|
788
|
+
const segments = normalized.split(path2.sep).filter((segment) => segment.length > 0);
|
|
1551
789
|
if (segments.some((segment) => segment === "..")) {
|
|
1552
790
|
errors.push(`${label} must not escape the policy root with '..'`);
|
|
1553
791
|
continue;
|
|
@@ -1592,11 +830,11 @@ function parseCommandPolicy(value, label) {
|
|
|
1592
830
|
if (id && !ID_RE.test(id)) errors.push(`${label}.id must match ${ID_RE}`);
|
|
1593
831
|
if (command && command.trim().length === 0) errors.push(`${label}.command must not be empty`);
|
|
1594
832
|
if (cwd !== void 0) {
|
|
1595
|
-
if (
|
|
833
|
+
if (path2.isAbsolute(cwd)) {
|
|
1596
834
|
errors.push(`${label}.cwd must be relative to the policy root`);
|
|
1597
835
|
} else {
|
|
1598
|
-
const normalized =
|
|
1599
|
-
const segments = normalized.split(
|
|
836
|
+
const normalized = path2.normalize(cwd);
|
|
837
|
+
const segments = normalized.split(path2.sep).filter((segment) => segment.length > 0);
|
|
1600
838
|
if (segments.some((segment) => segment === "..")) {
|
|
1601
839
|
errors.push(`${label}.cwd must not escape the policy root with '..'`);
|
|
1602
840
|
}
|
|
@@ -1700,7 +938,7 @@ function isPlainRecord(value) {
|
|
|
1700
938
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1701
939
|
}
|
|
1702
940
|
function sha256(raw) {
|
|
1703
|
-
return
|
|
941
|
+
return createHash("sha256").update(raw, "utf8").digest("hex");
|
|
1704
942
|
}
|
|
1705
943
|
|
|
1706
944
|
// src/domains/safety/rejection-feedback.ts
|
|
@@ -1902,19 +1140,19 @@ function evaluateWriteRoots(roots, writeRootCwd, call) {
|
|
|
1902
1140
|
if (roots.length === 0) return null;
|
|
1903
1141
|
const target = writeRootTargetPath(call);
|
|
1904
1142
|
if (target === null) return null;
|
|
1905
|
-
const resolved =
|
|
1143
|
+
const resolved = path3.resolve(writeRootCwd, target);
|
|
1906
1144
|
for (const root of roots) {
|
|
1907
|
-
if (resolved === root || resolved.startsWith(`${root}${
|
|
1145
|
+
if (resolved === root || resolved.startsWith(`${root}${path3.sep}`)) return null;
|
|
1908
1146
|
}
|
|
1909
1147
|
return `write target '${target}' resolves to '${resolved}', which is outside the permitted write roots for this run: ${roots.join(", ")}`;
|
|
1910
1148
|
}
|
|
1911
1149
|
function createSafetyPolicyEngine(options = {}) {
|
|
1912
|
-
const cwd = canonicalizeExistingPath(
|
|
1913
|
-
const writeRootCwd =
|
|
1914
|
-
const writeRoots = (options.writeRoots ?? []).map((root) =>
|
|
1150
|
+
const cwd = canonicalizeExistingPath(path3.resolve(options.cwd ?? process.cwd()));
|
|
1151
|
+
const writeRootCwd = path3.resolve(options.cwd ?? process.cwd());
|
|
1152
|
+
const writeRoots = (options.writeRoots ?? []).map((root) => path3.resolve(root));
|
|
1915
1153
|
const packs = options.rulePacks ?? getCachedDefaultRulePacks();
|
|
1916
1154
|
const projectPolicy = options.projectPolicy ?? loadProjectSafetyPolicy(cwd);
|
|
1917
|
-
const projectPolicyRoot = projectPolicy.path === null ? cwd :
|
|
1155
|
+
const projectPolicyRoot = projectPolicy.path === null ? cwd : path3.dirname(path3.dirname(canonicalizeExistingPath(projectPolicy.path)));
|
|
1918
1156
|
const pathPolicyInput = projectPolicy.disableDefaultPathPolicy ? projectPolicy.pathPolicy : mergePathPolicyInputs(DEFAULT_DAMAGE_CONTROL_PATH_POLICY, projectPolicy.pathPolicy);
|
|
1919
1157
|
const expandedDefaults = projectPolicy.disableDefaultPathPolicy ? pathPolicyInput : mergePathPolicyInputs(pathPolicyInput, { zeroAccessPaths: clioCredentialStorePaths() });
|
|
1920
1158
|
const pathPolicy = compilePathPolicy(expandedDefaults, projectPolicyRoot);
|
|
@@ -2073,7 +1311,7 @@ function createSafetyPolicyEngine(options = {}) {
|
|
|
2073
1311
|
}
|
|
2074
1312
|
function clioCredentialStorePaths() {
|
|
2075
1313
|
try {
|
|
2076
|
-
return [
|
|
1314
|
+
return [path3.join(clioConfigDir(), "credentials.yaml")];
|
|
2077
1315
|
} catch {
|
|
2078
1316
|
return [];
|
|
2079
1317
|
}
|
|
@@ -2338,11 +1576,11 @@ function effectiveClassification(classification, match) {
|
|
|
2338
1576
|
}
|
|
2339
1577
|
function matchingProjectCommand(policy, command, cwd) {
|
|
2340
1578
|
if (!policy.valid || policy.path === null) return null;
|
|
2341
|
-
const policyRoot =
|
|
1579
|
+
const policyRoot = path3.dirname(path3.dirname(policy.path));
|
|
2342
1580
|
for (const entry of policy.commands) {
|
|
2343
1581
|
if (entry.command !== command) continue;
|
|
2344
1582
|
if (entry.shellOperators === "deny" && hasShellOperators(command)) continue;
|
|
2345
|
-
const allowedCwd = entry.cwd !== void 0 ?
|
|
1583
|
+
const allowedCwd = entry.cwd !== void 0 ? path3.resolve(policyRoot, entry.cwd) : policyRoot;
|
|
2346
1584
|
if (!isUnderOrSame(cwd, allowedCwd)) continue;
|
|
2347
1585
|
return entry;
|
|
2348
1586
|
}
|
|
@@ -2371,7 +1609,7 @@ function recognizeCommandChain(command, callCwd, workspaceRoot, policy) {
|
|
|
2371
1609
|
if (segment[0] === "cd") {
|
|
2372
1610
|
if (segment.length !== 2) return null;
|
|
2373
1611
|
const target = segment[1] ?? "";
|
|
2374
|
-
if (target.startsWith("~") || !isUnderOrSame(
|
|
1612
|
+
if (target.startsWith("~") || !isUnderOrSame(path3.resolve(callCwd, target), workspaceRoot)) return null;
|
|
2375
1613
|
ruleIds.push("builtin:cd-workspace");
|
|
2376
1614
|
continue;
|
|
2377
1615
|
}
|
|
@@ -2398,11 +1636,11 @@ function hasShellOperators(command) {
|
|
|
2398
1636
|
return hasSequencingOperators(command) || hasCommandSubstitution(command);
|
|
2399
1637
|
}
|
|
2400
1638
|
function isUnderOrSame(child, parent) {
|
|
2401
|
-
const rel =
|
|
2402
|
-
canonicalizeExistingPath(
|
|
2403
|
-
canonicalizeExistingPath(
|
|
1639
|
+
const rel = path3.relative(
|
|
1640
|
+
canonicalizeExistingPath(path3.resolve(parent)),
|
|
1641
|
+
canonicalizeExistingPath(path3.resolve(child))
|
|
2404
1642
|
);
|
|
2405
|
-
return rel === "" || !rel.startsWith("..") && !
|
|
1643
|
+
return rel === "" || !rel.startsWith("..") && !path3.isAbsolute(rel);
|
|
2406
1644
|
}
|
|
2407
1645
|
function commandArg(args) {
|
|
2408
1646
|
return typeof args?.command === "string" ? args.command : null;
|
|
@@ -2413,7 +1651,7 @@ function pathArg(args) {
|
|
|
2413
1651
|
return typeof candidate === "string" && candidate.length > 0 ? candidate : null;
|
|
2414
1652
|
}
|
|
2415
1653
|
function cwdArg(args, fallback) {
|
|
2416
|
-
const resolved = typeof args?.cwd === "string" && args.cwd.length > 0 ?
|
|
1654
|
+
const resolved = typeof args?.cwd === "string" && args.cwd.length > 0 ? path3.resolve(fallback, args.cwd) : fallback;
|
|
2417
1655
|
return canonicalizeExistingPath(resolved);
|
|
2418
1656
|
}
|
|
2419
1657
|
var CONTENT_BEARING_TOOLS = /* @__PURE__ */ new Set([ToolNames.Write, ToolNames.Edit, ToolNames.Artifact]);
|
|
@@ -2455,7 +1693,7 @@ function rulePackHash(packs) {
|
|
|
2455
1693
|
const payload = {
|
|
2456
1694
|
base: packPayload(packs.base.rules)
|
|
2457
1695
|
};
|
|
2458
|
-
return
|
|
1696
|
+
return createHash2("sha256").update(JSON.stringify(payload), "utf8").digest("hex");
|
|
2459
1697
|
}
|
|
2460
1698
|
function packPayload(rules) {
|
|
2461
1699
|
return rules.map((rule) => ({
|
|
@@ -2469,23 +1707,6 @@ function packPayload(rules) {
|
|
|
2469
1707
|
}
|
|
2470
1708
|
|
|
2471
1709
|
export {
|
|
2472
|
-
parseJsonObjectPayload,
|
|
2473
|
-
resultContractSourceId,
|
|
2474
|
-
parseVerifierResult,
|
|
2475
|
-
resultContractAuthorship,
|
|
2476
|
-
parseScoutResult,
|
|
2477
|
-
validateResultContract,
|
|
2478
|
-
validateRecipeResult,
|
|
2479
|
-
RESULT_CONTRACT_REPAIR_LIMIT,
|
|
2480
|
-
resultContractRepairMessages,
|
|
2481
|
-
parseResultContract,
|
|
2482
|
-
AUTONOMY_LEVELS,
|
|
2483
|
-
DEFAULT_AUTONOMY_LEVEL,
|
|
2484
|
-
isAutonomyLevel,
|
|
2485
|
-
DEFAULT_AUTONOMY_EXPOSURE,
|
|
2486
|
-
mapAutonomy,
|
|
2487
|
-
autonomyDenyRejection,
|
|
2488
|
-
autonomyAskRejection,
|
|
2489
1710
|
DEFAULT_RECENT_ENTRY_LIMIT,
|
|
2490
1711
|
assessFinishContract,
|
|
2491
1712
|
typedValidationSummary,
|
|
@@ -2493,4 +1714,4 @@ export {
|
|
|
2493
1714
|
WRITE_ROOT_REFUSED_TOOLS,
|
|
2494
1715
|
createSafetyPolicyEngine
|
|
2495
1716
|
};
|
|
2496
|
-
//# sourceMappingURL=chunk-
|
|
1717
|
+
//# sourceMappingURL=chunk-OBMAI2DP.js.map
|