@iowarp/clio-coder 0.4.1 → 0.4.3
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 +127 -0
- package/CONTRIBUTING.md +142 -52
- package/README.md +434 -473
- package/SECURITY.md +2 -1
- package/dist/{acp-ZILU3AUO.js → acp-H2NGRPWO.js} +12 -12
- package/dist/{agents-HYWGBGQR.js → agents-TL5LLUQP.js} +56 -55
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-N3QT7CBO.js → auth-E5SW4HMS.js} +23 -21
- package/dist/builtins-IA7V7FUC.js +22 -0
- package/dist/{chunk-7RY5VZPH.js → chunk-2APPQIER.js} +8 -8
- package/dist/{chunk-72GZI5EV.js → chunk-2JH2WHGE.js} +2 -2
- package/dist/{chunk-JA5QWE4Z.js → chunk-2UG5F4C5.js} +1973 -1664
- package/dist/{chunk-5YHDIDBP.js → chunk-2UH2KFUP.js} +2 -2
- package/dist/{chunk-CTJ4RNAA.js → chunk-2VIKGWFZ.js} +2 -2
- package/dist/{chunk-I66EAJFY.js → chunk-2WZ546HR.js} +267 -232
- package/dist/{chunk-GIZNH63R.js → chunk-35MSIRKH.js} +9 -4
- package/dist/chunk-3EBYEESD.js +314 -0
- package/dist/{chunk-J5LZHVIT.js → chunk-3M6DQK6S.js} +113 -35
- package/dist/{chunk-RKSR6VSF.js → chunk-4IUZQIJ3.js} +29 -1
- package/dist/{chunk-6FN3E6KX.js → chunk-4O6MANBS.js} +2 -2
- package/dist/chunk-4UVU7BJ5.js +39 -0
- package/dist/{chunk-VKRH2TCS.js → chunk-4WR7VSYB.js} +2 -2
- package/dist/{chunk-BBTJOK6Y.js → chunk-54CBCGIR.js} +5 -5
- package/dist/{chunk-AP73CFDC.js → chunk-5ICU3EUH.js} +2 -2
- package/dist/chunk-5MEZN6CB.js +1334 -0
- package/dist/{chunk-O42A54GG.js → chunk-5OIVVPHF.js} +2 -2
- package/dist/{chunk-ABLSQ6JX.js → chunk-64I3JVYM.js} +8 -2
- package/dist/{chunk-AFKWHWXF.js → chunk-6PTFB5VS.js} +39 -22
- package/dist/{chunk-VN3SHNBN.js → chunk-7DICMOS6.js} +2 -2
- package/dist/chunk-7DRAWPTZ.js +360 -0
- package/dist/chunk-7E7I3WLS.js +3762 -0
- package/dist/{chunk-BJGUKIG4.js → chunk-7ZYNNDKC.js} +7 -7
- package/dist/{chunk-XKA2ICR3.js → chunk-AF4YM7Z4.js} +652 -252
- package/dist/{chunk-GVQJ5CCZ.js → chunk-AX2THNSA.js} +12 -12
- package/dist/{chunk-IG7BCQBA.js → chunk-B4OAX3SI.js} +65 -3
- package/dist/{chunk-TD3PGPQA.js → chunk-B4VEBZKF.js} +3 -3
- package/dist/{chunk-74YWRRU5.js → chunk-BEPZRGGU.js} +10 -10
- package/dist/{chunk-FEFIFZTL.js → chunk-CE5AX47J.js} +2 -2
- package/dist/{chunk-UAPGZHYC.js → chunk-DWUOQKRU.js} +25 -11
- package/dist/{chunk-THYWACCR.js → chunk-E3TPLWFX.js} +3 -3
- package/dist/{chunk-7EPLI7VL.js → chunk-EKCHAPYA.js} +2 -2
- package/dist/{chunk-HLW2MRKE.js → chunk-F4EKGO4N.js} +3 -1
- package/dist/{chunk-PJJ6MY27.js → chunk-F5JHEYZM.js} +7 -7
- package/dist/{chunk-6CCS4G3W.js → chunk-FTMGRKEF.js} +3 -3
- package/dist/{chunk-SINK3QR6.js → chunk-G76U63X4.js} +17 -17
- package/dist/{chunk-EIMVLWB3.js → chunk-GHS5EBTQ.js} +64 -9
- package/dist/{chunk-QMXC4JB7.js → chunk-GI7YYQ3F.js} +187 -1419
- package/dist/{chunk-TZSKNMZG.js → chunk-GTUD2WMY.js} +2 -1
- package/dist/{chunk-6HMJX2VU.js → chunk-GWZNEVM2.js} +44 -12
- package/dist/chunk-GYV6VZOC.js +26 -0
- package/dist/{chunk-MQXIVJ35.js → chunk-HAXOFFRH.js} +5 -5
- package/dist/{chunk-UXN6JT4W.js → chunk-HEQY7ZFI.js} +3 -3
- package/dist/{chunk-7PWAODYW.js → chunk-I7XBWTYH.js} +2 -2
- package/dist/{chunk-GCSMB2KY.js → chunk-I7ZPNEJM.js} +145 -102
- package/dist/{chunk-WNP7O5WZ.js → chunk-ID64D7PE.js} +4 -4
- package/dist/{chunk-QTFGO774.js → chunk-IGLP3ODT.js} +29 -16
- package/dist/chunk-IJNZMHLA.js +101 -0
- package/dist/{chunk-BDPT6GTK.js → chunk-INY6HTFL.js} +7 -7
- package/dist/{chunk-PBP4B7XR.js → chunk-IUE3Y34X.js} +2 -2
- package/dist/{chunk-6NJQITNH.js → chunk-IWT4SF4R.js} +6 -3
- package/dist/{chunk-R23Z6K6I.js → chunk-JDAY6FIL.js} +19 -19
- package/dist/chunk-JEQ3XTHC.js +42 -0
- package/dist/{chunk-FSP7CMNU.js → chunk-JGRC33J2.js} +50 -4
- package/dist/{chunk-TVH4ONAM.js → chunk-JKKCYP3C.js} +10 -10
- package/dist/{chunk-HJWWJ6IL.js → chunk-JSC3U7TI.js} +16 -4
- package/dist/{chunk-C537JADH.js → chunk-KK4JZPBQ.js} +19 -141
- package/dist/{chunk-K6BF4U2H.js → chunk-KKOJXO6R.js} +62 -14
- package/dist/{chunk-IHXBNWMM.js → chunk-KXDSS5WJ.js} +7 -3
- package/dist/{chunk-6DWBAZ5U.js → chunk-L47TF46W.js} +5 -7
- package/dist/{chunk-HUAS7ITX.js → chunk-LDJG7DW3.js} +91 -42
- package/dist/{chunk-CDNVLKUX.js → chunk-LLDJM5XK.js} +13 -7
- package/dist/{chunk-YPI3QQCF.js → chunk-MCEPRMZW.js} +2 -4
- package/dist/{chunk-Y4CAGMM6.js → chunk-MNJGS2IN.js} +5 -6
- package/dist/{chunk-VKFQTNDV.js → chunk-MUW2BDDH.js} +4 -4
- package/dist/{chunk-E67WX76H.js → chunk-MWUZBSAQ.js} +104 -152
- package/dist/{chunk-OJTRZGR3.js → chunk-N2Z7HLVY.js} +21 -21
- package/dist/{chunk-TVHHYFHE.js → chunk-NEDJ26B5.js} +2 -2
- package/dist/{chunk-FYUN5KZ3.js → chunk-NIQJ66N4.js} +21 -21
- package/dist/{chunk-U2WB7TZS.js → chunk-NMJXSHBJ.js} +97 -85
- package/dist/{chunk-CWVRRIEI.js → chunk-NZMNUPZZ.js} +2 -2
- package/dist/{chunk-VEGN6WIQ.js → chunk-O5CVSAG5.js} +3 -3
- package/dist/{chunk-MOPSG2X7.js → chunk-OML5D5V5.js} +8 -8
- package/dist/{chunk-2VG7KLYV.js → chunk-PAJQJ7BS.js} +5816 -3255
- package/dist/{chunk-ZW55JB7N.js → chunk-PUVDKJ2Y.js} +2 -2
- package/dist/{chunk-BTGG6BG2.js → chunk-QWGDJJYJ.js} +158 -19
- package/dist/chunk-R6Q67RJH.js +134 -0
- package/dist/{chunk-ZJLUDYFY.js → chunk-RRNP2ANY.js} +6 -6
- package/dist/{chunk-PVAMAVBB.js → chunk-RSJ25QSL.js} +102 -2
- package/dist/{chunk-NLFAQR7Z.js → chunk-S66XZJOF.js} +3 -23
- package/dist/chunk-SKHCAU7K.js +385 -0
- package/dist/chunk-SZAA6XDG.js +30 -0
- package/dist/{chunk-J4HBWF6Y.js → chunk-TM6LQDI3.js} +131 -28
- package/dist/chunk-UOIZ7DA4.js +41 -0
- package/dist/{chunk-MA3H6DM5.js → chunk-UPZU6GE4.js} +25 -3
- package/dist/{chunk-BWW4HLO4.js → chunk-UXCU4E3T.js} +8 -6
- package/dist/{chunk-N5UK64DP.js → chunk-V2ANDPVT.js} +4 -4
- package/dist/{chunk-AK5XEFVZ.js → chunk-VA5FNYMT.js} +26 -13
- package/dist/{chunk-6VC4OV3Z.js → chunk-VIA6RFQZ.js} +3 -11
- package/dist/{chunk-ZAZB4JMW.js → chunk-VKPAQYEB.js} +27 -8
- package/dist/{chunk-QKIFBZKT.js → chunk-VW6DOEDG.js} +497 -81
- package/dist/{chunk-SCYB3HA4.js → chunk-W6RRQCPQ.js} +63 -19
- package/dist/{chunk-2NM363SV.js → chunk-WBKFA554.js} +10 -10
- package/dist/{chunk-R32CLGZ6.js → chunk-WCXUNS7U.js} +82 -21
- package/dist/{chunk-GPPB3JBE.js → chunk-WRBAGUNF.js} +3 -3
- package/dist/{chunk-IXJT6DCX.js → chunk-XIVNBFZS.js} +85 -30
- package/dist/{chunk-UEDMSP56.js → chunk-XPWWI35G.js} +417 -201
- package/dist/chunk-XRZT5WY5.js +47 -0
- package/dist/{chunk-3QSOM6PA.js → chunk-Y3CBHOR6.js} +2 -2
- package/dist/{chunk-VXMFAE2W.js → chunk-YPC6ZR5L.js} +19 -6
- package/dist/{chunk-AKB4GYDL.js → chunk-YQWYVTMC.js} +5 -5
- package/dist/{chunk-6I5ILFOF.js → chunk-ZA4VCIGV.js} +3 -3
- package/dist/{chunk-7OBGU7UB.js → chunk-ZDN3Y73Y.js} +12 -18
- package/dist/{chunk-3I5NY75V.js → chunk-ZWPRK62N.js} +8 -5
- package/dist/cli/index.js +41 -39
- package/dist/{clio-IT3G3VQH.js → clio-CMMK4KRR.js} +9 -9
- package/dist/{code-nav-RK6S7F6E.js → code-nav-MDZNQS33.js} +89 -21
- package/dist/{components-UBWCQSRW.js → components-UCUQ4QXW.js} +4 -4
- package/dist/{config-3QZRWZJF.js → config-SVM5P5YI.js} +131 -84
- package/dist/{configure-FL7Y3KJF.js → configure-LE3IK2TJ.js} +28 -26
- package/dist/{context-5HE7ODYK.js → context-2OHRKS42.js} +69 -64
- package/dist/{context-KYQFRVDC.js → context-E3VC7RX5.js} +15 -11
- package/dist/{context-XNHL75JV.js → context-VNCR7KAG.js} +93 -65
- package/dist/{context-clear-N545L53A.js → context-clear-BW4O37TG.js} +64 -60
- package/dist/context-map-COB37XXN.js +505 -0
- package/dist/{context-working-set-QHKXSV2F.js → context-working-set-VDS25HXZ.js} +19 -18
- package/dist/{dispatch-runner-RGIE5PCT.js → dispatch-runner-5AHT53RF.js} +93 -82
- package/dist/{docs-5NAF6AU7.js → docs-PD3EXDKU.js} +21 -20
- package/dist/{doctor-ZGPEGHIP.js → doctor-WNNVO6FY.js} +48 -47
- package/dist/{eval-GXLL44RD.js → eval-7G7SGAYO.js} +287 -115
- package/dist/{eval-inventory-HBWSWQOK.js → eval-inventory-Y6QRFOH5.js} +4 -4
- package/dist/{evidence-HWLBRH3Q.js → evidence-VD6736FQ.js} +67 -64
- package/dist/{evolve-FTZBMNVW.js → evolve-AL3NGVRL.js} +65 -62
- package/dist/{extensions-VHRBEID7.js → extensions-MOVJ32NM.js} +9 -7
- package/dist/{fleet-CKZHJWZJ.js → fleet-QZHUMAGI.js} +114 -111
- package/dist/{fleet-commands-EXDXBMV6.js → fleet-commands-BAYT5FJZ.js} +10 -10
- package/dist/{fleet-decisions-OTHB6KRL.js → fleet-decisions-IREVMRU4.js} +7 -6
- package/dist/{fleet-graph-YTEZUCUT.js → fleet-graph-YCTT3HTI.js} +22 -19
- package/dist/{fleet-inspect-SS6YMDCK.js → fleet-inspect-QVJTDAVB.js} +58 -55
- package/dist/{fleet-preflight-PBY4VYOM.js → fleet-preflight-25QAFPK4.js} +4 -4
- package/dist/{fleet-validate-KMEM5L3S.js → fleet-validate-5O57AAJ7.js} +26 -23
- package/dist/{fleet-verify-QD5M7E7Q.js → fleet-verify-CPH2W2T6.js} +59 -56
- package/dist/{fleet-view-WAMJYNDT.js → fleet-view-SWBR3VGQ.js} +58 -55
- package/dist/{init-5XQRBOFV.js → init-J477LKZH.js} +82 -79
- package/dist/{interop-34TVO25M.js → interop-3FCM6XLG.js} +11 -11
- package/dist/{library-3QY6KF57.js → library-QUQEIUG6.js} +30 -27
- package/dist/{memory-L4UTIIIW.js → memory-SGGSEP65.js} +67 -64
- package/dist/{models-ZVX3QOWE.js → models-HEKUAXXK.js} +53 -46
- package/dist/{monitor-CEKVSYTS.js → monitor-HKU57TYQ.js} +63 -60
- package/dist/{orchestrator-77BAP6BC.js → orchestrator-VDFAEFAI.js} +1831 -1057
- package/dist/{panes-7STHOAUJ.js → panes-DN2SSFOH.js} +5 -5
- package/dist/{panes-SHAUIRXY.js → panes-TALGNPZT.js} +29 -14
- package/dist/{paths-L7LGY6RN.js → paths-NBMFAIEZ.js} +5 -5
- package/dist/reset-EAJFFJVB.js +344 -0
- package/dist/{resources-74GKTLSF.js → resources-OVKSEFVE.js} +29 -20
- package/dist/{run-HBAUJNNZ.js → run-7DP7ZF2J.js} +120 -115
- package/dist/{share-G3APVLVP.js → share-WML67FT3.js} +32 -27
- package/dist/{skills-35HHUKCR.js → skills-SG662R2K.js} +41 -31
- package/dist/{skills-eval-QN4HSHDC.js → skills-eval-VVZEUU46.js} +78 -77
- package/dist/{skills-inventory-J357J34F.js → skills-inventory-I2E23GET.js} +23 -20
- package/dist/{slash-commands-JZZCQA32.js → slash-commands-S7MBJDQK.js} +40 -36
- package/dist/{steer-XAVHJM22.js → steer-2LQOMCPB.js} +3 -3
- package/dist/{support-U7QOWY26.js → support-CC2UJBJ6.js} +6 -6
- package/dist/{targets-DSM6CY3M.js → targets-4QC3HIEW.js} +54 -54
- package/dist/{terminal-lease-JOPFUVEM.js → terminal-lease-TUHIJ6Y2.js} +5 -5
- package/dist/{tools-MKNWVPBH.js → tools-TFGJICCU.js} +10 -10
- package/dist/{trace-ECQ7TIYZ.js → trace-FXMXUZUF.js} +55 -7
- package/dist/uninstall-5PEVOE5B.js +408 -0
- package/dist/upgrade-M4WXY6KN.js +303 -0
- package/dist/{usage-X52N3IDJ.js → usage-N7ZNVLEM.js} +151 -104
- package/dist/{verifiers-EJTVVSMA.js → verifiers-DJTP4XX6.js} +15 -15
- package/dist/{verify-YJL6XET2.js → verify-RWE4PPEK.js} +9 -9
- package/dist/{web-fetch-MPIFL3LL.js → web-fetch-MPARV2K7.js} +2 -2
- package/dist/{wiki-generate-4NDZTQ4B.js → wiki-generate-C7IQOXSP.js} +89 -86
- package/dist/{with-panes-OBOBFIIR.js → with-panes-4GCGSL7J.js} +53 -257
- package/dist/worker/entry.js +90 -74
- package/docs/README.md +176 -81
- package/docs/{acp.md → architecture/acp.md} +36 -20
- package/docs/{alcf-provider.md → architecture/alcf-provider.md} +8 -5
- package/docs/{architecture.md → architecture/architecture.md} +43 -22
- package/docs/{artifact-placement.md → architecture/artifact-placement.md} +27 -23
- package/docs/architecture/artifact-versions.md +90 -0
- package/docs/{capacity-and-scheduling.md → architecture/capacity-and-scheduling.md} +26 -13
- package/docs/{context-engine.md → architecture/context-engine.md} +29 -25
- package/docs/{context-working-set.md → architecture/context-working-set.md} +13 -10
- package/docs/{dispatch-architecture-rationale.md → architecture/dispatch-architecture-rationale.md} +12 -9
- package/docs/{dispatch-typed-intent.md → architecture/dispatch-typed-intent.md} +68 -46
- package/docs/{evidence-and-memory.md → architecture/evidence-and-memory.md} +23 -16
- package/docs/{middleware-and-components.md → architecture/middleware-and-components.md} +11 -5
- package/docs/{model-catalog.md → architecture/model-catalog.md} +61 -27
- package/docs/{observability.md → architecture/observability.md} +38 -14
- package/docs/{pi-boundary.md → architecture/pi-boundary.md} +24 -11
- package/docs/{prompt-envelope-and-tools.md → architecture/prompt-envelope-and-tools.md} +57 -20
- package/docs/{provider-adapter-cookbook.md → architecture/provider-adapter-cookbook.md} +99 -25
- package/docs/{safety-model.md → architecture/safety-model.md} +35 -20
- package/docs/{session-lifecycle.md → architecture/session-lifecycle.md} +8 -5
- package/docs/architecture/time-conventions.md +125 -0
- package/docs/{trace-store.md → architecture/trace-store.md} +13 -5
- package/docs/{tui-design.md → architecture/tui-design.md} +13 -13
- package/docs/{worker-dispatch-mechanics.md → architecture/worker-dispatch-mechanics.md} +27 -30
- package/docs/{built-in-agents.md → guide/built-in-agents.md} +65 -35
- package/docs/{commands-and-modes.md → guide/commands-and-modes.md} +66 -61
- package/docs/{configuration-and-targets.md → guide/configuration-and-targets.md} +323 -297
- package/docs/guide/configuration-reference.md +1163 -0
- package/docs/{environment-variables.md → guide/environment-variables.md} +33 -28
- package/docs/{exit-codes-and-output.md → guide/exit-codes-and-output.md} +6 -3
- package/docs/{extensions-and-sharing.md → guide/extensions-and-sharing.md} +41 -14
- package/docs/{fleet-dispatch.md → guide/fleet-dispatch.md} +39 -43
- package/docs/{glossary.md → guide/glossary.md} +14 -11
- package/docs/{installation-and-lifecycle.md → guide/installation-and-lifecycle.md} +81 -17
- package/docs/guide/panes-and-files.md +290 -0
- package/docs/{proactive-memory.md → guide/proactive-memory.md} +131 -107
- package/docs/{resource-library.md → guide/resource-library.md} +13 -4
- package/docs/{skills-marketplace.md → guide/skills-marketplace.md} +25 -3
- package/docs/{tool-usage.md → guide/tool-usage.md} +87 -23
- package/docs/{troubleshooting.md → guide/troubleshooting.md} +9 -4
- package/docs/{config-knobs-audit.md → history/config-knobs-audit.md} +11 -11
- package/docs/{release-cut-checklist.md → history/release-cut-checklist.md} +29 -2
- package/docs/process/development-pipeline.md +152 -0
- package/docs/process/documentation-coverage.md +100 -0
- package/docs/process/documentation-guide.md +187 -0
- package/docs/{eval-runner.md → process/eval-runner.md} +108 -53
- package/docs/{evals-internal.md → process/evals-internal.md} +10 -10
- package/docs/{evolution.md → process/evolution.md} +2 -2
- package/docs/{fleet-demo-runbook.md → process/fleet-demo-runbook.md} +11 -7
- package/docs/{git-commit-provenance.md → process/git-commit-provenance.md} +11 -4
- package/docs/{performance-methodology.md → process/performance-methodology.md} +87 -69
- package/docs/{scientific-validation.md → process/scientific-validation.md} +4 -4
- package/evals/README.md +2 -2
- package/evals/behavioral-model.yaml +3 -2
- package/package.json +10 -8
- package/skills/README.md +52 -41
- package/skills/coding/ast-grep/SKILL.md +102 -31
- package/skills/coding/ast-grep/evals.md +26 -0
- package/skills/coding/coding-standards/SKILL.md +41 -6
- package/skills/coding/coding-standards/evals.md +23 -0
- package/skills/coding/prototype/SKILL.md +88 -29
- package/skills/coding/prototype/evals.md +19 -0
- package/skills/coding/tdd/SKILL.md +81 -54
- package/skills/coding/tdd/evals.md +20 -0
- package/skills/context/context-handoff/SKILL.md +44 -3
- package/skills/context/context-handoff/evals.md +44 -0
- package/skills/context/context-prime/SKILL.md +46 -16
- package/skills/context/context-prime/evals.md +45 -0
- package/skills/git/branch-closeout/SKILL.md +132 -0
- package/skills/git/branch-closeout/evals.md +133 -0
- package/skills/git/branch-closeout/references/closeout-checklist.md +81 -0
- package/skills/git/file-ticket/SKILL.md +78 -64
- package/skills/git/file-ticket/assets/issue-template.md +22 -0
- package/skills/git/file-ticket/evals.md +31 -26
- package/skills/git/file-ticket/references/issue-discovery.md +49 -0
- package/skills/git/fix-issue/SKILL.md +88 -65
- package/skills/git/fix-issue/evals.md +35 -31
- package/skills/git/fix-issue/references/diagnosis-and-rca.md +46 -0
- package/skills/git/resolve-merge-conflicts/SKILL.md +101 -52
- package/skills/git/resolve-merge-conflicts/evals.md +52 -25
- package/skills/git/resolve-merge-conflicts/references/conflict-matrix.md +126 -0
- package/skills/git/ship/SKILL.md +103 -67
- package/skills/git/ship/assets/pr-template.md +21 -0
- package/skills/git/ship/evals.md +44 -28
- package/skills/git/ship/references/remote-and-branch-policy.md +62 -0
- package/skills/git/worktree-create/SKILL.md +80 -50
- package/skills/git/worktree-create/evals.md +40 -33
- package/skills/git/worktree-create/references/worktree-setup.md +62 -66
- package/skills/git/worktree-merge/SKILL.md +112 -65
- package/skills/git/worktree-merge/evals.md +42 -34
- package/skills/git/worktree-merge/references/merge-strategies.md +52 -0
- package/skills/meta/clio-coder-dev/SKILL.md +9 -5
- package/skills/meta/clio-coder-dev/evals.md +3 -2
- package/skills/meta/clio-coder-test/SKILL.md +102 -95
- package/skills/meta/clio-coder-test/evals.md +9 -4
- package/skills/meta/clio-coder-test/references/harness.md +100 -124
- package/skills/meta/clio-coder-test/references/test-map.md +77 -50
- package/skills/meta/credentials/SKILL.md +2 -2
- package/skills/meta/find-skills/SKILL.md +2 -2
- package/skills/meta/herdr/SKILL.md +2 -2
- package/skills/meta/skill-craft/SKILL.md +22 -16
- package/skills/planning/archify/SKILL.md +196 -0
- package/skills/planning/archify/evals.md +65 -0
- package/skills/planning/architecture/SKILL.md +62 -13
- package/skills/planning/architecture/evals.md +65 -0
- package/skills/planning/backlog/SKILL.md +131 -15
- package/skills/planning/backlog/evals.md +142 -0
- package/skills/planning/prd/SKILL.md +47 -7
- package/skills/planning/prd/evals.md +54 -0
- package/skills/planning/product-intent/SKILL.md +58 -3
- package/skills/planning/product-intent/evals.md +70 -0
- package/skills/planning/tech-spec/SKILL.md +54 -3
- package/skills/planning/tech-spec/evals.md +73 -0
- package/skills/registry.yaml +70 -62
- package/skills/remote.yaml +13 -0
- package/skills/research/arxiv-literature/SKILL.md +77 -19
- package/skills/research/arxiv-literature/evals.md +50 -0
- package/skills/research/experiment-protocol/SKILL.md +21 -2
- package/skills/research/experiment-protocol/evals.md +23 -0
- package/skills/research/scientific-debugging/SKILL.md +24 -2
- package/skills/research/scientific-debugging/evals.md +18 -0
- package/skills/research/scientific-modernization/SKILL.md +27 -2
- package/skills/research/scientific-modernization/evals.md +27 -0
- package/skills/skill-marketplace.json +97 -62
- package/skills/workflow/cut-it/SKILL.md +66 -6
- package/skills/workflow/cut-it/evals.md +101 -0
- package/skills/workflow/design-council/SKILL.md +118 -28
- package/skills/workflow/design-council/evals.md +161 -0
- package/skills/workflow/grill-me/SKILL.md +87 -11
- package/skills/workflow/grill-me/evals.md +153 -0
- package/skills/workflow/workflow-distiller/SKILL.md +77 -18
- package/skills/workflow/workflow-distiller/evals.md +118 -0
- package/src/cli/args.ts +2 -2
- package/src/cli/bootstrap-generate.ts +1 -1
- package/src/cli/config-inspect.ts +65 -12
- package/src/cli/configure-interop.ts +105 -13
- package/src/cli/configure-oauth.ts +57 -0
- package/src/cli/configure-onboarding.ts +980 -0
- package/src/cli/configure-target.ts +594 -0
- package/src/cli/configure.ts +1082 -532
- package/src/cli/context-map.ts +114 -0
- package/src/cli/context.ts +4 -0
- package/src/cli/docs.ts +22 -14
- package/src/cli/doctor-naming.ts +5 -5
- package/src/cli/doctor-toolchain.ts +3 -3
- package/src/cli/eval.ts +1 -2
- package/src/cli/extensions.ts +2 -1
- package/src/cli/fleet.ts +1 -1
- package/src/cli/index.ts +3 -1
- package/src/cli/internal-dispatch.ts +3 -4
- package/src/cli/lifecycle-presenter.ts +436 -0
- package/src/cli/models.ts +10 -2
- package/src/cli/modes/print.ts +5 -1
- package/src/cli/panes.ts +19 -5
- package/src/cli/reset.ts +228 -106
- package/src/cli/run.ts +9 -4
- package/src/cli/select.ts +664 -0
- package/src/cli/share.ts +5 -1
- package/src/cli/skills-eval.ts +3 -3
- package/src/cli/skills.ts +9 -2
- package/src/cli/targets.ts +5 -6
- package/src/cli/trace.ts +55 -4
- package/src/cli/uninstall.ts +233 -165
- package/src/cli/upgrade.ts +204 -149
- package/src/cli/usage.ts +86 -27
- package/src/cli/validate-model.ts +3 -3
- package/src/cli/wiki-generate.ts +1 -1
- package/src/core/artifact-paths.ts +1 -1
- package/src/core/bash-exec.ts +131 -86
- package/src/core/bus-events.ts +51 -6
- package/src/core/config.ts +61 -1
- package/src/core/defaults.ts +7 -4
- package/src/core/dispatch-outcome.ts +16 -0
- package/src/core/external-diagnostic.ts +44 -0
- package/src/core/gateway-routing.ts +157 -0
- package/src/core/guardrails.ts +10 -49
- package/src/core/prompt-hint.ts +9 -0
- package/src/core/safe-exec.ts +17 -2
- package/src/core/skill-activation.ts +89 -2
- package/src/domains/agents/builtins/architect.md +2 -3
- package/src/domains/agents/builtins/coder.md +3 -2
- package/src/domains/agents/builtins/debugger.md +2 -2
- package/src/domains/agents/builtins/documenter.md +2 -2
- package/src/domains/agents/builtins/git-master.md +1 -1
- package/src/domains/agents/builtins/oracle.md +1 -1
- package/src/domains/agents/builtins/provenance.md +1 -1
- package/src/domains/agents/builtins/researcher.md +1 -1
- package/src/domains/agents/builtins/scout.md +1 -1
- package/src/domains/agents/builtins/tester.md +2 -2
- package/src/domains/agents/builtins/verifier.md +2 -2
- package/src/domains/agents/builtins/wiki-writer.md +1 -1
- package/src/domains/agents/builtins/world-knowledge.md +31 -0
- package/src/domains/agents/catalog.ts +13 -15
- package/src/domains/agents/contract.ts +2 -0
- package/src/domains/agents/extension.ts +23 -1
- package/src/domains/agents/result-contract.ts +70 -0
- package/src/domains/config/keybindings.ts +8 -0
- package/src/domains/context/extension.ts +0 -3
- package/src/domains/context/wiki/map-seed.ts +589 -0
- package/src/domains/context/wiki/plan.ts +2 -2
- package/src/domains/context/working-set/path-index.ts +1 -0
- package/src/domains/dispatch/admission.ts +29 -0
- package/src/domains/dispatch/agent-candidates.ts +10 -0
- package/src/domains/dispatch/budget-envelope.ts +86 -1
- package/src/domains/dispatch/capability-match.ts +11 -0
- package/src/domains/dispatch/capacity-lease.ts +17 -0
- package/src/domains/dispatch/contract.ts +11 -1
- package/src/domains/dispatch/extension.ts +237 -49
- package/src/domains/dispatch/host-verification.ts +435 -39
- package/src/domains/dispatch/intent-requirements.ts +10 -0
- package/src/domains/dispatch/intent.ts +18 -1
- package/src/domains/dispatch/path-scope.ts +235 -24
- package/src/domains/dispatch/run-event-journal.ts +4 -15
- package/src/domains/dispatch/state.ts +2 -3
- package/src/domains/dispatch/transport.ts +45 -21
- package/src/domains/dispatch/types.ts +58 -3
- package/src/domains/dispatch/worker-model-metadata.ts +38 -0
- package/src/domains/eval/artifacts/store.ts +5 -0
- package/src/domains/eval/metrics/call-ledger-stream.ts +34 -11
- package/src/domains/eval/metrics/token-stream.ts +201 -31
- package/src/domains/eval/metrics/tracked.ts +40 -4
- package/src/domains/eval/runners/clio-run.ts +5 -2
- package/src/domains/eval/schema/suite.ts +28 -0
- package/src/domains/eval/schema/verdict.ts +2 -2
- package/src/domains/eval/store.ts +8 -1
- package/src/domains/eval/suites/resolve.ts +13 -1
- package/src/domains/eval/suites/run.ts +24 -3
- package/src/domains/evidence/trust-status.ts +10 -1
- package/src/domains/extensions/contract.ts +15 -1
- package/src/domains/extensions/discovery.ts +238 -41
- package/src/domains/extensions/extension.ts +105 -6
- package/src/domains/extensions/index.ts +24 -0
- package/src/domains/extensions/integrity.ts +189 -0
- package/src/domains/extensions/manager.ts +17 -1
- package/src/domains/extensions/resource-path.ts +27 -0
- package/src/domains/extensions/resources.ts +18 -38
- package/src/domains/extensions/snapshot-store.ts +39 -0
- package/src/domains/extensions/snapshot.ts +180 -0
- package/src/domains/extensions/state.ts +385 -57
- package/src/domains/extensions/types.ts +118 -1
- package/src/domains/interop/registry.ts +6 -2
- package/src/domains/interop/types.ts +4 -0
- package/src/domains/lifecycle/migrations/2026-09-01-extension-install-digests.ts +27 -0
- package/src/domains/lifecycle/migrations/index.ts +6 -0
- package/src/domains/lifecycle/naming-resources.ts +19 -4
- package/src/domains/lifecycle/naming-yazi.ts +10 -5
- package/src/domains/memory/task-memory-policy.ts +70 -26
- package/src/domains/memory/task-memory-telemetry.ts +1 -0
- package/src/domains/middleware/contract.ts +26 -0
- package/src/domains/middleware/extension.ts +24 -24
- package/src/domains/middleware/hook-receipts.ts +27 -4
- package/src/domains/middleware/hooks-io.ts +65 -32
- package/src/domains/middleware/hooks.ts +64 -0
- package/src/domains/middleware/index.ts +28 -5
- package/src/domains/middleware/marketplace-offer.ts +3 -35
- package/src/domains/middleware/memory-intervention.ts +127 -32
- package/src/domains/middleware/memory-step-endpoint.ts +3 -2
- package/src/domains/middleware/registrations.ts +326 -0
- package/src/domains/middleware/runtime.ts +28 -0
- package/src/domains/middleware/skills-reminder.ts +31 -2
- package/src/domains/middleware/snapshot.ts +20 -7
- package/src/domains/mux/contract.ts +38 -0
- package/src/domains/mux/detect.ts +6 -13
- package/src/domains/mux/index.ts +1 -1
- package/src/domains/mux/operations.ts +44 -5
- package/src/domains/mux/yazi/assets/yazi.toml +2 -2
- package/src/domains/mux/yazi/session.ts +53 -4
- package/src/domains/mux/yazi/theme.ts +117 -17
- package/src/domains/observability/compaction-usage.ts +118 -0
- package/src/domains/observability/contract.ts +10 -11
- package/src/domains/observability/cost.ts +1 -1
- package/src/domains/observability/extension.ts +17 -4
- package/src/domains/observability/out-of-turn-usage.ts +52 -21
- package/src/domains/observability/projection.ts +14 -90
- package/src/domains/observability/trace-store.ts +43 -7
- package/src/domains/prompts/compiler.ts +73 -53
- package/src/domains/prompts/contract.ts +15 -3
- package/src/domains/prompts/extension.ts +97 -9
- package/src/domains/prompts/fragments/identity/clio-worker.md +1 -3
- package/src/domains/prompts/fragments/identity/clio.md +6 -12
- package/src/domains/prompts/fragments/identity/docs-routing.md +1 -2
- package/src/domains/prompts/fragments/identity/self-awareness.md +3 -11
- package/src/domains/prompts/fragments/operating/contract.md +7 -15
- package/src/domains/prompts/fragments/operating/delegation.md +32 -34
- package/src/domains/prompts/fragments/operating/skills.md +10 -24
- package/src/domains/prompts/fragments/operating/worker.md +1 -8
- package/src/domains/providers/contract.ts +4 -1
- package/src/domains/providers/extension.ts +40 -9
- package/src/domains/providers/index.ts +1 -1
- package/src/domains/providers/model-capabilities.ts +9 -0
- package/src/domains/providers/model-discovery.ts +2 -0
- package/src/domains/providers/model-runtime-capabilities.ts +99 -25
- package/src/domains/providers/models/local-models/clio-coder-local-coding-targets.yaml +699 -114
- package/src/domains/providers/runtime-resolution.ts +31 -0
- package/src/domains/providers/runtimes/antigravity/antigravity-code.ts +225 -45
- package/src/domains/providers/runtimes/common/lmstudio-http.ts +6 -2
- package/src/domains/providers/runtimes/common/local-synth.ts +2 -0
- package/src/domains/providers/runtimes/common/probe-helpers.ts +7 -2
- package/src/domains/providers/runtimes/local-native/llamacpp.ts +9 -1
- package/src/domains/providers/runtimes/protocol/litellm.ts +119 -29
- package/src/domains/providers/support.ts +11 -5
- package/src/domains/providers/target-model-cache.ts +25 -2
- package/src/domains/providers/types/capability-flags.ts +2 -0
- package/src/domains/providers/types/cost-provenance.ts +19 -0
- package/src/domains/providers/types/local-model-quirks.ts +85 -37
- package/src/domains/providers/types/runtime-descriptor.ts +20 -1
- package/src/domains/providers/types/target-descriptor.ts +19 -0
- package/src/domains/resources/index.ts +3 -0
- package/src/domains/resources/skills/install.ts +72 -7
- package/src/domains/resources/skills/loader.ts +23 -19
- package/src/domains/resources/skills/marketplace.ts +63 -11
- package/src/domains/safety/autonomy.ts +15 -0
- package/src/domains/safety/call-target.ts +1 -1
- package/src/domains/safety/index.ts +1 -0
- package/src/domains/safety/loop-detector.ts +7 -4
- package/src/domains/safety/path-policy.ts +1 -1
- package/src/domains/safety/policy-engine.ts +34 -11
- package/src/domains/safety/protected-artifacts.ts +191 -88
- package/src/domains/safety/run-effects.ts +2 -22
- package/src/domains/safety/skill-authority.ts +55 -0
- package/src/domains/session/compaction/compact.ts +72 -22
- package/src/domains/session/entries.ts +6 -0
- package/src/domains/session/task-board.ts +10 -9
- package/src/domains/session/usage.ts +3 -3
- package/src/domains/share/archive.ts +164 -7
- package/src/engine/acp/server.ts +62 -9
- package/src/engine/agent.ts +13 -3
- package/src/engine/ai.ts +26 -8
- package/src/engine/antigravity/subprocess-runtime.ts +386 -120
- package/src/engine/api-registry.ts +3 -0
- package/src/engine/apis/llamacpp-residency.ts +3 -4
- package/src/engine/apis/lmstudio.ts +3 -3
- package/src/engine/apis/ollama-native.ts +6 -6
- package/src/engine/apis/openai-completions.ts +145 -39
- package/src/engine/apis/output-budget.ts +8 -18
- package/src/engine/apis/residency.ts +8 -27
- package/src/engine/external-subprocess.ts +114 -6
- package/src/engine/gemma-channel-filter.ts +19 -0
- package/src/engine/loop-guard.ts +92 -12
- package/src/engine/worker-runtime.ts +40 -11
- package/src/engine/worker-tools.ts +3 -1
- package/src/entry/background-model-metadata.ts +18 -0
- package/src/entry/compaction-prompt.ts +57 -0
- package/src/entry/extension-hook-sources.ts +28 -0
- package/src/entry/extension-reload.ts +309 -0
- package/src/entry/orchestrator.ts +464 -251
- package/src/entry/task-memory-lifecycle.ts +35 -0
- package/src/interactive/application-controller.ts +2 -1
- package/src/interactive/bus-notices.ts +8 -1
- package/src/interactive/chat-loop-messages.ts +16 -17
- package/src/interactive/chat-loop.ts +75 -3
- package/src/interactive/chat-panel.ts +36 -13
- package/src/interactive/chat-renderer.ts +72 -7
- package/src/interactive/cost-overlay.ts +26 -2
- package/src/interactive/dispatch-board.ts +6 -11
- package/src/interactive/footer/widgets.ts +13 -0
- package/src/interactive/interactive-application.ts +39 -4
- package/src/interactive/interactive-input-runtime.ts +4 -0
- package/src/interactive/interactive-presentation.ts +2 -2
- package/src/interactive/interactive-slash-runtime.ts +4 -1
- package/src/interactive/overlays/extensions.ts +9 -1
- package/src/interactive/overlays/help-reference.ts +13 -0
- package/src/interactive/overlays/settings.ts +27 -16
- package/src/interactive/panes-runtime.ts +111 -35
- package/src/interactive/prompt-cache-identity.ts +88 -0
- package/src/interactive/renderers/worker-entry.ts +32 -0
- package/src/interactive/slash-commands.ts +153 -20
- package/src/interactive/stream-pacing-policy.ts +0 -23
- package/src/interactive/theme/labels.ts +19 -13
- package/src/interactive/turn-context.ts +39 -20
- package/src/interactive/turn-recovery.ts +8 -0
- package/src/interactive/turn-runtime.ts +27 -11
- package/src/interactive/turn-state.ts +7 -0
- package/src/interactive/worker-receipts.ts +1 -0
- package/src/interactive/worker-stream.ts +6 -1
- package/src/interactive/yazi-bridge.ts +60 -6
- package/src/tools/agent-tools.ts +30 -1
- package/src/tools/artifact.ts +2 -2
- package/src/tools/ask-user.ts +3 -3
- package/src/tools/bash.ts +1 -1
- package/src/tools/bootstrap.ts +4 -0
- package/src/tools/builtin-tool-catalog.ts +52 -22
- package/src/tools/codewiki/code-nav-surface.ts +6 -0
- package/src/tools/codewiki/code-nav.ts +99 -13
- package/src/tools/context/docs-engine.ts +20 -7
- package/src/tools/context/index.ts +59 -21
- package/src/tools/core-bootstrap.ts +28 -6
- package/src/tools/credential-present.ts +1 -2
- package/src/tools/dispatch-arguments.ts +6 -1
- package/src/tools/dispatch-event-text.ts +10 -0
- package/src/tools/dispatch-plan.ts +49 -4
- package/src/tools/dispatch-run-events.ts +1 -1
- package/src/tools/dispatch-runner.ts +12 -0
- package/src/tools/dispatch-schema.ts +338 -0
- package/src/tools/dispatch-types.ts +3 -0
- package/src/tools/dispatch.ts +9 -254
- package/src/tools/ledger.ts +3 -5
- package/src/tools/monitor-surface.ts +5 -13
- package/src/tools/observation.ts +4 -5
- package/src/tools/panes-surface.ts +4 -11
- package/src/tools/panes.ts +4 -2
- package/src/tools/policy.ts +15 -2
- package/src/tools/read.ts +5 -6
- package/src/tools/registry.ts +41 -12
- package/src/tools/result-shaping.ts +18 -14
- package/src/tools/steer-surface.ts +1 -1
- package/src/tools/tasks.ts +1 -1
- package/src/tools/truncate.ts +6 -5
- package/src/tools/verify/surface.ts +6 -12
- package/src/tools/web-fetch-surface.ts +1 -3
- package/src/tools/worker-evidence.ts +3 -1
- package/src/worker/spec-contract.ts +4 -0
- package/dist/builtins-UJLMOVOV.js +0 -17
- package/dist/chunk-5QIAJV2D.js +0 -48
- package/dist/chunk-JZWT5J3Y.js +0 -814
- package/dist/chunk-K7VKOLQQ.js +0 -15
- package/dist/chunk-PMZCIOCJ.js +0 -25
- package/dist/chunk-SUW5DORT.js +0 -819
- package/dist/chunk-UOV2BYIW.js +0 -107
- package/dist/chunk-WR6U3OVP.js +0 -45
- package/dist/chunk-Y45G3AXC.js +0 -1558
- package/dist/reset-EOLM7GVE.js +0 -230
- package/dist/uninstall-N34PCTGJ.js +0 -331
- package/dist/upgrade-H7TOM7YL.js +0 -323
- package/docs/artifact-versions.md +0 -67
- package/docs/development-pipeline.md +0 -121
- package/docs/documentation-coverage.md +0 -46
- package/docs/documentation-guide.md +0 -167
- package/docs/time-conventions.md +0 -101
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
1
2
|
import {
|
|
2
3
|
asDirectoryPathBoundary,
|
|
3
4
|
normalizePathBoundaryEntry,
|
|
@@ -14,6 +15,7 @@ const POSIX_ABSOLUTE_TOKEN_RE = /(?:^|[\s("'])((?:\/[\w.~+-]+)+)/gu;
|
|
|
14
15
|
const WINDOWS_ABSOLUTE_TOKEN_RE = /(?:^|[\s("'])([A-Za-z]:[\\/][^\s"']+)/gu;
|
|
15
16
|
const BACKSLASH_PATH_RE = /\b[A-Za-z_.-][\w.-]*\\(?:(?:[\w.-]+\\)+[\w.-]+|[\w-]+\.[A-Za-z0-9]{1,8})\b/gu;
|
|
16
17
|
const DOUBLE_SEPARATOR_PATH_RE = /\b[\w.-]+\/\/[\w./-]+/gu;
|
|
18
|
+
const PARENT_PREFIX_RE = /^(?:\.\.\/)+/u;
|
|
17
19
|
|
|
18
20
|
export type DispatchPathProvenanceKind = "declared" | "derived" | "inferred";
|
|
19
21
|
export type DispatchPathConfidence = "certain" | "high" | "medium" | "low";
|
|
@@ -49,11 +51,24 @@ export interface DispatchPathScopeProvenance {
|
|
|
49
51
|
writeBoundaries: DispatchPathProvenanceEntry[];
|
|
50
52
|
}
|
|
51
53
|
|
|
54
|
+
/**
|
|
55
|
+
* A prose token whose leading "../" run inference had to reinterpret, kept so
|
|
56
|
+
* the notice can name the raw token beside the scope it produced. `resolved` is
|
|
57
|
+
* the repository path the stripped remainder anchored to, or null when nothing
|
|
58
|
+
* under the dispatch root carried it and the token took no part in scope.
|
|
59
|
+
*/
|
|
60
|
+
export interface DispatchInferredParentToken {
|
|
61
|
+
token: string;
|
|
62
|
+
resolved: string | null;
|
|
63
|
+
source: "task" | "briefing";
|
|
64
|
+
}
|
|
65
|
+
|
|
52
66
|
export interface DispatchPathScope {
|
|
53
67
|
source: "declared" | "inferred";
|
|
54
68
|
workingContextPaths: ReadonlyArray<string>;
|
|
55
69
|
writeBoundaries: ReadonlyArray<string>;
|
|
56
70
|
inferredOnlyPaths: ReadonlyArray<string>;
|
|
71
|
+
parentTokens: ReadonlyArray<DispatchInferredParentToken>;
|
|
57
72
|
provenance: DispatchPathScopeProvenance;
|
|
58
73
|
}
|
|
59
74
|
|
|
@@ -64,6 +79,19 @@ export interface DeclaredScopeReplacementNotice {
|
|
|
64
79
|
message: string;
|
|
65
80
|
}
|
|
66
81
|
|
|
82
|
+
export interface InferredScopeParentTokenNotice {
|
|
83
|
+
code: "legacy_scope_inferred";
|
|
84
|
+
level: "warning";
|
|
85
|
+
paths: ReadonlyArray<{
|
|
86
|
+
path: string;
|
|
87
|
+
policy: "working-context";
|
|
88
|
+
provenance: "inferred";
|
|
89
|
+
source: "task" | "briefing";
|
|
90
|
+
confidence: "low";
|
|
91
|
+
}>;
|
|
92
|
+
message: string;
|
|
93
|
+
}
|
|
94
|
+
|
|
67
95
|
export type DispatchPathScopeInferenceErrorCode = "legacy_scope_path_absolute" | "legacy_scope_path_malformed";
|
|
68
96
|
|
|
69
97
|
export class DispatchPathScopeInferenceError extends Error {
|
|
@@ -139,19 +167,78 @@ export function declaredIntentPathProvenance(input: {
|
|
|
139
167
|
return sortedEntries(entries);
|
|
140
168
|
}
|
|
141
169
|
|
|
142
|
-
|
|
170
|
+
/** One prose token read as a repository path, as an anchored "../" quote, or as neither. */
|
|
171
|
+
type InferredPathToken =
|
|
172
|
+
| { kind: "token"; token: string }
|
|
173
|
+
| { kind: "anchored"; token: string; resolved: string }
|
|
174
|
+
| { kind: "dropped"; token: string };
|
|
175
|
+
|
|
176
|
+
function inferredPaths(
|
|
177
|
+
req: Pick<DispatchRequest, "task" | "briefing">,
|
|
178
|
+
root: string,
|
|
179
|
+
): { paths: string[]; droppedTokens: string[] } {
|
|
143
180
|
const paths = new Set<string>();
|
|
181
|
+
const droppedTokens = new Set<string>();
|
|
144
182
|
const text = `${req.task}\n${req.briefing ?? ""}`;
|
|
145
183
|
for (const match of text.matchAll(DISPATCH_PATH_TOKEN_RE)) {
|
|
146
|
-
const
|
|
184
|
+
const inferred = inferredPathToken(match[0], root);
|
|
185
|
+
if (inferred.kind === "dropped") {
|
|
186
|
+
droppedTokens.add(inferred.token);
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
const token = inferred.kind === "anchored" ? inferred.resolved : inferred.token;
|
|
147
190
|
if (token.startsWith("http://") || token.startsWith("https://")) continue;
|
|
148
191
|
paths.add(token);
|
|
149
192
|
}
|
|
150
|
-
return [...paths];
|
|
193
|
+
return { paths: [...paths], droppedTokens: [...droppedTokens] };
|
|
151
194
|
}
|
|
152
195
|
|
|
153
|
-
|
|
154
|
-
|
|
196
|
+
/**
|
|
197
|
+
* A leading "./" is how prose quotes an import specifier ("./parser.js"); it
|
|
198
|
+
* names the same repository path without the prefix, and the boundary grammar
|
|
199
|
+
* would otherwise refuse the whole dispatch for a dot segment.
|
|
200
|
+
*
|
|
201
|
+
* A leading "../" run is that same quote copied out of a file whose location
|
|
202
|
+
* this function never sees. Both callers, strictInferredPaths and
|
|
203
|
+
* inferredPaths, are handed the task or briefing text and nothing else, so the
|
|
204
|
+
* origin the run is measured against is unknowable here and no arithmetic on
|
|
205
|
+
* the run's length can decide whether it escapes. What is decidable is whether
|
|
206
|
+
* the remainder names something under the dispatch root, so the run is
|
|
207
|
+
* stripped and the remainder probed: "../src/store.js" quoted out of
|
|
208
|
+
* test/store.test.ts anchors to src/store.js, and "../../../etc/passwd"
|
|
209
|
+
* anchors to nothing in a checkout that holds no etc/passwd.
|
|
210
|
+
*
|
|
211
|
+
* That is a deliberate reading of issue #266, recorded here because it is the
|
|
212
|
+
* one place the choice is made. Criterion 1 ("never rejects the dispatch") and
|
|
213
|
+
* criterion 2 ("a prose token whose .. segments would leave the repository
|
|
214
|
+
* root is still refused") ask for opposite answers on a leading run, and only
|
|
215
|
+
* criterion 1 is decidable without an origin, so a run that names nothing is
|
|
216
|
+
* dropped rather than refused. Neither outcome widens authority: an inferred
|
|
217
|
+
* path selects project rules and compiles context but never becomes a write
|
|
218
|
+
* boundary, and an anchored remainder carries no ".." so path.resolve keeps it
|
|
219
|
+
* under the root. Both outcomes are named to the operator by
|
|
220
|
+
* inferredScopeParentTokenNotice, so the reinterpretation is never silent.
|
|
221
|
+
*
|
|
222
|
+
* The probe costs one existsSync per "../"-leading token (3 microseconds on a
|
|
223
|
+
* hit and 2 on a miss over 5,000 warm calls on this checkout) and no stat at
|
|
224
|
+
* all for the ordinary token, which the grammar matches dozens of per dispatch
|
|
225
|
+
* (the 27 tokens per task measured for REPORTABLE_OMITTED_PATH_RE below).
|
|
226
|
+
*
|
|
227
|
+
* A ".." or "." outside the leading run ("../src/../../b.ts", "../src/./b.ts")
|
|
228
|
+
* walks back out of a segment it already anchored, which is decidable without
|
|
229
|
+
* an origin, so it falls through to the boundary grammar and keeps its
|
|
230
|
+
* refusal, as does a run that leaves no remainder at all ("../..").
|
|
231
|
+
*/
|
|
232
|
+
function inferredPathToken(raw: string, root: string): InferredPathToken {
|
|
233
|
+
const token = raw.replace(/^\.\//u, "").replace(/\.+$/u, "");
|
|
234
|
+
const parents = PARENT_PREFIX_RE.exec(token)?.[0];
|
|
235
|
+
if (parents === undefined) return { kind: "token", token };
|
|
236
|
+
const rest = token.slice(parents.length);
|
|
237
|
+
const segments = rest.split("/");
|
|
238
|
+
if (rest.length === 0 || segments.includes("..") || segments.includes(".")) return { kind: "token", token };
|
|
239
|
+
return existsSync(resolvePathBoundary(root, rest))
|
|
240
|
+
? { kind: "anchored", token, resolved: rest }
|
|
241
|
+
: { kind: "dropped", token };
|
|
155
242
|
}
|
|
156
243
|
|
|
157
244
|
function failMalformedText(text: string, source: "task" | "briefing"): void {
|
|
@@ -188,18 +275,31 @@ function failMalformedText(text: string, source: "task" | "briefing"): void {
|
|
|
188
275
|
function strictInferredPaths(
|
|
189
276
|
text: string,
|
|
190
277
|
source: "task" | "briefing",
|
|
191
|
-
|
|
278
|
+
root: string,
|
|
279
|
+
): {
|
|
280
|
+
paths: Array<{ path: string; evidence: DispatchPathProvenanceEvidence }>;
|
|
281
|
+
parentTokens: DispatchInferredParentToken[];
|
|
282
|
+
} {
|
|
192
283
|
failMalformedText(text, source);
|
|
193
284
|
const withoutUrls = text.replace(HTTP_URL_RE, (url) => " ".repeat(url.length));
|
|
194
285
|
const evidence: DispatchPathProvenanceEvidence =
|
|
195
286
|
source === "task"
|
|
196
287
|
? { provenance: "inferred", source, confidence: "medium", reason: "task_path_token" }
|
|
197
288
|
: { provenance: "inferred", source, confidence: "low", reason: "briefing_path_token" };
|
|
198
|
-
const
|
|
289
|
+
const paths: Array<{ path: string; evidence: DispatchPathProvenanceEvidence }> = [];
|
|
290
|
+
const parentTokens: DispatchInferredParentToken[] = [];
|
|
199
291
|
for (const match of withoutUrls.matchAll(DISPATCH_PATH_TOKEN_RE)) {
|
|
200
|
-
const
|
|
292
|
+
const inferred = inferredPathToken(match[0], root);
|
|
293
|
+
if (inferred.kind === "dropped") {
|
|
294
|
+
parentTokens.push({ token: inferred.token, resolved: null, source });
|
|
295
|
+
continue;
|
|
296
|
+
}
|
|
297
|
+
if (inferred.kind === "anchored") {
|
|
298
|
+
parentTokens.push({ token: inferred.token, resolved: inferred.resolved, source });
|
|
299
|
+
}
|
|
300
|
+
const token = inferred.kind === "anchored" ? inferred.resolved : inferred.token;
|
|
201
301
|
try {
|
|
202
|
-
|
|
302
|
+
paths.push({ path: normalizePathBoundaryEntry(token), evidence });
|
|
203
303
|
} catch (error) {
|
|
204
304
|
const code =
|
|
205
305
|
error instanceof PathBoundaryError && error.code === "absolute"
|
|
@@ -213,7 +313,7 @@ function strictInferredPaths(
|
|
|
213
313
|
);
|
|
214
314
|
}
|
|
215
315
|
}
|
|
216
|
-
return
|
|
316
|
+
return { paths, parentTokens };
|
|
217
317
|
}
|
|
218
318
|
|
|
219
319
|
function legacyPathScope(req: DispatchRequest, cwd: string): DispatchPathScope {
|
|
@@ -229,13 +329,21 @@ function legacyPathScope(req: DispatchRequest, cwd: string): DispatchPathScope {
|
|
|
229
329
|
addProvenance(workingEntries, root, writeEvidence);
|
|
230
330
|
addProvenance(writeEntries, asDirectoryPathBoundary(resolvePathBoundary(cwd, root)), writeEvidence);
|
|
231
331
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
332
|
+
// One map across both fields, first field winning: an orchestrator that
|
|
333
|
+
// restates the file it is asking about quotes the same specifier in the task
|
|
334
|
+
// and in the briefing, and the notice must name it once rather than spend two
|
|
335
|
+
// of its twelve render slots on the same token.
|
|
336
|
+
const parentTokens = new Map<string, DispatchInferredParentToken>();
|
|
337
|
+
const recordParentTokens = (entries: ReadonlyArray<DispatchInferredParentToken>): void => {
|
|
338
|
+
for (const entry of entries) if (!parentTokens.has(entry.token)) parentTokens.set(entry.token, entry);
|
|
339
|
+
};
|
|
340
|
+
const taskScope = strictInferredPaths(req.task, "task", cwd);
|
|
341
|
+
for (const candidate of taskScope.paths) addProvenance(workingEntries, candidate.path, candidate.evidence);
|
|
342
|
+
recordParentTokens(taskScope.parentTokens);
|
|
235
343
|
if (req.briefing !== undefined) {
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
344
|
+
const briefingScope = strictInferredPaths(req.briefing, "briefing", cwd);
|
|
345
|
+
for (const candidate of briefingScope.paths) addProvenance(workingEntries, candidate.path, candidate.evidence);
|
|
346
|
+
recordParentTokens(briefingScope.parentTokens);
|
|
239
347
|
}
|
|
240
348
|
const workingContext = [...workingEntries.values()].map((entry) => ({
|
|
241
349
|
path: entry.path,
|
|
@@ -250,6 +358,7 @@ function legacyPathScope(req: DispatchRequest, cwd: string): DispatchPathScope {
|
|
|
250
358
|
workingContextPaths: workingContext.map((entry) => entry.path),
|
|
251
359
|
writeBoundaries: writeBoundaries.map((entry) => entry.path),
|
|
252
360
|
inferredOnlyPaths: [],
|
|
361
|
+
parentTokens: [...parentTokens.values()],
|
|
253
362
|
provenance: {
|
|
254
363
|
version: 1,
|
|
255
364
|
mode: "legacy-inferred",
|
|
@@ -266,7 +375,15 @@ export function resolveDispatchPathScope(req: DispatchRequest): DispatchPathScop
|
|
|
266
375
|
|
|
267
376
|
const declaredProvenance = declaredIntentPathProvenance(req.intent);
|
|
268
377
|
const declaredPaths = declaredProvenance.map((entry) => entry.path);
|
|
269
|
-
const
|
|
378
|
+
const inferred = inferredPaths(req, cwd);
|
|
379
|
+
// A dropped token cannot be covered by a declaration, so it is always listed.
|
|
380
|
+
// An anchored one is listed under the path it anchored to and goes through
|
|
381
|
+
// the same coverage test the notice has always applied, which is why
|
|
382
|
+
// "../src/store.js" under a declared "src/" stops reading as an omitted path.
|
|
383
|
+
const inferredOnlyPaths = [
|
|
384
|
+
...inferred.paths.filter((candidate) => !pathBoundaryCovers(declaredPaths, candidate)),
|
|
385
|
+
...inferred.droppedTokens,
|
|
386
|
+
];
|
|
270
387
|
const writeEvidence = DECLARED_EVIDENCE.writeRoots;
|
|
271
388
|
const writeBoundaries = req.intent.writeRoots.map((root) => ({
|
|
272
389
|
path: resolvePathBoundary(cwd, root),
|
|
@@ -277,6 +394,11 @@ export function resolveDispatchPathScope(req: DispatchRequest): DispatchPathScop
|
|
|
277
394
|
workingContextPaths: declaredPaths,
|
|
278
395
|
writeBoundaries: writeBoundaries.map((entry) => entry.path),
|
|
279
396
|
inferredOnlyPaths,
|
|
397
|
+
// Empty on purpose: the declaration is the scope here, so no "../" token
|
|
398
|
+
// changed what the worker sees and there is nothing for the legacy notice
|
|
399
|
+
// to report. A dropped one still reaches the operator through
|
|
400
|
+
// inferredOnlyPaths above.
|
|
401
|
+
parentTokens: [],
|
|
280
402
|
provenance: {
|
|
281
403
|
version: 1,
|
|
282
404
|
mode: "declared",
|
|
@@ -286,24 +408,113 @@ export function resolveDispatchPathScope(req: DispatchRequest): DispatchPathScop
|
|
|
286
408
|
};
|
|
287
409
|
}
|
|
288
410
|
|
|
411
|
+
/**
|
|
412
|
+
* The prose token grammar also matches version numbers, ratios, and Latin
|
|
413
|
+
* abbreviations ("0.5", "v24.9", "e.g", "dead/raw"). Those never select a rule
|
|
414
|
+
* or a boundary, so the replacement notice names only tokens that read as
|
|
415
|
+
* repository paths: a segment with a source or document file extension, or
|
|
416
|
+
* a trailing directory separator. Method names (`Store.fromText`, `store.set`)
|
|
417
|
+
* share the dotted shape and are excluded by the extension list. A live three-task dispatch printed 27
|
|
418
|
+
* "omitted paths" per task, most of them numbers, three times over.
|
|
419
|
+
*/
|
|
420
|
+
const REPORTABLE_OMITTED_PATH_RE =
|
|
421
|
+
/\.(?:[cm]?[jt]sx?|json|ya?ml|md|txt|py|go|rs|c|h|cc|cpp|hpp|java|rb|sh|toml|css|html|sql|lock)(?:\/|$)|\/$/u;
|
|
422
|
+
const OMITTED_PATH_REPORT_CAP = 12;
|
|
423
|
+
|
|
424
|
+
/** Omitted prose paths worth telling the operator about, capped for the transcript. */
|
|
425
|
+
function reportableOmittedPaths(scope: DispatchPathScope): string[] {
|
|
426
|
+
return scope.inferredOnlyPaths.filter((path) => REPORTABLE_OMITTED_PATH_RE.test(path));
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
function renderOmittedPaths(paths: ReadonlyArray<string>): string {
|
|
430
|
+
if (paths.length <= OMITTED_PATH_REPORT_CAP) return paths.join(", ");
|
|
431
|
+
return `${paths.slice(0, OMITTED_PATH_REPORT_CAP).join(", ")} and ${paths.length - OMITTED_PATH_REPORT_CAP} more`;
|
|
432
|
+
}
|
|
433
|
+
|
|
289
434
|
/** Render the named diagnostic for the declared-scope replacement tradeoff. */
|
|
290
435
|
export function declaredScopeReplacementDiagnostic(scope: DispatchPathScope): string | null {
|
|
291
|
-
if (scope.source !== "declared"
|
|
292
|
-
|
|
293
|
-
|
|
436
|
+
if (scope.source !== "declared") return null;
|
|
437
|
+
const omitted = reportableOmittedPaths(scope);
|
|
438
|
+
if (omitted.length === 0) return null;
|
|
439
|
+
return `typed_scope_replaced_inferred_paths: typed intent omitted prose-inferred paths ${renderOmittedPaths(
|
|
440
|
+
omitted,
|
|
294
441
|
)}; those paths did not select project rules or expand worker authority`;
|
|
295
442
|
}
|
|
296
443
|
|
|
297
444
|
/** Render the interactive warning for the declared-scope replacement tradeoff. */
|
|
298
445
|
export function declaredScopeReplacementNotice(scope: DispatchPathScope): DeclaredScopeReplacementNotice | null {
|
|
299
|
-
if (scope.source !== "declared"
|
|
300
|
-
const omittedPaths =
|
|
446
|
+
if (scope.source !== "declared") return null;
|
|
447
|
+
const omittedPaths = reportableOmittedPaths(scope);
|
|
448
|
+
if (omittedPaths.length === 0) return null;
|
|
301
449
|
return {
|
|
302
450
|
code: "typed_scope_replaced_inferred_paths",
|
|
303
451
|
level: "warning",
|
|
304
452
|
omittedPaths,
|
|
305
|
-
message: `[dispatch scope] typed intent replaced prose path inference; omitted paths: ${
|
|
306
|
-
|
|
453
|
+
message: `[dispatch scope] typed intent replaced prose path inference; omitted paths: ${renderOmittedPaths(
|
|
454
|
+
omittedPaths,
|
|
307
455
|
)}. Those paths did not select project rules or expand worker authority.`,
|
|
308
456
|
};
|
|
309
457
|
}
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* A reinterpreted "../" token is the one legacy-mode scope fact worth the
|
|
461
|
+
* transcript. It fires only where a leading "../" run made inference choose
|
|
462
|
+
* between a path the prose never literally spelled and no path at all, which
|
|
463
|
+
* before this release failed the whole dispatch, so unlike a per-dispatch
|
|
464
|
+
* inference notice it cannot warn on the ordinary case that
|
|
465
|
+
* `publishDispatchPathScope` deliberately keeps quiet. The anchored token earns
|
|
466
|
+
* the line more than the dropped one: dropping subtracts from scope, while
|
|
467
|
+
* anchoring puts "src/store.js" in working context because prose said
|
|
468
|
+
* "../src/store.js", and a rewrite the operator cannot see is one nobody can
|
|
469
|
+
* check.
|
|
470
|
+
*
|
|
471
|
+
* Declared mode records none. The declaration is the scope there, and a prose
|
|
472
|
+
* token that never entered it is already the subject of
|
|
473
|
+
* `declaredScopeReplacementNotice`. That notice filters by
|
|
474
|
+
* REPORTABLE_OMITTED_PATH_RE, so a declared-mode drop of "../data/blob.bin" or
|
|
475
|
+
* "../src/helper" is in fact named nowhere; that is the accepted cost of not
|
|
476
|
+
* spending a second per-dispatch notice on a token that took no part in a scope
|
|
477
|
+
* the intent had already fixed.
|
|
478
|
+
*
|
|
479
|
+
* The legacy list is not filtered by REPORTABLE_OMITTED_PATH_RE, because the
|
|
480
|
+
* "../" prefix is itself the filter: the version numbers, ratios, and Latin
|
|
481
|
+
* abbreviations that filter exists for ("0.5", "v24.9", "e.g", "4/10") cannot
|
|
482
|
+
* carry one.
|
|
483
|
+
*
|
|
484
|
+
* Both notices render one `<raw token> -> <anchored path or "dropped">` pair
|
|
485
|
+
* per entry, under the same twelve-entry cap the replacement notice uses.
|
|
486
|
+
*/
|
|
487
|
+
function renderParentTokens(tokens: ReadonlyArray<DispatchInferredParentToken>): string {
|
|
488
|
+
return renderOmittedPaths(tokens.map((entry) => `${entry.token} -> ${entry.resolved ?? "dropped"}`));
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
/** Render the named diagnostic for prose tokens whose leading "../" run was reinterpreted. */
|
|
492
|
+
export function inferredScopeParentTokenDiagnostic(scope: DispatchPathScope): string | null {
|
|
493
|
+
const tokens = scope.parentTokens;
|
|
494
|
+
if (tokens.length === 0) return null;
|
|
495
|
+
return `legacy_scope_inferred: prose inference resolved path tokens carrying a leading '../' run against the dispatch root ${renderParentTokens(
|
|
496
|
+
tokens,
|
|
497
|
+
)}; an anchored token selects project rules without expanding worker authority and a dropped one took no part in scope`;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/** Render the interactive warning for prose tokens whose leading "../" run was reinterpreted. */
|
|
501
|
+
export function inferredScopeParentTokenNotice(scope: DispatchPathScope): InferredScopeParentTokenNotice | null {
|
|
502
|
+
const tokens = scope.parentTokens;
|
|
503
|
+
if (tokens.length === 0) return null;
|
|
504
|
+
return {
|
|
505
|
+
code: "legacy_scope_inferred",
|
|
506
|
+
level: "warning",
|
|
507
|
+
// Every entry names the raw prose token, the one spelling both outcomes
|
|
508
|
+
// share; the message carries what each one resolved to.
|
|
509
|
+
paths: tokens.map((entry) => ({
|
|
510
|
+
path: entry.token,
|
|
511
|
+
policy: "working-context",
|
|
512
|
+
provenance: "inferred",
|
|
513
|
+
source: entry.source,
|
|
514
|
+
confidence: "low",
|
|
515
|
+
})),
|
|
516
|
+
message: `[dispatch scope] prose inference resolved path tokens carrying a leading '../' run against the dispatch root: ${renderParentTokens(
|
|
517
|
+
tokens,
|
|
518
|
+
)}. An anchored token selects project rules without expanding worker authority; a dropped one took no part in scope.`,
|
|
519
|
+
};
|
|
520
|
+
}
|
|
@@ -51,9 +51,6 @@ export const RUN_EVENT_JOURNAL_FILE = "events.ndjson";
|
|
|
51
51
|
export const RUN_EVENT_JOURNAL_CAP_BYTES = 2 * 1024 * 1024;
|
|
52
52
|
/** Pending bytes that trigger a flush of droppable lines. */
|
|
53
53
|
export const RUN_EVENT_JOURNAL_FLUSH_BYTES = 8 * 1024;
|
|
54
|
-
/** Per-process env override, resolved ahead of settings (see runEventJournalEnabled). */
|
|
55
|
-
export const RUN_EVENT_JOURNAL_ENV_VAR = "CLIO_CODER_RUN_JOURNAL";
|
|
56
|
-
|
|
57
54
|
interface JournalLineBase {
|
|
58
55
|
seq: number;
|
|
59
56
|
at: string;
|
|
@@ -119,7 +116,7 @@ export interface RunEventJournal extends RunEventJournalSink {
|
|
|
119
116
|
let configuredEnabled: boolean | undefined;
|
|
120
117
|
|
|
121
118
|
/**
|
|
122
|
-
* Install the `
|
|
119
|
+
* Install the `fleet.history.journal` setting. Called from the composition root beside
|
|
123
120
|
* `configureGuardrails` so the journal never reads settings.yaml itself; a
|
|
124
121
|
* settings read on the dispatch event path would be both a cost and a throw
|
|
125
122
|
* site (readSettings rejects an invalid file).
|
|
@@ -128,17 +125,9 @@ export function configureRunEventJournal(enabled: boolean | undefined): void {
|
|
|
128
125
|
configuredEnabled = enabled;
|
|
129
126
|
}
|
|
130
127
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if (normalized === "1" || normalized === "true" || normalized === "on") return true;
|
|
135
|
-
if (normalized === "0" || normalized === "false" || normalized === "off") return false;
|
|
136
|
-
return undefined;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/** env override > configured settings > on. */
|
|
140
|
-
function runEventJournalEnabled(env: NodeJS.ProcessEnv = process.env): boolean {
|
|
141
|
-
return parseEnvFlag(env[RUN_EVENT_JOURNAL_ENV_VAR]) ?? configuredEnabled ?? true;
|
|
128
|
+
/** Effective settings projection, then the shipped default. */
|
|
129
|
+
function runEventJournalEnabled(): boolean {
|
|
130
|
+
return configuredEnabled ?? true;
|
|
142
131
|
}
|
|
143
132
|
|
|
144
133
|
// ---------------------------------------------------------------------------
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* receipts/<runId>.json per-run RunReceipt
|
|
7
7
|
*
|
|
8
8
|
* The ledger holds an in-memory mirror of runs.json. `create()` and `update()`
|
|
9
|
-
* mutate memory only; `persist()` writes the bounded ring (default
|
|
10
|
-
*
|
|
9
|
+
* mutate memory only; `persist()` writes the settings-bounded ring (default
|
|
10
|
+
* 1000) atomically via engine.atomicWrite.
|
|
11
11
|
*
|
|
12
12
|
* No worker spawning, no domain wire-up, no SafeEventBus emission yet. Those
|
|
13
13
|
* land in P6S3 and P6S5. This slice is a pure persistence primitive.
|
|
@@ -159,7 +159,6 @@ function readRuns(): RunEnvelope[] {
|
|
|
159
159
|
|
|
160
160
|
function resolveMaxRuns(opt?: number | undefined): number {
|
|
161
161
|
if (opt !== undefined && opt > 0) return Math.floor(opt);
|
|
162
|
-
// env (CLIO_CODER_MAX_DISPATCH_RUNS) > settings guardrails > default; see core/guardrails.ts.
|
|
163
162
|
return resolveGuardrail("maxDispatchRuns");
|
|
164
163
|
}
|
|
165
164
|
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
*
|
|
11
11
|
* SSH tier invariants:
|
|
12
12
|
* - The remote environment is a whitelist, never the orchestrator's
|
|
13
|
-
* process.env. Remote workers default to
|
|
14
|
-
* worker on a node that serves models for the operator can never
|
|
15
|
-
* resident model.
|
|
13
|
+
* process.env. Remote workers default to a user-managed target lifecycle
|
|
14
|
+
* so a worker on a node that serves models for the operator can never
|
|
15
|
+
* evict a resident model.
|
|
16
16
|
* - The orchestrator cwd is entered on the remote node (shared-filesystem
|
|
17
17
|
* assumption; path parity is a doctor preflight, and placement refuses
|
|
18
18
|
* nodes that have not passed it).
|
|
@@ -62,9 +62,9 @@ export interface SshNodeEndpoint {
|
|
|
62
62
|
*/
|
|
63
63
|
clioCoderEntry?: string;
|
|
64
64
|
/**
|
|
65
|
-
* Residency posture
|
|
66
|
-
* remote workers must never evict models resident on
|
|
67
|
-
* is an explicit per-node opt-in.
|
|
65
|
+
* Residency posture projected into the remote worker's target lifecycle.
|
|
66
|
+
* Defaults to "observe": remote workers must never evict models resident on
|
|
67
|
+
* their node. "manage" is an explicit per-node opt-in.
|
|
68
68
|
*/
|
|
69
69
|
residency?: "observe" | "manage";
|
|
70
70
|
connectTimeoutSec?: number;
|
|
@@ -99,14 +99,33 @@ const DEFAULT_REMOTE_CLIO_ENTRY = "clio-coder worker";
|
|
|
99
99
|
* orchestrator-supplied credential.
|
|
100
100
|
*/
|
|
101
101
|
function remoteEnvAssignments(node: SshNodeEndpoint): string {
|
|
102
|
-
const residency = node.residency ?? "observe";
|
|
103
102
|
// `$$` is the login shell's pid, and it leads the process group the remote
|
|
104
103
|
// command runs in. `exec` replaces that shell in place, so the worker
|
|
105
104
|
// inherits both the pid and the group leadership, and the value it announces
|
|
106
105
|
// is the group an abort must signal.
|
|
107
106
|
const labels = (node.labels ?? []).map((label) => label.trim()).filter((label) => label.length > 0);
|
|
108
107
|
const labelAssignment = labels.length > 0 ? ` CLIO_CODER_WORKER_LABELS=${shellQuote(labels.join(","))}` : "";
|
|
109
|
-
return `AI_AGENT=${AI_AGENT_NAME}
|
|
108
|
+
return `AI_AGENT=${AI_AGENT_NAME} CLIO_CODER_WORKER_PGID=$$${labelAssignment}`;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
type TargetLifecycle = NonNullable<WorkerSpec["target"]["lifecycle"]>;
|
|
112
|
+
|
|
113
|
+
export function resolveSshTargetLifecycle(
|
|
114
|
+
residency: SshNodeEndpoint["residency"],
|
|
115
|
+
targetLifecycle: WorkerSpec["target"]["lifecycle"],
|
|
116
|
+
): TargetLifecycle {
|
|
117
|
+
if (targetLifecycle === "user-managed" || residency !== "manage") return "user-managed";
|
|
118
|
+
return "clio-coder-managed";
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function workerSpecForSshNode(node: SshNodeEndpoint, spec: WorkerSpec): WorkerSpec {
|
|
122
|
+
return {
|
|
123
|
+
...spec,
|
|
124
|
+
target: {
|
|
125
|
+
...spec.target,
|
|
126
|
+
lifecycle: resolveSshTargetLifecycle(node.residency, spec.target.lifecycle),
|
|
127
|
+
},
|
|
128
|
+
};
|
|
110
129
|
}
|
|
111
130
|
|
|
112
131
|
function buildRemoteWorkerCommand(node: SshNodeEndpoint, cwd: string): string {
|
|
@@ -174,20 +193,25 @@ export function createSshWorkerTransport(node: SshNodeEndpoint, opts?: SshTransp
|
|
|
174
193
|
// are the transport's own and compose with the caller's rather than
|
|
175
194
|
// replacing them; every other option is forwarded as handed.
|
|
176
195
|
const { cwd: _consumedCwd, onAnnounce, onForcedKill, ...forwarded } = spawnOpts ?? {};
|
|
177
|
-
return spawnWorkerProcess(
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
196
|
+
return spawnWorkerProcess(
|
|
197
|
+
sshBinary,
|
|
198
|
+
buildSshArgs(node, buildRemoteWorkerCommand(node, cwd)),
|
|
199
|
+
workerSpecForSshNode(node, spec),
|
|
200
|
+
{
|
|
201
|
+
...(opts?.shutdownGraceMs !== undefined ? { shutdownGraceMs: opts.shutdownGraceMs } : {}),
|
|
202
|
+
...forwarded,
|
|
203
|
+
env: process.env,
|
|
204
|
+
onAnnounce: (attestation) => {
|
|
205
|
+
remote.pid = attestation.pid;
|
|
206
|
+
remote.processGroupId = attestation.processGroupId;
|
|
207
|
+
onAnnounce?.(attestation);
|
|
208
|
+
},
|
|
209
|
+
onForcedKill: () => {
|
|
210
|
+
killRemote();
|
|
211
|
+
onForcedKill?.();
|
|
212
|
+
},
|
|
189
213
|
},
|
|
190
|
-
|
|
214
|
+
);
|
|
191
215
|
},
|
|
192
216
|
};
|
|
193
217
|
}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* are pure data: no class methods, no engine refs.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
import type { GatewayRoutingObservation } from "../../core/gateway-routing.js";
|
|
9
10
|
import type { ResponseModelIdObservation } from "../../core/response-model-id.js";
|
|
10
11
|
import type { SkillActivation } from "../../core/skill-activation.js";
|
|
11
12
|
import type { ToolProfileName } from "../../tools/profiles.js";
|
|
@@ -584,7 +585,7 @@ export interface RunReceiptSafetySummary {
|
|
|
584
585
|
* (reason code `guard_block`); a call that required permission and was denied
|
|
585
586
|
* non-interactively is counted under `permissionRequested`, not `blocked`, so
|
|
586
587
|
* scripts can tell "approval would have been needed" apart from a policy
|
|
587
|
-
* block (see docs/safety-model.md). Such a call still appears in
|
|
588
|
+
* block (see docs/architecture/safety-model.md). Such a call still appears in
|
|
588
589
|
* `blockedAttempts` because its outcome was blocked, so `decisions.blocked`
|
|
589
590
|
* is not a proxy for the number of blocked attempts; use `blockedAttempts`
|
|
590
591
|
* or the `toolStats`/`toolActivity` blocked counts for that.
|
|
@@ -652,6 +653,8 @@ export interface RunReceiptUpstreamResponse {
|
|
|
652
653
|
responseModelIdObservation: ResponseModelIdObservation;
|
|
653
654
|
differingResponseModelId: string | null;
|
|
654
655
|
providerResponseId: string | null;
|
|
656
|
+
/** Physical route and proxy attempts reported by LiteLLM, when this call used that gateway. */
|
|
657
|
+
gatewayRouting?: GatewayRoutingObservation;
|
|
655
658
|
}
|
|
656
659
|
|
|
657
660
|
/**
|
|
@@ -712,14 +715,66 @@ export interface RunHostVerificationCheck {
|
|
|
712
715
|
memo: boolean;
|
|
713
716
|
outputTail: string;
|
|
714
717
|
artifactPath?: string;
|
|
715
|
-
/**
|
|
718
|
+
/** Run that owns the evidence when it did not come from this run: a memo hit, or the batch member the shared check ran under. */
|
|
716
719
|
evidenceRunId?: string;
|
|
717
720
|
}
|
|
718
721
|
|
|
722
|
+
/**
|
|
723
|
+
* Why a batch-settled failing check was or was not charged to a run. It is a
|
|
724
|
+
* batch-wide fact and is sealed identically on every receipt in the batch; each
|
|
725
|
+
* receipt's own `status` is what that run is judged by.
|
|
726
|
+
*/
|
|
727
|
+
export interface RunHostVerificationAttribution {
|
|
728
|
+
/** Declared check id that failed. */
|
|
729
|
+
check: string;
|
|
730
|
+
/**
|
|
731
|
+
* Absolute repository paths the check's own output named, capped at 32. The
|
|
732
|
+
* paths that decided the charge come first so a truncated list still contains
|
|
733
|
+
* the evidence behind the verdict; each group is sorted.
|
|
734
|
+
*/
|
|
735
|
+
implicated: string[];
|
|
736
|
+
/** Run ids the failure is charged to, sorted; empty when every named path belongs to a run that did not declare the check. */
|
|
737
|
+
charged: string[];
|
|
738
|
+
/**
|
|
739
|
+
* The weakest evidence behind the charge set, never the strongest, so the
|
|
740
|
+
* record cannot claim a certainty it does not have.
|
|
741
|
+
*
|
|
742
|
+
* `write_roots`: every charged run has an implicated path inside its own
|
|
743
|
+
* declared write roots. `attributed_elsewhere`: nothing is charged because
|
|
744
|
+
* every implicated path falls inside the write roots of a live batch member
|
|
745
|
+
* that did not declare this check. `unattributable`: the charge is not backed
|
|
746
|
+
* by per-run path evidence, which covers a failure that named no path, one
|
|
747
|
+
* that named only paths no member claims, and one charged to a run that
|
|
748
|
+
* declared no write roots at all. The first two of those charge every run that
|
|
749
|
+
* declared the check: a real failure with no owner is charged to everyone
|
|
750
|
+
* rather than excused for everyone.
|
|
751
|
+
*/
|
|
752
|
+
basis: "write_roots" | "attributed_elsewhere" | "unattributable";
|
|
753
|
+
}
|
|
754
|
+
|
|
719
755
|
export interface RunHostVerification {
|
|
720
|
-
|
|
756
|
+
/**
|
|
757
|
+
* `verified` states that every declared check passed, which is the claim
|
|
758
|
+
* `trust-status.ts:619` turns into "validated by host-verification".
|
|
759
|
+
* `not_implicated` is the batch-settled exculpation: a declared check failed
|
|
760
|
+
* for the batch and this run's `checks` carries its non-zero exit code, but
|
|
761
|
+
* the failure was charged elsewhere, so no validator speaks for this run.
|
|
762
|
+
*/
|
|
763
|
+
status: "verified" | "rejected" | "skipped" | "not_implicated";
|
|
721
764
|
reason?: string;
|
|
722
765
|
checks: RunHostVerificationCheck[];
|
|
766
|
+
/**
|
|
767
|
+
* How the declared checks were run. Absent means the single-run strategy every
|
|
768
|
+
* receipt carried before batch settlement existed: the checks ran for this run
|
|
769
|
+
* alone, straight after it finished. `batch-settled` means they ran once for
|
|
770
|
+
* the whole parallel batch after every live member had finished. The field is
|
|
771
|
+
* omitted rather than stamped `"single"` so a single-task receipt digests
|
|
772
|
+
* exactly as it did before (`receipt-integrity.ts:145-147` is the same
|
|
773
|
+
* reasoning applied one field over).
|
|
774
|
+
*/
|
|
775
|
+
strategy?: "batch-settled";
|
|
776
|
+
/** Per-failing-check attribution for a batch-settled run; absent when nothing failed. */
|
|
777
|
+
attribution?: RunHostVerificationAttribution[];
|
|
723
778
|
}
|
|
724
779
|
|
|
725
780
|
export interface RunReceipt {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ProvidersContract } from "../providers/contract.js";
|
|
2
|
+
|
|
3
|
+
/** Preparation owns its wait; a late HTTP body cannot start an expired worker. */
|
|
4
|
+
export async function prepareWorkerModelMetadata(
|
|
5
|
+
providers: ProvidersContract,
|
|
6
|
+
targetId: string,
|
|
7
|
+
deadlineAt: number,
|
|
8
|
+
signal?: AbortSignal,
|
|
9
|
+
now: () => number = Date.now,
|
|
10
|
+
): Promise<void> {
|
|
11
|
+
signal?.throwIfAborted();
|
|
12
|
+
const status = providers.list().find((entry) => entry.target.id === targetId);
|
|
13
|
+
if (status?.target.runtime !== "litellm" || status.health.lastCheckAt !== null) return;
|
|
14
|
+
const remainingMs = deadlineAt - now();
|
|
15
|
+
const deadlineError = new Error("dispatch: admission deadline expired during worker model metadata preparation");
|
|
16
|
+
if (remainingMs <= 0) throw deadlineError;
|
|
17
|
+
const controller = new AbortController();
|
|
18
|
+
const abort = (): void => controller.abort(signal?.reason);
|
|
19
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
20
|
+
const timer = setTimeout(() => controller.abort(deadlineError), Math.min(remainingMs, 2_147_483_647));
|
|
21
|
+
let rejectAborted!: (reason: unknown) => void;
|
|
22
|
+
const aborted = new Promise<never>((_resolve, reject) => {
|
|
23
|
+
rejectAborted = reject;
|
|
24
|
+
});
|
|
25
|
+
const onAbort = (): void => rejectAborted(controller.signal.reason);
|
|
26
|
+
controller.signal.addEventListener("abort", onAbort, { once: true });
|
|
27
|
+
try {
|
|
28
|
+
// The provider also fences publication after each await. Promise.race
|
|
29
|
+
// observes the probe's eventual rejection if an HTTP body settles late.
|
|
30
|
+
await Promise.race([providers.probeTarget(targetId, { reasoning: false, signal: controller.signal }), aborted]);
|
|
31
|
+
controller.signal.throwIfAborted();
|
|
32
|
+
if (now() >= deadlineAt) throw deadlineError;
|
|
33
|
+
} finally {
|
|
34
|
+
clearTimeout(timer);
|
|
35
|
+
signal?.removeEventListener("abort", abort);
|
|
36
|
+
controller.signal.removeEventListener("abort", onAbort);
|
|
37
|
+
}
|
|
38
|
+
}
|