chainlesschain 0.166.17 → 0.166.18
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 +14 -7
- package/package.json +1 -1
- package/src/assets/web-panel/assets/{AIOps-CVW2n2rh.js → AIOps-CQSBl3hY.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-DtuM163O.js → ActionButton-IQt-vRLt.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-BXvl_qHu.js → Analytics-DkHC8O7k.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-VDBTFKOp.js → AppLayout-CSti2P2T.js} +3 -3
- package/src/assets/web-panel/assets/{Artifacts-BNz2xCiG.js → Artifacts-C57hxn3v.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-DTu9Hn9P.js → Audit-DByLntcf.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-D2OCPzLe.js → BackgroundAgents-D1Bd2EOa.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-C9M-vG7G.js → Backup-VstHzHng.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-BUkCNiUQ.js → BaseInput-CLhdexIf.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-OJ2ajF7l.js → Chat-BefC_JZS.js} +6 -6
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-BdZt76Ab.js → ChatBubbleRenderer-DbXMvgmn.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-C1gXKDsc.js → Checkbox-CEY982vx.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-BXbznLg7.js → Codegen-Dcm_DTvJ.js} +1 -1
- package/src/assets/web-panel/assets/{Col-CbCq5N0i.js → Col-C8SSu4KA.js} +1 -1
- package/src/assets/web-panel/assets/{Community-V8Ks6Yun.js → Community-BVV9vwRR.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-DkeHQTpQ.js → Compact-B7c5Vo18.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-JeLKwn4Q.js → Compliance-Tq9jSZ5a.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-azfetcBz.js → Cowork-BJUjT09Q.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-Q691i_Gp.js → Cron-CjV9PEaS.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-BLjDRbr_.js → Crosschain-Dl7ReL8F.js} +1 -1
- package/src/assets/web-panel/assets/{DID-D8ptXplK.js → DID-CG8PjWmM.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-Ctj2VVZL.js → Dashboard-CDBM6wmF.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-D8VgkMJ8.js → Dropdown-8_55bXTD.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-CQPe5S6q.js → EmailListRenderer-D3qOU1Cm.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-ySA-7SiN.js → FamilyGuardDashboard-Bv5oWMZF.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-1PMD-fBf.js → Federation-hpZ1xkKd.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-C_jr6U4Q.js → FormItemContext-BN7GT191.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-Bu3bKf2B.js → GenericCardRenderer-PCRhfA7M.js} +1 -1
- package/src/assets/web-panel/assets/{Git-Dv4Fa_T5.js → Git-CIlP2vy7.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-DOEy1n1k.js → Governance-81lgm7YL.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-DkvqzWcJ.js → Inference-Cs24xMOV.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DdUJK949.js → KnowledgeGraph-CrJLVCZo.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-CRelcdUZ.js → Logs-DLyO8RKT.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-0AHbbTA4.js → MarkdownRenderer-DBOqijrP.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-BuuBKsev.js → Marketplace-Dz7AbQZc.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DlgpEmA1.js → McpTools-BM0aFiWv.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-DTfdqUGy.js → Memory-C9SJzENX.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-CXLE5ZFO.js → MobileBridge-BO2HnNRk.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-Dz25OB0n.js → MobileProjects-CK_jMz0l.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-kEL0fhgD.js → Mtc-CfhrJsdO.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-BE4UvFJU.js → MtcAudit-BE2ELxgI.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-CSApSn8c.js → Multisig-CgR_E3Jd.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-D11FpKWx.js → NLProgramming-Cw9445_K.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-CDL-D2CS.js → Notes-DZimkTrb.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-C0Q6lO-c.js → NotificationSettings-DxHVh4uT.js} +1 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-Iy-pnX56.js +1 -0
- package/src/assets/web-panel/assets/{Organization-Dc-maVAq.js → Organization-pPXJtWo4.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-B5mUpSvi.js → Overflow-YamdTJwA.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-TjXV53wq.js → P2P-BvqP53x7.js} +2 -2
- package/src/assets/web-panel/assets/PdhVaultBrowser-Blz1Xn2n.js +7 -0
- package/src/assets/web-panel/assets/{Permissions-DKRzQ2O6.js → Permissions-CgFRQqFJ.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-Dx2eqft8.js → PersonalDataHub-CFeo3-6O.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-CnYZMB5p.js → Pipeline-BkaRojEK.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-BonKpPnp.js → Privacy-BNZEx2Qp.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-DWO0Du3J.js → ProjectInit-HUBOgEEK.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-C9jqyYRv.js → ProjectSettings-CFMmhROS.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-CYpKwXbz.js → Projects-Dc517BXp.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-CW-fkwJq.js → Providers-DTLf8bgj.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-Cw0J3Zud.js → QrScannerModal-BBNjPszk.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-BH4A4IpR.js → QuickAsk-DCsHvk3G.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-CDwMwJus.js → Recommend-Dpr5YSop.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-DKIPwzTf.js → RemoteSession-DmKnvqGg.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-CklDj7qS.js → Reputation-CSRfuurX.js} +1 -1
- package/src/assets/web-panel/assets/{Row-DJWZKsH0.js → Row-CDj3pQ_w.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-BfSLCewo.js → RssFeed-DI0a_kNq.js} +2 -2
- package/src/assets/web-panel/assets/{Search-B0IST--x.js → Search-jAy7B2nU.js} +1 -1
- package/src/assets/web-panel/assets/{Security-h1sYNWtt.js → Security-CkHTqYhc.js} +4 -4
- package/src/assets/web-panel/assets/{Services-Gh0-oxI_.js → Services-CP-0Nzga.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-CNDV_jOs.js → Skeleton-BkF5-p3n.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-ByCLTh1n.js → Skills-BDu-utDE.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-BfyrJTJz.js → Sla-CQvq_2Qb.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-BQzo9kNX.js → SpeechSettings-T7Ap512g.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-B6fS6z_1.js → SyncSettings-Bt-PLvot.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-C-uKCP-l.js → Tasks-yLEcCogg.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-D6oDy7wL.js → Templates-ByN3fmbr.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-D3LT2wNQ.js → Tenant-DBI7hITH.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-BteLcv_O.js → Terminal-B77_DlGX.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-DHHuxfqH.js → TimelineRenderer-CsLTB_QO.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-BRQeykXw.js → Tokens-BV2N6cR8.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-p2XaFWEu.js → Trigger-CjXWGH3p.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-BxadBMft.js → Trust-uqXIq3WC.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-DRBP7LDk.js → UkeySign-D-6qu4vY.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-CZ3NZkh7.js → VideoEditing-CxGmx_2e.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-C3NTBN7G.js → Wallet-DSq7WlAg.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-C7LVgMlb.js → WebAuthn-CDBiD57O.js} +2 -2
- package/src/assets/web-panel/assets/{WorkflowEditor-0_Iveog7.js → WorkflowEditor-Z8f63TSb.js} +1 -1
- package/src/assets/web-panel/assets/{chat-DzzluYo3.js → chat-B-UZFBjy.js} +1 -1
- package/src/assets/web-panel/assets/{colors-DSMYXpaj.js → colors-CFk7K-7Q.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-W76u1VSV.js → compact-item-X0IVMvgi.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-otsESjb5.js → createContext-DWg4j2n6.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-B2IW1J_J.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-3sNLrvug.js → hasIn-CkVCwNNF.js} +1 -1
- package/src/assets/web-panel/assets/{index-BdtmEKat.js → index-5OcZHdzc.js} +1 -1
- package/src/assets/web-panel/assets/{index-DS9WYDMf.js → index-B273IY-E.js} +1 -1
- package/src/assets/web-panel/assets/{index-NaO9AE-F.js → index-B3-B3FWD.js} +1 -1
- package/src/assets/web-panel/assets/{index-BcGJtmHM.js → index-BB4KHHcv.js} +1 -1
- package/src/assets/web-panel/assets/index-BCp2ir-1.js +1 -0
- package/src/assets/web-panel/assets/{index-pVm_iUre.js → index-BG-GaZri.js} +1 -1
- package/src/assets/web-panel/assets/{index-BpcQYzP7.js → index-BPBia4b-.js} +1 -1
- package/src/assets/web-panel/assets/{index-BXLx9HfA.js → index-BipwEbTA.js} +1 -1
- package/src/assets/web-panel/assets/{index-uSCkbpZH.js → index-BoskgPt9.js} +1 -1
- package/src/assets/web-panel/assets/{index-DMmdIpLA.js → index-Btqk6zWb.js} +1 -1
- package/src/assets/web-panel/assets/index-Bw4iuzRD.js +1 -0
- package/src/assets/web-panel/assets/{index-DLDh1OW3.js → index-BzXjYUmd.js} +1 -1
- package/src/assets/web-panel/assets/{index-B9X_jqXe.js → index-C1ZAOJRW.js} +1 -1
- package/src/assets/web-panel/assets/{index-vBKPcmAP.js → index-CCLwoATF.js} +1 -1
- package/src/assets/web-panel/assets/{index-vUmYkqmu.js → index-CDfSD07S.js} +1 -1
- package/src/assets/web-panel/assets/{index-D7A5U2IH.js → index-CLlP1E4X.js} +1 -1
- package/src/assets/web-panel/assets/{index-ClOFeZ-t.js → index-CMCEXBRh.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cg86EzNp.js → index-CN8HZlLH.js} +1 -1
- package/src/assets/web-panel/assets/{index-Ddd4mird.js → index-CNKFsBlz.js} +1 -1
- package/src/assets/web-panel/assets/{index-CE7tSow-.js → index-CUBkvFPH.js} +1 -1
- package/src/assets/web-panel/assets/{index-GlIOE4ja.js → index-Ca0mij1n.js} +1 -1
- package/src/assets/web-panel/assets/{index-DdU7IkKX.js → index-CbIAWbma.js} +1 -1
- package/src/assets/web-panel/assets/{index-UUHCwfNq.js → index-CbihMThv.js} +1 -1
- package/src/assets/web-panel/assets/{index-BRsD1PT2.js → index-CvOa-IFV.js} +1 -1
- package/src/assets/web-panel/assets/{index-C2aht9-M.js → index-Cvwu_rA_.js} +1 -1
- package/src/assets/web-panel/assets/{index-BJsQio5O.js → index-D-EJNxgR.js} +1 -1
- package/src/assets/web-panel/assets/{index-q7ftLqNt.js → index-D8uEL8Uw.js} +1 -1
- package/src/assets/web-panel/assets/{index-B1I1AYJs.js → index-D92g4l3n.js} +1 -1
- package/src/assets/web-panel/assets/{index-DZKAzEge.js → index-DCqpl_E_.js} +1 -1
- package/src/assets/web-panel/assets/{index-CKoFyHYQ.js → index-DLSBks8h.js} +1 -1
- package/src/assets/web-panel/assets/{index-BDlDO2px.js → index-Db_5xhrU.js} +1 -1
- package/src/assets/web-panel/assets/{index-CENWwjef.js → index-DcDggpWR.js} +1 -1
- package/src/assets/web-panel/assets/{index-DH4cl52p.js → index-DeWKPQGs.js} +1 -1
- package/src/assets/web-panel/assets/{index-DTA8Iavv.js → index-DhVHoqGL.js} +3 -3
- package/src/assets/web-panel/assets/{index-DmpaC2yk.js → index-DyWlOuak.js} +1 -1
- package/src/assets/web-panel/assets/{index-BA8mZxd-.js → index-LU54bChK.js} +1 -1
- package/src/assets/web-panel/assets/{index-CtFOt5x1.js → index-OjnAwUJo.js} +1 -1
- package/src/assets/web-panel/assets/{index-B5LOYdYm.js → index-P83LDnCz.js} +1 -1
- package/src/assets/web-panel/assets/{index-MhQQ3h8q.js → index-_-9k3Tna.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-DF6llUXV.js → initDefaultProps-CFNgY8lJ.js} +1 -1
- package/src/assets/web-panel/assets/{motion-vtDV8_5K.js → motion-D-5RrDzn.js} +1 -1
- package/src/assets/web-panel/assets/{move-B6c0bdy2.js → move-DN-L0Bd-.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-DlLYWuBK.js → mtc-parser-6mgLSeCK.js} +1 -1
- package/src/assets/web-panel/assets/{omit-BH0zOxLN.js → omit-ClWW8eTP.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-D9di8_In.js → pickAttrs-Vystq3R8.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-BDSngufM.js → placementArrow-D0H9hK4W.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-C_EawMvP.js → responsiveObserve-B3iNRU-a.js} +1 -1
- package/src/assets/web-panel/assets/{slide-B_4wShxA.js → slide-CiMXe6am.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-CbQu6qJ-.js → statusUtils-CGDZJ1uT.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-CvXJWYXb.js → styleChecker-D2zA6NkY.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-jjY1XknO.js → useFlexGapSupport-C1sYU6QE.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-CMXBdsK_.js → useFs-BzUHSjg2.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-YbAhhPXx.js → usePersonalDataHub-CxB5yZCq.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-BFCTKc0H.js → vnode-BfUfMwtc.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-CY9aBl5O.js → zoom-CFYmj1TO.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +1 -1
- package/src/commands/agent.js +80 -2
- package/src/commands/evolution.js +33 -27
- package/src/commands/serve.js +11 -2
- package/src/data/changelog.json +5 -5
- package/src/gateways/ws/session-protocol.js +1 -0
- package/src/gateways/ws/ws-agent-handler.js +70 -2
- package/src/gateways/ws/ws-server.js +8 -0
- package/src/lib/app-server/cli-agent-kernel-adapter.js +4 -0
- package/src/lib/app-server/graph-runtime.js +115 -8
- package/src/lib/app-server/server.js +21 -2
- package/src/lib/app-server/websocket-transport.js +2 -0
- package/src/lib/evolution/agent-evolution-ingress.js +300 -0
- package/src/lib/evolution/agent-evolution-runtime-composition-brand.js +22 -0
- package/src/lib/evolution/agent-evolution-runtime-composition.js +369 -0
- package/src/lib/evolution/evidence-backed-wiki-maintainer.js +752 -0
- package/src/lib/evolution/evolution-artifact-ports.js +48 -0
- package/src/lib/evolution/evolution-eval-gate.js +11 -4
- package/src/lib/evolution/evolution-evidence-artifact-adapter.js +499 -0
- package/src/lib/evolution/evolution-evidence-projector.js +61 -1
- package/src/lib/evolution/evolution-file-witness.js +601 -0
- package/src/lib/evolution/evolution-ledger-file-backend.js +176 -0
- package/src/lib/evolution/evolution-ledger-ports.js +353 -16
- package/src/lib/evolution/evolution-ledger.js +1355 -54
- package/src/lib/evolution/evolution-run-ledger-adapter.js +409 -0
- package/src/lib/evolution/evolution-run-wiki-maintenance-source.js +300 -0
- package/src/lib/evolution/scheduled-batch-wiki-maintenance-source.js +368 -0
- package/src/lib/evolution/skill-candidate-registry.js +649 -0
- package/src/lib/evolution/skill-promotion-controller.js +109 -38
- package/src/lib/evolution/skill-promotion-review-ledger-adapter.js +451 -0
- package/src/lib/evolution/skill-promotion-review.js +793 -0
- package/src/lib/evolution/skill-registry-transition-capability.js +55 -0
- package/src/lib/evolution/skill-registry-transition-ledger-adapter.js +1280 -0
- package/src/lib/evolution/skill-registry-transition-source.js +372 -0
- package/src/lib/evolution/skill-release-registry.js +2191 -11
- package/src/lib/evolution/skill-target-matrix-eval.js +133 -10
- package/src/lib/evolution/structured-memory-agent-control-plane.js +222 -0
- package/src/lib/evolution/structured-memory-authority-ledger-adapter.js +351 -0
- package/src/lib/evolution/structured-memory-ledger-adapter.js +220 -0
- package/src/lib/evolution/structured-memory-policy-receipt-writer.js +164 -0
- package/src/lib/evolution/structured-memory-post-compact-hook.js +87 -0
- package/src/lib/evolution/structured-memory-promotion-receipt-writer.js +221 -0
- package/src/lib/evolution/structured-memory-semantic-review-pipeline.js +313 -0
- package/src/lib/evolution/wiki-maintainer-ledger-adapter.js +200 -0
- package/src/lib/evolution/wiki-maintenance-trigger-ledger-adapter.js +687 -0
- package/src/lib/evolution-system.js +65 -30
- package/src/lib/mcp-lifecycle-authority.js +21 -2
- package/src/lib/remote-approval-bridge.js +24 -0
- package/src/lib/scheduler-kernel/store.js +62 -14
- package/src/repl/agent-repl.js +45 -0
- package/src/runtime/agent-runtime.js +114 -1
- package/src/runtime/headless-runner.js +19 -0
- package/src/runtime/headless-stream.js +43 -0
- package/src/runtime/runtime-factory.js +19 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-ZRE0OKbj.js +0 -1
- package/src/assets/web-panel/assets/PdhVaultBrowser-DvV2btIr.js +0 -7
- package/src/assets/web-panel/assets/devWarning-BztaXF84.js +0 -1
- package/src/assets/web-panel/assets/index-4jP_hG_4.js +0 -1
- package/src/assets/web-panel/assets/index-zxwuAXL5.js +0 -1
- package/src/lib/learning/learning-hooks.js +0 -123
|
@@ -62,8 +62,21 @@ export const EVOLUTION_ARTIFACT_RETENTIONS = Object.freeze(["ttl", "ledger"]);
|
|
|
62
62
|
export const EVOLUTION_ARTIFACT_LEDGER_RETENTION_TYPES = Object.freeze([
|
|
63
63
|
"skill-release-transition-intent",
|
|
64
64
|
"skill-release-finalization",
|
|
65
|
+
"skill-release-state-migration",
|
|
65
66
|
"skill-mutation-audit",
|
|
66
67
|
"skill-mutation-nonce-claim",
|
|
68
|
+
"skill-promotion-review-decision",
|
|
69
|
+
"skill-promotion-review-packet",
|
|
70
|
+
"skill-registry-transition-attempt",
|
|
71
|
+
"skill-registry-transition-request",
|
|
72
|
+
"skill-registry-transition-settlement",
|
|
73
|
+
"evolution-run-event",
|
|
74
|
+
"structured-memory-authority-receipt",
|
|
75
|
+
"structured-memory-event",
|
|
76
|
+
"structured-memory-snapshot",
|
|
77
|
+
"wiki-maintenance-request",
|
|
78
|
+
"wiki-maintenance-settlement",
|
|
79
|
+
"wiki-revision",
|
|
67
80
|
]);
|
|
68
81
|
export const EVOLUTION_ARTIFACT_LEDGER_RETENTION_PURPOSES = Object.freeze([
|
|
69
82
|
"evolution-ledger",
|
|
@@ -86,6 +99,7 @@ export const EVOLUTION_ARTIFACT_TYPES = Object.freeze([
|
|
|
86
99
|
"eval-suite",
|
|
87
100
|
"evaluation",
|
|
88
101
|
"evaluation-result",
|
|
102
|
+
"evolution-run-event",
|
|
89
103
|
"evidence",
|
|
90
104
|
"model-projection",
|
|
91
105
|
"policy",
|
|
@@ -98,7 +112,19 @@ export const EVOLUTION_ARTIFACT_TYPES = Object.freeze([
|
|
|
98
112
|
"skill-candidate",
|
|
99
113
|
"skill-mutation-audit",
|
|
100
114
|
"skill-mutation-nonce-claim",
|
|
115
|
+
"skill-promotion-review-decision",
|
|
116
|
+
"skill-promotion-review-packet",
|
|
117
|
+
"skill-registry-transition-attempt",
|
|
118
|
+
"skill-registry-transition-request",
|
|
119
|
+
"skill-registry-transition-settlement",
|
|
101
120
|
"skill-release-finalization",
|
|
121
|
+
"skill-release-state-migration",
|
|
122
|
+
"structured-memory-authority-receipt",
|
|
123
|
+
"structured-memory-event",
|
|
124
|
+
"structured-memory-snapshot",
|
|
125
|
+
"wiki-maintenance-request",
|
|
126
|
+
"wiki-maintenance-settlement",
|
|
127
|
+
"wiki-revision",
|
|
102
128
|
"skill-release-transition-intent",
|
|
103
129
|
"source",
|
|
104
130
|
"source-evidence",
|
|
@@ -253,6 +279,7 @@ const CONSTRUCTOR_REQUIRED_KEYS = new Set([
|
|
|
253
279
|
"tenantId",
|
|
254
280
|
]);
|
|
255
281
|
const LEDGER_RESOLVER_OPTION_KEYS = new Set(["purpose"]);
|
|
282
|
+
const EVOLUTION_LEDGER_ARTIFACT_RESOLVERS = new WeakSet();
|
|
256
283
|
const isProxy = Object.freeze(utilTypes.isProxy.bind(utilTypes));
|
|
257
284
|
const isDate = Object.freeze(utilTypes.isDate.bind(utilTypes));
|
|
258
285
|
const dateGetTime = Object.freeze(
|
|
@@ -268,11 +295,24 @@ const LEDGER_RETENTION_PURPOSES_BY_TYPE = new Map([
|
|
|
268
295
|
"skill-release-finalization",
|
|
269
296
|
new Set(["evolution-ledger", "skill-release-transition"]),
|
|
270
297
|
],
|
|
298
|
+
["skill-release-state-migration", new Set(["evolution-ledger"])],
|
|
271
299
|
["skill-mutation-audit", new Set(["evolution-ledger", "skill-mutation"])],
|
|
272
300
|
[
|
|
273
301
|
"skill-mutation-nonce-claim",
|
|
274
302
|
new Set(["evolution-ledger", "skill-mutation"]),
|
|
275
303
|
],
|
|
304
|
+
["skill-promotion-review-decision", new Set(["evolution-ledger"])],
|
|
305
|
+
["skill-promotion-review-packet", new Set(["evolution-ledger"])],
|
|
306
|
+
["skill-registry-transition-attempt", new Set(["evolution-ledger"])],
|
|
307
|
+
["skill-registry-transition-request", new Set(["evolution-ledger"])],
|
|
308
|
+
["skill-registry-transition-settlement", new Set(["evolution-ledger"])],
|
|
309
|
+
["evolution-run-event", new Set(["evolution-ledger"])],
|
|
310
|
+
["wiki-revision", new Set(["evolution-ledger"])],
|
|
311
|
+
["structured-memory-authority-receipt", new Set(["evolution-ledger"])],
|
|
312
|
+
["structured-memory-event", new Set(["evolution-ledger"])],
|
|
313
|
+
["structured-memory-snapshot", new Set(["evolution-ledger"])],
|
|
314
|
+
["wiki-maintenance-request", new Set(["evolution-ledger"])],
|
|
315
|
+
["wiki-maintenance-settlement", new Set(["evolution-ledger"])],
|
|
276
316
|
]);
|
|
277
317
|
|
|
278
318
|
export class EvolutionArtifactPortError extends Error {
|
|
@@ -3254,6 +3294,7 @@ export class EvolutionArtifactPorts {
|
|
|
3254
3294
|
);
|
|
3255
3295
|
const resolveReadOnly = (request) =>
|
|
3256
3296
|
this.#resolveLedgerRequest(request, normalizedPurpose);
|
|
3297
|
+
EVOLUTION_LEDGER_ARTIFACT_RESOLVERS.add(resolveReadOnly);
|
|
3257
3298
|
return Object.freeze(resolveReadOnly);
|
|
3258
3299
|
}
|
|
3259
3300
|
}
|
|
@@ -3274,4 +3315,11 @@ export function createEvolutionLedgerArtifactResolver(ports, options) {
|
|
|
3274
3315
|
return ports.createEvolutionLedgerArtifactResolver(options);
|
|
3275
3316
|
}
|
|
3276
3317
|
|
|
3318
|
+
export function isEvolutionLedgerArtifactResolver(value) {
|
|
3319
|
+
return (
|
|
3320
|
+
typeof value === "function" &&
|
|
3321
|
+
EVOLUTION_LEDGER_ARTIFACT_RESOLVERS.has(value)
|
|
3322
|
+
);
|
|
3323
|
+
}
|
|
3324
|
+
|
|
3277
3325
|
Object.freeze(EvolutionArtifactPorts.prototype);
|
|
@@ -17,7 +17,7 @@ export const EVOLUTION_EVAL_SUITE_SCHEMA =
|
|
|
17
17
|
export const EVOLUTION_EVAL_POLICY_SCHEMA =
|
|
18
18
|
"chainlesschain.evolution-eval-policy/v2";
|
|
19
19
|
export const EVOLUTION_EVAL_RECEIPT_SCHEMA =
|
|
20
|
-
"chainlesschain.evolution-eval-receipt/
|
|
20
|
+
"chainlesschain.evolution-eval-receipt/v4";
|
|
21
21
|
export const EVOLUTION_EVAL_SUITE_AUTHORITY_SCHEMA =
|
|
22
22
|
"chainlesschain.evolution-eval-suite-authority-receipt/v1";
|
|
23
23
|
export const EVOLUTION_EVAL_ENVIRONMENT_SCHEMA =
|
|
@@ -695,6 +695,7 @@ const RECEIPT_KEYS = new Set([
|
|
|
695
695
|
"provenanceAudience",
|
|
696
696
|
"trainerAuthority",
|
|
697
697
|
"trainerRevision",
|
|
698
|
+
"confidenceZ",
|
|
698
699
|
"decision",
|
|
699
700
|
"reasonCodes",
|
|
700
701
|
"splitCounts",
|
|
@@ -3483,6 +3484,7 @@ function receiptEvidenceCore(core) {
|
|
|
3483
3484
|
provenanceAudience: core.provenanceAudience,
|
|
3484
3485
|
trainerAuthority: core.trainerAuthority,
|
|
3485
3486
|
trainerRevision: core.trainerRevision,
|
|
3487
|
+
confidenceZ: core.confidenceZ,
|
|
3486
3488
|
validationResultDigest: core.validation
|
|
3487
3489
|
? digest(core.validation, "chainlesschain.evolution-eval-comparison/v2")
|
|
3488
3490
|
: null,
|
|
@@ -3497,7 +3499,7 @@ export function computeEvolutionEvalReceiptDigest(receiptCore) {
|
|
|
3497
3499
|
const core = cloneCanonical(receiptCore);
|
|
3498
3500
|
delete core.receiptDigest;
|
|
3499
3501
|
delete core.attestation;
|
|
3500
|
-
return digest(core, "chainlesschain.evolution-eval-receipt/
|
|
3502
|
+
return digest(core, "chainlesschain.evolution-eval-receipt/v4");
|
|
3501
3503
|
}
|
|
3502
3504
|
|
|
3503
3505
|
async function signFinalReceipt({
|
|
@@ -5178,6 +5180,7 @@ export class EvolutionEvalGate {
|
|
|
5178
5180
|
provenanceAudience: run.provenanceAudience,
|
|
5179
5181
|
trainerAuthority: run.trainerAuthority,
|
|
5180
5182
|
trainerRevision: run.trainerRevision,
|
|
5183
|
+
confidenceZ: this.#policy.confidenceZ,
|
|
5181
5184
|
decision: outcome.decision,
|
|
5182
5185
|
reasonCodes: outcome.reasonCodes,
|
|
5183
5186
|
splitCounts: run.splitCounts,
|
|
@@ -5192,7 +5195,7 @@ export class EvolutionEvalGate {
|
|
|
5192
5195
|
};
|
|
5193
5196
|
core.evidenceRoot = digest(
|
|
5194
5197
|
receiptEvidenceCore(core),
|
|
5195
|
-
"chainlesschain.evolution-eval-evidence-root/
|
|
5198
|
+
"chainlesschain.evolution-eval-evidence-root/v4",
|
|
5196
5199
|
);
|
|
5197
5200
|
for (const split of ["validation", "test"]) {
|
|
5198
5201
|
if (core[split] === null) continue;
|
|
@@ -5958,6 +5961,10 @@ function verifyReceiptStructure(value) {
|
|
|
5958
5961
|
normalizeId(value.provenanceAudience, "receipt.provenanceAudience", 256);
|
|
5959
5962
|
normalizeId(value.trainerAuthority, "receipt.trainerAuthority", 256);
|
|
5960
5963
|
normalizeId(value.trainerRevision, "receipt.trainerRevision", 256);
|
|
5964
|
+
normalizeFinite(value.confidenceZ, "receipt.confidenceZ", {
|
|
5965
|
+
minimum: 1.64,
|
|
5966
|
+
maximum: 4,
|
|
5967
|
+
});
|
|
5961
5968
|
if (
|
|
5962
5969
|
!["accepted", "rejected", "needs-more-evidence"].includes(value.decision)
|
|
5963
5970
|
) {
|
|
@@ -6022,7 +6029,7 @@ function verifyReceiptStructure(value) {
|
|
|
6022
6029
|
}
|
|
6023
6030
|
const expectedEvidenceRoot = digest(
|
|
6024
6031
|
receiptEvidenceCore(value),
|
|
6025
|
-
"chainlesschain.evolution-eval-evidence-root/
|
|
6032
|
+
"chainlesschain.evolution-eval-evidence-root/v4",
|
|
6026
6033
|
);
|
|
6027
6034
|
if (value.evidenceRoot !== expectedEvidenceRoot) {
|
|
6028
6035
|
throw evalError(
|
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable composition for the evidence projection boundary.
|
|
3
|
+
*
|
|
4
|
+
* Raw plaintext is handed only to a captured encryption authority. ArtifactStore
|
|
5
|
+
* receives opaque ciphertext, while model/trusted projections and their complete
|
|
6
|
+
* derivation lineage are persisted through authenticated EvolutionArtifactPorts.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import crypto from "node:crypto";
|
|
10
|
+
import { types as utilTypes } from "node:util";
|
|
11
|
+
|
|
12
|
+
import { ArtifactStore } from "../artifact-store.js";
|
|
13
|
+
import {
|
|
14
|
+
EvolutionArtifactPorts,
|
|
15
|
+
EVOLUTION_ARTIFACT_DEFAULT_TTL_MS,
|
|
16
|
+
EVOLUTION_ARTIFACT_MAX_TTL_MS,
|
|
17
|
+
} from "./evolution-artifact-ports.js";
|
|
18
|
+
import {
|
|
19
|
+
EVOLUTION_RAW_STORAGE_RECEIPT_SCHEMA,
|
|
20
|
+
EvolutionEvidenceBundleVerifier,
|
|
21
|
+
EvolutionEvidenceProjector,
|
|
22
|
+
} from "./evolution-evidence-projector.js";
|
|
23
|
+
|
|
24
|
+
export const EVOLUTION_ENCRYPTED_RAW_LINEAGE_SCHEMA =
|
|
25
|
+
"chainlesschain.evolution-encrypted-raw-lineage/v1";
|
|
26
|
+
export const EVOLUTION_EVIDENCE_DERIVATION_MANIFEST_SCHEMA =
|
|
27
|
+
"chainlesschain.evolution-evidence-derivation-manifest/v1";
|
|
28
|
+
export const EVOLUTION_EVIDENCE_ARTIFACT_RESULT_SCHEMA =
|
|
29
|
+
"chainlesschain.evolution-evidence-artifact-result/v1";
|
|
30
|
+
|
|
31
|
+
const SAFE_ID_PATTERN = /^[a-z][a-z0-9]*(?:[._:-][a-z0-9]+)*$/u;
|
|
32
|
+
const RAW_RESULT_KEYS = new Set(["algorithm", "keyRef", "sealedBytes"]);
|
|
33
|
+
const RAW_REQUEST_KEYS = new Set([
|
|
34
|
+
"tenantId",
|
|
35
|
+
"principalId",
|
|
36
|
+
"evidenceId",
|
|
37
|
+
"sourceCommitment",
|
|
38
|
+
"commitmentReceiptDigest",
|
|
39
|
+
"sourceVerificationReceiptDigest",
|
|
40
|
+
"storagePolicyReceiptDigest",
|
|
41
|
+
"storagePolicyDigest",
|
|
42
|
+
"storagePolicyRevision",
|
|
43
|
+
"storagePolicyDecisionExpiresAt",
|
|
44
|
+
"requestNonce",
|
|
45
|
+
"requestedAt",
|
|
46
|
+
"sensitivity",
|
|
47
|
+
"retention",
|
|
48
|
+
"acl",
|
|
49
|
+
"aad",
|
|
50
|
+
"payload",
|
|
51
|
+
]);
|
|
52
|
+
const COMPONENT_DESCRIPTOR_KEYS = new Set([
|
|
53
|
+
"digest",
|
|
54
|
+
"envelope",
|
|
55
|
+
"ref",
|
|
56
|
+
"type",
|
|
57
|
+
]);
|
|
58
|
+
const COMPONENT_TYPES = Object.freeze({
|
|
59
|
+
rawRecord: "source-evidence",
|
|
60
|
+
modelProjection: "model-projection",
|
|
61
|
+
trustedProjection: "trusted-projection",
|
|
62
|
+
receipt: "receipt",
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
function canonicalJson(value, seen = new Set()) {
|
|
66
|
+
if (value === null || typeof value === "boolean")
|
|
67
|
+
return JSON.stringify(value);
|
|
68
|
+
if (typeof value === "number") {
|
|
69
|
+
if (!Number.isFinite(value))
|
|
70
|
+
throw new TypeError("canonical value contains a non-finite number");
|
|
71
|
+
return JSON.stringify(value);
|
|
72
|
+
}
|
|
73
|
+
if (typeof value === "string") return JSON.stringify(value);
|
|
74
|
+
if (!value || typeof value !== "object" || seen.has(value)) {
|
|
75
|
+
throw new TypeError("canonical value must be an acyclic JSON value");
|
|
76
|
+
}
|
|
77
|
+
seen.add(value);
|
|
78
|
+
let output;
|
|
79
|
+
if (Array.isArray(value)) {
|
|
80
|
+
output = `[${value.map((entry) => canonicalJson(entry, seen)).join(",")}]`;
|
|
81
|
+
} else {
|
|
82
|
+
const prototype = Object.getPrototypeOf(value);
|
|
83
|
+
if (prototype !== Object.prototype && prototype !== null) {
|
|
84
|
+
throw new TypeError("canonical value must use plain objects");
|
|
85
|
+
}
|
|
86
|
+
output = `{${Object.keys(value)
|
|
87
|
+
.sort()
|
|
88
|
+
.map((key) => `${JSON.stringify(key)}:${canonicalJson(value[key], seen)}`)
|
|
89
|
+
.join(",")}}`;
|
|
90
|
+
}
|
|
91
|
+
seen.delete(value);
|
|
92
|
+
return output;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function digestBytes(bytes) {
|
|
96
|
+
return `sha256:${crypto.createHash("sha256").update(bytes).digest("hex")}`;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function digestRecord(domain, value) {
|
|
100
|
+
return digestBytes(Buffer.from(`${domain}\0${canonicalJson(value)}`, "utf8"));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function deepFreeze(value, seen = new WeakSet()) {
|
|
104
|
+
if (!value || typeof value !== "object" || seen.has(value)) return value;
|
|
105
|
+
seen.add(value);
|
|
106
|
+
for (const child of Object.values(value)) deepFreeze(child, seen);
|
|
107
|
+
return Object.freeze(value);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function clone(value) {
|
|
111
|
+
return JSON.parse(canonicalJson(value));
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function assertPlainExact(value, keys, label) {
|
|
115
|
+
if (
|
|
116
|
+
!value ||
|
|
117
|
+
typeof value !== "object" ||
|
|
118
|
+
Array.isArray(value) ||
|
|
119
|
+
utilTypes.isProxy(value) ||
|
|
120
|
+
![Object.prototype, null].includes(Object.getPrototypeOf(value))
|
|
121
|
+
) {
|
|
122
|
+
throw new TypeError(`${label} must be a non-proxy plain object`);
|
|
123
|
+
}
|
|
124
|
+
const ownKeys = Reflect.ownKeys(value);
|
|
125
|
+
if (
|
|
126
|
+
ownKeys.length !== keys.size ||
|
|
127
|
+
ownKeys.some((key) => typeof key !== "string" || !keys.has(key))
|
|
128
|
+
) {
|
|
129
|
+
throw new TypeError(`${label} contains unsupported fields`);
|
|
130
|
+
}
|
|
131
|
+
for (const key of ownKeys) {
|
|
132
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
133
|
+
if (!descriptor || !("value" in descriptor) || !descriptor.enumerable) {
|
|
134
|
+
throw new TypeError(
|
|
135
|
+
`${label}.${String(key)} must be an enumerable data property`,
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function assertInstance(value, prototype, label) {
|
|
142
|
+
if (
|
|
143
|
+
!value ||
|
|
144
|
+
utilTypes.isProxy(value) ||
|
|
145
|
+
Object.getPrototypeOf(value) !== prototype
|
|
146
|
+
) {
|
|
147
|
+
throw new TypeError(`${label} must be the repository implementation`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function normalizeId(value, label) {
|
|
152
|
+
if (
|
|
153
|
+
typeof value !== "string" ||
|
|
154
|
+
value.length > 256 ||
|
|
155
|
+
!SAFE_ID_PATTERN.test(value)
|
|
156
|
+
) {
|
|
157
|
+
throw new TypeError(`${label} is invalid`);
|
|
158
|
+
}
|
|
159
|
+
return value;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function captureMethod(owner, method, label) {
|
|
163
|
+
if (
|
|
164
|
+
!owner ||
|
|
165
|
+
utilTypes.isProxy(owner) ||
|
|
166
|
+
typeof owner[method] !== "function"
|
|
167
|
+
) {
|
|
168
|
+
throw new TypeError(`${label} must provide ${method}()`);
|
|
169
|
+
}
|
|
170
|
+
const fn = owner[method];
|
|
171
|
+
return (...args) => Reflect.apply(fn, owner, args);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Ciphertext-only Raw persistence. The encryptor is expected to be backed by a
|
|
176
|
+
* tenant KMS/HSM in production and must never return plaintext or key bytes.
|
|
177
|
+
*/
|
|
178
|
+
export class ArtifactStoreEncryptedRawStore {
|
|
179
|
+
#tenantId;
|
|
180
|
+
#publish;
|
|
181
|
+
#verifyIntegrity;
|
|
182
|
+
#encrypt;
|
|
183
|
+
|
|
184
|
+
constructor({ tenantId, artifactStore, encryptor } = {}) {
|
|
185
|
+
this.#tenantId = normalizeId(tenantId, "Raw store tenantId");
|
|
186
|
+
assertInstance(artifactStore, ArtifactStore.prototype, "artifactStore");
|
|
187
|
+
this.#publish = captureMethod(
|
|
188
|
+
artifactStore,
|
|
189
|
+
"publishDataOnce",
|
|
190
|
+
"artifactStore",
|
|
191
|
+
);
|
|
192
|
+
this.#verifyIntegrity = captureMethod(
|
|
193
|
+
artifactStore,
|
|
194
|
+
"verifyIntegrity",
|
|
195
|
+
"artifactStore",
|
|
196
|
+
);
|
|
197
|
+
this.#encrypt = captureMethod(encryptor, "encrypt", "Raw encryptor");
|
|
198
|
+
Object.freeze(this);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
async putEncrypted(request) {
|
|
202
|
+
assertPlainExact(request, RAW_REQUEST_KEYS, "Raw storage request");
|
|
203
|
+
if (!Object.isFrozen(request)) {
|
|
204
|
+
throw new TypeError("Raw storage request must be immutable");
|
|
205
|
+
}
|
|
206
|
+
if (request.tenantId !== this.#tenantId) {
|
|
207
|
+
throw new TypeError("cross-tenant Raw storage is denied");
|
|
208
|
+
}
|
|
209
|
+
const evidenceId = normalizeId(request.evidenceId, "Raw evidenceId");
|
|
210
|
+
const plaintext = Buffer.from(canonicalJson(request.payload), "utf8");
|
|
211
|
+
const aadBytes = Buffer.from(canonicalJson(request.aad), "utf8");
|
|
212
|
+
const encrypted = await this.#encrypt(
|
|
213
|
+
Object.freeze({
|
|
214
|
+
aad: Buffer.from(aadBytes),
|
|
215
|
+
evidenceId,
|
|
216
|
+
plaintext: Buffer.from(plaintext),
|
|
217
|
+
tenantId: this.#tenantId,
|
|
218
|
+
}),
|
|
219
|
+
);
|
|
220
|
+
assertPlainExact(encrypted, RAW_RESULT_KEYS, "Raw encryption result");
|
|
221
|
+
if (encrypted.algorithm !== "aes-256-gcm") {
|
|
222
|
+
throw new TypeError(
|
|
223
|
+
"Raw encryption authority returned an unsupported algorithm",
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
if (
|
|
227
|
+
typeof encrypted.keyRef !== "string" ||
|
|
228
|
+
!encrypted.keyRef.startsWith(`kms://${this.#tenantId}/`) ||
|
|
229
|
+
encrypted.keyRef.length > 2048
|
|
230
|
+
) {
|
|
231
|
+
throw new TypeError(
|
|
232
|
+
"Raw encryption authority returned an invalid keyRef",
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
if (
|
|
236
|
+
!Buffer.isBuffer(encrypted.sealedBytes) ||
|
|
237
|
+
encrypted.sealedBytes.length < 29
|
|
238
|
+
) {
|
|
239
|
+
throw new TypeError(
|
|
240
|
+
"Raw encryption authority returned invalid ciphertext",
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
const sealedBytes = Buffer.from(encrypted.sealedBytes);
|
|
244
|
+
const cipherDigest = digestBytes(sealedBytes);
|
|
245
|
+
const aadDigest = digestRecord(
|
|
246
|
+
"chainlesschain.evolution-raw-storage-aad/v1",
|
|
247
|
+
request.aad,
|
|
248
|
+
);
|
|
249
|
+
const lineage = deepFreeze({
|
|
250
|
+
aadDigest,
|
|
251
|
+
algorithm: encrypted.algorithm,
|
|
252
|
+
cipherDigest,
|
|
253
|
+
evidenceId,
|
|
254
|
+
keyRef: encrypted.keyRef,
|
|
255
|
+
schema: EVOLUTION_ENCRYPTED_RAW_LINEAGE_SCHEMA,
|
|
256
|
+
tenantId: this.#tenantId,
|
|
257
|
+
});
|
|
258
|
+
const expiresAtMs = Date.parse(request.retention?.expiresAt);
|
|
259
|
+
const requestedAtMs = Date.parse(request.requestedAt);
|
|
260
|
+
if (
|
|
261
|
+
!Number.isFinite(expiresAtMs) ||
|
|
262
|
+
!Number.isFinite(requestedAtMs) ||
|
|
263
|
+
expiresAtMs <= requestedAtMs
|
|
264
|
+
) {
|
|
265
|
+
throw new TypeError("Raw retention is invalid");
|
|
266
|
+
}
|
|
267
|
+
const publication = this.#publish({
|
|
268
|
+
data: sealedBytes,
|
|
269
|
+
fileName: `${cipherDigest.slice("sha256:".length)}.raw.enc`,
|
|
270
|
+
title: "Encrypted evolution Raw evidence",
|
|
271
|
+
kind: "data",
|
|
272
|
+
mime: "application/octet-stream",
|
|
273
|
+
ttlDays: Math.max(
|
|
274
|
+
1,
|
|
275
|
+
Math.ceil((expiresAtMs - requestedAtMs) / 86_400_000),
|
|
276
|
+
),
|
|
277
|
+
immutable: true,
|
|
278
|
+
recordDigest: cipherDigest,
|
|
279
|
+
lineage,
|
|
280
|
+
});
|
|
281
|
+
const entry = publication?.entry;
|
|
282
|
+
if (
|
|
283
|
+
!entry ||
|
|
284
|
+
entry.recordDigest !== cipherDigest ||
|
|
285
|
+
entry.sha256 !== cipherDigest.slice("sha256:".length) ||
|
|
286
|
+
this.#verifyIntegrity(entry).ok !== true
|
|
287
|
+
) {
|
|
288
|
+
throw new Error("encrypted Raw artifact failed persistence readback");
|
|
289
|
+
}
|
|
290
|
+
const core = {
|
|
291
|
+
schema: EVOLUTION_RAW_STORAGE_RECEIPT_SCHEMA,
|
|
292
|
+
stored: true,
|
|
293
|
+
tenantId: this.#tenantId,
|
|
294
|
+
evidenceId,
|
|
295
|
+
sourceCommitment: request.sourceCommitment,
|
|
296
|
+
commitmentReceiptDigest: request.commitmentReceiptDigest,
|
|
297
|
+
sourceVerificationReceiptDigest: request.sourceVerificationReceiptDigest,
|
|
298
|
+
storagePolicyReceiptDigest: request.storagePolicyReceiptDigest,
|
|
299
|
+
storagePolicyDigest: request.storagePolicyDigest,
|
|
300
|
+
storagePolicyRevision: request.storagePolicyRevision,
|
|
301
|
+
storagePolicyDecisionExpiresAt: request.storagePolicyDecisionExpiresAt,
|
|
302
|
+
requestNonce: request.requestNonce,
|
|
303
|
+
requestedAt: request.requestedAt,
|
|
304
|
+
storedAt: request.requestedAt,
|
|
305
|
+
artifactRef: `artifact://${this.#tenantId}/raw/${entry.id}`,
|
|
306
|
+
cipherDigest,
|
|
307
|
+
keyRef: encrypted.keyRef,
|
|
308
|
+
algorithm: encrypted.algorithm,
|
|
309
|
+
aadDigest,
|
|
310
|
+
sensitivity: request.sensitivity,
|
|
311
|
+
retention: clone(request.retention),
|
|
312
|
+
acl: clone(request.acl),
|
|
313
|
+
};
|
|
314
|
+
return deepFreeze({
|
|
315
|
+
...core,
|
|
316
|
+
receiptDigest: digestRecord(
|
|
317
|
+
"chainlesschain.evolution-raw-storage-receipt/v1",
|
|
318
|
+
core,
|
|
319
|
+
),
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
function componentDescriptor(type, publication) {
|
|
325
|
+
return deepFreeze({
|
|
326
|
+
digest: publication.digest,
|
|
327
|
+
envelope: publication.envelope,
|
|
328
|
+
ref: clone(publication.ref),
|
|
329
|
+
type,
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/** Commit-point adapter for authenticated projection bundles. */
|
|
334
|
+
export class EvolutionEvidenceArtifactAdapter {
|
|
335
|
+
#tenantId;
|
|
336
|
+
#audience;
|
|
337
|
+
#purpose;
|
|
338
|
+
#ttlMs;
|
|
339
|
+
#project;
|
|
340
|
+
#verify;
|
|
341
|
+
#ports;
|
|
342
|
+
|
|
343
|
+
constructor({
|
|
344
|
+
tenantId,
|
|
345
|
+
audience,
|
|
346
|
+
purpose = "evidence-projection",
|
|
347
|
+
ttlMs = EVOLUTION_ARTIFACT_DEFAULT_TTL_MS,
|
|
348
|
+
projector,
|
|
349
|
+
bundleVerifier,
|
|
350
|
+
artifactPorts,
|
|
351
|
+
} = {}) {
|
|
352
|
+
this.#tenantId = normalizeId(tenantId, "evidence adapter tenantId");
|
|
353
|
+
this.#audience = normalizeId(audience, "evidence adapter audience");
|
|
354
|
+
this.#purpose = normalizeId(purpose, "evidence adapter purpose");
|
|
355
|
+
if (
|
|
356
|
+
!Number.isSafeInteger(ttlMs) ||
|
|
357
|
+
ttlMs < 1 ||
|
|
358
|
+
ttlMs > EVOLUTION_ARTIFACT_MAX_TTL_MS
|
|
359
|
+
) {
|
|
360
|
+
throw new TypeError("evidence adapter ttlMs is invalid");
|
|
361
|
+
}
|
|
362
|
+
assertInstance(
|
|
363
|
+
projector,
|
|
364
|
+
EvolutionEvidenceProjector.prototype,
|
|
365
|
+
"projector",
|
|
366
|
+
);
|
|
367
|
+
assertInstance(
|
|
368
|
+
bundleVerifier,
|
|
369
|
+
EvolutionEvidenceBundleVerifier.prototype,
|
|
370
|
+
"bundleVerifier",
|
|
371
|
+
);
|
|
372
|
+
assertInstance(
|
|
373
|
+
artifactPorts,
|
|
374
|
+
EvolutionArtifactPorts.prototype,
|
|
375
|
+
"artifactPorts",
|
|
376
|
+
);
|
|
377
|
+
this.#ttlMs = ttlMs;
|
|
378
|
+
this.#project = captureMethod(projector, "project", "projector");
|
|
379
|
+
this.#verify = captureMethod(bundleVerifier, "verify", "bundleVerifier");
|
|
380
|
+
this.#ports = artifactPorts;
|
|
381
|
+
Object.freeze(this);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
#put(type, value) {
|
|
385
|
+
return this.#ports.putCanonical(type, value, {
|
|
386
|
+
audience: this.#audience,
|
|
387
|
+
purpose: this.#purpose,
|
|
388
|
+
retention: "ttl",
|
|
389
|
+
ttlMs: this.#ttlMs,
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
async projectAndPersist(input) {
|
|
394
|
+
const bundle = await this.#project(input);
|
|
395
|
+
const verification = await this.#verify(bundle);
|
|
396
|
+
if (
|
|
397
|
+
verification.verified !== true ||
|
|
398
|
+
verification.tenantId !== this.#tenantId ||
|
|
399
|
+
verification.receiptDigest !== bundle.receipt.receiptDigest ||
|
|
400
|
+
verification.attestationDigest !== bundle.attestation.attestationDigest
|
|
401
|
+
) {
|
|
402
|
+
throw new Error("projection bundle verification is unbound");
|
|
403
|
+
}
|
|
404
|
+
const components = {};
|
|
405
|
+
for (const [field, type] of Object.entries(COMPONENT_TYPES)) {
|
|
406
|
+
components[field] = componentDescriptor(
|
|
407
|
+
type,
|
|
408
|
+
this.#put(type, bundle[field]),
|
|
409
|
+
);
|
|
410
|
+
}
|
|
411
|
+
const manifest = deepFreeze({
|
|
412
|
+
schema: EVOLUTION_EVIDENCE_DERIVATION_MANIFEST_SCHEMA,
|
|
413
|
+
tenantId: this.#tenantId,
|
|
414
|
+
evidenceId: bundle.receipt.evidenceId,
|
|
415
|
+
sourceCommitment: bundle.receipt.sourceCommitment,
|
|
416
|
+
rulesetDigest: bundle.receipt.rulesetDigest,
|
|
417
|
+
projectionReceiptDigest: bundle.receipt.receiptDigest,
|
|
418
|
+
attestation: clone(bundle.attestation),
|
|
419
|
+
components: deepFreeze(components),
|
|
420
|
+
});
|
|
421
|
+
const publication = this.#put("evidence", manifest);
|
|
422
|
+
return deepFreeze({
|
|
423
|
+
schema: EVOLUTION_EVIDENCE_ARTIFACT_RESULT_SCHEMA,
|
|
424
|
+
tenantId: this.#tenantId,
|
|
425
|
+
evidenceId: manifest.evidenceId,
|
|
426
|
+
manifest: componentDescriptor("evidence", publication),
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
async resolve(result) {
|
|
431
|
+
assertPlainExact(
|
|
432
|
+
result,
|
|
433
|
+
new Set(["schema", "tenantId", "evidenceId", "manifest"]),
|
|
434
|
+
"evidence artifact result",
|
|
435
|
+
);
|
|
436
|
+
if (
|
|
437
|
+
result.schema !== EVOLUTION_EVIDENCE_ARTIFACT_RESULT_SCHEMA ||
|
|
438
|
+
result.tenantId !== this.#tenantId
|
|
439
|
+
) {
|
|
440
|
+
throw new TypeError(
|
|
441
|
+
"evidence artifact result is invalid or cross-tenant",
|
|
442
|
+
);
|
|
443
|
+
}
|
|
444
|
+
assertPlainExact(
|
|
445
|
+
result.manifest,
|
|
446
|
+
COMPONENT_DESCRIPTOR_KEYS,
|
|
447
|
+
"evidence manifest descriptor",
|
|
448
|
+
);
|
|
449
|
+
if (result.manifest.type !== "evidence") {
|
|
450
|
+
throw new TypeError("evidence manifest descriptor type is invalid");
|
|
451
|
+
}
|
|
452
|
+
const manifestResolved = this.#ports.resolve(result.manifest.envelope, {
|
|
453
|
+
expectedDigest: result.manifest.digest,
|
|
454
|
+
expectedType: "evidence",
|
|
455
|
+
purpose: this.#purpose,
|
|
456
|
+
tenantId: this.#tenantId,
|
|
457
|
+
});
|
|
458
|
+
const manifest = manifestResolved.value;
|
|
459
|
+
if (
|
|
460
|
+
manifest.schema !== EVOLUTION_EVIDENCE_DERIVATION_MANIFEST_SCHEMA ||
|
|
461
|
+
manifest.tenantId !== this.#tenantId ||
|
|
462
|
+
manifest.evidenceId !== result.evidenceId
|
|
463
|
+
) {
|
|
464
|
+
throw new Error("evidence derivation manifest is invalid");
|
|
465
|
+
}
|
|
466
|
+
const bundle = { attestation: clone(manifest.attestation) };
|
|
467
|
+
for (const [field, type] of Object.entries(COMPONENT_TYPES)) {
|
|
468
|
+
const descriptor = manifest.components[field];
|
|
469
|
+
assertPlainExact(
|
|
470
|
+
descriptor,
|
|
471
|
+
COMPONENT_DESCRIPTOR_KEYS,
|
|
472
|
+
`evidence ${field} descriptor`,
|
|
473
|
+
);
|
|
474
|
+
if (!descriptor || descriptor.type !== type) {
|
|
475
|
+
throw new Error("evidence derivation component type is invalid");
|
|
476
|
+
}
|
|
477
|
+
bundle[field] = this.#ports.resolve(descriptor.envelope, {
|
|
478
|
+
expectedDigest: descriptor.digest,
|
|
479
|
+
expectedType: type,
|
|
480
|
+
purpose: this.#purpose,
|
|
481
|
+
tenantId: this.#tenantId,
|
|
482
|
+
}).value;
|
|
483
|
+
}
|
|
484
|
+
const verification = await this.#verify(bundle);
|
|
485
|
+
if (
|
|
486
|
+
verification.receiptDigest !== manifest.projectionReceiptDigest ||
|
|
487
|
+
verification.attestationDigest !==
|
|
488
|
+
manifest.attestation.attestationDigest ||
|
|
489
|
+
bundle.receipt.rulesetDigest !== manifest.rulesetDigest ||
|
|
490
|
+
bundle.receipt.sourceCommitment !== manifest.sourceCommitment
|
|
491
|
+
) {
|
|
492
|
+
throw new Error("persisted evidence derivation lineage is unbound");
|
|
493
|
+
}
|
|
494
|
+
return deepFreeze({ bundle, manifest: clone(manifest), verification });
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
Object.freeze(ArtifactStoreEncryptedRawStore.prototype);
|
|
499
|
+
Object.freeze(EvolutionEvidenceArtifactAdapter.prototype);
|