chainlesschain 0.165.2 → 0.165.4
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/README.md +151 -29
- package/package.json +2 -2
- package/src/assets/web-panel/assets/{AIOps-lS1R0Cza.js → AIOps-C__nnraW.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-BmlgBPsj.js → ActionButton-CsKWHEZ-.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-CNKczv1S.js → Analytics-BhIjfjWO.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-BuZGJARQ.js → AppLayout-BjuXFzWZ.js} +4 -4
- package/src/assets/web-panel/assets/{Artifacts-Dm73Sl-O.js → Artifacts-k6whDkZJ.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-BGMW7A5e.js → Audit-C4FBMYRh.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-BQ6M54JR.js → BackgroundAgents-C_vRrSXk.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-DBzGP0bR.js → Backup-CngFZeVp.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-D1mLCoOV.js → BaseInput-B_H9EBRm.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-BUfcN7p8.js → Chat-DLEC5kt7.js} +4 -4
- package/src/assets/web-panel/assets/ChatBubbleRenderer-xijcWkJe.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-Du0Yg5Pi.js → Checkbox-m3ClR4xh.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-B2RXziHW.js → Codegen-CmLSFrgp.js} +1 -1
- package/src/assets/web-panel/assets/{Col-DWhekOrR.js → Col-DFGQteHN.js} +1 -1
- package/src/assets/web-panel/assets/{Community-HQhrkon4.js → Community-EUUVORHE.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-izHNb4uz.js → Compact-2PSg0Yr7.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-BDwLy41-.js → Compliance-CcKur7gB.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-DFJhLa7K.js → Cowork-DK_Fezfa.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-DYY9RG7-.js → Cron-Dbw89xl7.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-rr7tJTtv.js → Crosschain-CH66h_Ec.js} +1 -1
- package/src/assets/web-panel/assets/{DID-D2sfHRLi.js → DID-D1igRb17.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-q_eGdhha.js → Dashboard-DVAsrobk.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-Cufrh2Bz.js → Dropdown-Dl7W8AQs.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-B-kdv10f.js → EmailListRenderer-D5tpaEQC.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-D21XjgfG.js → FamilyGuardDashboard-O_VQf8gq.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-CAwRTLZH.js → Federation-BTVcgS9n.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-vx3daNDF.js → FormItemContext-BRnkJAIz.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-CRWY2wU4.js → GenericCardRenderer-8OWSCkDj.js} +1 -1
- package/src/assets/web-panel/assets/{Git-Q6SwauyD.js → Git-WXLYTQj2.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-BJ1q4IQZ.js → Governance-BezaUhtc.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-CSWjROgD.js → Inference-CuRay3Gu.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-fzuQsWuY.js → KnowledgeGraph-DfWLDW1m.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-DVF8Mnns.js → Logs-C55y2pPY.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-hDpWdiBc.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-BQP7LOA4.js → Marketplace-Dk08Uycg.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-BNlJCmNc.js → McpTools-C11fSB5V.js} +4 -4
- package/src/assets/web-panel/assets/{Memory-DLLg5WQ4.js → Memory-mr0eZc97.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-CR2skNAF.js → MobileBridge-C0iCSRbb.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-BxVavObl.js → MobileProjects-CY-xMG8Z.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-B17pgqMI.js → Mtc-Bplqc_Wc.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-4UmV5cIL.js → MtcAudit-BlzwsoSM.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-DoMEXEcU.js → Multisig-BBLmTty6.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-h9DMXFX4.js → NLProgramming-DtT1uf1W.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-Cihn-xX8.js → Notes-DcqQAxTK.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-BE6ZGa3R.js → NotificationSettings-cb0kWoZe.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-CnwojoSI.js → OrderTableRenderer-kw9HZQNN.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-B2vpwmjb.js → Organization-DlTlbkUN.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-C4z28R0-.js → Overflow-pp1qs-oY.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-BVlFkwhW.js → P2P-BESLnyYz.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-BXbEdL5B.js → PdhVaultBrowser-B-J1mGuf.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-C28xs4lp.js → Permissions-B36PeT1_.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-Dgl_rBjM.js → PersonalDataHub-CTK2ad-3.js} +3 -3
- package/src/assets/web-panel/assets/{Pipeline-3QUIhrKI.js → Pipeline-zJNGXsac.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-8Gh33OZ5.js → Privacy-b9fz0Qf0.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-BNmg4tZi.js → ProjectInit-DjZbZgiB.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-vgMfeCf9.js → ProjectSettings-C-hHJXlD.js} +2 -2
- package/src/assets/web-panel/assets/Projects-BC9KSDM6.js +1 -0
- package/src/assets/web-panel/assets/{Providers-CXoOa8eX.js → Providers-Dz-CAYYU.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-BhfTF0oS.js → QrScannerModal-A0yoQ3-3.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-C746HEAj.js → QuickAsk-DrFgFJNC.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-BSej8Eo0.js → Recommend-KC8hF1g4.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-f3gmnlG3.js → RemoteSession-DGTPIk6u.js} +3 -3
- package/src/assets/web-panel/assets/{Reputation-CyvybpkN.js → Reputation-QmbwM7Yk.js} +1 -1
- package/src/assets/web-panel/assets/{Row-DwV2PeYn.js → Row-BxjJylia.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-11GrzjZy.js → RssFeed-B7Wda1J6.js} +3 -3
- package/src/assets/web-panel/assets/{Search-BjKXkrAY.js → Search-_plQ_YSA.js} +1 -1
- package/src/assets/web-panel/assets/{Security-eWiFb9Yk.js → Security-CD2YJZfx.js} +2 -2
- package/src/assets/web-panel/assets/{Services-CdCsMAtt.js → Services-qQE7NmwE.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-4Q2UTKQ5.js → Skeleton-DgQqkFf7.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-v4rtYrRj.js → Skills-C4C0oFFt.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-CRhsFvd_.js → Sla-Px2N2B5c.js} +1 -1
- package/src/assets/web-panel/assets/SpeechSettings-DN6C3lQd.js +1 -0
- package/src/assets/web-panel/assets/{SyncSettings-D16zonl7.js → SyncSettings-jm5aH_m7.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-Xxozz0i_.js → Tasks-DlkJcv67.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-CXJpPtCT.js → Templates-DyrTHUBs.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-XRV0L1ZF.js → Tenant-mC434PtL.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-CYuO1i_w.js → Terminal-o0_s3NgK.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-BXqitWsu.js → TimelineRenderer-DAGlAXOw.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-BvPrDHIy.js → Tokens-BnulS_bs.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-DhCrSTf5.js → Trigger-suQbVXYM.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-DmsuZD6K.js → Trust-DbIJAPo5.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-D_yrts5C.js → UkeySign-CQNpbIHi.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-B01ihPrm.js → VideoEditing-D8aWCERk.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-DpUjKa-N.js → Wallet-CuLpYfZc.js} +2 -2
- package/src/assets/web-panel/assets/{WebAuthn-CL07yON6.js → WebAuthn-CsfG8ZMc.js} +2 -2
- package/src/assets/web-panel/assets/{WorkflowEditor-CLMflnRr.js → WorkflowEditor-BYsEAZbd.js} +1 -1
- package/src/assets/web-panel/assets/{chat-DtUqe8h_.js → chat-FT4Um3-I.js} +1 -1
- package/src/assets/web-panel/assets/{colors-DPKrgVfy.js → colors-CKbS_Wlt.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-BTt2GtOm.js → compact-item-CFJtzuJM.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-D_VeUc1J.js → createContext-B9kSRW6K.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-DJZ0gAMu.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-1kndiylj.js → hasIn-DR-x0Xpi.js} +1 -1
- package/src/assets/web-panel/assets/{index-dVc-CXY4.js → index-7jHr_A_k.js} +1 -1
- package/src/assets/web-panel/assets/{index-DFIZ_1Sf.js → index-B3ZX81mK.js} +1 -1
- package/src/assets/web-panel/assets/{index-fk2Rjacw.js → index-B7osrXqy.js} +3 -3
- package/src/assets/web-panel/assets/{index-CHG-KcS4.js → index-BGbPnC5x.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dbbymxpj.js → index-BI5hP_qy.js} +1 -1
- package/src/assets/web-panel/assets/{index-BaZAbw9A.js → index-BK3TiKVq.js} +1 -1
- package/src/assets/web-panel/assets/{index-CzjkKUmR.js → index-BVPU43b1.js} +1 -1
- package/src/assets/web-panel/assets/{index-BAXfRKfG.js → index-BW-t9n-q.js} +1 -1
- package/src/assets/web-panel/assets/{index-8nz_fmlj.js → index-BfFCQHL3.js} +1 -1
- package/src/assets/web-panel/assets/index-Bizb4hkw.js +1 -0
- package/src/assets/web-panel/assets/{index-DdkplL9R.js → index-Bt4fS2eL.js} +1 -1
- package/src/assets/web-panel/assets/{index-DG2MZQ3f.js → index-BwR7yc2h.js} +1 -1
- package/src/assets/web-panel/assets/{index-DfKBRdSS.js → index-Bzz0C1BZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-GsoUQ2M7.js → index-C2JvmYRc.js} +1 -1
- package/src/assets/web-panel/assets/{index-l1BETrDb.js → index-CGaXUsIs.js} +1 -1
- package/src/assets/web-panel/assets/{index-4bna2_SR.js → index-CJmIQ9XR.js} +1 -1
- package/src/assets/web-panel/assets/{index-DfGl8CqG.js → index-C_enk9I_.js} +1 -1
- package/src/assets/web-panel/assets/{index-D95OFht7.js → index-Cr2FLUsD.js} +1 -1
- package/src/assets/web-panel/assets/{index-DsJCDUJG.js → index-CvrCCqJt.js} +1 -1
- package/src/assets/web-panel/assets/{index-sDoMHTNA.js → index-D4LfPvWA.js} +1 -1
- package/src/assets/web-panel/assets/{index-By5n8up9.js → index-DMGmg497.js} +1 -1
- package/src/assets/web-panel/assets/{index-ocf06EVQ.js → index-DShSkww-.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bhudc_Ez.js → index-DTxNy0ZU.js} +1 -1
- package/src/assets/web-panel/assets/{index-CX81qSM4.js → index-DW4BWjTk.js} +1 -1
- package/src/assets/web-panel/assets/{index-BlDNVgBt.js → index-DWdqx7zI.js} +1 -1
- package/src/assets/web-panel/assets/{index-CcO04eDn.js → index-Dap9c3eD.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dwqmtk65.js → index-DcfxhKXR.js} +1 -1
- package/src/assets/web-panel/assets/{index-2eyAXE3d.js → index-DdkIhfi-.js} +1 -1
- package/src/assets/web-panel/assets/{index-brCInrzq.js → index-DeSgw-WV.js} +1 -1
- package/src/assets/web-panel/assets/{index-DJ8vXGOa.js → index-DiNUEpSQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-BHpBMWCh.js → index-DjEP7WkH.js} +1 -1
- package/src/assets/web-panel/assets/{index-m31Ka8hZ.js → index-DtkFqPVA.js} +1 -1
- package/src/assets/web-panel/assets/{index-CtF7EN49.js → index-KqDaCApw.js} +1 -1
- package/src/assets/web-panel/assets/index-OHSl-xCh.js +1 -0
- package/src/assets/web-panel/assets/{index-B9KvcS7R.js → index-OSzjTzGM.js} +1 -1
- package/src/assets/web-panel/assets/{index-CauoBQkH.js → index-QBSeNVO3.js} +1 -1
- package/src/assets/web-panel/assets/{index-FzdwcSy2.js → index-WE08gMJP.js} +1 -1
- package/src/assets/web-panel/assets/{index-DxdTdBix.js → index-r2VI1Ikk.js} +1 -1
- package/src/assets/web-panel/assets/{index-BepLZwgB.js → index-tqSEHPRT.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-CvyYJd7z.js → initDefaultProps-Dd7n7VgI.js} +1 -1
- package/src/assets/web-panel/assets/{motion-DYZkhUdz.js → motion-BwxouRw1.js} +1 -1
- package/src/assets/web-panel/assets/{move-slnJRVT1.js → move-DObN0PG9.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-DVc0CKmy.js → mtc-parser-B3nOUQc7.js} +1 -1
- package/src/assets/web-panel/assets/{omit-BCXAtHCq.js → omit-o9WU2Nbl.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-DBsemz_K.js → pickAttrs-CL_vvfQ_.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-BRtkJ-nv.js → placementArrow-CYrM2tyK.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-Cebq7EZn.js → responsiveObserve-k_06cQ96.js} +1 -1
- package/src/assets/web-panel/assets/{slide-DT7qvId2.js → slide-CPKG0pxS.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-pQiITLkG.js → statusUtils-BDDEeLTw.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-c-19BVKQ.js → styleChecker-Cmb7RTh7.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-DsS5-0bE.js → useFlexGapSupport-e2IedC4N.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-CxGiMe5n.js → useFs-CE_gxVnm.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-D9btVID5.js → usePersonalDataHub-BkMIIKMz.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-CUYFsFEN.js → vnode-DW886XV1.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-CXmn_35j.js → zoom-Dwo_adaf.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +3 -3
- package/src/commands/agent.js +105 -35
- package/src/commands/artifacts.js +363 -33
- package/src/commands/cowork.js +202 -36
- package/src/commands/session-budget.js +155 -0
- package/src/commands/session-location.js +948 -0
- package/src/commands/session.js +72 -46
- package/src/data/changelog.json +26 -0
- package/src/gateways/ws/artifact-protocol.js +77 -13
- package/src/gateways/ws/session-protocol.js +391 -24
- package/src/gateways/ws/ws-agent-handler.js +191 -14
- package/src/gateways/ws/ws-server.js +14 -3
- package/src/gateways/ws/ws-session-gateway.js +101 -5
- package/src/harness/jsonl-session-store.js +1210 -0
- package/src/lib/agent-team/team-runner.js +43 -13
- package/src/lib/artifact-access-ledger.js +461 -0
- package/src/lib/artifact-cleanup-ledger.js +861 -0
- package/src/lib/artifact-deletion-ledger.js +677 -0
- package/src/lib/artifact-store.js +256 -51
- package/src/lib/background-agent-keeper-protocol.js +75 -4
- package/src/lib/background-agent-launch-barrier.js +74 -0
- package/src/lib/background-agent-supervisor.js +149 -5
- package/src/lib/background-turn-bootstrap-protocol.js +4 -0
- package/src/lib/command-lifecycle-report.js +8 -4
- package/src/lib/cowork-adapter.js +9 -5
- package/src/lib/cowork-task-runner.js +20 -0
- package/src/lib/cowork-workflow.js +178 -20
- package/src/lib/direct-model-usage.js +62 -22
- package/src/lib/dynamic-workflow-runtime.js +3184 -111
- package/src/lib/execution-location-result-apply.js +339 -0
- package/src/lib/execution-location-result-artifact.js +271 -0
- package/src/lib/execution-location-result-review.js +253 -0
- package/src/lib/execution-location-result-store.js +331 -0
- package/src/lib/execution-location-result.js +617 -0
- package/src/lib/execution-location-target.js +236 -1
- package/src/lib/managed-tool-checkpoint.js +47 -4
- package/src/lib/process-execution-broker/workspace-transaction.js +3 -0
- package/src/lib/session-budget-production-root.js +376 -0
- package/src/lib/session-budget-runtime.js +109 -18
- package/src/lib/session-budget-usage.js +63 -0
- package/src/lib/session-host-snapshot.js +19 -2
- package/src/lib/session-resource-budget.js +766 -105
- package/src/lib/sub-agent-context.js +69 -22
- package/src/lib/web-ui-server.js +12 -1
- package/src/lib/with-file-lock.js +175 -26
- package/src/repl/agent-repl.js +237 -16
- package/src/runtime/agent-core.js +123 -0
- package/src/runtime/headless-runner.js +135 -46
- package/src/runtime/headless-stream.js +133 -25
- package/src/runtime/policies/agent-policy.js +10 -0
- package/src/workers/background-agent-keeper.js +112 -19
- package/src/workers/background-agent-worker.js +383 -134
- package/src/workers/background-turn-bootstrap.js +13 -8
- package/src/assets/web-panel/assets/ChatBubbleRenderer-CY5m8ZHg.js +0 -1
- package/src/assets/web-panel/assets/MarkdownRenderer-BLif4QSg.js +0 -1
- package/src/assets/web-panel/assets/Projects-BhtAVilc.js +0 -1
- package/src/assets/web-panel/assets/SpeechSettings-DLjKsDVu.js +0 -1
- package/src/assets/web-panel/assets/devWarning-Bj5nUW2v.js +0 -1
- package/src/assets/web-panel/assets/index-CPcM-eqo.js +0 -1
- package/src/assets/web-panel/assets/index-xeSyVoRe.js +0 -1
|
@@ -9,19 +9,57 @@ import {
|
|
|
9
9
|
import { captureAmbientExecutionLocation } from "../lib/execution-location-runtime.js";
|
|
10
10
|
import {
|
|
11
11
|
EXECUTION_LOCATION_TARGET_ATTESTATION_SCHEMA,
|
|
12
|
+
EXECUTION_LOCATION_TARGET_RESULT_COLLECTION_SCHEMA,
|
|
12
13
|
EXECUTION_LOCATION_TARGET_RESUME_SCHEMA,
|
|
13
14
|
attestExecutionLocationTarget,
|
|
15
|
+
collectExecutionLocationTargetResult,
|
|
16
|
+
createExecutionLocationTargetResultCollectionRequest,
|
|
14
17
|
readExecutionLocationProfile,
|
|
15
18
|
resumeExecutionLocationTarget,
|
|
16
19
|
} from "../lib/execution-location-target.js";
|
|
20
|
+
import {
|
|
21
|
+
EXECUTION_LOCATION_RESULT_BUNDLE_SCHEMA,
|
|
22
|
+
EXECUTION_LOCATION_RESULT_VERIFICATION_SCHEMA,
|
|
23
|
+
MAX_EXECUTION_LOCATION_RESULT_BUNDLE_BYTES,
|
|
24
|
+
createExecutionLocationResultBundle,
|
|
25
|
+
readExecutionLocationResultBundle,
|
|
26
|
+
readExecutionLocationResultFile,
|
|
27
|
+
verifyExecutionLocationResultBundle,
|
|
28
|
+
} from "../lib/execution-location-result.js";
|
|
17
29
|
import {
|
|
18
30
|
MAX_SESSION_REPLICA_BYTES,
|
|
19
31
|
SESSION_EXECUTION_LOCATION_HANDOFF_INSTALL_SCHEMA,
|
|
32
|
+
SESSION_EXECUTION_LOCATION_RESULT_APPLY_RECEIPT_SCHEMA,
|
|
33
|
+
SESSION_EXECUTION_LOCATION_RESULT_COLLECTION_RECEIPT_SCHEMA,
|
|
34
|
+
SESSION_EXECUTION_LOCATION_RESULT_COLLECTION_RECEIPT_SCHEMA_V1,
|
|
20
35
|
getVerifiedSessionExecutionLocationAuthority,
|
|
21
36
|
installSessionReplica,
|
|
22
37
|
installSessionReplicaWithLocationHandoff,
|
|
38
|
+
readVerifiedSessionExecutionLocationResultApply,
|
|
39
|
+
readVerifiedSessionExecutionLocationResultSettlement,
|
|
23
40
|
readVerifiedTranscriptBytes,
|
|
41
|
+
reserveSessionExecutionLocationResultApply,
|
|
42
|
+
settleSessionExecutionLocationResultApply,
|
|
43
|
+
settleSessionExecutionLocationResultCollection,
|
|
24
44
|
} from "../harness/jsonl-session-store.js";
|
|
45
|
+
import {
|
|
46
|
+
readStoredExecutionLocationResultBundle,
|
|
47
|
+
storeExecutionLocationResultBundle,
|
|
48
|
+
} from "../lib/execution-location-result-store.js";
|
|
49
|
+
import {
|
|
50
|
+
EXECUTION_LOCATION_RESULT_REVIEW_SCHEMA,
|
|
51
|
+
createExecutionLocationResultReview,
|
|
52
|
+
} from "../lib/execution-location-result-review.js";
|
|
53
|
+
import {
|
|
54
|
+
EXECUTION_LOCATION_RESULT_ARTIFACT_IMPORT_SCHEMA,
|
|
55
|
+
importExecutionLocationResultArtifact,
|
|
56
|
+
} from "../lib/execution-location-result-artifact.js";
|
|
57
|
+
import {
|
|
58
|
+
executeControlledExecutionLocationResultApply,
|
|
59
|
+
terminalExecutionLocationResultApplyTransaction,
|
|
60
|
+
verifyExecutionLocationResultApplySourceGit,
|
|
61
|
+
} from "../lib/execution-location-result-apply.js";
|
|
62
|
+
import { executionBroker } from "../lib/process-execution-broker/index.js";
|
|
25
63
|
import {
|
|
26
64
|
sameFileStatIdentity,
|
|
27
65
|
samePathHandleFileIdentity,
|
|
@@ -31,6 +69,8 @@ import {
|
|
|
31
69
|
const MAX_HANDOFF_FACTS_BYTES = 1024 * 1024;
|
|
32
70
|
export const SESSION_EXECUTION_LOCATION_AUTHORITY_SCHEMA =
|
|
33
71
|
"cc-session-execution-location-authority/v1";
|
|
72
|
+
export const EXECUTION_LOCATION_RESULT_PREVIEW_SCHEMA =
|
|
73
|
+
"cc-execution-location-result-preview/v1";
|
|
34
74
|
|
|
35
75
|
function readHandoffFacts(filePath, deps = {}) {
|
|
36
76
|
const runtimeFs = deps.fs || fs;
|
|
@@ -314,6 +354,621 @@ export function prepareSessionReplicaHandoff(sessionId, options, deps = {}) {
|
|
|
314
354
|
);
|
|
315
355
|
}
|
|
316
356
|
|
|
357
|
+
function parseResultFileSpec(value, label) {
|
|
358
|
+
const text = String(value || "");
|
|
359
|
+
const separator = text.indexOf("=");
|
|
360
|
+
if (separator <= 0 || separator === text.length - 1) {
|
|
361
|
+
throw new Error(`${label} must be <media-type>=<path>`);
|
|
362
|
+
}
|
|
363
|
+
return {
|
|
364
|
+
mediaType: text.slice(0, separator),
|
|
365
|
+
path: text.slice(separator + 1),
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
function collectResultFileSpec(value, previous) {
|
|
370
|
+
return [...previous, value];
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
function resultBoundary(authority) {
|
|
374
|
+
const root = authority?.binding?.policy?.dataBoundary?.root;
|
|
375
|
+
if (typeof root !== "string" || root.length === 0) {
|
|
376
|
+
throw new Error(
|
|
377
|
+
"verified execution location data boundary is required for result files",
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
return root;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
export function createSessionExecutionLocationResultBundle(
|
|
384
|
+
sessionId,
|
|
385
|
+
options,
|
|
386
|
+
deps = {},
|
|
387
|
+
) {
|
|
388
|
+
const sessionAuthority = projectSessionExecutionLocation(sessionId, deps);
|
|
389
|
+
const boundaryRoot = resultBoundary(sessionAuthority);
|
|
390
|
+
const readFile =
|
|
391
|
+
deps.readExecutionLocationResultFile || readExecutionLocationResultFile;
|
|
392
|
+
const read = (filePath, fileOptions = {}) =>
|
|
393
|
+
readFile(filePath, {
|
|
394
|
+
boundaryRoot,
|
|
395
|
+
...fileOptions,
|
|
396
|
+
...(deps.resultFileDependencies || {}),
|
|
397
|
+
});
|
|
398
|
+
const readItems = (values, label) =>
|
|
399
|
+
(values || []).map((value) => {
|
|
400
|
+
const spec = parseResultFileSpec(value, label);
|
|
401
|
+
return {
|
|
402
|
+
mediaType: spec.mediaType,
|
|
403
|
+
bytes: read(spec.path, { allowEmpty: true }),
|
|
404
|
+
};
|
|
405
|
+
});
|
|
406
|
+
return (
|
|
407
|
+
deps.createExecutionLocationResultBundle ||
|
|
408
|
+
createExecutionLocationResultBundle
|
|
409
|
+
)({
|
|
410
|
+
sessionAuthority,
|
|
411
|
+
resultId: options.resultId,
|
|
412
|
+
summaryBytes: read(options.summary),
|
|
413
|
+
diffBytes: read(options.diff, { allowEmpty: true }),
|
|
414
|
+
artifacts: readItems(options.artifact, "--artifact"),
|
|
415
|
+
evidence: readItems(options.evidence, "--evidence"),
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
export function verifySessionExecutionLocationResultBundle(
|
|
420
|
+
sessionId,
|
|
421
|
+
bundlePath,
|
|
422
|
+
expectedHandoffId,
|
|
423
|
+
deps = {},
|
|
424
|
+
) {
|
|
425
|
+
const sourceAuthority = projectSessionExecutionLocation(sessionId, deps);
|
|
426
|
+
const boundaryRoot = resultBoundary(sourceAuthority);
|
|
427
|
+
const bundle = (
|
|
428
|
+
deps.readExecutionLocationResultBundle || readExecutionLocationResultBundle
|
|
429
|
+
)(bundlePath, {
|
|
430
|
+
boundaryRoot,
|
|
431
|
+
maxBytes: MAX_EXECUTION_LOCATION_RESULT_BUNDLE_BYTES,
|
|
432
|
+
...(deps.resultFileDependencies || {}),
|
|
433
|
+
});
|
|
434
|
+
return (
|
|
435
|
+
deps.verifyExecutionLocationResultBundle ||
|
|
436
|
+
verifyExecutionLocationResultBundle
|
|
437
|
+
)({
|
|
438
|
+
bundle,
|
|
439
|
+
sourceAuthority,
|
|
440
|
+
expectedHandoffId,
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
export function collectSessionExecutionLocationResult(
|
|
445
|
+
sessionId,
|
|
446
|
+
target,
|
|
447
|
+
options,
|
|
448
|
+
deps = {},
|
|
449
|
+
) {
|
|
450
|
+
const profile = (
|
|
451
|
+
deps.readExecutionLocationProfile || readExecutionLocationProfile
|
|
452
|
+
)(options.profile, deps);
|
|
453
|
+
const parseItems = (values, label) =>
|
|
454
|
+
(values || []).map((value) => parseResultFileSpec(value, label));
|
|
455
|
+
const artifacts = parseItems(options.artifact, "--artifact");
|
|
456
|
+
const evidence = parseItems(options.evidence, "--evidence");
|
|
457
|
+
const request = (
|
|
458
|
+
deps.createExecutionLocationTargetResultCollectionRequest ||
|
|
459
|
+
createExecutionLocationTargetResultCollectionRequest
|
|
460
|
+
)({
|
|
461
|
+
requestId: options.requestId,
|
|
462
|
+
sessionId,
|
|
463
|
+
target,
|
|
464
|
+
profile,
|
|
465
|
+
expectedTargetFactsDigest: options.expectedTargetFactsDigest,
|
|
466
|
+
expectedHandoffId: options.expectedHandoffId,
|
|
467
|
+
resultId: options.resultId,
|
|
468
|
+
summaryPath: options.summary,
|
|
469
|
+
diffPath: options.diff,
|
|
470
|
+
artifacts,
|
|
471
|
+
evidence,
|
|
472
|
+
});
|
|
473
|
+
const prior = (
|
|
474
|
+
deps.readVerifiedSessionExecutionLocationResultSettlement ||
|
|
475
|
+
readVerifiedSessionExecutionLocationResultSettlement
|
|
476
|
+
)(sessionId, request.requestId, { requestDigest: request.requestDigest });
|
|
477
|
+
if (prior !== null) {
|
|
478
|
+
if (prior.storage) {
|
|
479
|
+
const bundle = (
|
|
480
|
+
deps.readStoredExecutionLocationResultBundle ||
|
|
481
|
+
readStoredExecutionLocationResultBundle
|
|
482
|
+
)(prior.storage, deps.resultStoreOptions || {});
|
|
483
|
+
const verification = (
|
|
484
|
+
deps.verifyExecutionLocationResultBundle ||
|
|
485
|
+
verifyExecutionLocationResultBundle
|
|
486
|
+
)({
|
|
487
|
+
bundle,
|
|
488
|
+
sourceAuthority: {
|
|
489
|
+
sessionId: prior.sessionId,
|
|
490
|
+
headHash: prior.sourceHeadHash,
|
|
491
|
+
eventCount: prior.sourceEventCount,
|
|
492
|
+
},
|
|
493
|
+
expectedHandoffId: prior.handoffId,
|
|
494
|
+
});
|
|
495
|
+
if (
|
|
496
|
+
verification.verificationDigest !== prior.verificationDigest ||
|
|
497
|
+
bundle.bundleDigest !== prior.bundleDigest
|
|
498
|
+
) {
|
|
499
|
+
throw new Error("stored result bundle does not match settlement");
|
|
500
|
+
}
|
|
501
|
+
return Object.freeze({
|
|
502
|
+
...prior,
|
|
503
|
+
settlementAppended: false,
|
|
504
|
+
recovered: true,
|
|
505
|
+
bundleAvailable: true,
|
|
506
|
+
bundle,
|
|
507
|
+
verification,
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
return Object.freeze({
|
|
511
|
+
...prior,
|
|
512
|
+
settlementAppended: false,
|
|
513
|
+
recovered: true,
|
|
514
|
+
bundleAvailable: false,
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
const handoff = projectExecutionLocationHandoff(
|
|
518
|
+
sessionId,
|
|
519
|
+
target,
|
|
520
|
+
options.facts,
|
|
521
|
+
deps,
|
|
522
|
+
);
|
|
523
|
+
const readSourceAuthority = () => {
|
|
524
|
+
const authority = (
|
|
525
|
+
deps.getVerifiedSessionExecutionLocationAuthority ||
|
|
526
|
+
getVerifiedSessionExecutionLocationAuthority
|
|
527
|
+
)(sessionId);
|
|
528
|
+
return {
|
|
529
|
+
sessionId: authority.sessionId,
|
|
530
|
+
headHash: authority.headHash,
|
|
531
|
+
eventCount: authority.eventCount,
|
|
532
|
+
};
|
|
533
|
+
};
|
|
534
|
+
const collection = (
|
|
535
|
+
deps.collectExecutionLocationTargetResult ||
|
|
536
|
+
collectExecutionLocationTargetResult
|
|
537
|
+
)(
|
|
538
|
+
{
|
|
539
|
+
requestId: request.requestId,
|
|
540
|
+
handoff,
|
|
541
|
+
profile,
|
|
542
|
+
expectedTargetFactsDigest: options.expectedTargetFactsDigest,
|
|
543
|
+
expectedHandoffId: options.expectedHandoffId,
|
|
544
|
+
resultId: options.resultId,
|
|
545
|
+
summaryPath: options.summary,
|
|
546
|
+
diffPath: options.diff,
|
|
547
|
+
artifacts,
|
|
548
|
+
evidence,
|
|
549
|
+
readSourceAuthority,
|
|
550
|
+
},
|
|
551
|
+
deps,
|
|
552
|
+
);
|
|
553
|
+
if (collection.requestDigest !== request.requestDigest) {
|
|
554
|
+
throw new Error(
|
|
555
|
+
"result collection request digest changed during collection",
|
|
556
|
+
);
|
|
557
|
+
}
|
|
558
|
+
const storage = (
|
|
559
|
+
deps.storeExecutionLocationResultBundle ||
|
|
560
|
+
storeExecutionLocationResultBundle
|
|
561
|
+
)(collection.bundle, deps.resultStoreOptions || {});
|
|
562
|
+
const settlement = (
|
|
563
|
+
deps.settleSessionExecutionLocationResultCollection ||
|
|
564
|
+
settleSessionExecutionLocationResultCollection
|
|
565
|
+
)(sessionId, request.requestId, collection, storage.receipt);
|
|
566
|
+
return Object.freeze({
|
|
567
|
+
...collection,
|
|
568
|
+
storage: Object.freeze({ ...storage.receipt, stored: storage.stored }),
|
|
569
|
+
settlement,
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
function readSessionExecutionLocationResultReviewAuthority(
|
|
574
|
+
sessionId,
|
|
575
|
+
requestId,
|
|
576
|
+
deps,
|
|
577
|
+
) {
|
|
578
|
+
const settlement = (
|
|
579
|
+
deps.readVerifiedSessionExecutionLocationResultSettlement ||
|
|
580
|
+
readVerifiedSessionExecutionLocationResultSettlement
|
|
581
|
+
)(sessionId, requestId);
|
|
582
|
+
if (settlement === null) {
|
|
583
|
+
throw new Error("result collection settlement was not found");
|
|
584
|
+
}
|
|
585
|
+
if (!settlement.storage) {
|
|
586
|
+
throw new Error(
|
|
587
|
+
"legacy result settlement has no durable bundle available for review",
|
|
588
|
+
);
|
|
589
|
+
}
|
|
590
|
+
const bundle = (
|
|
591
|
+
deps.readStoredExecutionLocationResultBundle ||
|
|
592
|
+
readStoredExecutionLocationResultBundle
|
|
593
|
+
)(settlement.storage, deps.resultStoreOptions || {});
|
|
594
|
+
const review = (
|
|
595
|
+
deps.createExecutionLocationResultReview ||
|
|
596
|
+
createExecutionLocationResultReview
|
|
597
|
+
)({ settlement, bundle });
|
|
598
|
+
return Object.freeze({ settlement, bundle, review });
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
export function reviewSessionExecutionLocationResult(
|
|
602
|
+
sessionId,
|
|
603
|
+
requestId,
|
|
604
|
+
deps = {},
|
|
605
|
+
) {
|
|
606
|
+
return readSessionExecutionLocationResultReviewAuthority(
|
|
607
|
+
sessionId,
|
|
608
|
+
requestId,
|
|
609
|
+
deps,
|
|
610
|
+
).review;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
function selectResultPreviewRecord(bundle, selectorInput) {
|
|
614
|
+
const selector = String(selectorInput || "");
|
|
615
|
+
if (selector === "summary" || selector === "diff") {
|
|
616
|
+
return { kind: selector, record: bundle[selector] };
|
|
617
|
+
}
|
|
618
|
+
const match = /^(artifact|evidence):(sha256:[a-f0-9]{64})$/u.exec(selector);
|
|
619
|
+
if (!match) {
|
|
620
|
+
throw new Error(
|
|
621
|
+
"result preview item must be summary, diff, artifact:<sha256>, or evidence:<sha256>",
|
|
622
|
+
);
|
|
623
|
+
}
|
|
624
|
+
const [, kind, digest] = match;
|
|
625
|
+
const record = bundle[kind === "artifact" ? "artifacts" : "evidence"].find(
|
|
626
|
+
(entry) => entry.digest === digest,
|
|
627
|
+
);
|
|
628
|
+
if (!record) {
|
|
629
|
+
throw new Error(`reviewed ${kind} digest was not found`);
|
|
630
|
+
}
|
|
631
|
+
return { kind, record };
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
export function previewSessionExecutionLocationResult(
|
|
635
|
+
sessionId,
|
|
636
|
+
requestId,
|
|
637
|
+
reviewDigest,
|
|
638
|
+
item,
|
|
639
|
+
deps = {},
|
|
640
|
+
) {
|
|
641
|
+
const loaded = readSessionExecutionLocationResultReviewAuthority(
|
|
642
|
+
sessionId,
|
|
643
|
+
requestId,
|
|
644
|
+
deps,
|
|
645
|
+
);
|
|
646
|
+
assertReviewDigest(loaded.review, reviewDigest);
|
|
647
|
+
const selected = selectResultPreviewRecord(loaded.bundle, item);
|
|
648
|
+
const bytes = Buffer.from(selected.record.contentBase64, "base64");
|
|
649
|
+
const reviewedRecord =
|
|
650
|
+
selected.kind === "artifact" || selected.kind === "evidence"
|
|
651
|
+
? loaded.review[
|
|
652
|
+
selected.kind === "artifact" ? "artifacts" : "evidence"
|
|
653
|
+
].find((entry) => entry.digest === selected.record.digest)
|
|
654
|
+
: loaded.review[selected.kind];
|
|
655
|
+
if (
|
|
656
|
+
bytes.byteLength !== selected.record.byteLength ||
|
|
657
|
+
reviewedRecord?.digest !== selected.record.digest ||
|
|
658
|
+
reviewedRecord?.byteLength !== selected.record.byteLength ||
|
|
659
|
+
reviewedRecord?.mediaType !== selected.record.mediaType
|
|
660
|
+
) {
|
|
661
|
+
throw new Error(
|
|
662
|
+
"result preview content no longer matches review authority",
|
|
663
|
+
);
|
|
664
|
+
}
|
|
665
|
+
return Object.freeze({
|
|
666
|
+
schema: EXECUTION_LOCATION_RESULT_PREVIEW_SCHEMA,
|
|
667
|
+
sessionId,
|
|
668
|
+
requestId,
|
|
669
|
+
reviewDigest: loaded.review.reviewDigest,
|
|
670
|
+
item: String(item),
|
|
671
|
+
kind: selected.kind,
|
|
672
|
+
mediaType: selected.record.mediaType,
|
|
673
|
+
byteLength: selected.record.byteLength,
|
|
674
|
+
digest: selected.record.digest,
|
|
675
|
+
bytes,
|
|
676
|
+
});
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
export function importSessionExecutionLocationResultArtifact(
|
|
680
|
+
sessionId,
|
|
681
|
+
requestId,
|
|
682
|
+
reviewDigest,
|
|
683
|
+
item,
|
|
684
|
+
deps = {},
|
|
685
|
+
) {
|
|
686
|
+
const preview = previewSessionExecutionLocationResult(
|
|
687
|
+
sessionId,
|
|
688
|
+
requestId,
|
|
689
|
+
reviewDigest,
|
|
690
|
+
item,
|
|
691
|
+
deps,
|
|
692
|
+
);
|
|
693
|
+
return (
|
|
694
|
+
deps.importExecutionLocationResultArtifact ||
|
|
695
|
+
importExecutionLocationResultArtifact
|
|
696
|
+
)(preview, { artifactStore: deps.artifactStore });
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
function terminalSafeText(bytes) {
|
|
700
|
+
const text = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
701
|
+
return text.replace(
|
|
702
|
+
// The explicit control ranges are the terminal-injection boundary.
|
|
703
|
+
// eslint-disable-next-line no-control-regex
|
|
704
|
+
/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f-\u009f\u200e\u200f\u202a-\u202e\u2066-\u2069]/gu,
|
|
705
|
+
(character) =>
|
|
706
|
+
character.codePointAt(0) <= 0xff
|
|
707
|
+
? `\\x${character.codePointAt(0).toString(16).padStart(2, "0")}`
|
|
708
|
+
: `\\u${character.codePointAt(0).toString(16).padStart(4, "0")}`,
|
|
709
|
+
);
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
export function writeSessionExecutionLocationResultPreview(preview, deps = {}) {
|
|
713
|
+
const output = deps.stdout || process.stdout;
|
|
714
|
+
const isTerminal = deps.isTTY ?? output.isTTY === true;
|
|
715
|
+
if (!isTerminal) {
|
|
716
|
+
output.write(preview.bytes);
|
|
717
|
+
return;
|
|
718
|
+
}
|
|
719
|
+
if (!["summary", "diff"].includes(preview.kind)) {
|
|
720
|
+
throw new Error(
|
|
721
|
+
"binary artifact/evidence preview requires redirected stdout",
|
|
722
|
+
);
|
|
723
|
+
}
|
|
724
|
+
output.write(terminalSafeText(preview.bytes));
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
function assertReviewDigest(review, expectedReviewDigest) {
|
|
728
|
+
if (review.reviewDigest !== String(expectedReviewDigest || "")) {
|
|
729
|
+
throw new Error(
|
|
730
|
+
"result apply review digest does not match stored authority",
|
|
731
|
+
);
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
function resultApplyProjection(receipt, options = {}) {
|
|
736
|
+
return Object.freeze({
|
|
737
|
+
...receipt,
|
|
738
|
+
recovered: options.recovered === true,
|
|
739
|
+
allowed: receipt.applied === true,
|
|
740
|
+
stage: options.stage || (receipt.applied ? "complete" : receipt.status),
|
|
741
|
+
process: options.process || null,
|
|
742
|
+
});
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
function settleResultApplyFromTransaction(
|
|
746
|
+
sessionId,
|
|
747
|
+
applyId,
|
|
748
|
+
transactionState,
|
|
749
|
+
deps,
|
|
750
|
+
options = {},
|
|
751
|
+
) {
|
|
752
|
+
const terminalTransaction = (
|
|
753
|
+
deps.terminalExecutionLocationResultApplyTransaction ||
|
|
754
|
+
terminalExecutionLocationResultApplyTransaction
|
|
755
|
+
)(transactionState);
|
|
756
|
+
const outcome =
|
|
757
|
+
transactionState.state === "committed" ? "applied" : "rolled_back";
|
|
758
|
+
const receipt = (
|
|
759
|
+
deps.settleSessionExecutionLocationResultApply ||
|
|
760
|
+
settleSessionExecutionLocationResultApply
|
|
761
|
+
)(sessionId, applyId, outcome, terminalTransaction);
|
|
762
|
+
return resultApplyProjection(receipt, {
|
|
763
|
+
recovered: options.recovered,
|
|
764
|
+
stage: options.stage || (outcome === "applied" ? "complete" : "recovery"),
|
|
765
|
+
process: options.process,
|
|
766
|
+
});
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
function readPriorResultApply(sessionId, applyId, deps) {
|
|
770
|
+
return (
|
|
771
|
+
deps.readVerifiedSessionExecutionLocationResultApply ||
|
|
772
|
+
readVerifiedSessionExecutionLocationResultApply
|
|
773
|
+
)(sessionId, applyId);
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
function inspectResultApplyTransaction(receipt, deps) {
|
|
777
|
+
const broker = deps.executionBroker || executionBroker;
|
|
778
|
+
if (typeof broker.inspectWorkspaceTransaction !== "function") {
|
|
779
|
+
throw new Error("result apply transaction inspection is unavailable");
|
|
780
|
+
}
|
|
781
|
+
return broker.inspectWorkspaceTransaction(receipt.transaction.id, {
|
|
782
|
+
...(deps.transactionStateDir ? { stateDir: deps.transactionStateDir } : {}),
|
|
783
|
+
});
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
export function applySessionExecutionLocationResult(
|
|
787
|
+
sessionId,
|
|
788
|
+
options,
|
|
789
|
+
deps = {},
|
|
790
|
+
) {
|
|
791
|
+
const loaded = readSessionExecutionLocationResultReviewAuthority(
|
|
792
|
+
sessionId,
|
|
793
|
+
options.requestId,
|
|
794
|
+
deps,
|
|
795
|
+
);
|
|
796
|
+
assertReviewDigest(loaded.review, options.reviewDigest);
|
|
797
|
+
const prior = readPriorResultApply(sessionId, options.applyId, deps);
|
|
798
|
+
if (prior !== null && prior.terminal !== null) {
|
|
799
|
+
if (
|
|
800
|
+
prior.requestId !== options.requestId ||
|
|
801
|
+
prior.reviewDigest !== loaded.review.reviewDigest
|
|
802
|
+
) {
|
|
803
|
+
throw new Error("result apply id is already bound to different inputs");
|
|
804
|
+
}
|
|
805
|
+
return resultApplyProjection(prior, { recovered: true });
|
|
806
|
+
}
|
|
807
|
+
if (prior !== null) {
|
|
808
|
+
if (
|
|
809
|
+
prior.requestId !== options.requestId ||
|
|
810
|
+
prior.reviewDigest !== loaded.review.reviewDigest
|
|
811
|
+
) {
|
|
812
|
+
throw new Error("result apply id is already bound to different inputs");
|
|
813
|
+
}
|
|
814
|
+
const transactionState = inspectResultApplyTransaction(prior, deps);
|
|
815
|
+
if (["committed", "rolled_back"].includes(transactionState.state)) {
|
|
816
|
+
return settleResultApplyFromTransaction(
|
|
817
|
+
sessionId,
|
|
818
|
+
options.applyId,
|
|
819
|
+
transactionState,
|
|
820
|
+
deps,
|
|
821
|
+
{ recovered: true },
|
|
822
|
+
);
|
|
823
|
+
}
|
|
824
|
+
throw new Error(
|
|
825
|
+
`result apply recovery is required for transaction ${prior.transaction.id}`,
|
|
826
|
+
);
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
const authority = (
|
|
830
|
+
deps.getVerifiedSessionExecutionLocationAuthority ||
|
|
831
|
+
getVerifiedSessionExecutionLocationAuthority
|
|
832
|
+
)(sessionId);
|
|
833
|
+
if (
|
|
834
|
+
authority.headHash !== loaded.settlement.settlementEventHash ||
|
|
835
|
+
authority.eventCount !== loaded.settlement.settlementEventCount
|
|
836
|
+
) {
|
|
837
|
+
throw new Error("source session advanced after result settlement");
|
|
838
|
+
}
|
|
839
|
+
const broker = deps.executionBroker || executionBroker;
|
|
840
|
+
const source = (
|
|
841
|
+
deps.verifyExecutionLocationResultApplySourceGit ||
|
|
842
|
+
verifyExecutionLocationResultApplySourceGit
|
|
843
|
+
)(authority, {
|
|
844
|
+
broker,
|
|
845
|
+
workspaceRoot: options.workspace,
|
|
846
|
+
platform: deps.platform,
|
|
847
|
+
});
|
|
848
|
+
const diffBytes = Buffer.from(loaded.bundle.diff.contentBase64, "base64");
|
|
849
|
+
const execution = (
|
|
850
|
+
deps.executeControlledExecutionLocationResultApply ||
|
|
851
|
+
executeControlledExecutionLocationResultApply
|
|
852
|
+
)({
|
|
853
|
+
broker,
|
|
854
|
+
sessionId,
|
|
855
|
+
applyId: options.applyId,
|
|
856
|
+
workspaceRoot: source.workspaceRoot,
|
|
857
|
+
diffBytes,
|
|
858
|
+
...(deps.transactionStateDir ? { stateDir: deps.transactionStateDir } : {}),
|
|
859
|
+
onPrepared: (transaction) => {
|
|
860
|
+
const pinnedSource = (
|
|
861
|
+
deps.verifyExecutionLocationResultApplySourceGit ||
|
|
862
|
+
verifyExecutionLocationResultApplySourceGit
|
|
863
|
+
)(authority, {
|
|
864
|
+
broker,
|
|
865
|
+
workspaceRoot: source.workspaceRoot,
|
|
866
|
+
platform: deps.platform,
|
|
867
|
+
});
|
|
868
|
+
if (
|
|
869
|
+
pinnedSource.sourceGit.rootDigest !== source.sourceGit.rootDigest ||
|
|
870
|
+
pinnedSource.sourceGit.commit !== source.sourceGit.commit
|
|
871
|
+
) {
|
|
872
|
+
throw new Error("source Git identity changed during apply preparation");
|
|
873
|
+
}
|
|
874
|
+
return (
|
|
875
|
+
deps.reserveSessionExecutionLocationResultApply ||
|
|
876
|
+
reserveSessionExecutionLocationResultApply
|
|
877
|
+
)(
|
|
878
|
+
sessionId,
|
|
879
|
+
options.applyId,
|
|
880
|
+
loaded.review,
|
|
881
|
+
pinnedSource.sourceGit,
|
|
882
|
+
transaction,
|
|
883
|
+
);
|
|
884
|
+
},
|
|
885
|
+
});
|
|
886
|
+
if (execution.stage === "reservation") {
|
|
887
|
+
const reserved = readPriorResultApply(sessionId, options.applyId, deps);
|
|
888
|
+
if (reserved === null) throw execution.error;
|
|
889
|
+
if (
|
|
890
|
+
reserved.reviewDigest !== loaded.review.reviewDigest ||
|
|
891
|
+
reserved.transaction.id !== execution.transaction.id
|
|
892
|
+
) {
|
|
893
|
+
throw new Error("result apply reservation response is ambiguous");
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
const receipt = (
|
|
897
|
+
deps.settleSessionExecutionLocationResultApply ||
|
|
898
|
+
settleSessionExecutionLocationResultApply
|
|
899
|
+
)(sessionId, options.applyId, execution.outcome, execution.transaction);
|
|
900
|
+
return resultApplyProjection(receipt, {
|
|
901
|
+
stage: execution.stage,
|
|
902
|
+
process: execution.process,
|
|
903
|
+
});
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
export function recoverSessionExecutionLocationResultApply(
|
|
907
|
+
sessionId,
|
|
908
|
+
options,
|
|
909
|
+
deps = {},
|
|
910
|
+
) {
|
|
911
|
+
const loaded = readSessionExecutionLocationResultReviewAuthority(
|
|
912
|
+
sessionId,
|
|
913
|
+
options.requestId,
|
|
914
|
+
deps,
|
|
915
|
+
);
|
|
916
|
+
assertReviewDigest(loaded.review, options.reviewDigest);
|
|
917
|
+
const prior = readPriorResultApply(sessionId, options.applyId, deps);
|
|
918
|
+
if (prior === null) {
|
|
919
|
+
throw new Error("result apply reservation was not found");
|
|
920
|
+
}
|
|
921
|
+
if (
|
|
922
|
+
prior.requestId !== options.requestId ||
|
|
923
|
+
prior.reviewDigest !== loaded.review.reviewDigest
|
|
924
|
+
) {
|
|
925
|
+
throw new Error("result apply recovery authority does not match review");
|
|
926
|
+
}
|
|
927
|
+
if (prior.terminal !== null) {
|
|
928
|
+
return resultApplyProjection(prior, { recovered: true });
|
|
929
|
+
}
|
|
930
|
+
const broker = deps.executionBroker || executionBroker;
|
|
931
|
+
const authority = (
|
|
932
|
+
deps.getVerifiedSessionExecutionLocationAuthority ||
|
|
933
|
+
getVerifiedSessionExecutionLocationAuthority
|
|
934
|
+
)(sessionId);
|
|
935
|
+
const source = (
|
|
936
|
+
deps.verifyExecutionLocationResultApplySourceGit ||
|
|
937
|
+
verifyExecutionLocationResultApplySourceGit
|
|
938
|
+
)(authority, {
|
|
939
|
+
broker,
|
|
940
|
+
workspaceRoot: options.workspace,
|
|
941
|
+
platform: deps.platform,
|
|
942
|
+
});
|
|
943
|
+
let transactionState = inspectResultApplyTransaction(prior, deps);
|
|
944
|
+
if (!["committed", "rolled_back"].includes(transactionState.state)) {
|
|
945
|
+
if (typeof broker.recoverWorkspaceTransactions !== "function") {
|
|
946
|
+
throw new Error("result apply workspace recovery is unavailable");
|
|
947
|
+
}
|
|
948
|
+
broker.recoverWorkspaceTransactions({
|
|
949
|
+
id: prior.transaction.id,
|
|
950
|
+
workspaceRoot: source.workspaceRoot,
|
|
951
|
+
reason: "explicit session result apply recovery",
|
|
952
|
+
...(deps.transactionStateDir
|
|
953
|
+
? { stateDir: deps.transactionStateDir }
|
|
954
|
+
: {}),
|
|
955
|
+
});
|
|
956
|
+
transactionState = inspectResultApplyTransaction(prior, deps);
|
|
957
|
+
}
|
|
958
|
+
if (!["committed", "rolled_back"].includes(transactionState.state)) {
|
|
959
|
+
throw new Error(
|
|
960
|
+
`result apply transaction still requires manual recovery: ${transactionState.state}`,
|
|
961
|
+
);
|
|
962
|
+
}
|
|
963
|
+
return settleResultApplyFromTransaction(
|
|
964
|
+
sessionId,
|
|
965
|
+
options.applyId,
|
|
966
|
+
transactionState,
|
|
967
|
+
deps,
|
|
968
|
+
{ recovered: true, stage: "recovery" },
|
|
969
|
+
);
|
|
970
|
+
}
|
|
971
|
+
|
|
317
972
|
function renderBinding(binding) {
|
|
318
973
|
const git = binding.source.git;
|
|
319
974
|
return [
|
|
@@ -350,6 +1005,57 @@ function writeProjection(projection, options = {}) {
|
|
|
350
1005
|
);
|
|
351
1006
|
return;
|
|
352
1007
|
}
|
|
1008
|
+
if (projection.schema === EXECUTION_LOCATION_RESULT_BUNDLE_SCHEMA) {
|
|
1009
|
+
process.stdout.write(
|
|
1010
|
+
`RESULT BUNDLE ${projection.resultId}\nBundle: ${projection.bundleDigest}\nBytes: ${projection.totalBytes}\nUse --json to transfer the canonical bundle bytes.\n`,
|
|
1011
|
+
);
|
|
1012
|
+
return;
|
|
1013
|
+
}
|
|
1014
|
+
if (projection.schema === EXECUTION_LOCATION_RESULT_VERIFICATION_SCHEMA) {
|
|
1015
|
+
process.stdout.write(
|
|
1016
|
+
`RESULT VERIFIED ${projection.resultId}\nBundle: ${projection.bundleDigest}\nVerification: ${projection.verificationDigest}\nApplied: no\n`,
|
|
1017
|
+
);
|
|
1018
|
+
return;
|
|
1019
|
+
}
|
|
1020
|
+
if (projection.schema === EXECUTION_LOCATION_RESULT_REVIEW_SCHEMA) {
|
|
1021
|
+
process.stdout.write(
|
|
1022
|
+
`RESULT REVIEWED ${projection.resultId}\nReview: ${projection.reviewDigest}\nBundle: ${projection.bundleDigest}\nSummary: ${projection.summary.byteLength} bytes (${projection.summary.digest})\nDiff: ${projection.diff.byteLength} bytes (${projection.diff.digest})\nApplied: no\n`,
|
|
1023
|
+
);
|
|
1024
|
+
return;
|
|
1025
|
+
}
|
|
1026
|
+
if (projection.schema === EXECUTION_LOCATION_RESULT_ARTIFACT_IMPORT_SCHEMA) {
|
|
1027
|
+
process.stdout.write(
|
|
1028
|
+
`RESULT ARTIFACT ${projection.imported ? "IMPORTED" : "AVAILABLE"} ${projection.artifact.id}\nImport: ${projection.importDigest}\nReview: ${projection.source.reviewDigest}\nItem: ${projection.source.item}\nArtifact bytes: ${projection.artifact.size} (${projection.source.sourceDigest})\nContent emitted: no\n`,
|
|
1029
|
+
);
|
|
1030
|
+
return;
|
|
1031
|
+
}
|
|
1032
|
+
if (
|
|
1033
|
+
projection.schema === SESSION_EXECUTION_LOCATION_RESULT_APPLY_RECEIPT_SCHEMA
|
|
1034
|
+
) {
|
|
1035
|
+
process.stdout.write(
|
|
1036
|
+
`RESULT APPLY ${projection.applied ? "APPLIED" : "ROLLED BACK"} ${projection.applyId}\nReview: ${projection.reviewDigest}\nTransaction: ${projection.transaction.id}\nEvidence: ${projection.transaction.evidenceDigest || "pending"}\nRecovered: ${projection.recovered ? "yes" : "no"}\n`,
|
|
1037
|
+
);
|
|
1038
|
+
return;
|
|
1039
|
+
}
|
|
1040
|
+
if (
|
|
1041
|
+
projection.schema === EXECUTION_LOCATION_TARGET_RESULT_COLLECTION_SCHEMA
|
|
1042
|
+
) {
|
|
1043
|
+
process.stdout.write(
|
|
1044
|
+
`RESULT COLLECTED ${projection.resultId}\nBundle: ${projection.bundleDigest}\nCollection: ${projection.collectionDigest}\nApplied: no\nGaps: ${projection.gaps.join(", ")}\n`,
|
|
1045
|
+
);
|
|
1046
|
+
return;
|
|
1047
|
+
}
|
|
1048
|
+
if (
|
|
1049
|
+
[
|
|
1050
|
+
SESSION_EXECUTION_LOCATION_RESULT_COLLECTION_RECEIPT_SCHEMA,
|
|
1051
|
+
SESSION_EXECUTION_LOCATION_RESULT_COLLECTION_RECEIPT_SCHEMA_V1,
|
|
1052
|
+
].includes(projection.schema)
|
|
1053
|
+
) {
|
|
1054
|
+
process.stdout.write(
|
|
1055
|
+
`RESULT COLLECTION SETTLED ${projection.resultId}\nRequest: ${projection.requestId}\nSettlement: ${projection.receiptDigest}\nBundle bytes available: ${projection.bundleAvailable ? "yes" : "no"}\nApplied: no\n`,
|
|
1056
|
+
);
|
|
1057
|
+
return;
|
|
1058
|
+
}
|
|
353
1059
|
if (projection.schema === "chainlesschain.session-replica-install/v1") {
|
|
354
1060
|
process.stdout.write(
|
|
355
1061
|
`${projection.installed ? "INSTALLED" : "ALREADY PRESENT"} ${projection.sessionId}\nReceipt: ${projection.receiptDigest}\n`,
|
|
@@ -399,6 +1105,16 @@ function runAction(action, options = {}) {
|
|
|
399
1105
|
}
|
|
400
1106
|
}
|
|
401
1107
|
|
|
1108
|
+
function runPreviewAction(action, deps = {}) {
|
|
1109
|
+
try {
|
|
1110
|
+
writeSessionExecutionLocationResultPreview(action(), deps);
|
|
1111
|
+
return 0;
|
|
1112
|
+
} catch (error) {
|
|
1113
|
+
process.stderr.write(`Execution location failed: ${error.message}\n`);
|
|
1114
|
+
return 1;
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
|
|
402
1118
|
export function registerSessionLocationSubcommands(session, deps = {}) {
|
|
403
1119
|
const location = session
|
|
404
1120
|
.command("location")
|
|
@@ -584,4 +1300,236 @@ export function registerSessionLocationSubcommands(session, deps = {}) {
|
|
|
584
1300
|
options,
|
|
585
1301
|
);
|
|
586
1302
|
});
|
|
1303
|
+
|
|
1304
|
+
location
|
|
1305
|
+
.command("result-pack <id>")
|
|
1306
|
+
.description(
|
|
1307
|
+
"Build a bounded result bundle from a verified target handoff session",
|
|
1308
|
+
)
|
|
1309
|
+
.requiredOption("--result-id <id>", "Stable result bundle id")
|
|
1310
|
+
.requiredOption(
|
|
1311
|
+
"--summary <path>",
|
|
1312
|
+
"UTF-8 summary file inside the data boundary",
|
|
1313
|
+
)
|
|
1314
|
+
.requiredOption("--diff <path>", "Diff file inside the data boundary")
|
|
1315
|
+
.option(
|
|
1316
|
+
"--artifact <media-type=path>",
|
|
1317
|
+
"Artifact bytes to include (repeatable)",
|
|
1318
|
+
collectResultFileSpec,
|
|
1319
|
+
[],
|
|
1320
|
+
)
|
|
1321
|
+
.option(
|
|
1322
|
+
"--evidence <media-type=path>",
|
|
1323
|
+
"Evidence bytes to include (repeatable)",
|
|
1324
|
+
collectResultFileSpec,
|
|
1325
|
+
[],
|
|
1326
|
+
)
|
|
1327
|
+
.option("--json", "Write the canonical bundle including base64 content")
|
|
1328
|
+
.action((id, options) => {
|
|
1329
|
+
process.exitCode = runAction(
|
|
1330
|
+
() => createSessionExecutionLocationResultBundle(id, options, deps),
|
|
1331
|
+
options,
|
|
1332
|
+
);
|
|
1333
|
+
});
|
|
1334
|
+
|
|
1335
|
+
location
|
|
1336
|
+
.command("result-verify <id>")
|
|
1337
|
+
.description(
|
|
1338
|
+
"Rehash a returned bundle and bind it to the unchanged source session",
|
|
1339
|
+
)
|
|
1340
|
+
.requiredOption("--bundle <path>", "Returned canonical bundle JSON")
|
|
1341
|
+
.requiredOption(
|
|
1342
|
+
"--expected-handoff-id <sha256>",
|
|
1343
|
+
"Exact handoff id accepted before target execution",
|
|
1344
|
+
)
|
|
1345
|
+
.option("--json", "Machine-readable content-free verification receipt")
|
|
1346
|
+
.action((id, options) => {
|
|
1347
|
+
process.exitCode = runAction(
|
|
1348
|
+
() =>
|
|
1349
|
+
verifySessionExecutionLocationResultBundle(
|
|
1350
|
+
id,
|
|
1351
|
+
options.bundle,
|
|
1352
|
+
options.expectedHandoffId,
|
|
1353
|
+
deps,
|
|
1354
|
+
),
|
|
1355
|
+
options,
|
|
1356
|
+
);
|
|
1357
|
+
});
|
|
1358
|
+
|
|
1359
|
+
location
|
|
1360
|
+
.command("result-collect <id> <target>")
|
|
1361
|
+
.description(
|
|
1362
|
+
"Fetch a target result through the fixed transport and verify it on source",
|
|
1363
|
+
)
|
|
1364
|
+
.requiredOption("--facts <path>", "Accepted handoff facts JSON")
|
|
1365
|
+
.requiredOption("--profile <path>", "Secret-free target profile JSON")
|
|
1366
|
+
.requiredOption(
|
|
1367
|
+
"--expected-target-facts-digest <sha256>",
|
|
1368
|
+
"Exact stable target facts digest accepted before execution",
|
|
1369
|
+
)
|
|
1370
|
+
.requiredOption(
|
|
1371
|
+
"--expected-handoff-id <sha256>",
|
|
1372
|
+
"Exact canonical target handoff id",
|
|
1373
|
+
)
|
|
1374
|
+
.requiredOption(
|
|
1375
|
+
"--request-id <id>",
|
|
1376
|
+
"Stable idempotency id for canonical collection settlement",
|
|
1377
|
+
)
|
|
1378
|
+
.requiredOption("--result-id <id>", "Stable result bundle id")
|
|
1379
|
+
.requiredOption("--summary <path>", "Target summary path")
|
|
1380
|
+
.requiredOption("--diff <path>", "Target diff path")
|
|
1381
|
+
.option(
|
|
1382
|
+
"--artifact <media-type=path>",
|
|
1383
|
+
"Target artifact bytes to include (repeatable)",
|
|
1384
|
+
collectResultFileSpec,
|
|
1385
|
+
[],
|
|
1386
|
+
)
|
|
1387
|
+
.option(
|
|
1388
|
+
"--evidence <media-type=path>",
|
|
1389
|
+
"Target evidence bytes to include (repeatable)",
|
|
1390
|
+
collectResultFileSpec,
|
|
1391
|
+
[],
|
|
1392
|
+
)
|
|
1393
|
+
.option(
|
|
1394
|
+
"--json",
|
|
1395
|
+
"Machine-readable collection with bundle bytes and verification receipt",
|
|
1396
|
+
)
|
|
1397
|
+
.action((id, target, options) => {
|
|
1398
|
+
process.exitCode = runAction(
|
|
1399
|
+
() => collectSessionExecutionLocationResult(id, target, options, deps),
|
|
1400
|
+
options,
|
|
1401
|
+
);
|
|
1402
|
+
});
|
|
1403
|
+
|
|
1404
|
+
location
|
|
1405
|
+
.command("result-review <id>")
|
|
1406
|
+
.description(
|
|
1407
|
+
"Review stored result metadata without exposing or applying content",
|
|
1408
|
+
)
|
|
1409
|
+
.requiredOption(
|
|
1410
|
+
"--request-id <id>",
|
|
1411
|
+
"Canonical result collection request id",
|
|
1412
|
+
)
|
|
1413
|
+
.option("--json", "Machine-readable content-free review authority")
|
|
1414
|
+
.action((id, options) => {
|
|
1415
|
+
process.exitCode = runAction(
|
|
1416
|
+
() => reviewSessionExecutionLocationResult(id, options.requestId, deps),
|
|
1417
|
+
options,
|
|
1418
|
+
);
|
|
1419
|
+
});
|
|
1420
|
+
|
|
1421
|
+
location
|
|
1422
|
+
.command("result-preview <id>")
|
|
1423
|
+
.description(
|
|
1424
|
+
"Explicitly stream one reviewed result item without changing the workspace",
|
|
1425
|
+
)
|
|
1426
|
+
.requiredOption(
|
|
1427
|
+
"--request-id <id>",
|
|
1428
|
+
"Canonical result collection request id",
|
|
1429
|
+
)
|
|
1430
|
+
.requiredOption(
|
|
1431
|
+
"--review-digest <sha256>",
|
|
1432
|
+
"Exact content-free review digest accepted by the operator",
|
|
1433
|
+
)
|
|
1434
|
+
.requiredOption(
|
|
1435
|
+
"--item <selector>",
|
|
1436
|
+
"summary, diff, artifact:<sha256>, or evidence:<sha256>",
|
|
1437
|
+
)
|
|
1438
|
+
.action((id, options) => {
|
|
1439
|
+
process.exitCode = runPreviewAction(
|
|
1440
|
+
() =>
|
|
1441
|
+
previewSessionExecutionLocationResult(
|
|
1442
|
+
id,
|
|
1443
|
+
options.requestId,
|
|
1444
|
+
options.reviewDigest,
|
|
1445
|
+
options.item,
|
|
1446
|
+
deps,
|
|
1447
|
+
),
|
|
1448
|
+
deps.previewOutputDependencies || {},
|
|
1449
|
+
);
|
|
1450
|
+
});
|
|
1451
|
+
|
|
1452
|
+
location
|
|
1453
|
+
.command("result-import <id>")
|
|
1454
|
+
.description(
|
|
1455
|
+
"Import one explicitly reviewed result item into the managed ArtifactStore",
|
|
1456
|
+
)
|
|
1457
|
+
.requiredOption(
|
|
1458
|
+
"--request-id <id>",
|
|
1459
|
+
"Canonical result collection request id",
|
|
1460
|
+
)
|
|
1461
|
+
.requiredOption(
|
|
1462
|
+
"--review-digest <sha256>",
|
|
1463
|
+
"Exact content-free review digest accepted by the operator",
|
|
1464
|
+
)
|
|
1465
|
+
.requiredOption(
|
|
1466
|
+
"--item <selector>",
|
|
1467
|
+
"summary, diff, artifact:<sha256>, or evidence:<sha256>",
|
|
1468
|
+
)
|
|
1469
|
+
.option("--json", "Machine-readable content-free import receipt")
|
|
1470
|
+
.action((id, options) => {
|
|
1471
|
+
process.exitCode = runAction(
|
|
1472
|
+
() =>
|
|
1473
|
+
importSessionExecutionLocationResultArtifact(
|
|
1474
|
+
id,
|
|
1475
|
+
options.requestId,
|
|
1476
|
+
options.reviewDigest,
|
|
1477
|
+
options.item,
|
|
1478
|
+
deps,
|
|
1479
|
+
),
|
|
1480
|
+
options,
|
|
1481
|
+
);
|
|
1482
|
+
});
|
|
1483
|
+
|
|
1484
|
+
location
|
|
1485
|
+
.command("result-apply <id>")
|
|
1486
|
+
.description(
|
|
1487
|
+
"Apply one explicitly reviewed stored diff inside a durable workspace transaction",
|
|
1488
|
+
)
|
|
1489
|
+
.requiredOption(
|
|
1490
|
+
"--request-id <id>",
|
|
1491
|
+
"Canonical result collection request id",
|
|
1492
|
+
)
|
|
1493
|
+
.requiredOption("--apply-id <id>", "Stable result apply idempotency id")
|
|
1494
|
+
.requiredOption(
|
|
1495
|
+
"--review-digest <sha256>",
|
|
1496
|
+
"Exact content-free review digest accepted by the operator",
|
|
1497
|
+
)
|
|
1498
|
+
.option(
|
|
1499
|
+
"--workspace <path>",
|
|
1500
|
+
"Exact source Git workspace (defaults to session authority)",
|
|
1501
|
+
)
|
|
1502
|
+
.option("--json", "Machine-readable content-free apply receipt")
|
|
1503
|
+
.action((id, options) => {
|
|
1504
|
+
process.exitCode = runAction(
|
|
1505
|
+
() => applySessionExecutionLocationResult(id, options, deps),
|
|
1506
|
+
options,
|
|
1507
|
+
);
|
|
1508
|
+
});
|
|
1509
|
+
|
|
1510
|
+
location
|
|
1511
|
+
.command("result-apply-recover <id>")
|
|
1512
|
+
.description(
|
|
1513
|
+
"Explicitly recover a reserved result apply without replaying its diff",
|
|
1514
|
+
)
|
|
1515
|
+
.requiredOption(
|
|
1516
|
+
"--request-id <id>",
|
|
1517
|
+
"Canonical result collection request id",
|
|
1518
|
+
)
|
|
1519
|
+
.requiredOption("--apply-id <id>", "Reserved result apply id")
|
|
1520
|
+
.requiredOption(
|
|
1521
|
+
"--review-digest <sha256>",
|
|
1522
|
+
"Exact content-free review digest bound to the reservation",
|
|
1523
|
+
)
|
|
1524
|
+
.option(
|
|
1525
|
+
"--workspace <path>",
|
|
1526
|
+
"Exact source Git workspace (defaults to session authority)",
|
|
1527
|
+
)
|
|
1528
|
+
.option("--json", "Machine-readable content-free recovery receipt")
|
|
1529
|
+
.action((id, options) => {
|
|
1530
|
+
process.exitCode = runAction(
|
|
1531
|
+
() => recoverSessionExecutionLocationResultApply(id, options, deps),
|
|
1532
|
+
options,
|
|
1533
|
+
);
|
|
1534
|
+
});
|
|
587
1535
|
}
|