chainlesschain 0.166.90 → 0.166.92
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 +15 -13
- package/package.json +4 -4
- package/src/assets/linux-subreaper/linux-arm64/manifest.json +1 -1
- package/src/assets/linux-subreaper/linux-x64/manifest.json +1 -1
- package/src/assets/web-panel/assets/{AIOps-CZzXRe1-.js → AIOps-C74YzqwJ.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-_AZfbW1Q.js → ActionButton-TFef1hOE.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-CzaUx_wv.js → Analytics-CYsWpkkU.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-xHEeeD-m.js → AppLayout-CFf9kjwu.js} +4 -4
- package/src/assets/web-panel/assets/{Artifacts-DmTbtudE.js → Artifacts-TQqa94YO.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-Cn4ng4fo.js → Audit-B79ayqfS.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-DLUY1VD2.js → BackgroundAgents-pjkHfLP9.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-B2v--wB6.js → Backup-CE6A-t_r.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-Bgih7yAv.js → BaseInput-CwcgWMBY.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-1MiiA3yA.js → Chat-BIkDNesY.js} +6 -6
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-CPLynmbb.js → ChatBubbleRenderer-DgaokYts.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-DsyBa_NO.js → Checkbox-MbypIy5V.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-B7WCFx9H.js → Codegen-DiFHWDnt.js} +1 -1
- package/src/assets/web-panel/assets/{Col-D2x4GBGm.js → Col-BNMlYMso.js} +1 -1
- package/src/assets/web-panel/assets/{Community-Rnwg9nea.js → Community-B3HVyHOX.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-BPczlrRh.js → Compact-C7hlAubb.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-Br1L_wGU.js → Compliance-PaXZu6sE.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-DlsWB_oS.js → Cowork-BGiojbm-.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-BWo_KGpG.js → Cron-Bmr-1QAx.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-Cug7N8ge.js → Crosschain-BwUvWCVd.js} +1 -1
- package/src/assets/web-panel/assets/{DID-CMbyOZJN.js → DID-k_4QZocW.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-C4dl_UaE.js → Dashboard-_ieRo2C5.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-CBrC7M-9.js → Dropdown-DYHh6T27.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-DTq7tU4b.js → EmailListRenderer-BNlQcWQX.js} +1 -1
- package/src/assets/web-panel/assets/{EvolutionSettings-DWP3csxS.js → EvolutionSettings-DIkZ6U2D.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-DZl7zuv_.js → FamilyGuardDashboard-Dq7qSr0P.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-W-GSlVK5.js → Federation-C64e3Cbx.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-DMB7xYFV.js → FormItemContext-D-GE2vUa.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-DNv8GEoq.js → GenericCardRenderer-DO3B2gis.js} +1 -1
- package/src/assets/web-panel/assets/{Git-BZ0Bbzw6.js → Git-0ETirIQH.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-BNEdcOM5.js → Governance-C9fnRygX.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-C8249gIz.js → Inference-CLJ9RTsK.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-ngzebU3e.js → KnowledgeGraph-D3C_GxrN.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-CP15th-f.js → Logs-C5ctGbkN.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-Ce-eWK3j.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-CaH59OsY.js → Marketplace-GF_t6hJ_.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-C07vnJev.js → McpTools-BGsGzgQs.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-CqAOkVAS.js → Memory-CcrY2A0j.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-qp7mZimq.js → MobileBridge-Bi4T0RlS.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-DKhbqvTw.js → MobileProjects-DvjEGyvf.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-CRYCnWXv.js → Mtc-DL77Vf-k.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-Z08IrKws.js → MtcAudit-CDy_Uswb.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-BWdatUnH.js → Multisig-DL0BAO_c.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-BKWiCZ_m.js → NLProgramming-B-woh5IR.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-Bgpzk3sm.js → Notes-CEFVCxk7.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-DvtZEktR.js → NotificationSettings-BqPPMuAP.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-CBcy0szc.js → OrderTableRenderer-GUKQ1xwp.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-DRRL6vW1.js → Organization-B1gX8jlr.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-COmfB8Ns.js → Overflow-CeMxuUZy.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-BqMq_DSa.js → P2P-B5aIRWwJ.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-BX7iNvle.js → PdhVaultBrowser-6rYgejd4.js} +4 -4
- package/src/assets/web-panel/assets/{Permissions-DzYkjmV_.js → Permissions-CqCp2SIl.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-BBTcxBbN.js → PersonalDataHub-BsA7DJWW.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-eRkYFSbO.js → Pipeline-CiW6HeZh.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-Ch7IFKBh.js → Privacy-DckUOLYq.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-Ci8EcBYg.js → ProjectInit-CZppOOYR.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-B4lYHFbI.js → ProjectSettings-B9QPzhDU.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-zkE5cCo_.js → Projects-BErjjGha.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-BKDVD3_e.js → Providers-DehU6Qiz.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-BromrHlf.js → QrScannerModal-E1SUvv1m.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-CCgoY1gR.js → QuickAsk-COWFxyH3.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-DCPZvpq7.js → Recommend-D26pWKxX.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-DPnFP8HU.js → RemoteSession-DCOIaId3.js} +3 -3
- package/src/assets/web-panel/assets/{Reputation-l6r8ytAs.js → Reputation-DT_AHGAR.js} +1 -1
- package/src/assets/web-panel/assets/{Row-ke9Mk1cx.js → Row-B50S-1nl.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-DQOEzUEn.js → RssFeed-BaBnHg3Q.js} +2 -2
- package/src/assets/web-panel/assets/{Search-BqgA0aUz.js → Search-BVdnLuuS.js} +1 -1
- package/src/assets/web-panel/assets/{Security-FeGD_jqV.js → Security-BnacH74J.js} +3 -3
- package/src/assets/web-panel/assets/{Services-4kiYYAjZ.js → Services-CxM08Zch.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-BbU8Xegs.js → Skeleton-DE7CIc1N.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-Dl2bUMUL.js → Skills-CGI0SJmf.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-xRGALeaZ.js → Sla-DpEzPcqc.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-DZfd4RDm.js → SpeechSettings-CTmnmMHn.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-BRtCV9Ga.js → SyncSettings-Dxgrd9hd.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-DVRQklfG.js → Tasks-CW4slS0A.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-BbhE5jt5.js → Templates-DxvGWDgB.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-qXPDNKbK.js → Tenant-_Q0o2tNK.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-CV48Ks7E.js → Terminal-BTZn8pow.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-BLGfJIDr.js → TimelineRenderer-CauL0KFe.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-7G9H6Hrt.js → Tokens-CDoM2qeT.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger--F64N11F.js → Trigger-B-QYGEU7.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-Cq1r-D_y.js → Trust-BD6XJHT-.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-Dqyu4RVh.js → UkeySign-x4TFwCy0.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-DuFmWH_B.js → VideoEditing-t3imBK_0.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-C3mg7EWP.js → Wallet-BCfkWwNC.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-CDK-Aj_X.js → WebAuthn-WH314Mdm.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor--K7K-T1F.js → WorkflowEditor-jUlcjrUg.js} +1 -1
- package/src/assets/web-panel/assets/{chat-BQDcS6VP.js → chat-Dg3VASTL.js} +1 -1
- package/src/assets/web-panel/assets/{colors-BKxJL2-T.js → colors-BNvmBRKE.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-CFjQAMbY.js → compact-item-BGOfoqf4.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-DbgCsdQd.js → createContext-BNQeqKAs.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-B7_ypN1G.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-BhkaOBNv.js → hasIn-Bg3AjCrq.js} +1 -1
- package/src/assets/web-panel/assets/{index-DvWWFJHJ.js → index--I3UF5t1.js} +1 -1
- package/src/assets/web-panel/assets/{index-DJ2OiRvh.js → index-2D04Zltx.js} +3 -3
- package/src/assets/web-panel/assets/{index-BuWPqSGT.js → index-60AnjUTX.js} +1 -1
- package/src/assets/web-panel/assets/{index-D2Zb-Kd1.js → index-7QJUWemf.js} +1 -1
- package/src/assets/web-panel/assets/{index-C0DzhUOX.js → index-B--0QM0S.js} +1 -1
- package/src/assets/web-panel/assets/index-B-jSKJK6.js +1 -0
- package/src/assets/web-panel/assets/{index-COGy6wXn.js → index-B0mgngoB.js} +1 -1
- package/src/assets/web-panel/assets/{index-bMX8BBLE.js → index-BBCMulQ-.js} +1 -1
- package/src/assets/web-panel/assets/{index-CE506mgj.js → index-BSNhW95G.js} +1 -1
- package/src/assets/web-panel/assets/{index-CoOu7sdP.js → index-B_JmInC0.js} +1 -1
- package/src/assets/web-panel/assets/{index-B4LlAJqc.js → index-BaPvEvB4.js} +1 -1
- package/src/assets/web-panel/assets/{index-CRtUDiXx.js → index-Bkz1tgFR.js} +1 -1
- package/src/assets/web-panel/assets/{index-Du_SxxBY.js → index-BmTacaQV.js} +1 -1
- package/src/assets/web-panel/assets/{index-CSUDlsIr.js → index-CCFZN66A.js} +1 -1
- package/src/assets/web-panel/assets/{index-3uR0ThJO.js → index-COol3xfA.js} +1 -1
- package/src/assets/web-panel/assets/{index-DmYK9Tqt.js → index-CY8cRKHR.js} +1 -1
- package/src/assets/web-panel/assets/{index-T9ka3Xj3.js → index-Cbp-wp-U.js} +1 -1
- package/src/assets/web-panel/assets/{index-CB4oHynY.js → index-Co_LnCWD.js} +1 -1
- package/src/assets/web-panel/assets/{index-DEwHywz9.js → index-Cx2EXRfr.js} +1 -1
- package/src/assets/web-panel/assets/{index-CUs7XpUO.js → index-D-mSvCQK.js} +1 -1
- package/src/assets/web-panel/assets/{index-BRqlCTrz.js → index-D072oLjp.js} +1 -1
- package/src/assets/web-panel/assets/{index-sKfUUldY.js → index-D6UqK83L.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dhfa_BIl.js → index-DF_FKSVH.js} +1 -1
- package/src/assets/web-panel/assets/{index-D9sVcw6v.js → index-DLwEXRrb.js} +1 -1
- package/src/assets/web-panel/assets/{index-3djsY75k.js → index-DO0VlNtc.js} +1 -1
- package/src/assets/web-panel/assets/{index-BfGGsAU7.js → index-DS04wRll.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dn2QSsuI.js → index-DYn5DnDk.js} +1 -1
- package/src/assets/web-panel/assets/{index-D-Yh3-1z.js → index-D_O2ZjPk.js} +1 -1
- package/src/assets/web-panel/assets/{index-BNjYPJNU.js → index-DcCnO0RU.js} +1 -1
- package/src/assets/web-panel/assets/{index-DP1NrM9J.js → index-Dkp-okWa.js} +1 -1
- package/src/assets/web-panel/assets/{index-DdcrixaQ.js → index-OUFoxUgH.js} +1 -1
- package/src/assets/web-panel/assets/index-P4FXZJqI.js +1 -0
- package/src/assets/web-panel/assets/{index-7BY44UEv.js → index-Wo0f2iqb.js} +1 -1
- package/src/assets/web-panel/assets/{index-DjmVlpap.js → index-ZD5Kd8tx.js} +1 -1
- package/src/assets/web-panel/assets/{index-3YutaXnp.js → index-fOwii3LP.js} +1 -1
- package/src/assets/web-panel/assets/{index-aPdVzagA.js → index-hG7jXGEW.js} +1 -1
- package/src/assets/web-panel/assets/{index-De7daEnc.js → index-pVdQieac.js} +1 -1
- package/src/assets/web-panel/assets/{index-CJoXgJ2N.js → index-uH2LnAs_.js} +1 -1
- package/src/assets/web-panel/assets/{index-DFt48Z-x.js → index-xzaUx19r.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-wrqabmui.js → initDefaultProps-B8PN9AxJ.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BoyB3ilP.js → motion-BHivfw5Q.js} +1 -1
- package/src/assets/web-panel/assets/{move-Cq31cSFE.js → move-B0QU5nDd.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-BkxNt-8H.js → mtc-parser-DRwRM3PE.js} +1 -1
- package/src/assets/web-panel/assets/{omit-DofGni53.js → omit-SHt2rV2p.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-BnluLL16.js → pickAttrs-CcmDlEb2.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-C-yegJSP.js → placementArrow-DYatmXDS.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-CD3ziNhu.js → responsiveObserve-B7qrsXq5.js} +1 -1
- package/src/assets/web-panel/assets/{slide-ToZO4gQ1.js → slide-BRGhlOWd.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-DFVmDmVl.js → statusUtils-CT-7NXsQ.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-De0Y8g1O.js → styleChecker-rZdw_Yyp.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-wBKIYFKX.js → useFlexGapSupport-D8YNIP4P.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-CP9nmUMJ.js → useFs-B8pt0Gu-.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-vFGrVDyp.js → usePersonalDataHub-VMmYM1tt.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-BcBIjvjH.js → vnode-UNDuoPoq.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-DnXDAQxA.js → zoom-dN-u667S.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +1 -1
- package/src/commands/agent-process-ownership.js +121 -0
- package/src/commands/agent.js +2 -0
- package/src/commands/hub.js +86 -9
- package/src/data/changelog.json +54 -2
- package/src/lib/audit-logger.js +46 -20
- package/src/lib/checkpoint-restore-saga.js +11 -1
- package/src/lib/eval/verify01-host-evidence.js +36 -3
- package/src/lib/evolution/evolution-artifact-ports.js +26 -0
- package/src/lib/evolution/evolution-eval-cohort-enrollment.js +713 -47
- package/src/lib/evolution/evolution-eval-gate.js +146 -0
- package/src/lib/evolution/evolution-eval-launch-admission.js +168 -90
- package/src/lib/evolution/evolution-eval-ledger-capture.js +50 -0
- package/src/lib/evolution/evolution-eval-readonly-audit.js +106 -0
- package/src/lib/evolution/evolution-ledger-file-backend.js +20 -0
- package/src/lib/evolution/evolution-ledger-ports.js +59 -27
- package/src/lib/evolution/evolution-ledger-v2-journal.js +55 -18
- package/src/lib/evolution/evolution-workbench-file-resources.js +19 -1
- package/src/lib/evolution/rrsi-cohort-registration.js +275 -0
- package/src/lib/evolution/rrsi-contracts.js +742 -0
- package/src/lib/evolution/rrsi-data.js +196 -0
- package/src/lib/evolution/rrsi-evaluation-adapter.js +275 -0
- package/src/lib/evolution/rrsi-evaluation-variants.js +267 -0
- package/src/lib/evolution/rrsi-group-statistics.js +553 -0
- package/src/lib/evolution/rrsi-history-ledger-adapter.js +3261 -0
- package/src/lib/evolution/rrsi-native-batch-evidence.js +520 -0
- package/src/lib/evolution/rrsi-native-eval-row-collector.js +538 -0
- package/src/lib/evolution/rrsi-native-evaluation-batch.js +547 -0
- package/src/lib/evolution/rrsi-native-evaluation-plan.js +431 -0
- package/src/lib/evolution/rrsi-native-group-statistics-plan.js +121 -0
- package/src/lib/evolution/rrsi-native-group-statistics.js +482 -0
- package/src/lib/evolution/rrsi-native-quality-receipt-contracts.js +321 -0
- package/src/lib/evolution/rrsi-native-quality-receipt.js +256 -0
- package/src/lib/evolution/rrsi-native-statistics-protocol.js +330 -0
- package/src/lib/evolution/rrsi-parent-binding.js +290 -0
- package/src/lib/evolution/rrsi-pm-execution-bridge.js +500 -0
- package/src/lib/evolution/rrsi-pm-training-mapping.js +134 -0
- package/src/lib/evolution/rrsi-preparation-contracts.js +213 -0
- package/src/lib/evolution/rrsi-registry-history-binding.js +193 -0
- package/src/lib/evolution/rrsi-registry-store-policy.js +1191 -0
- package/src/lib/evolution/rrsi-runtime-composition.js +79 -0
- package/src/lib/evolution/rrsi-selector.js +434 -0
- package/src/lib/evolution/rrsi-statistics-simulation.js +354 -0
- package/src/lib/evolution/skill-candidate-registry.js +216 -29
- package/src/lib/evolution/skill-registry-maintenance.js +80 -0
- package/src/lib/evolution/skill-registry-writer-control.js +138 -0
- package/src/lib/evolution/skill-release-registry.js +399 -169
- package/src/lib/formal-quality-eval-runtime.js +2 -14
- package/src/lib/goal-store.js +225 -16
- package/src/lib/process-execution-broker/index.js +91 -1
- package/src/lib/process-execution-broker/platform-sandbox.js +42 -0
- package/src/lib/process-execution-broker/windows-native-evaluator-capabilities.js +757 -0
- package/src/lib/process-execution-broker/windows-native-evaluator.js +316 -0
- package/src/lib/process-execution-broker/windows-sandbox-helper.dll +0 -0
- package/src/lib/process-execution-broker/windows-sandbox-helper.exe +0 -0
- package/src/lib/process-execution-broker/windows-sandbox.cs +383 -11
- package/src/lib/record-replay/skill-recorder.js +38 -3
- package/src/lib/scheduler-kernel/authority-resolver.js +12 -163
- package/src/lib/scheduler-kernel/contract.js +27 -414
- package/src/lib/scheduler-kernel/runtime.js +21 -823
- package/src/lib/scheduler-kernel/service.js +11 -328
- package/src/lib/scheduler-kernel/source-locator-path.js +7 -142
- package/src/lib/scheduler-kernel/store.js +67 -5931
- package/src/lib/secure-fs.js +16 -1314
- package/src/lib/with-file-lock.js +122 -20
- package/src/assets/web-panel/assets/MarkdownRenderer-CW3B3JDq.js +0 -1
- package/src/assets/web-panel/assets/devWarning-DlIv9Mbc.js +0 -1
- package/src/assets/web-panel/assets/index-BC972Grv.js +0 -1
- package/src/assets/web-panel/assets/index-CVifyQqL.js +0 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isFormalQualityHermeticRuntime } from "@chainlesschain/session-core/host-storage-environment";
|
|
1
2
|
import { createHash } from "node:crypto";
|
|
2
3
|
import fs from "node:fs";
|
|
3
4
|
import os from "node:os";
|
|
@@ -23,20 +24,7 @@ export const FORMAL_QUALITY_FILE_TOOLS = Object.freeze([
|
|
|
23
24
|
* headless boundary through a launcher-only environment marker. Keep the
|
|
24
25
|
* check exact so inherited or malformed values never change normal CLI runs.
|
|
25
26
|
*/
|
|
26
|
-
export
|
|
27
|
-
if (environment?.[FORMAL_QUALITY_HERMETIC_ENV] !== "1") return false;
|
|
28
|
-
const configuredHome = String(environment?.CHAINLESSCHAIN_HOME || "").trim();
|
|
29
|
-
if (!configuredHome) return false;
|
|
30
|
-
const temporaryRoot = path.resolve(os.tmpdir());
|
|
31
|
-
const resolvedHome = path.resolve(configuredHome);
|
|
32
|
-
const relation = path.relative(temporaryRoot, resolvedHome);
|
|
33
|
-
return Boolean(
|
|
34
|
-
relation &&
|
|
35
|
-
relation !== ".." &&
|
|
36
|
-
!relation.startsWith(`..${path.sep}`) &&
|
|
37
|
-
!path.isAbsolute(relation),
|
|
38
|
-
);
|
|
39
|
-
}
|
|
27
|
+
export { isFormalQualityHermeticRuntime };
|
|
40
28
|
|
|
41
29
|
function formalQualityIsolationRoot(environment) {
|
|
42
30
|
if (!isFormalQualityHermeticRuntime(environment)) return null;
|
package/src/lib/goal-store.js
CHANGED
|
@@ -18,8 +18,15 @@
|
|
|
18
18
|
|
|
19
19
|
import fs from "node:fs";
|
|
20
20
|
import path from "node:path";
|
|
21
|
+
import { createHash } from "node:crypto";
|
|
21
22
|
import { getHomeDir } from "./paths.js";
|
|
22
23
|
import { withFileLock } from "./with-file-lock.js";
|
|
24
|
+
import {
|
|
25
|
+
createGoalRecord,
|
|
26
|
+
validateGoalRecord,
|
|
27
|
+
upgradeLegacyGoal,
|
|
28
|
+
goalError,
|
|
29
|
+
} from "@chainlesschain/session-core/goal-contract";
|
|
23
30
|
|
|
24
31
|
/** Valid goal lifecycle states. `active` goals are the ones injected. */
|
|
25
32
|
export const GOAL_STATUS = Object.freeze({
|
|
@@ -35,6 +42,25 @@ function defaultRoot() {
|
|
|
35
42
|
return path.join(getHomeDir(), "goals");
|
|
36
43
|
}
|
|
37
44
|
|
|
45
|
+
/** Store identity is path-bound metadata, not filesystem authorization. */
|
|
46
|
+
export function goalFileStoreId(root = defaultRoot()) {
|
|
47
|
+
const resolved = path.resolve(root);
|
|
48
|
+
const canonical =
|
|
49
|
+
process.platform === "win32" ? resolved.toLowerCase() : resolved;
|
|
50
|
+
return `cli-goals-${createHash("sha256").update(canonical).digest("hex")}`;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function fileRecord(value, root) {
|
|
54
|
+
const record = upgradeLegacyGoal(value, goalFileStoreId(root));
|
|
55
|
+
if (record.storeId !== goalFileStoreId(root))
|
|
56
|
+
throw goalError("GOAL_STORE_MISMATCH");
|
|
57
|
+
// Files are the legacy standalone CLI store. Project authority lives in the
|
|
58
|
+
// host database and must not be acquired by copying a record into this dir.
|
|
59
|
+
if (record.ownerRef !== null || record.projectRef !== null)
|
|
60
|
+
throw goalError("GOAL_PROJECT_STORE_REQUIRED");
|
|
61
|
+
return record;
|
|
62
|
+
}
|
|
63
|
+
|
|
38
64
|
function ensureDir(dir) {
|
|
39
65
|
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
40
66
|
}
|
|
@@ -83,6 +109,7 @@ function isUnsafeGoalId(id) {
|
|
|
83
109
|
id == null ||
|
|
84
110
|
id === "" ||
|
|
85
111
|
typeof id !== "string" ||
|
|
112
|
+
!/^[A-Za-z0-9][A-Za-z0-9._-]{0,255}$/u.test(id) ||
|
|
86
113
|
id.includes("/") ||
|
|
87
114
|
id.includes("\\") ||
|
|
88
115
|
id.includes("..")
|
|
@@ -133,17 +160,15 @@ export function createGoal(input = {}, opts = {}) {
|
|
|
133
160
|
}
|
|
134
161
|
const keyResults = (input.keyResults || []).map((kr) => normalizeKr(kr));
|
|
135
162
|
const goal = {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
163
|
+
...createGoalRecord({
|
|
164
|
+
id,
|
|
165
|
+
storeId: goalFileStoreId(root),
|
|
166
|
+
title: String(input.title || objective).trim(),
|
|
167
|
+
objective,
|
|
168
|
+
keyResults,
|
|
169
|
+
createdAt: nowIso(),
|
|
170
|
+
}),
|
|
141
171
|
progress: derivedProgress(keyResults) ?? 0,
|
|
142
|
-
linkedSessions: [],
|
|
143
|
-
notes: [],
|
|
144
|
-
drift: { lastProgressAt: null, flags: [] },
|
|
145
|
-
createdAt: nowIso(),
|
|
146
|
-
updatedAt: nowIso(),
|
|
147
172
|
};
|
|
148
173
|
ensureDir(root);
|
|
149
174
|
const file = goalFile(root, id);
|
|
@@ -186,21 +211,42 @@ export function getGoal(id, opts = {}) {
|
|
|
186
211
|
const file = goalFile(root, id);
|
|
187
212
|
if (!fs.existsSync(file)) return null;
|
|
188
213
|
try {
|
|
189
|
-
|
|
214
|
+
const value = JSON.parse(fs.readFileSync(file, "utf-8"));
|
|
215
|
+
if (value?.id !== id) return null;
|
|
216
|
+
if (Object.hasOwn(value, "schema") || Object.hasOwn(value, "schemaVersion"))
|
|
217
|
+
fileRecord(value, root);
|
|
218
|
+
return value;
|
|
190
219
|
} catch {
|
|
191
220
|
return null;
|
|
192
221
|
}
|
|
193
222
|
}
|
|
194
223
|
|
|
195
|
-
function saveGoal(goal, opts = {}) {
|
|
224
|
+
function saveGoal(goal, opts = {}, before = null) {
|
|
196
225
|
if (isUnsafeGoalId(goal && goal.id)) {
|
|
197
226
|
throw new Error(`非法 goal id: ${String(goal && goal.id).slice(0, 60)}`);
|
|
198
227
|
}
|
|
199
228
|
const root = opts.root || defaultRoot();
|
|
200
229
|
ensureDir(root);
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
230
|
+
const previous = before || fileRecord(goal, root);
|
|
231
|
+
const migrated = goal.schema ? goal : { ...fileRecord(goal, root) };
|
|
232
|
+
if (previous.completion !== null && migrated.status === "done")
|
|
233
|
+
throw goalError("GOAL_TERMINAL_REVISION_DENIED");
|
|
234
|
+
const controls = ["status", "objective", "keyResults"];
|
|
235
|
+
const changedControl = controls.some(
|
|
236
|
+
(key) => JSON.stringify(previous[key]) !== JSON.stringify(migrated[key]),
|
|
237
|
+
);
|
|
238
|
+
const saved = fileRecord(
|
|
239
|
+
{
|
|
240
|
+
...migrated,
|
|
241
|
+
revision: previous.revision + 1,
|
|
242
|
+
controlGeneration: previous.controlGeneration + (changedControl ? 1 : 0),
|
|
243
|
+
completion: null,
|
|
244
|
+
updatedAt: nowIso(),
|
|
245
|
+
},
|
|
246
|
+
root,
|
|
247
|
+
);
|
|
248
|
+
atomicWriteFileSync(goalFile(root, goal.id), JSON.stringify(saved, null, 2));
|
|
249
|
+
return saved;
|
|
204
250
|
}
|
|
205
251
|
|
|
206
252
|
/** List goals, newest first. Optionally filter by status. */
|
|
@@ -233,8 +279,64 @@ function mutate(id, fn, opts = {}) {
|
|
|
233
279
|
() => {
|
|
234
280
|
const goal = getGoal(id, opts);
|
|
235
281
|
if (!goal) throw new Error(`no such goal: ${id}`);
|
|
282
|
+
let before;
|
|
283
|
+
try {
|
|
284
|
+
before = fileRecord(goal, root);
|
|
285
|
+
} catch (error) {
|
|
286
|
+
// Older CLI records had unbounded notes/strings. Preserve their full
|
|
287
|
+
// history and existing controls if the bounded contract cannot accept
|
|
288
|
+
// them. This fallback is never available to a versioned record.
|
|
289
|
+
if (
|
|
290
|
+
Object.hasOwn(goal, "schema") ||
|
|
291
|
+
Object.hasOwn(goal, "schemaVersion") ||
|
|
292
|
+
![
|
|
293
|
+
"GOAL_INVALID_ARRAY",
|
|
294
|
+
"GOAL_INVALID_TEXT",
|
|
295
|
+
"GOAL_INVALID_JSON",
|
|
296
|
+
].includes(error.code)
|
|
297
|
+
)
|
|
298
|
+
throw error;
|
|
299
|
+
const revision = goal.revision ?? 1;
|
|
300
|
+
const generation = goal.controlGeneration ?? 0;
|
|
301
|
+
if (
|
|
302
|
+
!Number.isSafeInteger(revision) ||
|
|
303
|
+
revision < 1 ||
|
|
304
|
+
!Number.isSafeInteger(generation) ||
|
|
305
|
+
generation < 0 ||
|
|
306
|
+
!Number.isSafeInteger(revision + 1) ||
|
|
307
|
+
!Number.isSafeInteger(generation + 1)
|
|
308
|
+
)
|
|
309
|
+
throw goalError("GOAL_INVALID_REVISION");
|
|
310
|
+
if (
|
|
311
|
+
opts.expectedRevision !== undefined &&
|
|
312
|
+
opts.expectedRevision !== revision
|
|
313
|
+
)
|
|
314
|
+
throw goalError("GOAL_REVISION_CONFLICT");
|
|
315
|
+
const controls = JSON.stringify([
|
|
316
|
+
goal.status,
|
|
317
|
+
goal.objective,
|
|
318
|
+
goal.keyResults,
|
|
319
|
+
]);
|
|
320
|
+
fn(goal);
|
|
321
|
+
goal.revision = revision + 1;
|
|
322
|
+
goal.controlGeneration =
|
|
323
|
+
generation +
|
|
324
|
+
(controls !==
|
|
325
|
+
JSON.stringify([goal.status, goal.objective, goal.keyResults])
|
|
326
|
+
? 1
|
|
327
|
+
: 0);
|
|
328
|
+
goal.updatedAt = nowIso();
|
|
329
|
+
atomicWriteFileSync(goalFile(root, id), JSON.stringify(goal, null, 2));
|
|
330
|
+
return goal;
|
|
331
|
+
}
|
|
332
|
+
if (
|
|
333
|
+
opts.expectedRevision !== undefined &&
|
|
334
|
+
(!Number.isSafeInteger(opts.expectedRevision) ||
|
|
335
|
+
opts.expectedRevision !== before.revision)
|
|
336
|
+
)
|
|
337
|
+
throw goalError("GOAL_REVISION_CONFLICT");
|
|
236
338
|
fn(goal);
|
|
237
|
-
return saveGoal(goal, opts);
|
|
339
|
+
return saveGoal(goal, opts, before);
|
|
238
340
|
},
|
|
239
341
|
{ failIfUnavailable: true },
|
|
240
342
|
);
|
|
@@ -385,6 +487,15 @@ export function deleteGoal(id, opts = {}) {
|
|
|
385
487
|
file,
|
|
386
488
|
() => {
|
|
387
489
|
if (!fs.existsSync(file)) return false;
|
|
490
|
+
if (opts.expectedRevision !== undefined) {
|
|
491
|
+
const current = getGoal(id, { root });
|
|
492
|
+
if (
|
|
493
|
+
!current ||
|
|
494
|
+
!Number.isSafeInteger(opts.expectedRevision) ||
|
|
495
|
+
opts.expectedRevision !== (current.revision ?? 1)
|
|
496
|
+
)
|
|
497
|
+
throw goalError("GOAL_REVISION_CONFLICT");
|
|
498
|
+
}
|
|
388
499
|
fs.rmSync(file);
|
|
389
500
|
return true;
|
|
390
501
|
},
|
|
@@ -419,3 +530,101 @@ export function resolveActiveGoal(sel = {}, opts = {}) {
|
|
|
419
530
|
// Ambiguous (multiple active, none linked) — caller must pick explicitly.
|
|
420
531
|
return null;
|
|
421
532
|
}
|
|
533
|
+
|
|
534
|
+
/** Injectable repository adapter using the same files/strict locks as cc goal.
|
|
535
|
+
* Reading a legacy file upgrades the returned view only; it never rewrites the
|
|
536
|
+
* file, binds an owner or enables scheduling. */
|
|
537
|
+
export function createGoalFileAdapter(opts = {}) {
|
|
538
|
+
const root = opts.root || defaultRoot();
|
|
539
|
+
const storeId = goalFileStoreId(root);
|
|
540
|
+
function read(id) {
|
|
541
|
+
if (isUnsafeGoalId(id)) throw goalError("GOAL_INVALID_ID");
|
|
542
|
+
const file = goalFile(root, id);
|
|
543
|
+
if (!fs.existsSync(file)) return null;
|
|
544
|
+
let value;
|
|
545
|
+
try {
|
|
546
|
+
value = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
547
|
+
} catch {
|
|
548
|
+
throw goalError("GOAL_RECORD_CORRUPT");
|
|
549
|
+
}
|
|
550
|
+
const record = fileRecord(value, root);
|
|
551
|
+
if (record.id !== id) throw goalError("GOAL_RECORD_CORRUPT");
|
|
552
|
+
return record;
|
|
553
|
+
}
|
|
554
|
+
return Object.freeze({
|
|
555
|
+
storeId,
|
|
556
|
+
get: read,
|
|
557
|
+
create(value) {
|
|
558
|
+
const record = fileRecord(value, root);
|
|
559
|
+
if (isUnsafeGoalId(record.id)) throw goalError("GOAL_INVALID_ID");
|
|
560
|
+
if (
|
|
561
|
+
record.revision !== 1 ||
|
|
562
|
+
record.controlGeneration !== 0 ||
|
|
563
|
+
record.status !== "active"
|
|
564
|
+
)
|
|
565
|
+
throw goalError("GOAL_INVALID_INITIAL_STATE");
|
|
566
|
+
ensureDir(root);
|
|
567
|
+
return withFileLock(
|
|
568
|
+
goalFile(root, record.id),
|
|
569
|
+
() => {
|
|
570
|
+
if (fs.existsSync(goalFile(root, record.id)))
|
|
571
|
+
throw goalError("GOAL_ALREADY_EXISTS");
|
|
572
|
+
atomicWriteFileSync(
|
|
573
|
+
goalFile(root, record.id),
|
|
574
|
+
JSON.stringify(record, null, 2),
|
|
575
|
+
);
|
|
576
|
+
return record;
|
|
577
|
+
},
|
|
578
|
+
{ failIfUnavailable: true },
|
|
579
|
+
);
|
|
580
|
+
},
|
|
581
|
+
compareAndSwap(id, expectedRevision, transform) {
|
|
582
|
+
if (isUnsafeGoalId(id)) throw goalError("GOAL_INVALID_ID");
|
|
583
|
+
if (
|
|
584
|
+
!Number.isSafeInteger(expectedRevision) ||
|
|
585
|
+
expectedRevision < 1 ||
|
|
586
|
+
typeof transform !== "function"
|
|
587
|
+
)
|
|
588
|
+
throw goalError("GOAL_INVALID_REVISION");
|
|
589
|
+
if (!fs.existsSync(goalFile(root, id)))
|
|
590
|
+
throw goalError("GOAL_NOT_FOUND_OR_DENIED");
|
|
591
|
+
return withFileLock(
|
|
592
|
+
goalFile(root, id),
|
|
593
|
+
() => {
|
|
594
|
+
const current = read(id);
|
|
595
|
+
if (current === null) throw goalError("GOAL_NOT_FOUND_OR_DENIED");
|
|
596
|
+
if (current.revision !== expectedRevision)
|
|
597
|
+
throw goalError("GOAL_REVISION_CONFLICT");
|
|
598
|
+
const next = fileRecord(validateGoalRecord(transform(current)), root);
|
|
599
|
+
if (
|
|
600
|
+
next.id !== id ||
|
|
601
|
+
next.revision !== current.revision + 1 ||
|
|
602
|
+
next.controlGeneration < current.controlGeneration
|
|
603
|
+
)
|
|
604
|
+
throw goalError("GOAL_INVALID_REPLACEMENT");
|
|
605
|
+
atomicWriteFileSync(
|
|
606
|
+
goalFile(root, id),
|
|
607
|
+
JSON.stringify(next, null, 2),
|
|
608
|
+
);
|
|
609
|
+
return next;
|
|
610
|
+
},
|
|
611
|
+
{ failIfUnavailable: true },
|
|
612
|
+
);
|
|
613
|
+
},
|
|
614
|
+
list({ status } = {}) {
|
|
615
|
+
if (status !== undefined && !STATUS_VALUES.has(status))
|
|
616
|
+
throw goalError("GOAL_INVALID_STATUS");
|
|
617
|
+
if (!fs.existsSync(root)) return [];
|
|
618
|
+
return fs
|
|
619
|
+
.readdirSync(root)
|
|
620
|
+
.filter((name) => name.endsWith(".json"))
|
|
621
|
+
.map((name) => read(name.slice(0, -5)))
|
|
622
|
+
.filter(
|
|
623
|
+
(record) =>
|
|
624
|
+
record !== null &&
|
|
625
|
+
(status === undefined || record.status === status),
|
|
626
|
+
)
|
|
627
|
+
.sort((a, b) => b.createdAt.localeCompare(a.createdAt));
|
|
628
|
+
},
|
|
629
|
+
});
|
|
630
|
+
}
|
|
@@ -46,6 +46,7 @@ import {
|
|
|
46
46
|
SANDBOX_BOUNDARIES,
|
|
47
47
|
} from "./platform-sandbox.js";
|
|
48
48
|
import { normalizeLinuxCgroupPolicy } from "./linux-cgroup-v2.js";
|
|
49
|
+
import { consumeWindowsNativeEvaluatorPolicy } from "./windows-native-evaluator.js";
|
|
49
50
|
import { acquireLinuxSubreaperHelper } from "./linux-subreaper-helper.js";
|
|
50
51
|
import { spawnLinuxSubreaperChild } from "./linux-subreaper-process.js";
|
|
51
52
|
import {
|
|
@@ -1625,7 +1626,49 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
1625
1626
|
requiredBoundaries,
|
|
1626
1627
|
launch,
|
|
1627
1628
|
);
|
|
1628
|
-
|
|
1629
|
+
const wallTimeMs = rawPolicy?.limits?.wallTimeMs;
|
|
1630
|
+
if (wallTimeMs !== undefined) {
|
|
1631
|
+
if (
|
|
1632
|
+
!Number.isSafeInteger(wallTimeMs) ||
|
|
1633
|
+
wallTimeMs < 1 ||
|
|
1634
|
+
wallTimeMs > 3600000
|
|
1635
|
+
) {
|
|
1636
|
+
throw this._sandboxBoundaryError(
|
|
1637
|
+
"invalid_wall_time_limit",
|
|
1638
|
+
"Native wall-time limit must be an integer from 1 to 3600000 milliseconds",
|
|
1639
|
+
);
|
|
1640
|
+
}
|
|
1641
|
+
if (!requiredBoundaries.includes(SANDBOX_BOUNDARIES.RESOURCE_LIMITS)) {
|
|
1642
|
+
requiredBoundaries.push(SANDBOX_BOUNDARIES.RESOURCE_LIMITS);
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
const windowsNativeEvaluator =
|
|
1646
|
+
rawPolicy?.windowsNativeEvaluator === undefined
|
|
1647
|
+
? null
|
|
1648
|
+
: consumeWindowsNativeEvaluatorPolicy(
|
|
1649
|
+
rawPolicy.windowsNativeEvaluator,
|
|
1650
|
+
launch,
|
|
1651
|
+
options,
|
|
1652
|
+
);
|
|
1653
|
+
if (windowsNativeEvaluator) {
|
|
1654
|
+
for (const boundary of [
|
|
1655
|
+
SANDBOX_BOUNDARIES.FILESYSTEM,
|
|
1656
|
+
SANDBOX_BOUNDARIES.NETWORK,
|
|
1657
|
+
SANDBOX_BOUNDARIES.PROCESS_TREE,
|
|
1658
|
+
SANDBOX_BOUNDARIES.RESOURCE_LIMITS,
|
|
1659
|
+
]) {
|
|
1660
|
+
if (!requiredBoundaries.includes(boundary))
|
|
1661
|
+
requiredBoundaries.push(boundary);
|
|
1662
|
+
}
|
|
1663
|
+
}
|
|
1664
|
+
return {
|
|
1665
|
+
profile,
|
|
1666
|
+
requiredBoundaries,
|
|
1667
|
+
linuxCgroup,
|
|
1668
|
+
executionContract,
|
|
1669
|
+
...(windowsNativeEvaluator ? { windowsNativeEvaluator } : {}),
|
|
1670
|
+
...(wallTimeMs !== undefined ? { wallTimeMs } : {}),
|
|
1671
|
+
};
|
|
1629
1672
|
}
|
|
1630
1673
|
|
|
1631
1674
|
_stripSandboxControlOptions(options) {
|
|
@@ -3660,6 +3703,12 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
3660
3703
|
...(sandboxPolicy.executionContract
|
|
3661
3704
|
? { executionContract: sandboxPolicy.executionContract }
|
|
3662
3705
|
: {}),
|
|
3706
|
+
...(sandboxPolicy.wallTimeMs !== undefined
|
|
3707
|
+
? { limits: Object.freeze({ wallTimeMs: sandboxPolicy.wallTimeMs }) }
|
|
3708
|
+
: {}),
|
|
3709
|
+
...(sandboxPolicy.windowsNativeEvaluator
|
|
3710
|
+
? { windowsNativeEvaluator: sandboxPolicy.windowsNativeEvaluator }
|
|
3711
|
+
: {}),
|
|
3663
3712
|
});
|
|
3664
3713
|
// Keep the legacy string profile in argument four. The built-in adapter
|
|
3665
3714
|
// reserves argument five for runtime injection, so the typed request is
|
|
@@ -3667,6 +3716,12 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
3667
3716
|
const sandboxAdapter = this._sandboxAdapter;
|
|
3668
3717
|
const applySandboxAdapter = sandboxAdapter.applySandbox;
|
|
3669
3718
|
const builtInSandboxAdapter = applySandboxAdapter === _applySandbox;
|
|
3719
|
+
if (sandboxPolicy.wallTimeMs !== undefined && !builtInSandboxAdapter) {
|
|
3720
|
+
throw this._sandboxBoundaryError(
|
|
3721
|
+
"native_wall_time_adapter_unattested",
|
|
3722
|
+
"Native wall-time enforcement requires the built-in Windows supervisor",
|
|
3723
|
+
);
|
|
3724
|
+
}
|
|
3670
3725
|
// Never dispatch the built-in through a mutable Function property or a
|
|
3671
3726
|
// global reflective helper after consulting an injected adapter getter.
|
|
3672
3727
|
// The lexical import is the identity we checked and the implementation we
|
|
@@ -3690,6 +3745,41 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
3690
3745
|
]);
|
|
3691
3746
|
let plan;
|
|
3692
3747
|
try {
|
|
3748
|
+
if (
|
|
3749
|
+
sandboxPolicy.wallTimeMs !== undefined &&
|
|
3750
|
+
(!rawPlan?.applied ||
|
|
3751
|
+
rawPlan.platform !== "win32" ||
|
|
3752
|
+
![
|
|
3753
|
+
"windows-job-restricted-token",
|
|
3754
|
+
"windows-appcontainer-job-restricted-token",
|
|
3755
|
+
].includes(rawPlan.backend) ||
|
|
3756
|
+
rawPlan.windowsWallTimeMs !== sandboxPolicy.wallTimeMs)
|
|
3757
|
+
) {
|
|
3758
|
+
throw this._sandboxBoundaryError(
|
|
3759
|
+
"native_wall_time_limit_unavailable",
|
|
3760
|
+
`The requested native wall-time limit was not enforced: ${rawPlan?.reason || "unattested_plan"}`,
|
|
3761
|
+
{
|
|
3762
|
+
requiredBoundaries,
|
|
3763
|
+
actualGuarantees: rawPlan?.guarantees || [],
|
|
3764
|
+
sandboxBackend: rawPlan?.backend,
|
|
3765
|
+
sandboxCandidateBackend: rawPlan?.candidateBackend,
|
|
3766
|
+
sandboxRuntimeProbe: rawPlan?.runtimeProbe,
|
|
3767
|
+
sandboxCandidateReason: rawPlan?.reason,
|
|
3768
|
+
},
|
|
3769
|
+
);
|
|
3770
|
+
}
|
|
3771
|
+
if (
|
|
3772
|
+
sandboxPolicy.windowsNativeEvaluator &&
|
|
3773
|
+
(rawPlan.backend !== "windows-appcontainer-job-restricted-token" ||
|
|
3774
|
+
rawPlan.policyAttested !== true ||
|
|
3775
|
+
rawPlan.windowsNativeEvaluatorDigest !==
|
|
3776
|
+
sandboxPolicy.windowsNativeEvaluator.manifestDigest)
|
|
3777
|
+
) {
|
|
3778
|
+
throw this._sandboxBoundaryError(
|
|
3779
|
+
"native_evaluator_plan_unattested",
|
|
3780
|
+
"The staged native evaluator policy was not enforced",
|
|
3781
|
+
);
|
|
3782
|
+
}
|
|
3693
3783
|
plan = this._validateSandboxPlan(rawPlan, {
|
|
3694
3784
|
command,
|
|
3695
3785
|
args: Object.freeze([...(args || [])]),
|
|
@@ -783,6 +783,8 @@ function normalizeSandboxRequest(profileOrRequest, explicitRequest) {
|
|
|
783
783
|
profile,
|
|
784
784
|
requiredBoundaries,
|
|
785
785
|
sync: request.sync === true,
|
|
786
|
+
wallTimeMs: request.limits?.wallTimeMs,
|
|
787
|
+
windowsNativeEvaluator: request.windowsNativeEvaluator || null,
|
|
786
788
|
pty: request.pty === true,
|
|
787
789
|
linuxCgroup: normalizeLinuxCgroupPolicy(request.linuxCgroup),
|
|
788
790
|
executionContract:
|
|
@@ -2106,6 +2108,12 @@ export function applyMacSandbox(
|
|
|
2106
2108
|
reason: "platform_mismatch",
|
|
2107
2109
|
});
|
|
2108
2110
|
}
|
|
2111
|
+
if (sandboxOpts.limits?.wallTimeMs !== undefined) {
|
|
2112
|
+
return createSandboxPlan({
|
|
2113
|
+
...base,
|
|
2114
|
+
reason: "native_wall_time_limit_unsupported",
|
|
2115
|
+
});
|
|
2116
|
+
}
|
|
2109
2117
|
|
|
2110
2118
|
if (
|
|
2111
2119
|
Array.isArray(sandboxOpts.requiredBoundaries) &&
|
|
@@ -4205,10 +4213,14 @@ function windowsAppContainerPolicyDigest({
|
|
|
4205
4213
|
},
|
|
4206
4214
|
job: {
|
|
4207
4215
|
killOnClose: true,
|
|
4216
|
+
wallTimeMs: launchSpec.wallTimeMs,
|
|
4208
4217
|
activeProcessLimit: launchSpec.activeProcessLimit,
|
|
4209
4218
|
cpuSeconds: launchSpec.cpuSeconds,
|
|
4210
4219
|
processMemoryBytes: launchSpec.processMemoryBytes,
|
|
4211
4220
|
},
|
|
4221
|
+
...(launchSpec.nativeEvaluator
|
|
4222
|
+
? { nativeEvaluator: launchSpec.nativeEvaluator }
|
|
4223
|
+
: {}),
|
|
4212
4224
|
execution: {
|
|
4213
4225
|
contractKind: executionContract?.kind || null,
|
|
4214
4226
|
contentSnapshot: snapshotLocks.length > 0,
|
|
@@ -4310,6 +4322,15 @@ export function applyWindowsSandbox(
|
|
|
4310
4322
|
if (runtime.platform !== "win32") {
|
|
4311
4323
|
return unavailablePlan("platform_mismatch");
|
|
4312
4324
|
}
|
|
4325
|
+
const wallTimeMs = sandboxOpts.limits?.wallTimeMs ?? 0;
|
|
4326
|
+
if (
|
|
4327
|
+
sandboxOpts.limits?.wallTimeMs !== undefined &&
|
|
4328
|
+
(!Number.isSafeInteger(wallTimeMs) ||
|
|
4329
|
+
wallTimeMs < 1 ||
|
|
4330
|
+
wallTimeMs > 3600000)
|
|
4331
|
+
) {
|
|
4332
|
+
return unavailablePlan("windows_wall_time_limit_invalid");
|
|
4333
|
+
}
|
|
4313
4334
|
let windowsDirectory;
|
|
4314
4335
|
try {
|
|
4315
4336
|
windowsDirectory = path.win32.resolve(runtime.windowsDir());
|
|
@@ -4499,6 +4520,7 @@ export function applyWindowsSandbox(
|
|
|
4499
4520
|
}
|
|
4500
4521
|
}
|
|
4501
4522
|
const launchSpec = {
|
|
4523
|
+
wallTimeMs,
|
|
4502
4524
|
cpuSeconds: Number(limits.cpu || 0),
|
|
4503
4525
|
processMemoryBytes: Number(
|
|
4504
4526
|
limits.as || (profile === "strict" ? 256 * 1024 * 1024 : 0),
|
|
@@ -4516,6 +4538,9 @@ export function applyWindowsSandbox(
|
|
|
4516
4538
|
windowsHide: invocation.options.windowsHide === true,
|
|
4517
4539
|
workingDirectory: targetWorkingDirectory,
|
|
4518
4540
|
environment: targetEnvironment,
|
|
4541
|
+
...(sandboxOpts.windowsNativeEvaluator
|
|
4542
|
+
? { nativeEvaluator: sandboxOpts.windowsNativeEvaluator }
|
|
4543
|
+
: {}),
|
|
4519
4544
|
};
|
|
4520
4545
|
if (entrySnapshot.locks) {
|
|
4521
4546
|
launchSpec.launchPathLocks = entrySnapshot.locks;
|
|
@@ -4917,6 +4942,9 @@ export function applyWindowsSandbox(
|
|
|
4917
4942
|
policyAttested: requiresAppContainer ? true : null,
|
|
4918
4943
|
policyDigest: appContainerPolicyDigest,
|
|
4919
4944
|
adapterTempRootAttestation: adapterSource.tempRootAttestation,
|
|
4945
|
+
windowsWallTimeMs: wallTimeMs || null,
|
|
4946
|
+
windowsNativeEvaluatorDigest:
|
|
4947
|
+
sandboxOpts.windowsNativeEvaluator?.manifestDigest || null,
|
|
4920
4948
|
runtimeProbe: entrySnapshotRuntimeProbe,
|
|
4921
4949
|
guarantees: [
|
|
4922
4950
|
...(requiresAppContainer
|
|
@@ -8896,6 +8924,13 @@ export function applyLinuxSandbox(
|
|
|
8896
8924
|
});
|
|
8897
8925
|
}
|
|
8898
8926
|
|
|
8927
|
+
if (sandboxOpts.limits?.wallTimeMs !== undefined) {
|
|
8928
|
+
return createSandboxPlan({
|
|
8929
|
+
...base,
|
|
8930
|
+
reason: "native_wall_time_limit_unsupported",
|
|
8931
|
+
});
|
|
8932
|
+
}
|
|
8933
|
+
|
|
8899
8934
|
const { limits = {} } = sandboxOpts;
|
|
8900
8935
|
const requiredBoundaries = Array.isArray(sandboxOpts.requiredBoundaries)
|
|
8901
8936
|
? sandboxOpts.requiredBoundaries
|
|
@@ -9984,7 +10019,14 @@ export function applySandbox(
|
|
|
9984
10019
|
pty: sandboxRequest.pty,
|
|
9985
10020
|
linuxCgroup: sandboxRequest.linuxCgroup,
|
|
9986
10021
|
executionContract: sandboxRequest.executionContract,
|
|
10022
|
+
windowsNativeEvaluator: sandboxRequest.windowsNativeEvaluator,
|
|
9987
10023
|
};
|
|
10024
|
+
if (sandboxRequest.wallTimeMs !== undefined) {
|
|
10025
|
+
profile.limits = {
|
|
10026
|
+
...profile.limits,
|
|
10027
|
+
wallTimeMs: sandboxRequest.wallTimeMs,
|
|
10028
|
+
};
|
|
10029
|
+
}
|
|
9988
10030
|
|
|
9989
10031
|
const applyRequestedLinuxCgroup = (plan) =>
|
|
9990
10032
|
applyLinuxCgroupV2ToPlan(plan, sandboxRequest.linuxCgroup, {
|