@svenroth-ai/shipwright 0.26.0 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/dist/assets/{EmbeddedTerminal-D3wpPNZP.js → EmbeddedTerminal-4xgNUBUu.js} +19 -19
- package/client/dist/assets/{abnfDiagram-VRR7QNED-BkLIltB3.js → abnfDiagram-VRR7QNED-BdCNbaqc.js} +1 -1
- package/client/dist/assets/{arc-Sw-Gh0nI.js → arc-DoZTTE1N.js} +1 -1
- package/client/dist/assets/{architectureDiagram-ZJ3FMSHR-rdxUi9Ks.js → architectureDiagram-ZJ3FMSHR-DFTG4KtO.js} +1 -1
- package/client/dist/assets/{blockDiagram-677ZJIJ3-Ch_9dj8a.js → blockDiagram-677ZJIJ3-C34UBjOB.js} +1 -1
- package/client/dist/assets/{c4Diagram-LMCZKHZV-CkFlO65x.js → c4Diagram-LMCZKHZV-CbqAB1Ou.js} +1 -1
- package/client/dist/assets/channel-DBcZw7Kn.js +1 -0
- package/client/dist/assets/{chunk-2Q5K7J3B-CypX83xu.js → chunk-2Q5K7J3B-4N6AnmBJ.js} +1 -1
- package/client/dist/assets/{chunk-32BRIVSS-DxVLYGdl.js → chunk-32BRIVSS-Cs67LiCy.js} +1 -1
- package/client/dist/assets/{chunk-5VM5RSS4-Cxk1evhx.js → chunk-5VM5RSS4-Bwd7rtD3.js} +1 -1
- package/client/dist/assets/{chunk-EX3LRPZG-n9q5S4yJ.js → chunk-EX3LRPZG-CQqGfptD.js} +1 -1
- package/client/dist/assets/{chunk-JWPE2WC7-jeL4xvir.js → chunk-JWPE2WC7-ClvKd4PN.js} +1 -1
- package/client/dist/assets/{chunk-MOJQB5TN-DDSHN0cj.js → chunk-MOJQB5TN-Cwvj8GE1.js} +1 -1
- package/client/dist/assets/{chunk-RYQCIY6F-C0bo383g.js → chunk-RYQCIY6F-DrWMx37d.js} +1 -1
- package/client/dist/assets/{chunk-V7JOEXUC-C0jDXXAU.js → chunk-V7JOEXUC-CYFfa4PY.js} +1 -1
- package/client/dist/assets/{chunk-VR4S4FIN-h-Rr4Pn2.js → chunk-VR4S4FIN-B5eWtesm.js} +1 -1
- package/client/dist/assets/{chunk-XXDRQBXY-BexSo0-s.js → chunk-XXDRQBXY-BQAZ6Our.js} +1 -1
- package/client/dist/assets/classDiagram-OUVF2IWQ-C3Q1V9DU.js +1 -0
- package/client/dist/assets/classDiagram-v2-EOCWNBFH-C3Q1V9DU.js +1 -0
- package/client/dist/assets/{cose-bilkent-JH36ORCC-BQXzaioj.js → cose-bilkent-JH36ORCC-C76Yia6h.js} +1 -1
- package/client/dist/assets/{cynefin-VYW2F7L2-BJIofhfe.js → cynefin-VYW2F7L2-pJe7rdTi.js} +1 -1
- package/client/dist/assets/{cynefinDiagram-TSTJHNR4-DmPqTM1T.js → cynefinDiagram-TSTJHNR4-EeHQ7dYV.js} +1 -1
- package/client/dist/assets/{dagre-VKFMJZFB-1xljvw6X.js → dagre-VKFMJZFB-VXOY6IHR.js} +1 -1
- package/client/dist/assets/{diagram-FQU43EPY-iyL9muCG.js → diagram-FQU43EPY-DW_-leqw.js} +1 -1
- package/client/dist/assets/{diagram-G47NLZAW-DREp2Th6.js → diagram-G47NLZAW-C_hsLD4u.js} +1 -1
- package/client/dist/assets/{diagram-NH7WQ7WH-h0X3Is2S.js → diagram-NH7WQ7WH-CbeQuO_f.js} +1 -1
- package/client/dist/assets/{diagram-OA4YK3LP-Bj8YZRFJ.js → diagram-OA4YK3LP-DRHY5d_c.js} +1 -1
- package/client/dist/assets/{diagram-WEI45ONY-BZOf805d.js → diagram-WEI45ONY-B87OYR_S.js} +1 -1
- package/client/dist/assets/{ebnfDiagram-CCIWWBDH-DO5JnXda.js → ebnfDiagram-CCIWWBDH-B8Z8WHF6.js} +1 -1
- package/client/dist/assets/{erDiagram-Q63AITRT-DRgcqg1T.js → erDiagram-Q63AITRT-DaD7oa9H.js} +1 -1
- package/client/dist/assets/{flowDiagram-23GEKE2U-C3J9QmrW.js → flowDiagram-23GEKE2U-GrMVpsea.js} +1 -1
- package/client/dist/assets/{ganttDiagram-NO4QXBWP-BIEl3Tkm.js → ganttDiagram-NO4QXBWP-K3X0DYBa.js} +1 -1
- package/client/dist/assets/{gitGraphDiagram-IHSO6WYX-BNF0tFWC.js → gitGraphDiagram-IHSO6WYX-B2SEx0xa.js} +1 -1
- package/client/dist/assets/index-CIpLt0ie.js +863 -0
- package/client/dist/assets/index-DGtnTeFd.css +1 -0
- package/client/dist/assets/{infoDiagram-FWYZ7A6U-DEyFxiyY.js → infoDiagram-FWYZ7A6U-Fi8fQ95G.js} +1 -1
- package/client/dist/assets/{ishikawaDiagram-FXEZZL3T-B_ehlg3I.js → ishikawaDiagram-FXEZZL3T-CrN7QJzt.js} +1 -1
- package/client/dist/assets/{journeyDiagram-5HDEW3XC-Dp00FyJS.js → journeyDiagram-5HDEW3XC-XHIsl7rM.js} +1 -1
- package/client/dist/assets/{kanban-definition-HUTT4EX6-CTAf16q8.js → kanban-definition-HUTT4EX6-A6HJqHw7.js} +1 -1
- package/client/dist/assets/{linear-9vNUgmYd.js → linear-D1vF9IQB.js} +1 -1
- package/client/dist/assets/{mermaid.core-A6tjaEVD.js → mermaid.core-D6w9zlA0.js} +4 -4
- package/client/dist/assets/{mindmap-definition-LN4V7U3C-DRW3bmCY.js → mindmap-definition-LN4V7U3C-CxRkUj6Z.js} +1 -1
- package/client/dist/assets/{pegDiagram-2B236MQR-DJFCjHp2.js → pegDiagram-2B236MQR-Bs9dp-8a.js} +1 -1
- package/client/dist/assets/{pieDiagram-ENE6RG2P-KRd-sGvC.js → pieDiagram-ENE6RG2P-DBWILzB8.js} +1 -1
- package/client/dist/assets/{quadrantDiagram-ABIIQ3AL-9TLZE3Hu.js → quadrantDiagram-ABIIQ3AL-DrCVJJx6.js} +1 -1
- package/client/dist/assets/{railroadDiagram-RFXS5EU6-y4tLtjXg.js → railroadDiagram-RFXS5EU6-BdPW2dNf.js} +1 -1
- package/client/dist/assets/{requirementDiagram-TGXJPOKE-B9EOQDQM.js → requirementDiagram-TGXJPOKE-Bj_g3tC5.js} +1 -1
- package/client/dist/assets/{sankeyDiagram-HTMAVEWB-zfwiDzkT.js → sankeyDiagram-HTMAVEWB-BGL9NnsS.js} +1 -1
- package/client/dist/assets/{sequenceDiagram-DBY2YBRQ-DW1LWepL.js → sequenceDiagram-DBY2YBRQ-DEirxTZY.js} +1 -1
- package/client/dist/assets/{sizeCapture-X5ZJPWSS-BM81Mik0.js → sizeCapture-X5ZJPWSS-BtLrvrea.js} +1 -1
- package/client/dist/assets/{stateDiagram-2N3HPSRC-D0EMIw1w.js → stateDiagram-2N3HPSRC-D3GXIouX.js} +1 -1
- package/client/dist/assets/stateDiagram-v2-6OUMAXLB-D3lXe_mJ.js +1 -0
- package/client/dist/assets/{swimlanes-5IMT3BWC-CKXNCX6M.js → swimlanes-5IMT3BWC-PMRQzNhU.js} +2 -2
- package/client/dist/assets/swimlanesDiagram-G3AALYLV-DMLbRFiO.js +8 -0
- package/client/dist/assets/{timeline-definition-FHXFAJF6-ByzIfvL5.js → timeline-definition-FHXFAJF6-CnBKJtD_.js} +1 -1
- package/client/dist/assets/{vennDiagram-L72KCM5P-Xep38xBH.js → vennDiagram-L72KCM5P-BYmiJYoh.js} +1 -1
- package/client/dist/assets/{wardleyDiagram-EHGQE667-DKWDpx6g.js → wardleyDiagram-EHGQE667-DU7vW8q3.js} +1 -1
- package/client/dist/assets/{xychartDiagram-FW5EYKEG-BGcwZTnu.js → xychartDiagram-FW5EYKEG-BEtPvBSU.js} +1 -1
- package/client/dist/index.html +2 -2
- package/lib/preflight.mjs +24 -5
- package/lib/probes.mjs +10 -4
- package/lib/server.mjs +149 -12
- package/lib/util.mjs +5 -1
- package/package.json +1 -1
- package/scripts/deploy-procs.mjs +105 -20
- package/scripts/deploy-swap.mjs +23 -2
- package/server/dist/config.d.ts +9 -0
- package/server/dist/config.d.ts.map +1 -1
- package/server/dist/config.js +1 -0
- package/server/dist/config.js.map +1 -1
- package/server/dist/core/campaign-events.d.ts.map +1 -1
- package/server/dist/core/campaign-events.js +1 -0
- package/server/dist/core/campaign-events.js.map +1 -1
- package/server/dist/core/campaign-loop-state.d.ts.map +1 -1
- package/server/dist/core/campaign-loop-state.js +54 -21
- package/server/dist/core/campaign-loop-state.js.map +1 -1
- package/server/dist/core/campaign-parse.d.ts +4 -0
- package/server/dist/core/campaign-parse.d.ts.map +1 -1
- package/server/dist/core/campaign-parse.js +9 -0
- package/server/dist/core/campaign-parse.js.map +1 -1
- package/server/dist/core/campaign-readiness-schema.d.ts +33 -0
- package/server/dist/core/campaign-readiness-schema.d.ts.map +1 -0
- package/server/dist/core/campaign-readiness-schema.js +70 -0
- package/server/dist/core/campaign-readiness-schema.js.map +1 -0
- package/server/dist/core/campaign-readiness.d.ts +59 -0
- package/server/dist/core/campaign-readiness.d.ts.map +1 -0
- package/server/dist/core/campaign-readiness.js +163 -0
- package/server/dist/core/campaign-readiness.js.map +1 -0
- package/server/dist/core/campaign-status-json.d.ts +3 -0
- package/server/dist/core/campaign-status-json.d.ts.map +1 -1
- package/server/dist/core/campaign-status-json.js +7 -0
- package/server/dist/core/campaign-status-json.js.map +1 -1
- package/server/dist/core/campaign-store.d.ts.map +1 -1
- package/server/dist/core/campaign-store.js +4 -1
- package/server/dist/core/campaign-store.js.map +1 -1
- package/server/dist/core/campaign-types.d.ts +8 -0
- package/server/dist/core/campaign-types.d.ts.map +1 -1
- package/server/dist/core/campaign-worktree-root.d.ts +19 -0
- package/server/dist/core/campaign-worktree-root.d.ts.map +1 -0
- package/server/dist/core/campaign-worktree-root.js +76 -0
- package/server/dist/core/campaign-worktree-root.js.map +1 -0
- package/server/dist/core/claim-record-lock.d.ts +30 -0
- package/server/dist/core/claim-record-lock.d.ts.map +1 -0
- package/server/dist/core/claim-record-lock.js +90 -0
- package/server/dist/core/claim-record-lock.js.map +1 -0
- package/server/dist/core/cli-child-spawn.d.ts +28 -0
- package/server/dist/core/cli-child-spawn.d.ts.map +1 -0
- package/server/dist/core/cli-child-spawn.js +146 -0
- package/server/dist/core/cli-child-spawn.js.map +1 -0
- package/server/dist/core/codex-models-probe.d.ts +46 -0
- package/server/dist/core/codex-models-probe.d.ts.map +1 -0
- package/server/dist/core/codex-models-probe.js +103 -0
- package/server/dist/core/codex-models-probe.js.map +1 -0
- package/server/dist/core/codex-oracle-runner.d.ts +68 -0
- package/server/dist/core/codex-oracle-runner.d.ts.map +1 -0
- package/server/dist/core/codex-oracle-runner.js +124 -0
- package/server/dist/core/codex-oracle-runner.js.map +1 -0
- package/server/dist/core/codex-status-report.d.ts +6 -0
- package/server/dist/core/codex-status-report.d.ts.map +1 -0
- package/server/dist/core/codex-status-report.js +40 -0
- package/server/dist/core/codex-status-report.js.map +1 -0
- package/server/dist/core/codex-task-watcher-types.d.ts +69 -0
- package/server/dist/core/codex-task-watcher-types.d.ts.map +1 -0
- package/server/dist/core/codex-task-watcher-types.js +12 -0
- package/server/dist/core/codex-task-watcher-types.js.map +1 -0
- package/server/dist/core/codex-task-watcher.d.ts +30 -0
- package/server/dist/core/codex-task-watcher.d.ts.map +1 -0
- package/server/dist/core/codex-task-watcher.js +252 -0
- package/server/dist/core/codex-task-watcher.js.map +1 -0
- package/server/dist/core/codex-terminal-signal-detect.d.ts +7 -0
- package/server/dist/core/codex-terminal-signal-detect.d.ts.map +1 -0
- package/server/dist/core/codex-terminal-signal-detect.js +113 -0
- package/server/dist/core/codex-terminal-signal-detect.js.map +1 -0
- package/server/dist/core/codex-thread-discovery.d.ts +21 -0
- package/server/dist/core/codex-thread-discovery.d.ts.map +1 -0
- package/server/dist/core/codex-thread-discovery.js +169 -0
- package/server/dist/core/codex-thread-discovery.js.map +1 -0
- package/server/dist/core/codextender-auth-file-sweep.d.ts +41 -0
- package/server/dist/core/codextender-auth-file-sweep.d.ts.map +1 -0
- package/server/dist/core/codextender-auth-file-sweep.js +97 -0
- package/server/dist/core/codextender-auth-file-sweep.js.map +1 -0
- package/server/dist/core/codextender-proxy-probe.d.ts +80 -0
- package/server/dist/core/codextender-proxy-probe.d.ts.map +1 -0
- package/server/dist/core/codextender-proxy-probe.js +179 -0
- package/server/dist/core/codextender-proxy-probe.js.map +1 -0
- package/server/dist/core/contract-version.d.ts +16 -1
- package/server/dist/core/contract-version.d.ts.map +1 -1
- package/server/dist/core/contract-version.js +16 -1
- package/server/dist/core/contract-version.js.map +1 -1
- package/server/dist/core/launcher-codex.d.ts +61 -0
- package/server/dist/core/launcher-codex.d.ts.map +1 -0
- package/server/dist/core/launcher-codex.js +187 -0
- package/server/dist/core/launcher-codex.js.map +1 -0
- package/server/dist/core/launcher-codextender-env.d.ts +44 -0
- package/server/dist/core/launcher-codextender-env.d.ts.map +1 -0
- package/server/dist/core/launcher-codextender-env.js +212 -0
- package/server/dist/core/launcher-codextender-env.js.map +1 -0
- package/server/dist/core/launcher-codextender.d.ts +72 -0
- package/server/dist/core/launcher-codextender.d.ts.map +1 -0
- package/server/dist/core/launcher-codextender.js +98 -0
- package/server/dist/core/launcher-codextender.js.map +1 -0
- package/server/dist/core/launcher-codextender.smoke-helpers.d.ts +25 -0
- package/server/dist/core/launcher-codextender.smoke-helpers.d.ts.map +1 -0
- package/server/dist/core/launcher-codextender.smoke-helpers.js +211 -0
- package/server/dist/core/launcher-codextender.smoke-helpers.js.map +1 -0
- package/server/dist/core/launcher-permission-flags.d.ts +17 -0
- package/server/dist/core/launcher-permission-flags.d.ts.map +1 -0
- package/server/dist/core/launcher-permission-flags.js +27 -0
- package/server/dist/core/launcher-permission-flags.js.map +1 -0
- package/server/dist/core/launcher.d.ts +18 -0
- package/server/dist/core/launcher.d.ts.map +1 -1
- package/server/dist/core/launcher.js +6 -0
- package/server/dist/core/launcher.js.map +1 -1
- package/server/dist/core/leadwright-preflight-transport.d.ts +27 -0
- package/server/dist/core/leadwright-preflight-transport.d.ts.map +1 -0
- package/server/dist/core/leadwright-preflight-transport.js +124 -0
- package/server/dist/core/leadwright-preflight-transport.js.map +1 -0
- package/server/dist/core/mission-context/artifacts-tests-ac.d.ts +6 -0
- package/server/dist/core/mission-context/artifacts-tests-ac.d.ts.map +1 -0
- package/server/dist/core/mission-context/artifacts-tests-ac.js +31 -0
- package/server/dist/core/mission-context/artifacts-tests-ac.js.map +1 -0
- package/server/dist/core/mission-context/artifacts-tests.d.ts.map +1 -1
- package/server/dist/core/mission-context/artifacts-tests.js +20 -0
- package/server/dist/core/mission-context/artifacts-tests.js.map +1 -1
- package/server/dist/core/mission-context/resolver-io.d.ts +10 -0
- package/server/dist/core/mission-context/resolver-io.d.ts.map +1 -1
- package/server/dist/core/mission-context/resolver-parts.d.ts +8 -7
- package/server/dist/core/mission-context/resolver-parts.d.ts.map +1 -1
- package/server/dist/core/mission-context/resolver-parts.js +22 -14
- package/server/dist/core/mission-context/resolver-parts.js.map +1 -1
- package/server/dist/core/mission-context/resolver.d.ts.map +1 -1
- package/server/dist/core/mission-context/resolver.js +1 -1
- package/server/dist/core/mission-context/resolver.js.map +1 -1
- package/server/dist/core/mission-context/run-id-recovery.d.ts +18 -2
- package/server/dist/core/mission-context/run-id-recovery.d.ts.map +1 -1
- package/server/dist/core/mission-context/run-id-recovery.js +38 -18
- package/server/dist/core/mission-context/run-id-recovery.js.map +1 -1
- package/server/dist/core/mission-context/traceability.d.ts.map +1 -1
- package/server/dist/core/mission-context/traceability.js +15 -1
- package/server/dist/core/mission-context/traceability.js.map +1 -1
- package/server/dist/core/mission-context/types-slice2.d.ts +44 -0
- package/server/dist/core/mission-context/types-slice2.d.ts.map +1 -1
- package/server/dist/core/model-tier-config-reader.d.ts +14 -1
- package/server/dist/core/model-tier-config-reader.d.ts.map +1 -1
- package/server/dist/core/model-tier-config-reader.js +34 -2
- package/server/dist/core/model-tier-config-reader.js.map +1 -1
- package/server/dist/core/powershell-probe.smoke-helpers.d.ts +12 -0
- package/server/dist/core/powershell-probe.smoke-helpers.d.ts.map +1 -0
- package/server/dist/core/powershell-probe.smoke-helpers.js +80 -0
- package/server/dist/core/powershell-probe.smoke-helpers.js.map +1 -0
- package/server/dist/core/readiness-install-hints.d.ts +1 -1
- package/server/dist/core/readiness-install-hints.d.ts.map +1 -1
- package/server/dist/core/readiness-install-hints.js +5 -0
- package/server/dist/core/readiness-install-hints.js.map +1 -1
- package/server/dist/core/readiness-probe-run.d.ts +61 -0
- package/server/dist/core/readiness-probe-run.d.ts.map +1 -1
- package/server/dist/core/readiness-probe-run.js +93 -15
- package/server/dist/core/readiness-probe-run.js.map +1 -1
- package/server/dist/core/readiness-probe.d.ts +1 -1
- package/server/dist/core/readiness-probe.d.ts.map +1 -1
- package/server/dist/core/readiness-probe.js +36 -8
- package/server/dist/core/readiness-probe.js.map +1 -1
- package/server/dist/core/sdk-sessions-merge.d.ts +19 -0
- package/server/dist/core/sdk-sessions-merge.d.ts.map +1 -1
- package/server/dist/core/sdk-sessions-merge.js +19 -5
- package/server/dist/core/sdk-sessions-merge.js.map +1 -1
- package/server/dist/core/sdk-sessions-refresh.d.ts +50 -0
- package/server/dist/core/sdk-sessions-refresh.d.ts.map +1 -0
- package/server/dist/core/sdk-sessions-refresh.js +69 -0
- package/server/dist/core/sdk-sessions-refresh.js.map +1 -0
- package/server/dist/core/sdk-sessions-store.d.ts +48 -0
- package/server/dist/core/sdk-sessions-store.d.ts.map +1 -1
- package/server/dist/core/sdk-sessions-store.js +8 -9
- package/server/dist/core/sdk-sessions-store.js.map +1 -1
- package/server/dist/core/sdk-sessions-validate.d.ts.map +1 -1
- package/server/dist/core/sdk-sessions-validate.js +11 -0
- package/server/dist/core/sdk-sessions-validate.js.map +1 -1
- package/server/dist/core/settings-reader.d.ts +18 -0
- package/server/dist/core/settings-reader.d.ts.map +1 -0
- package/server/dist/core/settings-reader.js +40 -0
- package/server/dist/core/settings-reader.js.map +1 -0
- package/server/dist/core/shell-quote.d.ts +29 -0
- package/server/dist/core/shell-quote.d.ts.map +1 -1
- package/server/dist/core/shell-quote.js +34 -0
- package/server/dist/core/shell-quote.js.map +1 -1
- package/server/dist/core/shipwright-plugin-version-reader.d.ts +15 -0
- package/server/dist/core/shipwright-plugin-version-reader.d.ts.map +1 -0
- package/server/dist/core/shipwright-plugin-version-reader.js +49 -0
- package/server/dist/core/shipwright-plugin-version-reader.js.map +1 -0
- package/server/dist/core/task-editability.d.ts +1 -1
- package/server/dist/core/task-editability.d.ts.map +1 -1
- package/server/dist/core/task-editability.js +1 -0
- package/server/dist/core/task-editability.js.map +1 -1
- package/server/dist/core/triage-cli-runner.d.ts.map +1 -1
- package/server/dist/core/triage-cli-runner.js +6 -21
- package/server/dist/core/triage-cli-runner.js.map +1 -1
- package/server/dist/core/triage-compose.d.ts.map +1 -1
- package/server/dist/core/triage-compose.js +34 -3
- package/server/dist/core/triage-compose.js.map +1 -1
- package/server/dist/core/triage-store.d.ts +2 -1
- package/server/dist/core/triage-store.d.ts.map +1 -1
- package/server/dist/core/triage-store.js +1 -1
- package/server/dist/core/triage-store.js.map +1 -1
- package/server/dist/external/create-external-routes-args.d.ts +122 -0
- package/server/dist/external/create-external-routes-args.d.ts.map +1 -0
- package/server/dist/external/create-external-routes-args.js +2 -0
- package/server/dist/external/create-external-routes-args.js.map +1 -0
- package/server/dist/external/inbox/_codex.d.ts +14 -0
- package/server/dist/external/inbox/_codex.d.ts.map +1 -0
- package/server/dist/external/inbox/_codex.js +88 -0
- package/server/dist/external/inbox/_codex.js.map +1 -0
- package/server/dist/external/inbox/_derive.d.ts +2 -25
- package/server/dist/external/inbox/_derive.d.ts.map +1 -1
- package/server/dist/external/inbox/_derive.js +11 -0
- package/server/dist/external/inbox/_derive.js.map +1 -1
- package/server/dist/external/inbox/_lead.d.ts +23 -0
- package/server/dist/external/inbox/_lead.d.ts.map +1 -0
- package/server/dist/external/inbox/_lead.js +83 -0
- package/server/dist/external/inbox/_lead.js.map +1 -0
- package/server/dist/external/inbox/_types.d.ts +55 -0
- package/server/dist/external/inbox/_types.d.ts.map +1 -0
- package/server/dist/external/inbox/_types.js +13 -0
- package/server/dist/external/inbox/_types.js.map +1 -0
- package/server/dist/external/inbox/routes.d.ts +7 -0
- package/server/dist/external/inbox/routes.d.ts.map +1 -1
- package/server/dist/external/inbox/routes.js +43 -2
- package/server/dist/external/inbox/routes.js.map +1 -1
- package/server/dist/external/launch/_helpers.d.ts +4 -0
- package/server/dist/external/launch/_helpers.d.ts.map +1 -1
- package/server/dist/external/launch/_helpers.js.map +1 -1
- package/server/dist/external/launch/action-substitution-branch.d.ts +12 -0
- package/server/dist/external/launch/action-substitution-branch.d.ts.map +1 -1
- package/server/dist/external/launch/action-substitution-branch.js +35 -1
- package/server/dist/external/launch/action-substitution-branch.js.map +1 -1
- package/server/dist/external/launch/branch-dispatch.d.ts +15 -0
- package/server/dist/external/launch/branch-dispatch.d.ts.map +1 -0
- package/server/dist/external/launch/branch-dispatch.js +73 -0
- package/server/dist/external/launch/branch-dispatch.js.map +1 -0
- package/server/dist/external/launch/campaign-step-branch.d.ts +7 -1
- package/server/dist/external/launch/campaign-step-branch.d.ts.map +1 -1
- package/server/dist/external/launch/campaign-step-branch.js +70 -2
- package/server/dist/external/launch/campaign-step-branch.js.map +1 -1
- package/server/dist/external/launch/claim-executor-permissions.d.ts +31 -0
- package/server/dist/external/launch/claim-executor-permissions.d.ts.map +1 -0
- package/server/dist/external/launch/claim-executor-permissions.js +107 -0
- package/server/dist/external/launch/claim-executor-permissions.js.map +1 -0
- package/server/dist/external/launch/claim-executor-template-arming.d.ts +42 -0
- package/server/dist/external/launch/claim-executor-template-arming.d.ts.map +1 -0
- package/server/dist/external/launch/claim-executor-template-arming.js +121 -0
- package/server/dist/external/launch/claim-executor-template-arming.js.map +1 -0
- package/server/dist/external/launch/claim-holder-gate.d.ts +51 -0
- package/server/dist/external/launch/claim-holder-gate.d.ts.map +1 -0
- package/server/dist/external/launch/claim-holder-gate.js +95 -0
- package/server/dist/external/launch/claim-holder-gate.js.map +1 -0
- package/server/dist/external/launch/claim-permission-perimeter-assert.d.ts +3 -0
- package/server/dist/external/launch/claim-permission-perimeter-assert.d.ts.map +1 -0
- package/server/dist/external/launch/claim-permission-perimeter-assert.js +24 -0
- package/server/dist/external/launch/claim-permission-perimeter-assert.js.map +1 -0
- package/server/dist/external/launch/legacy-fallback-branch.d.ts +14 -0
- package/server/dist/external/launch/legacy-fallback-branch.d.ts.map +1 -1
- package/server/dist/external/launch/legacy-fallback-branch.js +3 -1
- package/server/dist/external/launch/legacy-fallback-branch.js.map +1 -1
- package/server/dist/external/launch/master-run-branch.js +2 -2
- package/server/dist/external/launch/master-run-branch.js.map +1 -1
- package/server/dist/external/launch/mixed-intents-guard.d.ts +10 -0
- package/server/dist/external/launch/mixed-intents-guard.d.ts.map +1 -0
- package/server/dist/external/launch/mixed-intents-guard.js +49 -0
- package/server/dist/external/launch/mixed-intents-guard.js.map +1 -0
- package/server/dist/external/launch/parse-body.d.ts +29 -0
- package/server/dist/external/launch/parse-body.d.ts.map +1 -1
- package/server/dist/external/launch/parse-body.js +66 -0
- package/server/dist/external/launch/parse-body.js.map +1 -1
- package/server/dist/external/launch/routes.d.ts +3 -0
- package/server/dist/external/launch/routes.d.ts.map +1 -1
- package/server/dist/external/launch/routes.js +99 -128
- package/server/dist/external/launch/routes.js.map +1 -1
- package/server/dist/external/launch/runtime-chokepoint-codextender.d.ts +20 -0
- package/server/dist/external/launch/runtime-chokepoint-codextender.d.ts.map +1 -0
- package/server/dist/external/launch/runtime-chokepoint-codextender.js +51 -0
- package/server/dist/external/launch/runtime-chokepoint-codextender.js.map +1 -0
- package/server/dist/external/launch/runtime-chokepoint-errors.d.ts +33 -0
- package/server/dist/external/launch/runtime-chokepoint-errors.d.ts.map +1 -0
- package/server/dist/external/launch/runtime-chokepoint-errors.js +63 -0
- package/server/dist/external/launch/runtime-chokepoint-errors.js.map +1 -0
- package/server/dist/external/launch/runtime-chokepoint.d.ts +120 -0
- package/server/dist/external/launch/runtime-chokepoint.d.ts.map +1 -0
- package/server/dist/external/launch/runtime-chokepoint.js +201 -0
- package/server/dist/external/launch/runtime-chokepoint.js.map +1 -0
- package/server/dist/external/mission-context/routes.d.ts +33 -27
- package/server/dist/external/mission-context/routes.d.ts.map +1 -1
- package/server/dist/external/mission-context/routes.js +30 -27
- package/server/dist/external/mission-context/routes.js.map +1 -1
- package/server/dist/external/mission-context/test-harness.d.ts +6 -0
- package/server/dist/external/mission-context/test-harness.d.ts.map +1 -1
- package/server/dist/external/mission-context/test-harness.js +6 -1
- package/server/dist/external/mission-context/test-harness.js.map +1 -1
- package/server/dist/external/mission-context/wire.d.ts.map +1 -1
- package/server/dist/external/mission-context/wire.js +24 -2
- package/server/dist/external/mission-context/wire.js.map +1 -1
- package/server/dist/external/org/audit-log.d.ts +19 -0
- package/server/dist/external/org/audit-log.d.ts.map +1 -1
- package/server/dist/external/org/audit-log.js +33 -18
- package/server/dist/external/org/audit-log.js.map +1 -1
- package/server/dist/external/org/beat-effect-audit-read.d.ts +15 -0
- package/server/dist/external/org/beat-effect-audit-read.d.ts.map +1 -0
- package/server/dist/external/org/beat-effect-audit-read.js +73 -0
- package/server/dist/external/org/beat-effect-audit-read.js.map +1 -0
- package/server/dist/external/org/beat-register-health.d.ts +57 -0
- package/server/dist/external/org/beat-register-health.d.ts.map +1 -0
- package/server/dist/external/org/beat-register-health.js +125 -0
- package/server/dist/external/org/beat-register-health.js.map +1 -0
- package/server/dist/external/org/beat-register-release-core.d.ts.map +1 -1
- package/server/dist/external/org/beat-register-release-core.js +4 -1
- package/server/dist/external/org/beat-register-release-core.js.map +1 -1
- package/server/dist/external/org/beat-register-release-request.d.ts +20 -0
- package/server/dist/external/org/beat-register-release-request.d.ts.map +1 -0
- package/server/dist/external/org/beat-register-release-request.js +92 -0
- package/server/dist/external/org/beat-register-release-request.js.map +1 -0
- package/server/dist/external/org/beat-register-release.d.ts +3 -1
- package/server/dist/external/org/beat-register-release.d.ts.map +1 -1
- package/server/dist/external/org/beat-register-release.js +15 -57
- package/server/dist/external/org/beat-register-release.js.map +1 -1
- package/server/dist/external/org/beat-register.d.ts +18 -20
- package/server/dist/external/org/beat-register.d.ts.map +1 -1
- package/server/dist/external/org/beat-register.js +30 -56
- package/server/dist/external/org/beat-register.js.map +1 -1
- package/server/dist/external/org/beat-steps-read.d.ts +17 -0
- package/server/dist/external/org/beat-steps-read.d.ts.map +1 -0
- package/server/dist/external/org/beat-steps-read.js +89 -0
- package/server/dist/external/org/beat-steps-read.js.map +1 -0
- package/server/dist/external/org/charter-authority-read.d.ts +39 -0
- package/server/dist/external/org/charter-authority-read.d.ts.map +1 -0
- package/server/dist/external/org/charter-authority-read.js +142 -0
- package/server/dist/external/org/charter-authority-read.js.map +1 -0
- package/server/dist/external/org/commit-validate.d.ts +18 -0
- package/server/dist/external/org/commit-validate.d.ts.map +1 -0
- package/server/dist/external/org/commit-validate.js +59 -0
- package/server/dist/external/org/commit-validate.js.map +1 -0
- package/server/dist/external/org/commit-writes.d.ts +68 -0
- package/server/dist/external/org/commit-writes.d.ts.map +1 -0
- package/server/dist/external/org/commit-writes.js +110 -0
- package/server/dist/external/org/commit-writes.js.map +1 -0
- package/server/dist/external/org/commit.d.ts +73 -0
- package/server/dist/external/org/commit.d.ts.map +1 -0
- package/server/dist/external/org/commit.js +181 -0
- package/server/dist/external/org/commit.js.map +1 -0
- package/server/dist/external/org/commit.test-fixtures.d.ts +38 -0
- package/server/dist/external/org/commit.test-fixtures.d.ts.map +1 -0
- package/server/dist/external/org/commit.test-fixtures.js +67 -0
- package/server/dist/external/org/commit.test-fixtures.js.map +1 -0
- package/server/dist/external/org/countersign-core.d.ts +19 -0
- package/server/dist/external/org/countersign-core.d.ts.map +1 -0
- package/server/dist/external/org/countersign-core.js +122 -0
- package/server/dist/external/org/countersign-core.js.map +1 -0
- package/server/dist/external/org/countersign-request.d.ts +14 -0
- package/server/dist/external/org/countersign-request.d.ts.map +1 -0
- package/server/dist/external/org/countersign-request.js +78 -0
- package/server/dist/external/org/countersign-request.js.map +1 -0
- package/server/dist/external/org/countersign.d.ts +6 -5
- package/server/dist/external/org/countersign.d.ts.map +1 -1
- package/server/dist/external/org/countersign.js +12 -141
- package/server/dist/external/org/countersign.js.map +1 -1
- package/server/dist/external/org/daemon-config-read.d.ts +31 -0
- package/server/dist/external/org/daemon-config-read.d.ts.map +1 -0
- package/server/dist/external/org/daemon-config-read.js +50 -0
- package/server/dist/external/org/daemon-config-read.js.map +1 -0
- package/server/dist/external/org/decisions-lock.d.ts +6 -4
- package/server/dist/external/org/decisions-lock.d.ts.map +1 -1
- package/server/dist/external/org/decisions-lock.js +9 -8
- package/server/dist/external/org/decisions-lock.js.map +1 -1
- package/server/dist/external/org/domains.d.ts +35 -0
- package/server/dist/external/org/domains.d.ts.map +1 -0
- package/server/dist/external/org/domains.js +29 -0
- package/server/dist/external/org/domains.js.map +1 -0
- package/server/dist/external/org/existing-charters-read.d.ts +5 -0
- package/server/dist/external/org/existing-charters-read.d.ts.map +1 -0
- package/server/dist/external/org/existing-charters-read.js +31 -0
- package/server/dist/external/org/existing-charters-read.js.map +1 -0
- package/server/dist/external/org/lead-question-threads.d.ts +46 -0
- package/server/dist/external/org/lead-question-threads.d.ts.map +1 -0
- package/server/dist/external/org/lead-question-threads.js +132 -0
- package/server/dist/external/org/lead-question-threads.js.map +1 -0
- package/server/dist/external/org/leadwright-proposal-merge.d.ts +54 -0
- package/server/dist/external/org/leadwright-proposal-merge.d.ts.map +1 -0
- package/server/dist/external/org/leadwright-proposal-merge.js +47 -0
- package/server/dist/external/org/leadwright-proposal-merge.js.map +1 -0
- package/server/dist/external/org/mount.d.ts +11 -0
- package/server/dist/external/org/mount.d.ts.map +1 -1
- package/server/dist/external/org/mount.js +7 -1
- package/server/dist/external/org/mount.js.map +1 -1
- package/server/dist/external/org/org-chart-full-read.d.ts +19 -0
- package/server/dist/external/org/org-chart-full-read.d.ts.map +1 -0
- package/server/dist/external/org/org-chart-full-read.js +58 -0
- package/server/dist/external/org/org-chart-full-read.js.map +1 -0
- package/server/dist/external/org/org-file-lock.d.ts +41 -0
- package/server/dist/external/org/org-file-lock.d.ts.map +1 -0
- package/server/dist/external/org/org-file-lock.js +90 -0
- package/server/dist/external/org/org-file-lock.js.map +1 -0
- package/server/dist/external/org/routes.d.ts +10 -0
- package/server/dist/external/org/routes.d.ts.map +1 -1
- package/server/dist/external/org/routes.js +22 -1
- package/server/dist/external/org/routes.js.map +1 -1
- package/server/dist/external/org/usage.d.ts.map +1 -1
- package/server/dist/external/org/usage.js +20 -2
- package/server/dist/external/org/usage.js.map +1 -1
- package/server/dist/external/org/verdict.d.ts +57 -0
- package/server/dist/external/org/verdict.d.ts.map +1 -0
- package/server/dist/external/org/verdict.js +74 -0
- package/server/dist/external/org/verdict.js.map +1 -0
- package/server/dist/external/routes.d.ts +3 -101
- package/server/dist/external/routes.d.ts.map +1 -1
- package/server/dist/external/routes.js +12 -3
- package/server/dist/external/routes.js.map +1 -1
- package/server/dist/external/tasks/create.d.ts.map +1 -1
- package/server/dist/external/tasks/create.js +8 -0
- package/server/dist/external/tasks/create.js.map +1 -1
- package/server/dist/external/tasks/fork.d.ts +29 -0
- package/server/dist/external/tasks/fork.d.ts.map +1 -0
- package/server/dist/external/tasks/fork.js +166 -0
- package/server/dist/external/tasks/fork.js.map +1 -0
- package/server/dist/external/tasks/lifecycle.d.ts.map +1 -1
- package/server/dist/external/tasks/lifecycle.js +10 -57
- package/server/dist/external/tasks/lifecycle.js.map +1 -1
- package/server/dist/external/tasks/patch.d.ts.map +1 -1
- package/server/dist/external/tasks/patch.js +17 -0
- package/server/dist/external/tasks/patch.js.map +1 -1
- package/server/dist/external/tasks/routes.d.ts +2 -0
- package/server/dist/external/tasks/routes.d.ts.map +1 -1
- package/server/dist/external/tasks/routes.js +7 -0
- package/server/dist/external/tasks/routes.js.map +1 -1
- package/server/dist/external/transcript/routes.d.ts.map +1 -1
- package/server/dist/external/transcript/routes.js +25 -3
- package/server/dist/external/transcript/routes.js.map +1 -1
- package/server/dist/external-routes-wiring.d.ts +28 -0
- package/server/dist/external-routes-wiring.d.ts.map +1 -0
- package/server/dist/external-routes-wiring.js +61 -0
- package/server/dist/external-routes-wiring.js.map +1 -0
- package/server/dist/index.d.ts.map +1 -1
- package/server/dist/index.js +111 -44
- package/server/dist/index.js.map +1 -1
- package/server/dist/lib/resolveHonoHost.d.ts.map +1 -1
- package/server/dist/lib/resolveHonoHost.js +16 -1
- package/server/dist/lib/resolveHonoHost.js.map +1 -1
- package/server/dist/routes/_triage-api-harness.d.ts +1 -1
- package/server/dist/routes/_triage-api-harness.d.ts.map +1 -1
- package/server/dist/routes/_triage-api-harness.js.map +1 -1
- package/server/dist/routes/campaigns-readiness.d.ts +10 -0
- package/server/dist/routes/campaigns-readiness.d.ts.map +1 -0
- package/server/dist/routes/campaigns-readiness.js +58 -0
- package/server/dist/routes/campaigns-readiness.js.map +1 -0
- package/server/dist/routes/campaigns.d.ts.map +1 -1
- package/server/dist/routes/campaigns.js +3 -0
- package/server/dist/routes/campaigns.js.map +1 -1
- package/server/dist/routes/codex-models.d.ts +15 -0
- package/server/dist/routes/codex-models.d.ts.map +1 -0
- package/server/dist/routes/codex-models.js +77 -0
- package/server/dist/routes/codex-models.js.map +1 -0
- package/server/dist/routes/codextender-models.d.ts +16 -0
- package/server/dist/routes/codextender-models.d.ts.map +1 -0
- package/server/dist/routes/codextender-models.js +81 -0
- package/server/dist/routes/codextender-models.js.map +1 -0
- package/server/dist/routes/diagnostics.d.ts +27 -0
- package/server/dist/routes/diagnostics.d.ts.map +1 -1
- package/server/dist/routes/diagnostics.js +5 -1
- package/server/dist/routes/diagnostics.js.map +1 -1
- package/server/dist/routes/org-chart-lead-guard.d.ts +10 -0
- package/server/dist/routes/org-chart-lead-guard.d.ts.map +1 -0
- package/server/dist/routes/org-chart-lead-guard.js +49 -0
- package/server/dist/routes/org-chart-lead-guard.js.map +1 -0
- package/server/dist/routes/org-inventory-composite.d.ts +20 -0
- package/server/dist/routes/org-inventory-composite.d.ts.map +1 -0
- package/server/dist/routes/org-inventory-composite.js +100 -0
- package/server/dist/routes/org-inventory-composite.js.map +1 -0
- package/server/dist/routes/org-lead-setup-wizard.d.ts +10 -0
- package/server/dist/routes/org-lead-setup-wizard.d.ts.map +1 -0
- package/server/dist/routes/org-lead-setup-wizard.js +51 -0
- package/server/dist/routes/org-lead-setup-wizard.js.map +1 -0
- package/server/dist/routes/org-leads-composite.d.ts.map +1 -1
- package/server/dist/routes/org-leads-composite.js +35 -9
- package/server/dist/routes/org-leads-composite.js.map +1 -1
- package/server/dist/routes/org-threads-composite.d.ts +24 -0
- package/server/dist/routes/org-threads-composite.d.ts.map +1 -0
- package/server/dist/routes/org-threads-composite.js +51 -0
- package/server/dist/routes/org-threads-composite.js.map +1 -0
- package/server/dist/routes/org-writes.d.ts +14 -0
- package/server/dist/routes/org-writes.d.ts.map +1 -0
- package/server/dist/routes/org-writes.js +61 -0
- package/server/dist/routes/org-writes.js.map +1 -0
- package/server/dist/routes/org.d.ts +14 -0
- package/server/dist/routes/org.d.ts.map +1 -1
- package/server/dist/routes/org.js +63 -47
- package/server/dist/routes/org.js.map +1 -1
- package/server/dist/routes/settings.d.ts.map +1 -1
- package/server/dist/routes/settings.js +23 -2
- package/server/dist/routes/settings.js.map +1 -1
- package/server/dist/routes/triage.d.ts +17 -0
- package/server/dist/routes/triage.d.ts.map +1 -1
- package/server/dist/routes/triage.js +29 -0
- package/server/dist/routes/triage.js.map +1 -1
- package/server/dist/terminal/pty-manager.d.ts +37 -1
- package/server/dist/terminal/pty-manager.d.ts.map +1 -1
- package/server/dist/terminal/pty-manager.js +33 -3
- package/server/dist/terminal/pty-manager.js.map +1 -1
- package/server/dist/terminal/pty-write-chunker.d.ts +109 -0
- package/server/dist/terminal/pty-write-chunker.d.ts.map +1 -0
- package/server/dist/terminal/pty-write-chunker.js +234 -0
- package/server/dist/terminal/pty-write-chunker.js.map +1 -0
- package/server/dist/terminal/routes.d.ts.map +1 -1
- package/server/dist/terminal/routes.js +9 -0
- package/server/dist/terminal/routes.js.map +1 -1
- package/server/dist/terminal/ws-upgrade-handler.d.ts.map +1 -1
- package/server/dist/terminal/ws-upgrade-handler.fixtures.d.ts.map +1 -1
- package/server/dist/terminal/ws-upgrade-handler.fixtures.js +1 -0
- package/server/dist/terminal/ws-upgrade-handler.fixtures.js.map +1 -1
- package/server/dist/terminal/ws-upgrade-handler.js +14 -5
- package/server/dist/terminal/ws-upgrade-handler.js.map +1 -1
- package/server/dist/test/event-test-counts-fixtures.d.ts +40 -0
- package/server/dist/test/event-test-counts-fixtures.d.ts.map +1 -0
- package/server/dist/test/event-test-counts-fixtures.js +56 -0
- package/server/dist/test/event-test-counts-fixtures.js.map +1 -0
- package/server/dist/types/leadwright-beat-step.d.ts +19 -0
- package/server/dist/types/leadwright-beat-step.d.ts.map +1 -0
- package/server/dist/types/leadwright-beat-step.js +56 -0
- package/server/dist/types/leadwright-beat-step.js.map +1 -0
- package/server/dist/types/leadwright-preflight.d.ts +90 -0
- package/server/dist/types/leadwright-preflight.d.ts.map +1 -0
- package/server/dist/types/leadwright-preflight.js +65 -0
- package/server/dist/types/leadwright-preflight.js.map +1 -0
- package/server/dist/types/leadwright-schema-drift.d.ts +28 -0
- package/server/dist/types/leadwright-schema-drift.d.ts.map +1 -0
- package/server/dist/types/leadwright-schema-drift.js +89 -0
- package/server/dist/types/leadwright-schema-drift.js.map +1 -0
- package/server/dist/types/org-inventory.d.ts +53 -0
- package/server/dist/types/org-inventory.d.ts.map +1 -0
- package/server/dist/types/org-inventory.js +11 -0
- package/server/dist/types/org-inventory.js.map +1 -0
- package/server/dist/types/org.d.ts +76 -6
- package/server/dist/types/org.d.ts.map +1 -1
- package/server/dist/types/run-config-retry.d.ts +29 -0
- package/server/dist/types/run-config-retry.d.ts.map +1 -0
- package/server/dist/types/run-config-retry.js +47 -0
- package/server/dist/types/run-config-retry.js.map +1 -0
- package/server/dist/types/run-config-v2.d.ts +29 -41
- package/server/dist/types/run-config-v2.d.ts.map +1 -1
- package/server/dist/types/run-config-v2.js +16 -50
- package/server/dist/types/run-config-v2.js.map +1 -1
- package/server/dist/types/settings.d.ts +33 -0
- package/server/dist/types/settings.d.ts.map +1 -1
- package/server/dist/vendor/leadwright/beat-step.schema.json +83 -0
- package/server/dist/vendor/leadwright/claim-record-lock-contract.json +15 -0
- package/server/dist/vendor/leadwright/org-chart.schema.json +195 -0
- package/server/dist/vendor/leadwright/preflight-input.schema.json +318 -0
- package/server/dist/vendor/leadwright/preflight-result.schema.json +56 -0
- package/server/package.json +1 -1
- package/client/dist/assets/channel-BYPbLjRl.js +0 -1
- package/client/dist/assets/classDiagram-OUVF2IWQ-CsFIeTju.js +0 -1
- package/client/dist/assets/classDiagram-v2-EOCWNBFH-CsFIeTju.js +0 -1
- package/client/dist/assets/index-BnTOrFHb.js +0 -829
- package/client/dist/assets/index-CYPc6qxw.css +0 -1
- package/client/dist/assets/stateDiagram-v2-6OUMAXLB-B3E4_xxT.js +0 -1
- package/client/dist/assets/swimlanesDiagram-G3AALYLV-BegQBqnC.js +0 -8
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* commit.test-fixtures.ts — shared request/deps builders for commit.ts's
|
|
3
|
+
* test suite, split across commit.test.ts (validation/digest/write-order)
|
|
4
|
+
* and commit-lock.test.ts (lock/symlink error mapping) so neither file
|
|
5
|
+
* ratchets past the bloat ceiling.
|
|
6
|
+
*/
|
|
7
|
+
import { vi } from "vitest";
|
|
8
|
+
import { computeProposalDigest } from "./leadwright-proposal-merge.js";
|
|
9
|
+
export const EMPTY_ORG_CHART = { version: 2, po: "sven", leads: {} };
|
|
10
|
+
export const VALID_LEAD = {
|
|
11
|
+
name: "New Lead",
|
|
12
|
+
domain: "billing",
|
|
13
|
+
reports_to: null,
|
|
14
|
+
manages: [],
|
|
15
|
+
charter_path: "new-lead/charter.md",
|
|
16
|
+
learnings_path: "new-lead/learnings.md",
|
|
17
|
+
triggers: { cron: "0 * * * *", on: [] },
|
|
18
|
+
max_concurrent_tasks: 1,
|
|
19
|
+
budget: { window: "rolling-7d", usd: null, pause_at: 0.85, hard_stop_at: 0.95 },
|
|
20
|
+
projects: ["p1"],
|
|
21
|
+
allowed_skills: ["/x"],
|
|
22
|
+
allowed_tools: [],
|
|
23
|
+
escalation_target: "po",
|
|
24
|
+
model: "balanced",
|
|
25
|
+
paused: false,
|
|
26
|
+
};
|
|
27
|
+
export const ADDITIONS = { path: "/abs/p1", actionId: "/x", pluginDirs: ["/abs/plugins"] };
|
|
28
|
+
export function correctDigest() {
|
|
29
|
+
const merged = { ...EMPTY_ORG_CHART, leads: { "new-lead": VALID_LEAD } };
|
|
30
|
+
return computeProposalDigest({
|
|
31
|
+
orgChart: merged,
|
|
32
|
+
charters: [{ leadId: "new-lead", content: "# New Lead" }],
|
|
33
|
+
daemonConfig: {
|
|
34
|
+
orgChartPath: "/leads/org-chart.json",
|
|
35
|
+
webuiBaseUrl: "http://localhost:5173",
|
|
36
|
+
leadProjectRoots: { "new-lead": ADDITIONS.path },
|
|
37
|
+
leadActionIds: { "new-lead": ADDITIONS.actionId },
|
|
38
|
+
leadPluginDirs: { "new-lead": ADDITIONS.pluginDirs },
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
export function validBody(overrides = {}) {
|
|
43
|
+
return {
|
|
44
|
+
leadId: "new-lead",
|
|
45
|
+
lead: VALID_LEAD,
|
|
46
|
+
daemonConfigAdditions: ADDITIONS,
|
|
47
|
+
charterContent: "# New Lead",
|
|
48
|
+
expectedProposalDigest: correctDigest(),
|
|
49
|
+
...overrides,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
export function baseDeps(overrides = {}) {
|
|
53
|
+
return {
|
|
54
|
+
leadsRoot: "/leads",
|
|
55
|
+
leadwrightCheckoutRoot: "/leadwright",
|
|
56
|
+
webuiBaseUrl: "http://localhost:5173",
|
|
57
|
+
readOrgChartFullFn: vi.fn(() => ({ status: 200, body: EMPTY_ORG_CHART })),
|
|
58
|
+
daemonConfigReadFn: vi.fn(() => ({
|
|
59
|
+
status: 200,
|
|
60
|
+
body: { found: false, template: { orgChartPath: "/leads/org-chart.json", webuiBaseUrl: "http://localhost:5173" } },
|
|
61
|
+
})),
|
|
62
|
+
writeCharterFn: vi.fn(),
|
|
63
|
+
runLeadwrightPreflightFn: vi.fn(async () => ({ ranOk: true, result: { ok: true, findings: [] } })),
|
|
64
|
+
...overrides,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=commit.test-fixtures.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commit.test-fixtures.js","sourceRoot":"","sources":["../../../src/external/org/commit.test-fixtures.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { withDecisionsLock, type DecisionsLockDeps } from "./decisions-lock.js";
|
|
2
|
+
export type CountersignOutcome = {
|
|
3
|
+
status: "countersigned";
|
|
4
|
+
number: number;
|
|
5
|
+
} | {
|
|
6
|
+
status: "already_countersigned";
|
|
7
|
+
number: number;
|
|
8
|
+
} | {
|
|
9
|
+
status: "not_found";
|
|
10
|
+
} | {
|
|
11
|
+
status: "duplicate_identity";
|
|
12
|
+
count: number;
|
|
13
|
+
};
|
|
14
|
+
export interface CountersignCoreDeps extends DecisionsLockDeps {
|
|
15
|
+
/** Injectable for tests; production wires the real `withDecisionsLock`. */
|
|
16
|
+
withDecisionsLock?: typeof withDecisionsLock;
|
|
17
|
+
}
|
|
18
|
+
export declare function performCountersign(deps: CountersignCoreDeps, timestamp: string, leadId: string): Promise<CountersignOutcome>;
|
|
19
|
+
//# sourceMappingURL=countersign-core.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"countersign-core.d.ts","sourceRoot":"","sources":["../../../src/external/org/countersign-core.ts"],"names":[],"mappings":"AAoCA,OAAO,EACL,iBAAiB,EAMjB,KAAK,iBAAiB,EACvB,MAAM,qBAAqB,CAAC;AA8B7B,MAAM,MAAM,kBAAkB,GAC1B;IAAE,MAAM,EAAE,eAAe,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,MAAM,EAAE,uBAAuB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,GACvB;IAAE,MAAM,EAAE,oBAAoB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpD,MAAM,WAAW,mBAAoB,SAAQ,iBAAiB;IAC5D,2EAA2E;IAC3E,iBAAiB,CAAC,EAAE,OAAO,iBAAiB,CAAC;CAC9C;AAED,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,mBAAmB,EACzB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,kBAAkB,CAAC,CAsE7B"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* external/org/countersign-core.ts — the pure countersign action
|
|
3
|
+
* (`performCountersign`), split out of `countersign.ts` so the SAME action
|
|
4
|
+
* can be shared, unmodified, by both the secret-gated route
|
|
5
|
+
* (`countersign.ts`) and the plain browser-facing proxy (`routes/org.ts`) —
|
|
6
|
+
* same rationale as `beat-register-release-core.ts` / `-request.ts`.
|
|
7
|
+
*
|
|
8
|
+
* Moves EXACTLY ONE entry from `decisions-proposed.md` to `decision_log.md`,
|
|
9
|
+
* assigning the next sequential `ADR-NNNN` number inside the FR-04.28 lock
|
|
10
|
+
* (`decisions-lock.ts`). Two plan-review fixes baked in from the start:
|
|
11
|
+
*
|
|
12
|
+
* - Request identifies the entry by `{timestamp, leadId}`, not timestamp
|
|
13
|
+
* alone (two leads, or two proposals in the same wall-clock second,
|
|
14
|
+
* could otherwise collide).
|
|
15
|
+
* - Crash-safe / idempotent retry: `decision_log.md` is the source of
|
|
16
|
+
* truth for "already done" — if an entry with the same
|
|
17
|
+
* (timestamp, leadId) is already logged, the action does NOT mint a
|
|
18
|
+
* second number; it just makes sure the proposed-side copy is (still)
|
|
19
|
+
* removed and returns the existing number. This is why the log write
|
|
20
|
+
* happens BEFORE the proposed-side removal: a crash between the two
|
|
21
|
+
* leaves `decision_log.md` durable and the retry finds it there.
|
|
22
|
+
*
|
|
23
|
+
* External-review fix (MEDIUM, edge-case): "(timestamp, leadId) as identity"
|
|
24
|
+
* does not guarantee UNIQUENESS by construction, only disambiguation in the
|
|
25
|
+
* common case — the daemon could still write two genuinely distinct
|
|
26
|
+
* proposals sharing the same pair (e.g. two rapid proposals from one lead in
|
|
27
|
+
* the same wall-clock second). Both the initial-match and the
|
|
28
|
+
* idempotent-retry path now count matches: exactly one proceeds as before;
|
|
29
|
+
* two or more is a `duplicate_identity` conflict rather than silently
|
|
30
|
+
* discarding every match past the first.
|
|
31
|
+
*/
|
|
32
|
+
import { writeFileSync, renameSync, existsSync, unlinkSync } from "node:fs";
|
|
33
|
+
import { dirname, basename, join } from "node:path";
|
|
34
|
+
import { randomBytes } from "node:crypto";
|
|
35
|
+
import { withDecisionsLock, parseProposedEntries, parseLoggedEntries, findLoggedEntry, nextLoggedNumber, toLoggedBlock, } from "./decisions-lock.js";
|
|
36
|
+
/** Body of a header-delimited block, i.e. everything after its first line —
|
|
37
|
+
* used to tell genuine residual-cleanup (same body) from a genuinely
|
|
38
|
+
* distinct proposal that happens to reuse the same (timestamp, leadId). */
|
|
39
|
+
function bodyAfterHeader(block) {
|
|
40
|
+
const idx = block.indexOf("\n");
|
|
41
|
+
return idx === -1 ? "" : block.slice(idx + 1);
|
|
42
|
+
}
|
|
43
|
+
function atomicWrite(target, content) {
|
|
44
|
+
const tmp = join(dirname(target), `.${basename(target)}.tmp-${process.pid}-${Date.now()}-${randomBytes(4).toString("hex")}`);
|
|
45
|
+
try {
|
|
46
|
+
writeFileSync(tmp, content, "utf8");
|
|
47
|
+
renameSync(tmp, target);
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
// Doubt-review fix (minor): mirror file-write.ts's performWrite — don't
|
|
51
|
+
// leave an orphaned .tmp-* file behind on a failed rename.
|
|
52
|
+
try {
|
|
53
|
+
if (existsSync(tmp))
|
|
54
|
+
unlinkSync(tmp);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
/* swallow */
|
|
58
|
+
}
|
|
59
|
+
throw err;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export async function performCountersign(deps, timestamp, leadId) {
|
|
63
|
+
const lockFn = deps.withDecisionsLock ?? withDecisionsLock;
|
|
64
|
+
return lockFn(deps, (ctx) => {
|
|
65
|
+
const loggedRaw = ctx.readLogged();
|
|
66
|
+
const loggedEntries = parseLoggedEntries(loggedRaw);
|
|
67
|
+
const existing = findLoggedEntry(loggedEntries, timestamp, leadId);
|
|
68
|
+
if (existing) {
|
|
69
|
+
const proposedRaw = ctx.readProposed();
|
|
70
|
+
// External-review fix (MEDIUM, edge-case): two genuinely-distinct
|
|
71
|
+
// proposals can share the same (timestamp, leadId) pair (the ADR that
|
|
72
|
+
// adopted the pair as identity already acknowledged timestamp
|
|
73
|
+
// collisions are possible). `.find()` here used to silently discard
|
|
74
|
+
// every residual match past the first without ever logging it —
|
|
75
|
+
// indistinguishable from ordinary post-countersign cleanup. `.filter()`
|
|
76
|
+
// lets a genuine duplicate surface as a conflict instead.
|
|
77
|
+
const stillProposedMatches = parseProposedEntries(proposedRaw).filter((e) => e.timestamp === timestamp && e.leadId === leadId);
|
|
78
|
+
if (stillProposedMatches.length > 1) {
|
|
79
|
+
return { status: "duplicate_identity", count: stillProposedMatches.length };
|
|
80
|
+
}
|
|
81
|
+
if (stillProposedMatches.length === 1) {
|
|
82
|
+
const stillProposed = stillProposedMatches[0];
|
|
83
|
+
// Doubt-review fix (HIGH): a single still-proposed match is only
|
|
84
|
+
// safe to delete as residual cleanup if it's the SAME proposal
|
|
85
|
+
// that's already logged (crash between the log-write and the
|
|
86
|
+
// proposed-side removal). Without comparing bodies, a genuinely
|
|
87
|
+
// distinct proposal that later reuses the same (timestamp, leadId)
|
|
88
|
+
// pair — which this module's own header comment already treats as
|
|
89
|
+
// a possible, not merely theoretical, collision — would be
|
|
90
|
+
// silently deleted here and reported as "already countersigned"
|
|
91
|
+
// under the OLD entry's ADR number, with no trace left anywhere.
|
|
92
|
+
if (bodyAfterHeader(stillProposed.block) !== bodyAfterHeader(existing.block)) {
|
|
93
|
+
return { status: "duplicate_identity", count: 2 };
|
|
94
|
+
}
|
|
95
|
+
const nextProposed = proposedRaw.slice(0, stillProposed.startIndex) +
|
|
96
|
+
proposedRaw.slice(stillProposed.endIndex);
|
|
97
|
+
atomicWrite(ctx.proposedPath, nextProposed);
|
|
98
|
+
}
|
|
99
|
+
return { status: "already_countersigned", number: existing.number };
|
|
100
|
+
}
|
|
101
|
+
const proposedRaw = ctx.readProposed();
|
|
102
|
+
const matches = parseProposedEntries(proposedRaw).filter((e) => e.timestamp === timestamp && e.leadId === leadId);
|
|
103
|
+
if (matches.length === 0) {
|
|
104
|
+
return { status: "not_found" };
|
|
105
|
+
}
|
|
106
|
+
if (matches.length > 1) {
|
|
107
|
+
return { status: "duplicate_identity", count: matches.length };
|
|
108
|
+
}
|
|
109
|
+
const target = matches[0];
|
|
110
|
+
const number = nextLoggedNumber(loggedEntries);
|
|
111
|
+
const loggedBlock = toLoggedBlock(target.block, number);
|
|
112
|
+
const separator = loggedRaw.length > 0 && !loggedRaw.endsWith("\n") ? "\n" : "";
|
|
113
|
+
const nextLogged = loggedRaw + separator + loggedBlock;
|
|
114
|
+
const nextProposed = proposedRaw.slice(0, target.startIndex) + proposedRaw.slice(target.endIndex);
|
|
115
|
+
// Log FIRST (durable), then remove from proposed — the idempotent-retry
|
|
116
|
+
// check above trusts decision_log.md as "already done".
|
|
117
|
+
atomicWrite(ctx.loggedPath, nextLogged);
|
|
118
|
+
atomicWrite(ctx.proposedPath, nextProposed);
|
|
119
|
+
return { status: "countersigned", number };
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=countersign-core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"countersign-core.js","sourceRoot":"","sources":["../../../src/external/org/countersign-core.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type CountersignCoreDeps } from "./countersign-core.js";
|
|
2
|
+
export type HandleCountersignRequestDeps = CountersignCoreDeps;
|
|
3
|
+
export interface CountersignRequestResult {
|
|
4
|
+
status: 200 | 400 | 403 | 404 | 409;
|
|
5
|
+
body: Record<string, unknown>;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* `rawBody` is the already-JSON-parsed request body (or `undefined`/`null`
|
|
9
|
+
* on a parse failure the caller has already turned into its own 400) —
|
|
10
|
+
* parsing itself stays in each Hono shell since only it knows how to read
|
|
11
|
+
* `c.req`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function handleCountersignRequest(deps: HandleCountersignRequestDeps, rawBody: unknown): Promise<CountersignRequestResult>;
|
|
14
|
+
//# sourceMappingURL=countersign-request.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"countersign-request.d.ts","sourceRoot":"","sources":["../../../src/external/org/countersign-request.ts"],"names":[],"mappings":"AASA,OAAO,EAAsB,KAAK,mBAAmB,EAA2B,MAAM,uBAAuB,CAAC;AAQ9G,MAAM,MAAM,4BAA4B,GAAG,mBAAmB,CAAC;AAE/D,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;IACpC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,4BAA4B,EAClC,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,wBAAwB,CAAC,CAyDnC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* external/org/countersign-request.ts — request validation +
|
|
3
|
+
* `performCountersign` call + error-to-status mapping, as ONE function
|
|
4
|
+
* shared by both the secret-gated route (`countersign.ts`) and the plain
|
|
5
|
+
* browser-facing proxy (`routes/org.ts`) — same rationale as
|
|
6
|
+
* `beat-register-release-request.ts`: two independent route shells must not
|
|
7
|
+
* be free to duplicate (and silently drift on) this body.
|
|
8
|
+
*/
|
|
9
|
+
import { performCountersign } from "./countersign-core.js";
|
|
10
|
+
import { OrgSymlinkEscapeError } from "./decisions-lock.js";
|
|
11
|
+
import { LEAD_ID_RE } from "./_helpers.js";
|
|
12
|
+
/** Canonical ISO-8601 UTC ('Z') timestamp — the transfer format's own shape
|
|
13
|
+
* (spec: "Design decisions I own"). Tolerates 0-N fractional-second digits. */
|
|
14
|
+
const ISO_TIMESTAMP_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?Z$/;
|
|
15
|
+
/**
|
|
16
|
+
* `rawBody` is the already-JSON-parsed request body (or `undefined`/`null`
|
|
17
|
+
* on a parse failure the caller has already turned into its own 400) —
|
|
18
|
+
* parsing itself stays in each Hono shell since only it knows how to read
|
|
19
|
+
* `c.req`.
|
|
20
|
+
*/
|
|
21
|
+
export async function handleCountersignRequest(deps, rawBody) {
|
|
22
|
+
const { timestamp, leadId } = (rawBody ?? {});
|
|
23
|
+
if (typeof timestamp !== "string" || timestamp.length === 0) {
|
|
24
|
+
return { status: 400, body: { error: "timestamp_required" } };
|
|
25
|
+
}
|
|
26
|
+
if (typeof leadId !== "string" || leadId.length === 0) {
|
|
27
|
+
return { status: 400, body: { error: "leadId_required" } };
|
|
28
|
+
}
|
|
29
|
+
// External-review fix (MEDIUM, spec): the transfer format's identity pair
|
|
30
|
+
// is a canonical ISO-8601 timestamp + a kebab-case lead id, not merely
|
|
31
|
+
// "any non-empty string" — an arbitrary value silently 404s as
|
|
32
|
+
// proposal_not_found instead of being rejected as malformed input.
|
|
33
|
+
//
|
|
34
|
+
// Doubt-review fix (LOW): `$` without the `/m` flag still matches just
|
|
35
|
+
// before a single trailing "\n" (JS regex semantics, not just true
|
|
36
|
+
// end-of-input) — reject a literal newline explicitly first, so
|
|
37
|
+
// "<valid-ts>\n" 400s as timestamp_invalid instead of passing this check
|
|
38
|
+
// and only failing later, less precisely, as proposal_not_found.
|
|
39
|
+
if (timestamp.includes("\n") || !ISO_TIMESTAMP_RE.test(timestamp)) {
|
|
40
|
+
return { status: 400, body: { error: "timestamp_invalid", timestamp } };
|
|
41
|
+
}
|
|
42
|
+
if (!LEAD_ID_RE.test(leadId)) {
|
|
43
|
+
return { status: 400, body: { error: "leadId_invalid", leadId } };
|
|
44
|
+
}
|
|
45
|
+
let outcome;
|
|
46
|
+
try {
|
|
47
|
+
outcome = await performCountersign(deps, timestamp, leadId);
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
// Code-review fix: without this, a symlinked decisions-proposed.md /
|
|
51
|
+
// decision_log.md fell through to the generic 500 error handler
|
|
52
|
+
// instead of the family's typed 403 symlink_forbidden (file-write.ts
|
|
53
|
+
// applies the same defense class explicitly).
|
|
54
|
+
if (err instanceof OrgSymlinkEscapeError) {
|
|
55
|
+
return { status: 403, body: { error: "symlink_forbidden", path: err.path } };
|
|
56
|
+
}
|
|
57
|
+
throw err;
|
|
58
|
+
}
|
|
59
|
+
if (outcome.status === "not_found") {
|
|
60
|
+
return { status: 404, body: { error: "proposal_not_found", timestamp, leadId } };
|
|
61
|
+
}
|
|
62
|
+
if (outcome.status === "duplicate_identity") {
|
|
63
|
+
return {
|
|
64
|
+
status: 409,
|
|
65
|
+
body: { error: "duplicate_proposal_identity", timestamp, leadId, count: outcome.count },
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
status: 200,
|
|
70
|
+
body: {
|
|
71
|
+
countersigned: true,
|
|
72
|
+
alreadyCountersigned: outcome.status === "already_countersigned",
|
|
73
|
+
number: outcome.number,
|
|
74
|
+
adr: `ADR-${String(outcome.number).padStart(4, "0")}`,
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=countersign-request.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"countersign-request.js","sourceRoot":"","sources":["../../../src/external/org/countersign-request.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { Hono } from "hono";
|
|
2
|
-
import {
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}
|
|
2
|
+
import type { CountersignCoreDeps } from "./countersign-core.js";
|
|
3
|
+
export { performCountersign } from "./countersign-core.js";
|
|
4
|
+
export type { CountersignOutcome, CountersignCoreDeps } from "./countersign-core.js";
|
|
5
|
+
export { handleCountersignRequest } from "./countersign-request.js";
|
|
6
|
+
export type { HandleCountersignRequestDeps, CountersignRequestResult, } from "./countersign-request.js";
|
|
7
|
+
export type CountersignRouteDeps = CountersignCoreDeps;
|
|
7
8
|
export declare function registerCountersignRoute(app: Hono, deps: CountersignRouteDeps): void;
|
|
8
9
|
//# sourceMappingURL=countersign.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"countersign.d.ts","sourceRoot":"","sources":["../../../src/external/org/countersign.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"countersign.d.ts","sourceRoot":"","sources":["../../../src/external/org/countersign.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAGjC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAEjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACrF,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACpE,YAAY,EACV,4BAA4B,EAC5B,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAElC,MAAM,MAAM,oBAAoB,GAAG,mBAAmB,CAAC;AAEvD,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,oBAAoB,GAAG,IAAI,CAWpF"}
|
|
@@ -1,105 +1,17 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* external/org/countersign.ts — POST /api/external/org/decisions/countersign.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* - Crash-safe / idempotent retry: `decision_log.md` is the source of
|
|
12
|
-
* truth for "already done" — if an entry with the same
|
|
13
|
-
* (timestamp, leadId) is already logged, the action does NOT mint a
|
|
14
|
-
* second number; it just makes sure the proposed-side copy is (still)
|
|
15
|
-
* removed and returns the existing number. This is why the log write
|
|
16
|
-
* happens BEFORE the proposed-side removal: a crash between the two
|
|
17
|
-
* leaves `decision_log.md` durable and the retry finds it there.
|
|
18
|
-
*
|
|
19
|
-
* External-review fix (MEDIUM, edge-case): "(timestamp, leadId) as identity"
|
|
20
|
-
* does not guarantee UNIQUENESS by construction, only disambiguation in the
|
|
21
|
-
* common case — the daemon could still write two genuinely distinct
|
|
22
|
-
* proposals sharing the same pair (e.g. two rapid proposals from one lead in
|
|
23
|
-
* the same wall-clock second). Both the initial-match and the
|
|
24
|
-
* idempotent-retry path now count matches: exactly one proceeds as before;
|
|
25
|
-
* two or more is a `409 duplicate_proposal_identity` conflict rather than
|
|
26
|
-
* silently discarding every match past the first.
|
|
4
|
+
* Hono route shell only — parses the request and hands off to
|
|
5
|
+
* `handleCountersignRequest` (`countersign-request.ts`), which is ALSO used
|
|
6
|
+
* by the plain browser-facing proxy's countersign route (`routes/org.ts`,
|
|
7
|
+
* iterate-2026-09-06-decisions-proposed-countersign) so the two route shells
|
|
8
|
+
* cannot drift on validation or status-mapping. The countersign action
|
|
9
|
+
* itself (locking, decision-log/proposed-file mutation) lives in
|
|
10
|
+
* `countersign-core.ts`.
|
|
27
11
|
*/
|
|
28
|
-
import {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
import { withDecisionsLock, parseProposedEntries, parseLoggedEntries, findLoggedEntry, nextLoggedNumber, toLoggedBlock, OrgSymlinkEscapeError, } from "./decisions-lock.js";
|
|
32
|
-
import { LEAD_ID_RE } from "./_helpers.js";
|
|
33
|
-
/** Canonical ISO-8601 UTC ('Z') timestamp — the transfer format's own shape
|
|
34
|
-
* (spec: "Design decisions I own"). Tolerates 0-N fractional-second digits. */
|
|
35
|
-
const ISO_TIMESTAMP_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?Z$/;
|
|
36
|
-
function atomicWrite(target, content) {
|
|
37
|
-
const tmp = join(dirname(target), `.${basename(target)}.tmp-${process.pid}-${Date.now()}-${randomBytes(4).toString("hex")}`);
|
|
38
|
-
try {
|
|
39
|
-
writeFileSync(tmp, content, "utf8");
|
|
40
|
-
renameSync(tmp, target);
|
|
41
|
-
}
|
|
42
|
-
catch (err) {
|
|
43
|
-
// Doubt-review fix (minor): mirror file-write.ts's performWrite — don't
|
|
44
|
-
// leave an orphaned .tmp-* file behind on a failed rename.
|
|
45
|
-
try {
|
|
46
|
-
if (existsSync(tmp))
|
|
47
|
-
unlinkSync(tmp);
|
|
48
|
-
}
|
|
49
|
-
catch {
|
|
50
|
-
/* swallow */
|
|
51
|
-
}
|
|
52
|
-
throw err;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
async function countersign(deps, timestamp, leadId) {
|
|
56
|
-
const lockFn = deps.withDecisionsLock ?? withDecisionsLock;
|
|
57
|
-
return lockFn(deps, (ctx) => {
|
|
58
|
-
const loggedRaw = ctx.readLogged();
|
|
59
|
-
const loggedEntries = parseLoggedEntries(loggedRaw);
|
|
60
|
-
const existing = findLoggedEntry(loggedEntries, timestamp, leadId);
|
|
61
|
-
if (existing) {
|
|
62
|
-
const proposedRaw = ctx.readProposed();
|
|
63
|
-
// External-review fix (MEDIUM, edge-case): two genuinely-distinct
|
|
64
|
-
// proposals can share the same (timestamp, leadId) pair (the ADR that
|
|
65
|
-
// adopted the pair as identity already acknowledged timestamp
|
|
66
|
-
// collisions are possible). `.find()` here used to silently discard
|
|
67
|
-
// every residual match past the first without ever logging it —
|
|
68
|
-
// indistinguishable from ordinary post-countersign cleanup. `.filter()`
|
|
69
|
-
// lets a genuine duplicate surface as a conflict instead.
|
|
70
|
-
const stillProposedMatches = parseProposedEntries(proposedRaw).filter((e) => e.timestamp === timestamp && e.leadId === leadId);
|
|
71
|
-
if (stillProposedMatches.length > 1) {
|
|
72
|
-
return { status: "duplicate_identity", count: stillProposedMatches.length };
|
|
73
|
-
}
|
|
74
|
-
if (stillProposedMatches.length === 1) {
|
|
75
|
-
const stillProposed = stillProposedMatches[0];
|
|
76
|
-
const nextProposed = proposedRaw.slice(0, stillProposed.startIndex) +
|
|
77
|
-
proposedRaw.slice(stillProposed.endIndex);
|
|
78
|
-
atomicWrite(ctx.proposedPath, nextProposed);
|
|
79
|
-
}
|
|
80
|
-
return { status: "already_countersigned", number: existing.number };
|
|
81
|
-
}
|
|
82
|
-
const proposedRaw = ctx.readProposed();
|
|
83
|
-
const matches = parseProposedEntries(proposedRaw).filter((e) => e.timestamp === timestamp && e.leadId === leadId);
|
|
84
|
-
if (matches.length === 0) {
|
|
85
|
-
return { status: "not_found" };
|
|
86
|
-
}
|
|
87
|
-
if (matches.length > 1) {
|
|
88
|
-
return { status: "duplicate_identity", count: matches.length };
|
|
89
|
-
}
|
|
90
|
-
const target = matches[0];
|
|
91
|
-
const number = nextLoggedNumber(loggedEntries);
|
|
92
|
-
const loggedBlock = toLoggedBlock(target.block, number);
|
|
93
|
-
const separator = loggedRaw.length > 0 && !loggedRaw.endsWith("\n") ? "\n" : "";
|
|
94
|
-
const nextLogged = loggedRaw + separator + loggedBlock;
|
|
95
|
-
const nextProposed = proposedRaw.slice(0, target.startIndex) + proposedRaw.slice(target.endIndex);
|
|
96
|
-
// Log FIRST (durable), then remove from proposed — the idempotent-retry
|
|
97
|
-
// check above trusts decision_log.md as "already done".
|
|
98
|
-
atomicWrite(ctx.loggedPath, nextLogged);
|
|
99
|
-
atomicWrite(ctx.proposedPath, nextProposed);
|
|
100
|
-
return { status: "countersigned", number };
|
|
101
|
-
});
|
|
102
|
-
}
|
|
12
|
+
import { handleCountersignRequest } from "./countersign-request.js";
|
|
13
|
+
export { performCountersign } from "./countersign-core.js";
|
|
14
|
+
export { handleCountersignRequest } from "./countersign-request.js";
|
|
103
15
|
export function registerCountersignRoute(app, deps) {
|
|
104
16
|
app.post("/api/external/org/decisions/countersign", async (c) => {
|
|
105
17
|
let body;
|
|
@@ -109,49 +21,8 @@ export function registerCountersignRoute(app, deps) {
|
|
|
109
21
|
catch {
|
|
110
22
|
return c.json({ error: "invalid_json" }, 400);
|
|
111
23
|
}
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
return c.json({ error: "timestamp_required" }, 400);
|
|
115
|
-
}
|
|
116
|
-
if (typeof leadId !== "string" || leadId.length === 0) {
|
|
117
|
-
return c.json({ error: "leadId_required" }, 400);
|
|
118
|
-
}
|
|
119
|
-
// External-review fix (MEDIUM, spec): the transfer format's identity pair
|
|
120
|
-
// is a canonical ISO-8601 timestamp + a kebab-case lead id, not merely
|
|
121
|
-
// "any non-empty string" — an arbitrary value silently 404s as
|
|
122
|
-
// proposal_not_found instead of being rejected as malformed input.
|
|
123
|
-
if (!ISO_TIMESTAMP_RE.test(timestamp)) {
|
|
124
|
-
return c.json({ error: "timestamp_invalid", timestamp }, 400);
|
|
125
|
-
}
|
|
126
|
-
if (!LEAD_ID_RE.test(leadId)) {
|
|
127
|
-
return c.json({ error: "leadId_invalid", leadId }, 400);
|
|
128
|
-
}
|
|
129
|
-
let outcome;
|
|
130
|
-
try {
|
|
131
|
-
outcome = await countersign(deps, timestamp, leadId);
|
|
132
|
-
}
|
|
133
|
-
catch (err) {
|
|
134
|
-
// Code-review fix: without this, a symlinked decisions-proposed.md /
|
|
135
|
-
// decision_log.md fell through to the generic 500 error handler
|
|
136
|
-
// instead of the family's typed 403 symlink_forbidden (file-write.ts
|
|
137
|
-
// applies the same defense class explicitly).
|
|
138
|
-
if (err instanceof OrgSymlinkEscapeError) {
|
|
139
|
-
return c.json({ error: "symlink_forbidden", path: err.path }, 403);
|
|
140
|
-
}
|
|
141
|
-
throw err;
|
|
142
|
-
}
|
|
143
|
-
if (outcome.status === "not_found") {
|
|
144
|
-
return c.json({ error: "proposal_not_found", timestamp, leadId }, 404);
|
|
145
|
-
}
|
|
146
|
-
if (outcome.status === "duplicate_identity") {
|
|
147
|
-
return c.json({ error: "duplicate_proposal_identity", timestamp, leadId, count: outcome.count }, 409);
|
|
148
|
-
}
|
|
149
|
-
return c.json({
|
|
150
|
-
countersigned: true,
|
|
151
|
-
alreadyCountersigned: outcome.status === "already_countersigned",
|
|
152
|
-
number: outcome.number,
|
|
153
|
-
adr: `ADR-${String(outcome.number).padStart(4, "0")}`,
|
|
154
|
-
});
|
|
24
|
+
const result = await handleCountersignRequest(deps, body);
|
|
25
|
+
return c.json(result.body, result.status);
|
|
155
26
|
});
|
|
156
27
|
}
|
|
157
28
|
//# sourceMappingURL=countersign.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"countersign.js","sourceRoot":"","sources":["../../../src/external/org/countersign.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"countersign.js","sourceRoot":"","sources":["../../../src/external/org/countersign.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAGpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAQpE,MAAM,UAAU,wBAAwB,CAAC,GAAS,EAAE,IAA0B;IAC5E,GAAG,CAAC,IAAI,CAAC,yCAAyC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC9D,IAAI,IAAa,CAAC;QAClB,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,GAAG,CAAC,CAAC;QAChD,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,wBAAwB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC1D,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Hono } from "hono";
|
|
2
|
+
import type { PreflightDaemonConfig } from "../../types/leadwright-preflight.js";
|
|
3
|
+
export interface DaemonConfigReadDeps {
|
|
4
|
+
leadsRoot: string;
|
|
5
|
+
webuiBaseUrl: string;
|
|
6
|
+
lstatSync?: (path: string) => {
|
|
7
|
+
isSymbolicLink(): boolean;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export type DaemonConfigReadCoreResult = {
|
|
11
|
+
status: 200;
|
|
12
|
+
body: {
|
|
13
|
+
found: true;
|
|
14
|
+
config: PreflightDaemonConfig;
|
|
15
|
+
} | {
|
|
16
|
+
found: false;
|
|
17
|
+
template: {
|
|
18
|
+
orgChartPath: string;
|
|
19
|
+
webuiBaseUrl: string;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
} | {
|
|
23
|
+
status: 403 | 500 | 502;
|
|
24
|
+
body: {
|
|
25
|
+
error: string;
|
|
26
|
+
detail?: string;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
export declare function daemonConfigReadCore(deps: DaemonConfigReadDeps): DaemonConfigReadCoreResult;
|
|
30
|
+
export declare function registerDaemonConfigReadRoute(app: Hono, deps: DaemonConfigReadDeps): void;
|
|
31
|
+
//# sourceMappingURL=daemon-config-read.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon-config-read.d.ts","sourceRoot":"","sources":["../../../src/external/org/daemon-config-read.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAIjC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAEjF,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;QAAE,cAAc,IAAI,OAAO,CAAA;KAAE,CAAC;CAC7D;AAED,MAAM,MAAM,0BAA0B,GAClC;IAAE,MAAM,EAAE,GAAG,CAAC;IAAC,IAAI,EAAE;QAAE,KAAK,EAAE,IAAI,CAAC;QAAC,MAAM,EAAE,qBAAqB,CAAA;KAAE,GAAG;QAAE,KAAK,EAAE,KAAK,CAAC;QAAC,QAAQ,EAAE;YAAE,YAAY,EAAE,MAAM,CAAC;YAAC,YAAY,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAA;CAAE,GAClJ;IAAE,MAAM,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;IAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC;AAE1E,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,oBAAoB,GAAG,0BAA0B,CAyC3F;AAED,wBAAgB,6BAA6B,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,oBAAoB,GAAG,IAAI,CAKzF"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { readFileSync, lstatSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
export function daemonConfigReadCore(deps) {
|
|
4
|
+
const { leadsRoot, webuiBaseUrl } = deps;
|
|
5
|
+
const lstat = deps.lstatSync ?? ((p) => lstatSync(p));
|
|
6
|
+
const target = path.join(leadsRoot, "daemon-config.json");
|
|
7
|
+
try {
|
|
8
|
+
if (lstat(target).isSymbolicLink()) {
|
|
9
|
+
return { status: 403, body: { error: "symlink_forbidden" } };
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
catch (err) {
|
|
13
|
+
const code = err?.code;
|
|
14
|
+
if (code !== "ENOENT") {
|
|
15
|
+
return { status: 500, body: { error: "daemon_config_stat_failed", detail: String(err).slice(0, 200) } };
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
let raw;
|
|
19
|
+
try {
|
|
20
|
+
raw = readFileSync(target, "utf8");
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
const code = err?.code;
|
|
24
|
+
if (code === "ENOENT") {
|
|
25
|
+
return {
|
|
26
|
+
status: 200,
|
|
27
|
+
body: { found: false, template: { orgChartPath: path.join(leadsRoot, "org-chart.json"), webuiBaseUrl } },
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
return { status: 500, body: { error: "daemon_config_read_failed", detail: String(err).slice(0, 200) } };
|
|
31
|
+
}
|
|
32
|
+
let parsed;
|
|
33
|
+
try {
|
|
34
|
+
parsed = JSON.parse(raw);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return { status: 502, body: { error: "daemon_config_invalid" } };
|
|
38
|
+
}
|
|
39
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
40
|
+
return { status: 502, body: { error: "daemon_config_invalid" } };
|
|
41
|
+
}
|
|
42
|
+
return { status: 200, body: { found: true, config: parsed } };
|
|
43
|
+
}
|
|
44
|
+
export function registerDaemonConfigReadRoute(app, deps) {
|
|
45
|
+
app.get("/api/external/org/daemon-config", async (c) => {
|
|
46
|
+
const result = daemonConfigReadCore(deps);
|
|
47
|
+
return c.json(result.body, result.status);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=daemon-config-read.js.map
|