chainlesschain 0.163.3 → 0.163.5
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/package.json +3 -2
- package/scripts/command-lifecycle-report.mjs +330 -38
- package/src/assets/web-panel/assets/{AIOps-DIY6KxV-.js → AIOps-Cv2EE1Zy.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-BXH0muPt.js → ActionButton-CcpxMLuW.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-D39w8vmg.js → Analytics-DE8mJoMI.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-CUU1zvLs.js → AppLayout-DKn9dk9L.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-D8azHO3T.js → Artifacts-Cp3mG3Py.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-D0tAwXTg.js → Audit-zvsQfF2C.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-C29mhJll.js → BackgroundAgents-Bi85SsjN.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-D6Aa1Gro.js → Backup-Cw47Dj6s.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-B1uoHbPQ.js → BaseInput-C5Ip2afH.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-Bs4DLOR5.js → Chat-C0iAFkJv.js} +5 -5
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-DUYIBSle.js → ChatBubbleRenderer-BV9Wv7wO.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-CNcBPEa4.js → Checkbox-3KZZCiAF.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-CIY89763.js → Codegen-C8OMbBAz.js} +1 -1
- package/src/assets/web-panel/assets/{Col-CsPYFmgo.js → Col-B-MB84LJ.js} +1 -1
- package/src/assets/web-panel/assets/{Community-BBocEge4.js → Community-DpR7Dxao.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-TQ8Ux0Lf.js → Compact-CyDtz0OS.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-DfBsZTft.js → Compliance-5tiRa2An.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-Cg-I6FVH.js → Cowork-DnQaKZ5x.js} +4 -4
- package/src/assets/web-panel/assets/{Cron-DTQzfRTp.js → Cron-BaWfoEDf.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-DGxEKGpR.js → Crosschain-Bu0HoHhb.js} +1 -1
- package/src/assets/web-panel/assets/{DID-DLZ1RDSr.js → DID-31zk8upX.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-XneICKNI.js → Dashboard-BmVne-e2.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-BRU00J1-.js → Dropdown-B4PkoOWd.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-BzCbJuAy.js → EmailListRenderer-BZ6tyFtI.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-D7BRyNBG.js → FamilyGuardDashboard-Osozn4Ds.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-D9DeFIhW.js → Federation-DaH8TOAP.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-6rAtA9Ko.js → FormItemContext-tbU0uwis.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-8Hqy80pU.js → GenericCardRenderer-Df8LQBrL.js} +1 -1
- package/src/assets/web-panel/assets/{Git-Cmvkj1rt.js → Git-DsMB6-14.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-BRiQUjjw.js → Governance-BnH0dZzd.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-CKN_EzVf.js → Inference-DhnN1N_P.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-BCDHwpwQ.js → KnowledgeGraph-DnNshAgn.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-DK9ovhaB.js → Logs-BmBFX3_N.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-D53pHiHy.js → MarkdownRenderer-DCslfQU3.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-BILPGakp.js → Marketplace-CPEgWDc3.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DTVCOr9-.js → McpTools-C36qjgF9.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-Hzc1iow4.js → Memory-tNHvrgqN.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-GXfgnGYV.js → MobileBridge-Xaf6cKjc.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-B-3TJWsS.js → MobileProjects-D2E5TTeO.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-DwSJMWtK.js → Mtc-D4AJ2dwV.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-D2uxf-DA.js → MtcAudit-Df-gtn2_.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-DG6kbKK0.js → Multisig-DTCHLWld.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-f5p49EDU.js → NLProgramming-DruZ_1Jb.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-FUgHyzSD.js → Notes-Dx3pdGDs.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-DCHGee7e.js → NotificationSettings-Bi3L69oL.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-Dm6LlIoa.js → OrderTableRenderer-BHY33m7C.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-BawA7qAg.js → Organization-BG2ZVEV-.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-D6a5wZU1.js → Overflow-Viwtg4Mn.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-K8WavwnA.js → P2P-Clm_yc1Z.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-4JAJYaqx.js → PdhVaultBrowser-NKmmDiOw.js} +5 -5
- package/src/assets/web-panel/assets/{Permissions-BDWvi8PD.js → Permissions-DIL8u9Nk.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-DF_K4E9i.js → PersonalDataHub-B-jM4wt-.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-BYeZlesI.js → Pipeline-627I__H5.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-BIHlgnIc.js → Privacy-2DN2qrkW.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-Cvf-6B5P.js → ProjectInit-CN4wC0sF.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-CnwfJrRz.js → ProjectSettings-K35vsh5H.js} +2 -2
- package/src/assets/web-panel/assets/Projects-B_wQadhX.js +1 -0
- package/src/assets/web-panel/assets/{Providers-CxC7JuYv.js → Providers-MckaQUhQ.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-VLf3gAfL.js → QrScannerModal-BS3mtA_O.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-B5vGjRiF.js → QuickAsk-BHp_nofL.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend--UW4iYs-.js → Recommend-DlmnPuZj.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-DMSPcfKR.js → RemoteSession-tsyFbvpy.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-kQXlEHmj.js → Reputation-Ba1iWv2D.js} +1 -1
- package/src/assets/web-panel/assets/{Row-CxGu3pit.js → Row-NnlGC--f.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-Bi5lo8MZ.js → RssFeed-CjThSIRv.js} +3 -3
- package/src/assets/web-panel/assets/{Search-Cq_H5RTh.js → Search-CojUyC5x.js} +1 -1
- package/src/assets/web-panel/assets/{Security-YFbmkaQS.js → Security-c-sxeJEc.js} +3 -3
- package/src/assets/web-panel/assets/{Services-DLOGdaLm.js → Services-CtcKEEmF.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-CteIxb3D.js → Skeleton-CIBBXflN.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-CccopaIZ.js → Skills-D1XOOK9n.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-AzfEQKX1.js → Sla-hRfEp5Sn.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-ekGo5l77.js → SpeechSettings-Dexb1f_6.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-BmZmAgYH.js → SyncSettings-BJsSFGYy.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-D7q3Z4uL.js → Tasks-CfSZ8A1L.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-CX1Tgeka.js → Templates-idDf47W-.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-Zc59jF4i.js → Tenant-C-UsX6w6.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-CXOD7y83.js → Terminal-BgJtX5n1.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-B1aBHPBo.js → TimelineRenderer-DP0BLKTl.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-zALlOq_U.js → Tokens-LwCzqETp.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-CQfJMXaq.js → Trigger-D_9tVch0.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-BU0RcM-w.js → Trust-BH2UlEWh.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-IFZ3HsbH.js → UkeySign-CIpD0nYb.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-BzslgW0v.js → VideoEditing-9ShhYxK_.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-BZAcQNS6.js → Wallet-C7afGNIG.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-CBK1DMi0.js → WebAuthn-bUKn6i5R.js} +3 -3
- package/src/assets/web-panel/assets/{WorkflowEditor-BlMTPzO-.js → WorkflowEditor-CxgQaGyp.js} +1 -1
- package/src/assets/web-panel/assets/{chat-B51-8QVn.js → chat-DMVkmJwx.js} +1 -1
- package/src/assets/web-panel/assets/{colors-504RTByU.js → colors-CDzQh5nS.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-C-GP6IQM.js → compact-item-C51kEF4D.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-DOkIj7ID.js → createContext-BTk9bXBn.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-CdwPwYj8.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-DN7V-_FW.js → hasIn-CMje33rb.js} +1 -1
- package/src/assets/web-panel/assets/{index-CKTfZyfU.js → index-0Auljb10.js} +1 -1
- package/src/assets/web-panel/assets/{index-D9LyiN-L.js → index-B0-zMtKA.js} +1 -1
- package/src/assets/web-panel/assets/{index-DEMPUVa3.js → index-BAfY7m7i.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bkxhaeta.js → index-BBz9LIMS.js} +1 -1
- package/src/assets/web-panel/assets/{index-7jIqHbzw.js → index-BCRvG9lq.js} +1 -1
- package/src/assets/web-panel/assets/index-BEeOdfEe.js +1 -0
- package/src/assets/web-panel/assets/index-BTe0TOu6.js +1 -0
- package/src/assets/web-panel/assets/{index-P2mfY27Z.js → index-BTlsE8Df.js} +1 -1
- package/src/assets/web-panel/assets/{index-DAOpQvl_.js → index-BVePe_Rf.js} +1 -1
- package/src/assets/web-panel/assets/{index-CYopNjcJ.js → index-BW4F5YDF.js} +1 -1
- package/src/assets/web-panel/assets/{index-B_vGU-Js.js → index-BXQBPLyE.js} +1 -1
- package/src/assets/web-panel/assets/{index-kt_5rfcZ.js → index-BeEaAEIp.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cao5DZy7.js → index-BtlEqHLP.js} +1 -1
- package/src/assets/web-panel/assets/{index-DA2f1UV3.js → index-BzCkNylB.js} +1 -1
- package/src/assets/web-panel/assets/{index-B2-x9bS8.js → index-C1oZQmAA.js} +1 -1
- package/src/assets/web-panel/assets/{index-D1phyca8.js → index-C1oZReaY.js} +1 -1
- package/src/assets/web-panel/assets/{index-FcV8J_Qz.js → index-C4rQCS8T.js} +1 -1
- package/src/assets/web-panel/assets/{index-C3TSohzc.js → index-C5IWTMVl.js} +1 -1
- package/src/assets/web-panel/assets/{index-CySTJKeq.js → index-CCLj9hcD.js} +1 -1
- package/src/assets/web-panel/assets/{index-C9_48OzU.js → index-CDLkNkLj.js} +1 -1
- package/src/assets/web-panel/assets/{index-so8eIIxF.js → index-Cd0hmPxD.js} +1 -1
- package/src/assets/web-panel/assets/{index-CX78k-qf.js → index-CfC-piWZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DE-hmI2l.js → index-CtM8OT_7.js} +1 -1
- package/src/assets/web-panel/assets/{index-kAqQXfP6.js → index-CvSeVzqe.js} +1 -1
- package/src/assets/web-panel/assets/{index-C0k_Nqg9.js → index-CwGPwjUu.js} +1 -1
- package/src/assets/web-panel/assets/{index-CP2A226L.js → index-CypsfcEq.js} +1 -1
- package/src/assets/web-panel/assets/{index-CfiEM64n.js → index-D9rC-fGW.js} +3 -3
- package/src/assets/web-panel/assets/{index-yYTQZypF.js → index-DJfnCuMq.js} +1 -1
- package/src/assets/web-panel/assets/{index-f4Bo4KXm.js → index-DRG-aqOs.js} +1 -1
- package/src/assets/web-panel/assets/{index-By6u5IV1.js → index-DRLQyp2A.js} +1 -1
- package/src/assets/web-panel/assets/{index-ConjaJro.js → index-DgivOKHA.js} +1 -1
- package/src/assets/web-panel/assets/{index--n-ZciV3.js → index-DpcrFxMI.js} +1 -1
- package/src/assets/web-panel/assets/{index-CqcLo5WV.js → index-DqU9njjT.js} +1 -1
- package/src/assets/web-panel/assets/{index-CUhQpiYv.js → index-Ld_4mFmC.js} +1 -1
- package/src/assets/web-panel/assets/{index-C4DV_5uA.js → index-OS-vfbTA.js} +1 -1
- package/src/assets/web-panel/assets/{index-DaA__-q1.js → index-h31MwrME.js} +1 -1
- package/src/assets/web-panel/assets/{index-BFIFJ5Dr.js → index-hg_emBsi.js} +1 -1
- package/src/assets/web-panel/assets/{index-C8UltbXK.js → index-togc_uYn.js} +1 -1
- package/src/assets/web-panel/assets/{index-et5JIPHO.js → index-x53Vf7la.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-CPYEIdpV.js → initDefaultProps-vrA8K-ac.js} +1 -1
- package/src/assets/web-panel/assets/{motion-Cjim9pxs.js → motion-ByEzwIAl.js} +1 -1
- package/src/assets/web-panel/assets/{move-DuU-cgz3.js → move-Ck4AWjw-.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-DJHNAkta.js → mtc-parser-6p0l9SrB.js} +1 -1
- package/src/assets/web-panel/assets/{omit-DSQBgdBj.js → omit-B1CUPQ6R.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-CTmT_j5m.js → pickAttrs-B1STg1iW.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-Lfm6v-r4.js → placementArrow-DTTllkBV.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-CgrcPcDi.js → responsiveObserve-AIrrCfBb.js} +1 -1
- package/src/assets/web-panel/assets/{slide-CuE3110i.js → slide-C_fPMjdR.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-DiK5nbpf.js → statusUtils-D5ow2yIP.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-DPEJdQaZ.js → styleChecker-Dy3hEA--.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-CnnodGmp.js → useFlexGapSupport-WfzcfSh4.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-DWF84Yav.js → useFs-CKSejfas.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-a5b5Dw2f.js → usePersonalDataHub-od3zpPBN.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-DAluzXOq.js → vnode-DRD_2DFA.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-Dokg7uAZ.js → zoom-DmNrEtgf.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +1 -1
- package/src/commands/agenda.js +52 -6
- package/src/commands/artifacts.js +98 -0
- package/src/commands/cowork.js +24 -12
- package/src/commands/mcp.js +1 -1
- package/src/commands/review.js +221 -22
- package/src/commands/routine.js +40 -10
- package/src/commands/session-mcp-recovery.js +5 -5
- package/src/data/changelog.json +27 -1
- package/src/gateways/ws/ws-agent-handler.js +492 -14
- package/src/harness/jsonl-session-store.js +39 -1
- package/src/harness/mcp-client.js +172 -29
- package/src/harness/prompt-compressor.js +24 -0
- package/src/harness/provider-backed-compaction.js +205 -0
- package/src/lib/agent-schedule-store.js +197 -4
- package/src/lib/app-preview.js +3 -0
- package/src/lib/command-lifecycle-report.js +1340 -145
- package/src/lib/cowork-cron.js +243 -25
- package/src/lib/delivery-coordinator.js +30 -5
- package/src/lib/delivery-production-adapter.js +1777 -0
- package/src/lib/delivery-production-runner.js +240 -0
- package/src/lib/durable-security-store.js +29 -17
- package/src/lib/execution-trace/trace-context.cjs +179 -0
- package/src/lib/execution-trace/trace-context.js +8 -175
- package/src/lib/mcp-call-ledger-store.js +58 -6
- package/src/lib/mcp-host-recovery-runtime.js +2 -0
- package/src/lib/mcp-ledger-recovery-admission.js +39 -3
- package/src/lib/mcp-recovery-adjudication.js +256 -19
- package/src/lib/mcp-sandbox-policy.js +29 -0
- package/src/lib/mcp-stdio-capsule-builder-worker.cjs +495 -0
- package/src/lib/mcp-stdio-executable-identity.js +33 -2
- package/src/lib/mcp-stdio-immutable-vfs-resolver.cjs +830 -0
- package/src/lib/mcp-stdio-package-materialization.js +721 -333
- package/src/lib/micro-compact.js +11 -5
- package/src/lib/observability/index.js +2 -0
- package/src/lib/observability/otlp-exporter.js +2 -2
- package/src/lib/packer/pack-update-applier.js +8 -1
- package/src/lib/packer/pkg-config-generator.js +34 -0
- package/src/lib/process-execution-broker/index.js +48 -8
- package/src/lib/process-execution-broker/platform-sandbox.js +82 -1
- package/src/lib/routine-store.js +76 -3
- package/src/lib/scheduler-kernel/agenda-adapter.js +542 -0
- package/src/lib/scheduler-kernel/contract.js +315 -0
- package/src/lib/scheduler-kernel/cowork-cron-adapter.js +774 -0
- package/src/lib/scheduler-kernel/routine-adapter.js +517 -0
- package/src/lib/scheduler-kernel/runtime.js +527 -0
- package/src/lib/scheduler-kernel/store.js +1455 -0
- package/src/lib/session-host-lease.js +403 -30
- package/src/lib/session-message-provenance.js +4 -1
- package/src/lib/session-persistence-failure.js +4 -1
- package/src/lib/sub-agent-context.js +8 -0
- package/src/repl/agent-repl.js +309 -43
- package/src/runtime/agent-core.js +1079 -105
- package/src/runtime/headless-runner.js +260 -166
- package/src/runtime/headless-stream.js +254 -25
- package/src/assets/web-panel/assets/Projects-b-jPXzF4.js +0 -1
- package/src/assets/web-panel/assets/devWarning-kB0nCNwN.js +0 -1
- package/src/assets/web-panel/assets/index-Bya64sZE.js +0 -1
- package/src/assets/web-panel/assets/index-D_FWpDZM.js +0 -1
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { Buffer } from "node:buffer";
|
|
3
|
+
|
|
4
|
+
export const SCHEDULER_SCHEMA_VERSION = 1;
|
|
5
|
+
export const AUTHORITY_ENVELOPE_VERSION = 1;
|
|
6
|
+
|
|
7
|
+
export const OCCURRENCE_STATUS = Object.freeze({
|
|
8
|
+
QUEUED: "queued",
|
|
9
|
+
RUNNING: "running",
|
|
10
|
+
RETRY_WAIT: "retry_wait",
|
|
11
|
+
SUCCEEDED: "succeeded",
|
|
12
|
+
DEAD_LETTER: "dead_letter",
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export const DEFAULT_MAX_ATTEMPTS = 3;
|
|
16
|
+
export const MAX_JOB_ATTEMPTS = 32;
|
|
17
|
+
export const DEFAULT_HISTORY_LIMIT = 50;
|
|
18
|
+
export const MAX_HISTORY_LIMIT = 200;
|
|
19
|
+
export const MAX_JSON_BYTES = 1024 * 1024;
|
|
20
|
+
|
|
21
|
+
const AUTHORITY_FIELDS = new Set([
|
|
22
|
+
"schemaVersion",
|
|
23
|
+
"principal",
|
|
24
|
+
"tenantId",
|
|
25
|
+
"workspaceId",
|
|
26
|
+
"requestedCapabilities",
|
|
27
|
+
"authorizationRefs",
|
|
28
|
+
]);
|
|
29
|
+
const PRINCIPAL_FIELDS = new Set(["type", "id"]);
|
|
30
|
+
const AUTHORIZATION_REF_FIELDS = new Set([
|
|
31
|
+
"decisionId",
|
|
32
|
+
"policyRevision",
|
|
33
|
+
"grantIds",
|
|
34
|
+
"approvalIds",
|
|
35
|
+
"delegationIds",
|
|
36
|
+
]);
|
|
37
|
+
|
|
38
|
+
export class SchedulerKernelError extends Error {
|
|
39
|
+
constructor(code, message, details = undefined, options = undefined) {
|
|
40
|
+
super(message, options);
|
|
41
|
+
this.name = "SchedulerKernelError";
|
|
42
|
+
this.code = code;
|
|
43
|
+
if (details !== undefined) this.details = details;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function invalidArgument(message, details = undefined) {
|
|
48
|
+
return new SchedulerKernelError(
|
|
49
|
+
"SCHEDULER_INVALID_ARGUMENT",
|
|
50
|
+
message,
|
|
51
|
+
details,
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function assertPlainObject(value, field) {
|
|
56
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
57
|
+
throw invalidArgument(`${field} must be an object`);
|
|
58
|
+
}
|
|
59
|
+
const prototype = Object.getPrototypeOf(value);
|
|
60
|
+
if (prototype !== Object.prototype && prototype !== null) {
|
|
61
|
+
throw invalidArgument(`${field} must be a plain object`);
|
|
62
|
+
}
|
|
63
|
+
return value;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function assertKnownFields(value, fields, field) {
|
|
67
|
+
const unknown = Object.keys(value).filter((key) => !fields.has(key));
|
|
68
|
+
if (unknown.length > 0) {
|
|
69
|
+
throw invalidArgument(`${field} contains unknown fields`, {
|
|
70
|
+
fields: unknown.sort(),
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function normalizeIdentifier(value, field, { maxLength = 256 } = {}) {
|
|
76
|
+
if (typeof value !== "string") {
|
|
77
|
+
throw invalidArgument(`${field} must be a string`);
|
|
78
|
+
}
|
|
79
|
+
const normalized = value.trim();
|
|
80
|
+
const hasControlCharacter = [...normalized].some((character) => {
|
|
81
|
+
const codePoint = character.codePointAt(0);
|
|
82
|
+
return codePoint <= 31 || codePoint === 127;
|
|
83
|
+
});
|
|
84
|
+
if (
|
|
85
|
+
normalized.length === 0 ||
|
|
86
|
+
normalized.length > maxLength ||
|
|
87
|
+
hasControlCharacter
|
|
88
|
+
) {
|
|
89
|
+
throw invalidArgument(`${field} is not a valid identifier`);
|
|
90
|
+
}
|
|
91
|
+
return normalized;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function normalizeOptionalIdentifier(value, field) {
|
|
95
|
+
if (value === undefined || value === null) return null;
|
|
96
|
+
return normalizeIdentifier(value, field);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function normalizeIdentifierList(value, field) {
|
|
100
|
+
if (value === undefined) return [];
|
|
101
|
+
if (!Array.isArray(value)) {
|
|
102
|
+
throw invalidArgument(`${field} must be an array`);
|
|
103
|
+
}
|
|
104
|
+
if (value.length > 256) {
|
|
105
|
+
throw invalidArgument(`${field} exceeds 256 entries`);
|
|
106
|
+
}
|
|
107
|
+
return [
|
|
108
|
+
...new Set(
|
|
109
|
+
value.map((entry, index) =>
|
|
110
|
+
normalizeIdentifier(entry, `${field}[${index}]`),
|
|
111
|
+
),
|
|
112
|
+
),
|
|
113
|
+
].sort();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Normalize the authority evidence carried by a job and every occurrence.
|
|
118
|
+
*
|
|
119
|
+
* This envelope is deliberately descriptive. The scheduler stores the actor,
|
|
120
|
+
* requested capabilities and immutable decision/grant references, but it does
|
|
121
|
+
* not infer that those references authorize execution. A future dispatcher
|
|
122
|
+
* must still resolve and enforce the referenced policy before doing work.
|
|
123
|
+
*/
|
|
124
|
+
export function normalizeAuthorityEnvelope(input) {
|
|
125
|
+
const authority = assertPlainObject(input, "authority");
|
|
126
|
+
assertKnownFields(authority, AUTHORITY_FIELDS, "authority");
|
|
127
|
+
if (
|
|
128
|
+
authority.schemaVersion !== undefined &&
|
|
129
|
+
authority.schemaVersion !== AUTHORITY_ENVELOPE_VERSION
|
|
130
|
+
) {
|
|
131
|
+
throw invalidArgument(
|
|
132
|
+
`authority.schemaVersion must be ${AUTHORITY_ENVELOPE_VERSION}`,
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const principal = assertPlainObject(
|
|
137
|
+
authority.principal,
|
|
138
|
+
"authority.principal",
|
|
139
|
+
);
|
|
140
|
+
assertKnownFields(principal, PRINCIPAL_FIELDS, "authority.principal");
|
|
141
|
+
const refs = assertPlainObject(
|
|
142
|
+
authority.authorizationRefs ?? {},
|
|
143
|
+
"authority.authorizationRefs",
|
|
144
|
+
);
|
|
145
|
+
assertKnownFields(
|
|
146
|
+
refs,
|
|
147
|
+
AUTHORIZATION_REF_FIELDS,
|
|
148
|
+
"authority.authorizationRefs",
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
return {
|
|
152
|
+
schemaVersion: AUTHORITY_ENVELOPE_VERSION,
|
|
153
|
+
principal: {
|
|
154
|
+
type: normalizeIdentifier(principal.type, "authority.principal.type", {
|
|
155
|
+
maxLength: 64,
|
|
156
|
+
}),
|
|
157
|
+
id: normalizeIdentifier(principal.id, "authority.principal.id"),
|
|
158
|
+
},
|
|
159
|
+
tenantId: normalizeOptionalIdentifier(
|
|
160
|
+
authority.tenantId,
|
|
161
|
+
"authority.tenantId",
|
|
162
|
+
),
|
|
163
|
+
workspaceId: normalizeOptionalIdentifier(
|
|
164
|
+
authority.workspaceId,
|
|
165
|
+
"authority.workspaceId",
|
|
166
|
+
),
|
|
167
|
+
requestedCapabilities: normalizeIdentifierList(
|
|
168
|
+
authority.requestedCapabilities,
|
|
169
|
+
"authority.requestedCapabilities",
|
|
170
|
+
),
|
|
171
|
+
authorizationRefs: {
|
|
172
|
+
decisionId: normalizeOptionalIdentifier(
|
|
173
|
+
refs.decisionId,
|
|
174
|
+
"authority.authorizationRefs.decisionId",
|
|
175
|
+
),
|
|
176
|
+
policyRevision: normalizeOptionalIdentifier(
|
|
177
|
+
refs.policyRevision,
|
|
178
|
+
"authority.authorizationRefs.policyRevision",
|
|
179
|
+
),
|
|
180
|
+
grantIds: normalizeIdentifierList(
|
|
181
|
+
refs.grantIds,
|
|
182
|
+
"authority.authorizationRefs.grantIds",
|
|
183
|
+
),
|
|
184
|
+
approvalIds: normalizeIdentifierList(
|
|
185
|
+
refs.approvalIds,
|
|
186
|
+
"authority.authorizationRefs.approvalIds",
|
|
187
|
+
),
|
|
188
|
+
delegationIds: normalizeIdentifierList(
|
|
189
|
+
refs.delegationIds,
|
|
190
|
+
"authority.authorizationRefs.delegationIds",
|
|
191
|
+
),
|
|
192
|
+
},
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function normalizeJsonValue(value, field, state, depth) {
|
|
197
|
+
if (depth > 64) throw invalidArgument(`${field} exceeds maximum JSON depth`);
|
|
198
|
+
if (
|
|
199
|
+
value === null ||
|
|
200
|
+
typeof value === "string" ||
|
|
201
|
+
typeof value === "boolean"
|
|
202
|
+
) {
|
|
203
|
+
return value;
|
|
204
|
+
}
|
|
205
|
+
if (typeof value === "number") {
|
|
206
|
+
if (!Number.isFinite(value)) {
|
|
207
|
+
throw invalidArgument(`${field} contains a non-finite number`);
|
|
208
|
+
}
|
|
209
|
+
return Object.is(value, -0) ? 0 : value;
|
|
210
|
+
}
|
|
211
|
+
if (typeof value !== "object") {
|
|
212
|
+
throw invalidArgument(`${field} contains a non-JSON value`);
|
|
213
|
+
}
|
|
214
|
+
if (state.seen.has(value)) {
|
|
215
|
+
throw invalidArgument(`${field} contains a cycle`);
|
|
216
|
+
}
|
|
217
|
+
state.seen.add(value);
|
|
218
|
+
try {
|
|
219
|
+
if (Array.isArray(value)) {
|
|
220
|
+
return value.map((entry, index) =>
|
|
221
|
+
normalizeJsonValue(entry, `${field}[${index}]`, state, depth + 1),
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
assertPlainObject(value, field);
|
|
225
|
+
// A JSON object may legitimately contain an own `__proto__` key. A normal
|
|
226
|
+
// object assignment would interpret that key as a prototype mutation and
|
|
227
|
+
// silently drop it from the canonical bytes.
|
|
228
|
+
const normalized = Object.create(null);
|
|
229
|
+
for (const key of Object.keys(value).sort()) {
|
|
230
|
+
normalized[key] = normalizeJsonValue(
|
|
231
|
+
value[key],
|
|
232
|
+
`${field}.${key}`,
|
|
233
|
+
state,
|
|
234
|
+
depth + 1,
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
return normalized;
|
|
238
|
+
} finally {
|
|
239
|
+
state.seen.delete(value);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export function normalizeJson(value, field = "value") {
|
|
244
|
+
const normalized = normalizeJsonValue(value, field, { seen: new Set() }, 0);
|
|
245
|
+
const encoded = JSON.stringify(normalized);
|
|
246
|
+
if (Buffer.byteLength(encoded, "utf8") > MAX_JSON_BYTES) {
|
|
247
|
+
throw invalidArgument(`${field} exceeds ${MAX_JSON_BYTES} encoded bytes`);
|
|
248
|
+
}
|
|
249
|
+
return normalized;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export function canonicalJson(value, field = "value") {
|
|
253
|
+
return JSON.stringify(normalizeJson(value, field));
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
export function normalizeEpochMs(value, field) {
|
|
257
|
+
if (!Number.isSafeInteger(value) || value < 0) {
|
|
258
|
+
throw invalidArgument(
|
|
259
|
+
`${field} must be a non-negative safe-integer epoch ms`,
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
return value;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export function normalizeMaxAttempts(value = DEFAULT_MAX_ATTEMPTS) {
|
|
266
|
+
if (!Number.isSafeInteger(value) || value < 1 || value > MAX_JOB_ATTEMPTS) {
|
|
267
|
+
throw invalidArgument(
|
|
268
|
+
`maxAttempts must be an integer between 1 and ${MAX_JOB_ATTEMPTS}`,
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
return value;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
export function normalizeHistoryLimit(value = DEFAULT_HISTORY_LIMIT) {
|
|
275
|
+
if (!Number.isSafeInteger(value) || value < 1) {
|
|
276
|
+
throw invalidArgument("history limit must be a positive integer");
|
|
277
|
+
}
|
|
278
|
+
return Math.min(value, MAX_HISTORY_LIMIT);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Stable identity for one logical firing. All adapters must supply the same
|
|
283
|
+
* triggerKey for the same logical schedule. Including jobRevision prevents an
|
|
284
|
+
* edited job from silently inheriting the old definition's idempotency slot.
|
|
285
|
+
*/
|
|
286
|
+
export function deriveOccurrenceIdentity({
|
|
287
|
+
jobId,
|
|
288
|
+
jobRevision,
|
|
289
|
+
scheduledFor,
|
|
290
|
+
triggerKey,
|
|
291
|
+
}) {
|
|
292
|
+
const material = canonicalJson(
|
|
293
|
+
{
|
|
294
|
+
contractVersion: SCHEDULER_SCHEMA_VERSION,
|
|
295
|
+
jobId: normalizeIdentifier(jobId, "jobId"),
|
|
296
|
+
jobRevision:
|
|
297
|
+
Number.isSafeInteger(jobRevision) && jobRevision >= 1
|
|
298
|
+
? jobRevision
|
|
299
|
+
: (() => {
|
|
300
|
+
throw invalidArgument("jobRevision must be a positive integer");
|
|
301
|
+
})(),
|
|
302
|
+
scheduledFor: normalizeEpochMs(scheduledFor, "scheduledFor"),
|
|
303
|
+
triggerKey: normalizeIdentifier(triggerKey, "triggerKey"),
|
|
304
|
+
},
|
|
305
|
+
"occurrenceIdentity",
|
|
306
|
+
);
|
|
307
|
+
const digest = createHash("sha256")
|
|
308
|
+
.update("chainlesschain.scheduler.occurrence.v1\0", "utf8")
|
|
309
|
+
.update(material, "utf8")
|
|
310
|
+
.digest("hex");
|
|
311
|
+
return Object.freeze({
|
|
312
|
+
occurrenceId: `occ_${digest}`,
|
|
313
|
+
idempotencyKey: `scheduler:v1:${digest}`,
|
|
314
|
+
});
|
|
315
|
+
}
|