chainlesschain 0.166.42 → 0.166.44
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 +75 -14
- package/package.json +1 -1
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AIOps-CdsAAOAu.js → AIOps-HiHMDVK3.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-B8x5S-3u.js → ActionButton-H2RKuS8V.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-C1eOGwSM.js → Analytics-CBPFBB61.js} +3 -3
- package/src/assets/web-panel/assets/AppLayout-Da-3Laze.js +9 -0
- package/src/assets/web-panel/assets/{Artifacts-B0tiKn2i.js → Artifacts-DiRQ9yzD.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-DzGqTUvG.js → Audit-C9LtWEBh.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-CMXYcy56.js → BackgroundAgents-4rpi7fVg.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-DrN3N1_7.js → Backup-B8VQmHys.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-BC9aoifZ.js → BaseInput-iCVpF2DK.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-F3Z9p0vk.js → Chat-BrQaXBwC.js} +6 -6
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-LMGrVg9Z.js → ChatBubbleRenderer-HIyU-9c0.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-CDXlouzl.js → Checkbox-CsV__0_R.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-9c0RpaYc.js → Codegen-BvFeCIAE.js} +1 -1
- package/src/assets/web-panel/assets/{Col-C-60iGia.js → Col-CagxV1O8.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DXE04H2M.js → Community-DAWr4ahG.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-B4jEuBmH.js → Compact-Ba49Tdc2.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-uf13-dcK.js → Compliance-Brk-MSO4.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-D6hpxLI4.js → Cowork-DeKH1v0o.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-CSJobmkN.js → Cron-AHB-T-VL.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-B0_rTlsi.js → Crosschain-Zbcrtimh.js} +1 -1
- package/src/assets/web-panel/assets/{DID-D49FQsiZ.js → DID-ByFa1MWG.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-BvjvIYfC.js → Dashboard-9jKovyuH.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-BYe1gODU.js → Dropdown-DY8TaXi5.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-CJ6znfiH.js → EmailListRenderer-rcaSveQ8.js} +1 -1
- package/src/assets/web-panel/assets/EvolutionSettings-B3dcSq1H.js +1 -0
- package/src/assets/web-panel/assets/EvolutionSettings-Bdw8ApoT.css +1 -0
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-BnoKDllh.js → FamilyGuardDashboard-5ao8smvA.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-AqhVFmd4.js → Federation-RTpNXXHT.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-CNVYBpNg.js → FormItemContext-DWZvRMWv.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-BbdYCfjH.js → GenericCardRenderer-CWi8SGvx.js} +1 -1
- package/src/assets/web-panel/assets/{Git-B_xClOR0.js → Git-CCLgDIqs.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-CIKCDF9F.js → Governance-DUuyKrQl.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-BdRSc0oa.js → Inference-RkFcM2A0.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DknpIQPx.js → KnowledgeGraph-C-QTauZr.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BcCPhMaZ.js → Logs-B-7Dz5Ui.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-CgiHBe0A.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-DEMNuvwO.js → Marketplace-CK1kSFDt.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-D-tg9wfq.js → McpTools-BcaVwoY6.js} +2 -2
- package/src/assets/web-panel/assets/{Memory-BqCLu-X9.js → Memory-QEI4xRwF.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-bN6vwbZc.js → MobileBridge-BqD-R0Ek.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-BTM0-1MZ.js → MobileProjects-CwFoXf1M.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-CcGXXyEn.js → Mtc-CTZ6qICG.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-B2Z5wPnM.js → MtcAudit-Cn7y2BzO.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-DNW7dKam.js → Multisig-BCjsdGiN.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-Ciz-g5G3.js → NLProgramming-CupTVNtA.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-CeiEA6yF.js → Notes-C8kO3mGt.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-DgeiEPwB.js → NotificationSettings-Cn-MJ8sQ.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-D9DjubGK.js → OrderTableRenderer-BX4PrVfN.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-CeA2EC_G.js → Organization-G_RjOL7M.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-DT40ig7t.js → Overflow-BvX644ya.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-K4H13K3M.js → P2P-yWmLgYgQ.js} +2 -2
- package/src/assets/web-panel/assets/PdhVaultBrowser-yYL7-rno.js +7 -0
- package/src/assets/web-panel/assets/{Permissions-DYQogL6r.js → Permissions-DtU8fhcZ.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-DXhXVHar.js → PersonalDataHub-B17Vyk-x.js} +5 -5
- package/src/assets/web-panel/assets/{Pipeline-DQMdn5Ij.js → Pipeline-BZUsTyhP.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-BiF1thop.js → Privacy-BswdhlPL.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-C2ptWEn7.js → ProjectInit-sJxSlY0C.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-B5WCiDZD.js → ProjectSettings-BnbpdOke.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-BNH6LKU6.js → Projects-DUjauf-6.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-CgRJ8ZT1.js → Providers-DhF5I-UR.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-B3tuNJ3V.js → QrScannerModal-B3PeCAGo.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-D9CO1SNI.js → QuickAsk-Cpaxrabg.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-BGmwHY_U.js → Recommend-DqXFF66-.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-CliYaolm.js → RemoteSession-DtDQ76Ox.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-sCiX2kmm.js → Reputation-BgLLKwu2.js} +1 -1
- package/src/assets/web-panel/assets/{Row-DXHx_bk0.js → Row-BuMLhd8M.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-Bg79mIxI.js → RssFeed-BizxUzBA.js} +3 -3
- package/src/assets/web-panel/assets/{Search-CnKDYqyS.js → Search-CYNrJAQY.js} +1 -1
- package/src/assets/web-panel/assets/{Security-c-0QOrC2.js → Security-CIC02soH.js} +4 -4
- package/src/assets/web-panel/assets/{Services-BBBTb4YA.js → Services-DD3WxXxw.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-CtL_5fJe.js → Skeleton-C-d9Mbos.js} +1 -1
- package/src/assets/web-panel/assets/Skills-BBkg1Eqr.js +1 -0
- package/src/assets/web-panel/assets/{Sla-C5LGNImz.js → Sla-DgrqUhns.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-Btx0KgwX.js → SpeechSettings-CDXFwOHX.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-DFLNSWuu.js → SyncSettings-BBio_v8M.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-Btkyo0G7.js → Tasks-QQWSk-tc.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-CIIt_k5J.js → Templates-RAPdM85o.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-Nqo1PA2a.js → Tenant-2jI745PC.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-CGwV9hW9.js → Terminal-ZCtYBMAe.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-Bu3xrXyf.js → TimelineRenderer-DfI36Yg6.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-3bC3zrYj.js → Tokens-NQ1VaO0W.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-DG84V7Xf.js → Trigger-DwFh5AMe.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-rPhNXoYJ.js → Trust-Dr0v45uH.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-CamNxeAp.js → UkeySign-i7Q1Bdqr.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-CkIuH4Gm.js → VideoEditing-CXSkk4gl.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-SD5W5uHT.js → Wallet-8_cAjou4.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn--A4Sddxn.js → WebAuthn-jn_3Gma7.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-Ca7qvch8.js → WorkflowEditor-BmvodVLl.js} +1 -1
- package/src/assets/web-panel/assets/{chat-i8OBdjCB.js → chat-DGi3bmwL.js} +1 -1
- package/src/assets/web-panel/assets/{colors-BeYbJKQ8.js → colors-D8OSTOU0.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-BqpF-Sya.js → compact-item-DfNygJU_.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-qXTb29t3.js → createContext-B0lT0dbj.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-BUooUkHH.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-DOfL0KSW.js → hasIn-Xtzg_EDR.js} +1 -1
- package/src/assets/web-panel/assets/{index-X8TXf9Bb.js → index-4s8GZJ73.js} +1 -1
- package/src/assets/web-panel/assets/{index-0OxY_Nsh.js → index-B-B7DDjX.js} +1 -1
- package/src/assets/web-panel/assets/{index-CebShwk1.js → index-B0kDqFPU.js} +1 -1
- package/src/assets/web-panel/assets/{index-czHvbhS0.js → index-B2bgL5vL.js} +1 -1
- package/src/assets/web-panel/assets/{index-CXXeOim8.js → index-B3ittRaJ.js} +1 -1
- package/src/assets/web-panel/assets/{index--TQi5102.js → index-B4-hl9Rw.js} +1 -1
- package/src/assets/web-panel/assets/{index-C13IM9lj.js → index-BBR-_Pkv.js} +1 -1
- package/src/assets/web-panel/assets/{index-CH7mHJoh.js → index-BBegBTDb.js} +1 -1
- package/src/assets/web-panel/assets/{index-vNYrAXO6.js → index-BFRkiqtr.js} +1 -1
- package/src/assets/web-panel/assets/{index-DIikgsI1.js → index-BJ6nxb18.js} +1 -1
- package/src/assets/web-panel/assets/{index-B177TAO-.js → index-BVOyO-ZV.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bt7Ua7EC.js → index-BbTx5wo1.js} +1 -1
- package/src/assets/web-panel/assets/{index-nl9IxLfv.js → index-BhS9-r8Z.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cy8WApMp.js → index-BhYM_Rzp.js} +1 -1
- package/src/assets/web-panel/assets/{index-BmzmjSGb.js → index-BhhS0xnV.js} +1 -1
- package/src/assets/web-panel/assets/{index-D8c3Ctj4.js → index-BpsIkWwQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-C4_8KnUt.js → index-Bujix_OR.js} +1 -1
- package/src/assets/web-panel/assets/{index-CLrDyxeZ.js → index-Byto86PA.js} +1 -1
- package/src/assets/web-panel/assets/{index-Byn_IHXR.js → index-CIbYQLD-.js} +1 -1
- package/src/assets/web-panel/assets/{index-DWLxMPZ_.js → index-CLRMkKeD.js} +1 -1
- package/src/assets/web-panel/assets/{index-ByHZkqj5.js → index-CShl59Um.js} +1 -1
- package/src/assets/web-panel/assets/{index-TAvlGp5l.js → index-ConAvib0.js} +1 -1
- package/src/assets/web-panel/assets/{index-BKd03Rn4.js → index-Cp-yGWti.js} +1 -1
- package/src/assets/web-panel/assets/{index-rdW8KX_7.js → index-Cx_EAQEh.js} +1 -1
- package/src/assets/web-panel/assets/{index-JxyF4KNw.js → index-CyVOaMS7.js} +1 -1
- package/src/assets/web-panel/assets/{index-BYzQaGnV.js → index-DEH5ms1R.js} +1 -1
- package/src/assets/web-panel/assets/{index-zmvw3Ptl.js → index-DFkgqRqx.js} +1 -1
- package/src/assets/web-panel/assets/{index-BdbrE-hz.js → index-DVfE2S0f.js} +1 -1
- package/src/assets/web-panel/assets/{index-BOwR6mHU.js → index-DVnowoxR.js} +1 -1
- package/src/assets/web-panel/assets/index-DVu4QCII.js +1 -0
- package/src/assets/web-panel/assets/{index-Cvig0IjN.js → index-DWpRgQvO.js} +1 -1
- package/src/assets/web-panel/assets/{index-BD386d6M.js → index-DXNWsfbw.js} +1 -1
- package/src/assets/web-panel/assets/{index-BuzGZOAK.js → index-DZKM2nm2.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dio2mTWq.js → index-De9jsBiC.js} +1 -1
- package/src/assets/web-panel/assets/{index-GGEsF-NA.js → index-EV-o-rTH.js} +1 -1
- package/src/assets/web-panel/assets/index-XYnz-yJ_.js +1 -0
- package/src/assets/web-panel/assets/{index-B00rNoIx.js → index-hDo9-qDw.js} +1 -1
- package/src/assets/web-panel/assets/{index-C-P0NHi4.js → index-kdyFlPZw.js} +1 -1
- package/src/assets/web-panel/assets/{index-DCcXU9HN.js → index-svr-L6NS.js} +5 -5
- package/src/assets/web-panel/assets/{initDefaultProps-BKpYiODg.js → initDefaultProps-CPsOp_T6.js} +1 -1
- package/src/assets/web-panel/assets/{motion-DJ2p-V-R.js → motion-8Jakob3_.js} +1 -1
- package/src/assets/web-panel/assets/{move-CmA2ejm5.js → move-DAogsEBs.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-CAIGxQzN.js → mtc-parser-CkA9zZB_.js} +1 -1
- package/src/assets/web-panel/assets/{omit-DJlnhA7K.js → omit-DMHNkosQ.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-CZPrJyhF.js → pickAttrs-ByIvo_lk.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-CXy74okE.js → placementArrow-CafMUHzz.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-DexkLtci.js → responsiveObserve-CTehELUQ.js} +1 -1
- package/src/assets/web-panel/assets/{slide-BzjBJbPV.js → slide-BQISQ1KV.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-gnHIXw2X.js → statusUtils-Drm4jUoK.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-DHBjT1Gk.js → styleChecker-DGniLRqn.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-BmMStW87.js → useFlexGapSupport-DYz_z9wn.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-BcV5VGA2.js → useFs-DRAPQMjC.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-DBxxRRY2.js → usePersonalDataHub-CpgGLb8q.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-Bt5yp9hj.js → vnode-p6925VWJ.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-CMdUkOfw.js → zoom-ClpO8REK.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +1 -1
- package/src/commands/evolution-deployment.js +95 -0
- package/src/commands/evolution.js +2 -0
- package/src/constants.js +2 -2
- package/src/data/changelog.json +191 -752
- package/src/gateways/ws/evolution-deployment-topic-handlers.js +53 -0
- package/src/lib/evolution/evolution-deployment-config.js +81 -0
- package/src/lib/evolution/evolution-deployment-loader.js +62 -13
- package/src/lib/evolution/evolution-deployment-profile.js +114 -0
- package/src/lib/evolution/evolution-file-identity.js +42 -0
- package/src/lib/evolution/evolution-ledger-file-manifest-head-store.js +242 -0
- package/src/lib/evolution/evolution-ledger-manifest-chain.js +74 -18
- package/src/lib/evolution/evolution-ledger-v2-manifest-backend.js +135 -20
- package/src/lib/evolution/evolution-ledger.js +353 -209
- package/src/lib/llm-providers.js +1 -0
- package/src/lib/public-ide-capability-manifest.js +2 -0
- package/src/lib/read-file-loop-guard.js +17 -4
- package/src/lib/remote-read-loop-guard.js +13 -0
- package/src/lib/task-model-selector.js +1 -1
- package/src/lib/task-progress-tracker.js +36 -1
- package/src/lib/text-file-search.js +11 -0
- package/src/runtime/agent-core.js +6 -2
- package/src/runtime/agent-runtime.js +2 -0
- package/src/assets/web-panel/assets/AppLayout-CdnpAzuo.js +0 -9
- package/src/assets/web-panel/assets/MarkdownRenderer-H_GkKEp-.js +0 -1
- package/src/assets/web-panel/assets/PdhVaultBrowser-CF7TzZmx.js +0 -7
- package/src/assets/web-panel/assets/Skills-DvqrC2_v.js +0 -1
- package/src/assets/web-panel/assets/devWarning-DATyiD_X.js +0 -1
- package/src/assets/web-panel/assets/index-DmzMCELP.js +0 -1
- package/src/assets/web-panel/assets/index-TlPg2Jz6.js +0 -1
|
@@ -3,7 +3,10 @@ import fs from "node:fs";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { types as utilTypes } from "node:util";
|
|
5
5
|
import { readBoundedDescriptor } from "./bounded-descriptor-read.js";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
withEvolutionDirectoryFileIdentity,
|
|
8
|
+
withEvolutionFileIdentity,
|
|
9
|
+
} from "./evolution-file-identity.js";
|
|
7
10
|
import { sameFileStatIdentity } from "../secure-file-identity.js";
|
|
8
11
|
import { getHomeDir } from "../paths.js";
|
|
9
12
|
import { ensurePrivateDirectory, ensurePrivateFile } from "../secure-fs.js";
|
|
@@ -24,6 +27,8 @@ export const EVOLUTION_LEDGER_ANCHOR_SCHEMA =
|
|
|
24
27
|
"chainlesschain.evolution-ledger-head-anchor/v1";
|
|
25
28
|
export const EVOLUTION_LEDGER_RECEIPT_SCHEMA =
|
|
26
29
|
"chainlesschain.evolution-ledger-receipt/v2";
|
|
30
|
+
export const EVOLUTION_LEDGER_BATCH_RECEIPT_SCHEMA =
|
|
31
|
+
"chainlesschain.evolution-ledger-batch-receipt/v1";
|
|
27
32
|
export const EVOLUTION_LEDGER_VERIFICATION_SCHEMA =
|
|
28
33
|
"chainlesschain.evolution-ledger-verification/v2";
|
|
29
34
|
export const EVOLUTION_LEDGER_QUERY_SCHEMA =
|
|
@@ -97,6 +102,7 @@ const HEAD_STAGE_FILE_PATTERN =
|
|
|
97
102
|
const MAX_SOURCE_REFS = 256;
|
|
98
103
|
const MAX_AUDIT_ARTIFACT_RECORDS = 1_000_000;
|
|
99
104
|
const MAX_LEDGER_BATCH_QUERIES = 10_000;
|
|
105
|
+
const MAX_LEDGER_APPEND_BATCH = 1024;
|
|
100
106
|
const MAX_STATE_SNAPSHOT_BYTES = 256 * 1024 * 1024;
|
|
101
107
|
const STATE_QUERY_INDEXES = new WeakMap();
|
|
102
108
|
const TYPED_ARRAY_PROTOTYPE = Object.getPrototypeOf(Uint8Array.prototype);
|
|
@@ -136,6 +142,7 @@ const DECISIONS = new Set([
|
|
|
136
142
|
const REVOCATION_STATES = new Set(["not-revoked", "revoked", "tombstoned"]);
|
|
137
143
|
const DURABILITY_MECHANISMS = new Set([
|
|
138
144
|
"authenticated-witness-cas",
|
|
145
|
+
"authenticated-witness-batch-cas",
|
|
139
146
|
"directory-fsync",
|
|
140
147
|
"verified-existing",
|
|
141
148
|
]);
|
|
@@ -2787,8 +2794,12 @@ export class EvolutionLedger {
|
|
|
2787
2794
|
label,
|
|
2788
2795
|
allowMissing,
|
|
2789
2796
|
samePathHandle,
|
|
2797
|
+
{ expectedBytes = null, trustedParentPath = null } = {},
|
|
2790
2798
|
) {
|
|
2791
|
-
|
|
2799
|
+
const heldParent =
|
|
2800
|
+
trustedParentPath !== null &&
|
|
2801
|
+
samePath(path.dirname(filePath), trustedParentPath);
|
|
2802
|
+
if (!heldParent) this.#assertBoundaries();
|
|
2792
2803
|
let before;
|
|
2793
2804
|
try {
|
|
2794
2805
|
before = this.#fs.lstatSync(filePath);
|
|
@@ -2808,7 +2819,7 @@ export class EvolutionLedger {
|
|
|
2808
2819
|
before.nlink !== 1 ||
|
|
2809
2820
|
before.size < 2 ||
|
|
2810
2821
|
before.size > maximum ||
|
|
2811
|
-
!samePath(realpath(this.#fs, filePath), filePath)
|
|
2822
|
+
(!heldParent && !samePath(realpath(this.#fs, filePath), filePath))
|
|
2812
2823
|
) {
|
|
2813
2824
|
throw ledgerError(
|
|
2814
2825
|
"CC_EVOLUTION_LEDGER_CORRUPT",
|
|
@@ -2860,6 +2871,20 @@ export class EvolutionLedger {
|
|
|
2860
2871
|
`${label} changed while it was read`,
|
|
2861
2872
|
);
|
|
2862
2873
|
}
|
|
2874
|
+
if (expectedBytes !== null) {
|
|
2875
|
+
if (!Buffer.isBuffer(expectedBytes) || !bytes.equals(expectedBytes)) {
|
|
2876
|
+
throw ledgerError(
|
|
2877
|
+
"CC_EVOLUTION_LEDGER_CORRUPT",
|
|
2878
|
+
`${label} differs from its signed snapshot bytes`,
|
|
2879
|
+
);
|
|
2880
|
+
}
|
|
2881
|
+
return {
|
|
2882
|
+
bytes,
|
|
2883
|
+
contentDigest: sha256(bytes),
|
|
2884
|
+
fingerprint: fileFingerprint(before),
|
|
2885
|
+
record: null,
|
|
2886
|
+
};
|
|
2887
|
+
}
|
|
2863
2888
|
let text;
|
|
2864
2889
|
try {
|
|
2865
2890
|
text = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
@@ -2902,7 +2927,7 @@ export class EvolutionLedger {
|
|
|
2902
2927
|
};
|
|
2903
2928
|
} finally {
|
|
2904
2929
|
if (descriptor !== null) this.#fs.closeSync(descriptor);
|
|
2905
|
-
this.#assertBoundaries();
|
|
2930
|
+
if (!heldParent) this.#assertBoundaries();
|
|
2906
2931
|
}
|
|
2907
2932
|
}
|
|
2908
2933
|
|
|
@@ -3620,60 +3645,82 @@ export class EvolutionLedger {
|
|
|
3620
3645
|
);
|
|
3621
3646
|
const anchorFingerprints = {};
|
|
3622
3647
|
const segmentFingerprints = {};
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3648
|
+
withEvolutionDirectoryFileIdentity(
|
|
3649
|
+
this.#fs,
|
|
3650
|
+
this.#paths.anchorDir,
|
|
3651
|
+
(samePathHandle, _sameStableHandle, { parentPath }) => {
|
|
3652
|
+
for (let index = 0; index < anchorFiles.length; index += 1) {
|
|
3653
|
+
const entry = anchorFiles[index];
|
|
3654
|
+
const expectedBytes = Buffer.from(
|
|
3655
|
+
`${canonicalJson(anchorRecords[index])}\n`,
|
|
3656
|
+
"utf8",
|
|
3657
|
+
);
|
|
3658
|
+
const snapshotRecordDigest = sha256(expectedBytes);
|
|
3659
|
+
if (entry.contentDigest !== snapshotRecordDigest) {
|
|
3660
|
+
throw ledgerError(
|
|
3661
|
+
"CC_EVOLUTION_LEDGER_CORRUPT",
|
|
3662
|
+
`state snapshot anchor bytes are not bound at index ${index}`,
|
|
3663
|
+
);
|
|
3664
|
+
}
|
|
3665
|
+
const file = this.#readCanonicalFileWithIdentity(
|
|
3666
|
+
path.join(this.#paths.anchorDir, entry.name),
|
|
3667
|
+
64 * 1024,
|
|
3668
|
+
`state snapshot anchor file ${entry.name}`,
|
|
3669
|
+
false,
|
|
3670
|
+
samePathHandle,
|
|
3671
|
+
{ expectedBytes, trustedParentPath: parentPath },
|
|
3672
|
+
);
|
|
3673
|
+
if (file.contentDigest !== entry.contentDigest) {
|
|
3674
|
+
throw ledgerError(
|
|
3675
|
+
"CC_EVOLUTION_LEDGER_CORRUPT",
|
|
3676
|
+
`state snapshot anchor file changed: ${entry.name}`,
|
|
3677
|
+
);
|
|
3678
|
+
}
|
|
3679
|
+
anchorFingerprints[entry.name] = Object.freeze({
|
|
3680
|
+
contentDigest: file.contentDigest,
|
|
3681
|
+
fingerprint: file.fingerprint,
|
|
3682
|
+
});
|
|
3683
|
+
}
|
|
3684
|
+
},
|
|
3685
|
+
);
|
|
3686
|
+
withEvolutionDirectoryFileIdentity(
|
|
3687
|
+
this.#fs,
|
|
3688
|
+
this.#paths.segmentDir,
|
|
3689
|
+
(samePathHandle, _sameStableHandle, { parentPath }) => {
|
|
3690
|
+
for (let index = 0; index < segmentFiles.length; index += 1) {
|
|
3691
|
+
const entry = segmentFiles[index];
|
|
3692
|
+
const expectedBytes = Buffer.from(
|
|
3693
|
+
`${canonicalJson(eventRecords[index])}\n`,
|
|
3694
|
+
"utf8",
|
|
3695
|
+
);
|
|
3696
|
+
const snapshotRecordDigest = sha256(expectedBytes);
|
|
3697
|
+
if (entry.contentDigest !== snapshotRecordDigest) {
|
|
3698
|
+
throw ledgerError(
|
|
3699
|
+
"CC_EVOLUTION_LEDGER_CORRUPT",
|
|
3700
|
+
`state snapshot event bytes are not bound at index ${index}`,
|
|
3701
|
+
);
|
|
3702
|
+
}
|
|
3703
|
+
const file = this.#readCanonicalFileWithIdentity(
|
|
3704
|
+
path.join(this.#paths.segmentDir, entry.name),
|
|
3705
|
+
EVOLUTION_LEDGER_MAX_EVENT_BYTES,
|
|
3706
|
+
`state snapshot segment file ${entry.name}`,
|
|
3707
|
+
false,
|
|
3708
|
+
samePathHandle,
|
|
3709
|
+
{ expectedBytes, trustedParentPath: parentPath },
|
|
3710
|
+
);
|
|
3711
|
+
if (file.contentDigest !== entry.contentDigest) {
|
|
3712
|
+
throw ledgerError(
|
|
3713
|
+
"CC_EVOLUTION_LEDGER_CORRUPT",
|
|
3714
|
+
`state snapshot segment file changed: ${entry.name}`,
|
|
3715
|
+
);
|
|
3716
|
+
}
|
|
3717
|
+
segmentFingerprints[entry.name] = Object.freeze({
|
|
3718
|
+
contentDigest: file.contentDigest,
|
|
3719
|
+
fingerprint: file.fingerprint,
|
|
3720
|
+
});
|
|
3721
|
+
}
|
|
3722
|
+
},
|
|
3723
|
+
);
|
|
3677
3724
|
|
|
3678
3725
|
const maximumAnchor = anchors.at(-1);
|
|
3679
3726
|
const maximumEvent = events.at(-1) || null;
|
|
@@ -4426,11 +4473,36 @@ export class EvolutionLedger {
|
|
|
4426
4473
|
return this.#appendEvent(input, options, true);
|
|
4427
4474
|
}
|
|
4428
4475
|
|
|
4476
|
+
appendBatch(inputs, options = {}) {
|
|
4477
|
+
return this.#appendEvents(inputs, options, false, true);
|
|
4478
|
+
}
|
|
4479
|
+
|
|
4480
|
+
appendDomainEventBatch(inputs, options = {}) {
|
|
4481
|
+
return this.#appendEvents(inputs, options, true, true);
|
|
4482
|
+
}
|
|
4483
|
+
|
|
4429
4484
|
#appendEvent(input, options, domainEvent) {
|
|
4485
|
+
return this.#appendEvents([input], options, domainEvent, false);
|
|
4486
|
+
}
|
|
4487
|
+
|
|
4488
|
+
#appendEvents(inputs, options, domainEvent, batch) {
|
|
4489
|
+
const safeInputs = readDenseDataArray(
|
|
4490
|
+
inputs,
|
|
4491
|
+
batch ? "append batch" : "append input",
|
|
4492
|
+
batch ? MAX_LEDGER_APPEND_BATCH : 1,
|
|
4493
|
+
);
|
|
4494
|
+
if (safeInputs.length === 0) {
|
|
4495
|
+
throw ledgerError(
|
|
4496
|
+
"CC_EVOLUTION_LEDGER_SCHEMA_INVALID",
|
|
4497
|
+
"append batch must contain at least one event",
|
|
4498
|
+
);
|
|
4499
|
+
}
|
|
4430
4500
|
const safeOptions = normalizeAppendOptions(options);
|
|
4431
4501
|
const state = {
|
|
4432
4502
|
event: null,
|
|
4503
|
+
events: [],
|
|
4433
4504
|
receipt: null,
|
|
4505
|
+
receipts: [],
|
|
4434
4506
|
witnessAttempted: false,
|
|
4435
4507
|
witnessPublished: false,
|
|
4436
4508
|
};
|
|
@@ -4467,179 +4539,240 @@ export class EvolutionLedger {
|
|
|
4467
4539
|
},
|
|
4468
4540
|
);
|
|
4469
4541
|
}
|
|
4470
|
-
const generatedTimestamp = clockTimestamp(this.#clock);
|
|
4471
|
-
const normalized = domainEvent
|
|
4472
|
-
? normalizeDomainAppendInput(input, generatedTimestamp)
|
|
4473
|
-
: normalizeAppendInput(input, generatedTimestamp);
|
|
4474
4542
|
if (
|
|
4475
|
-
current.events.
|
|
4543
|
+
current.events.length + safeInputs.length >
|
|
4544
|
+
EVOLUTION_LEDGER_MAX_EVENTS
|
|
4476
4545
|
) {
|
|
4477
|
-
throw ledgerError(
|
|
4478
|
-
"CC_EVOLUTION_LEDGER_EVENT_CONFLICT",
|
|
4479
|
-
`eventId already exists: ${normalized.eventId}`,
|
|
4480
|
-
);
|
|
4481
|
-
}
|
|
4482
|
-
if (current.events.length >= EVOLUTION_LEDGER_MAX_EVENTS) {
|
|
4483
4546
|
throw ledgerError(
|
|
4484
4547
|
"CC_EVOLUTION_LEDGER_CAPACITY_EXCEEDED",
|
|
4485
4548
|
"evolution ledger capacity is exhausted",
|
|
4486
4549
|
);
|
|
4487
4550
|
}
|
|
4488
|
-
|
|
4489
|
-
//
|
|
4490
|
-
//
|
|
4491
|
-
|
|
4492
|
-
|
|
4493
|
-
|
|
4494
|
-
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
{ includeBytes: true },
|
|
4501
|
-
);
|
|
4502
|
-
const subject = evidence.artifacts.find(
|
|
4503
|
-
(artifact) =>
|
|
4504
|
-
artifact.artifactRef.ref === entry.subjectRef.ref &&
|
|
4505
|
-
artifact.artifactRef.digest === entry.subjectRef.digest,
|
|
4506
|
-
);
|
|
4507
|
-
if (!subject)
|
|
4508
|
-
throw ledgerError(
|
|
4509
|
-
WIKI_SOURCE_ADMISSION_INVALID_CODE,
|
|
4510
|
-
"Wiki admission subject was not resolved",
|
|
4511
|
-
);
|
|
4512
|
-
return Buffer.from(subject.bytesBase64, "base64");
|
|
4513
|
-
},
|
|
4514
|
-
});
|
|
4515
|
-
} catch (cause) {
|
|
4516
|
-
if (cause instanceof EvolutionLedgerError) throw cause;
|
|
4551
|
+
|
|
4552
|
+
// Normalize the complete batch before any filesystem mutation. This
|
|
4553
|
+
// prevents a malformed later item from leaving a valid earlier prefix.
|
|
4554
|
+
const normalizedInputs = safeInputs.map((input) => {
|
|
4555
|
+
const generatedTimestamp = clockTimestamp(this.#clock);
|
|
4556
|
+
return domainEvent
|
|
4557
|
+
? normalizeDomainAppendInput(input, generatedTimestamp)
|
|
4558
|
+
: normalizeAppendInput(input, generatedTimestamp);
|
|
4559
|
+
});
|
|
4560
|
+
const eventIds = new Set(current.events.map((event) => event.eventId));
|
|
4561
|
+
for (const normalized of normalizedInputs) {
|
|
4562
|
+
if (eventIds.has(normalized.eventId)) {
|
|
4517
4563
|
throw ledgerError(
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
: WIKI_SOURCE_ADMISSION_INVALID_CODE,
|
|
4521
|
-
"Wiki source admission rejected the proposed revision",
|
|
4522
|
-
{ cause },
|
|
4564
|
+
"CC_EVOLUTION_LEDGER_EVENT_CONFLICT",
|
|
4565
|
+
`eventId already exists: ${normalized.eventId}`,
|
|
4523
4566
|
);
|
|
4524
4567
|
}
|
|
4568
|
+
eventIds.add(normalized.eventId);
|
|
4525
4569
|
}
|
|
4526
|
-
const artifactValidationDigest = this.#resolveArtifacts(
|
|
4527
|
-
normalized,
|
|
4528
|
-
current.identity,
|
|
4529
|
-
);
|
|
4530
|
-
const event = domainEvent
|
|
4531
|
-
? this.#buildDomainEvent(
|
|
4532
|
-
normalized,
|
|
4533
|
-
previous,
|
|
4534
|
-
current.identity,
|
|
4535
|
-
artifactValidationDigest,
|
|
4536
|
-
)
|
|
4537
|
-
: this.#buildEvent(
|
|
4538
|
-
normalized,
|
|
4539
|
-
previous,
|
|
4540
|
-
current.identity,
|
|
4541
|
-
artifactValidationDigest,
|
|
4542
|
-
);
|
|
4543
|
-
state.event = event;
|
|
4544
|
-
const segmentDigest = domainDigest(SEGMENT_DOMAIN, event);
|
|
4545
|
-
const segmentPath = path.join(
|
|
4546
|
-
this.#paths.segmentDir,
|
|
4547
|
-
segmentFileName(event.sequence, segmentDigest),
|
|
4548
|
-
);
|
|
4549
|
-
const eventBytes = serializeRecord(
|
|
4550
|
-
event,
|
|
4551
|
-
EVOLUTION_LEDGER_MAX_EVENT_BYTES,
|
|
4552
|
-
"event segment",
|
|
4553
|
-
);
|
|
4554
|
-
this.#writeImmutable(
|
|
4555
|
-
segmentPath,
|
|
4556
|
-
eventBytes,
|
|
4557
|
-
"event segment",
|
|
4558
|
-
(temporaryPath) => {
|
|
4559
|
-
this.#invokeCrashHook("after-segment-link", {
|
|
4560
|
-
eventDigest: event.eventDigest,
|
|
4561
|
-
temporaryPath: path.basename(temporaryPath),
|
|
4562
|
-
});
|
|
4563
|
-
},
|
|
4564
|
-
);
|
|
4565
|
-
this.#invokeCrashHook("after-segment", {
|
|
4566
|
-
eventDigest: event.eventDigest,
|
|
4567
|
-
segmentDigest,
|
|
4568
|
-
});
|
|
4569
4570
|
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
|
|
4617
|
-
|
|
4618
|
-
|
|
4571
|
+
// Resolve artifacts, apply Wiki admission, and sign the complete plan
|
|
4572
|
+
// before the first segment is linked. Later authority failures cannot
|
|
4573
|
+
// turn a validation error into a partially committed batch.
|
|
4574
|
+
const planned = [];
|
|
4575
|
+
const knownEvents = [...current.events];
|
|
4576
|
+
let previousEvent = previous;
|
|
4577
|
+
let previousAnchor = current.anchors.at(-1);
|
|
4578
|
+
for (const normalized of normalizedInputs) {
|
|
4579
|
+
if (domainEvent && normalized.type === "wiki.revision.committed") {
|
|
4580
|
+
try {
|
|
4581
|
+
assertKnowledgeWikiSourceAdmission({
|
|
4582
|
+
input: normalized,
|
|
4583
|
+
events: knownEvents,
|
|
4584
|
+
resolveSubject: (entry) => {
|
|
4585
|
+
const evidence = this.#resolveArtifactEvidence(
|
|
4586
|
+
{ ...entry, sourceRefs: [] },
|
|
4587
|
+
current.identity,
|
|
4588
|
+
{ includeBytes: true },
|
|
4589
|
+
);
|
|
4590
|
+
const subject = evidence.artifacts.find(
|
|
4591
|
+
(artifact) =>
|
|
4592
|
+
artifact.artifactRef.ref === entry.subjectRef.ref &&
|
|
4593
|
+
artifact.artifactRef.digest === entry.subjectRef.digest,
|
|
4594
|
+
);
|
|
4595
|
+
if (!subject)
|
|
4596
|
+
throw ledgerError(
|
|
4597
|
+
WIKI_SOURCE_ADMISSION_INVALID_CODE,
|
|
4598
|
+
"Wiki admission subject was not resolved",
|
|
4599
|
+
);
|
|
4600
|
+
return Buffer.from(subject.bytesBase64, "base64");
|
|
4601
|
+
},
|
|
4602
|
+
});
|
|
4603
|
+
} catch (cause) {
|
|
4604
|
+
if (cause instanceof EvolutionLedgerError) throw cause;
|
|
4605
|
+
throw ledgerError(
|
|
4606
|
+
cause?.code === WIKI_SOURCE_REVOKED_CODE
|
|
4607
|
+
? WIKI_SOURCE_REVOKED_CODE
|
|
4608
|
+
: WIKI_SOURCE_ADMISSION_INVALID_CODE,
|
|
4609
|
+
"Wiki source admission rejected the proposed revision",
|
|
4610
|
+
{ cause },
|
|
4611
|
+
);
|
|
4612
|
+
}
|
|
4613
|
+
}
|
|
4614
|
+
const artifactValidationDigest = this.#resolveArtifacts(
|
|
4615
|
+
normalized,
|
|
4616
|
+
current.identity,
|
|
4617
|
+
);
|
|
4618
|
+
const event = domainEvent
|
|
4619
|
+
? this.#buildDomainEvent(
|
|
4620
|
+
normalized,
|
|
4621
|
+
previousEvent,
|
|
4622
|
+
current.identity,
|
|
4623
|
+
artifactValidationDigest,
|
|
4624
|
+
)
|
|
4625
|
+
: this.#buildEvent(
|
|
4626
|
+
normalized,
|
|
4627
|
+
previousEvent,
|
|
4628
|
+
current.identity,
|
|
4629
|
+
artifactValidationDigest,
|
|
4630
|
+
);
|
|
4631
|
+
const segmentDigest = domainDigest(SEGMENT_DOMAIN, event);
|
|
4632
|
+
const anchor = this.#buildAnchor(
|
|
4633
|
+
current.identity,
|
|
4634
|
+
previousAnchor,
|
|
4635
|
+
event,
|
|
4636
|
+
segmentDigest,
|
|
4637
|
+
);
|
|
4638
|
+
const eventBytes = serializeRecord(
|
|
4639
|
+
event,
|
|
4640
|
+
EVOLUTION_LEDGER_MAX_EVENT_BYTES,
|
|
4641
|
+
"event segment",
|
|
4642
|
+
);
|
|
4643
|
+
const anchorBytes = serializeRecord(anchor, 64 * 1024, "head anchor");
|
|
4644
|
+
planned.push({
|
|
4645
|
+
anchor,
|
|
4646
|
+
anchorBytes,
|
|
4647
|
+
event,
|
|
4648
|
+
eventBytes,
|
|
4649
|
+
segmentDigest,
|
|
4650
|
+
});
|
|
4651
|
+
knownEvents.push(event);
|
|
4652
|
+
previousEvent = event;
|
|
4653
|
+
previousAnchor = anchor;
|
|
4654
|
+
}
|
|
4655
|
+
|
|
4656
|
+
state.events = planned.map((entry) => entry.event);
|
|
4657
|
+
state.event = state.events.at(-1);
|
|
4658
|
+
const witnessedStates = [];
|
|
4659
|
+
let currentWitness = current.witness;
|
|
4660
|
+
for (const entry of planned) {
|
|
4661
|
+
const { anchor, anchorBytes, event, eventBytes, segmentDigest } =
|
|
4662
|
+
entry;
|
|
4663
|
+
const segmentPath = path.join(
|
|
4664
|
+
this.#paths.segmentDir,
|
|
4665
|
+
segmentFileName(event.sequence, segmentDigest),
|
|
4666
|
+
);
|
|
4667
|
+
this.#writeImmutable(
|
|
4668
|
+
segmentPath,
|
|
4669
|
+
eventBytes,
|
|
4670
|
+
"event segment",
|
|
4671
|
+
(temporaryPath) => {
|
|
4672
|
+
this.#invokeCrashHook("after-segment-link", {
|
|
4673
|
+
eventDigest: event.eventDigest,
|
|
4674
|
+
temporaryPath: path.basename(temporaryPath),
|
|
4675
|
+
});
|
|
4676
|
+
},
|
|
4677
|
+
);
|
|
4678
|
+
this.#invokeCrashHook("after-segment", {
|
|
4679
|
+
eventDigest: event.eventDigest,
|
|
4680
|
+
segmentDigest,
|
|
4681
|
+
});
|
|
4682
|
+
const anchorPath = path.join(
|
|
4683
|
+
this.#paths.anchorDir,
|
|
4684
|
+
anchorFileName(anchor.sequence, anchor.anchorDigest),
|
|
4685
|
+
);
|
|
4686
|
+
this.#writeImmutable(
|
|
4687
|
+
anchorPath,
|
|
4688
|
+
anchorBytes,
|
|
4689
|
+
"head anchor",
|
|
4690
|
+
(temporaryPath) => {
|
|
4691
|
+
this.#invokeCrashHook("after-anchor-link", {
|
|
4692
|
+
anchorDigest: anchor.anchorDigest,
|
|
4693
|
+
temporaryPath: path.basename(temporaryPath),
|
|
4694
|
+
});
|
|
4695
|
+
},
|
|
4696
|
+
);
|
|
4697
|
+
this.#invokeCrashHook("after-anchor", {
|
|
4698
|
+
anchorDigest: anchor.anchorDigest,
|
|
4699
|
+
eventDigest: event.eventDigest,
|
|
4700
|
+
});
|
|
4701
|
+
this.#requireDirectoryDurability([
|
|
4702
|
+
this.#paths.segmentDir,
|
|
4703
|
+
this.#paths.anchorDir,
|
|
4704
|
+
]);
|
|
4705
|
+
state.witnessAttempted = true;
|
|
4706
|
+
currentWitness = this.#advanceWitness(
|
|
4707
|
+
currentWitness,
|
|
4708
|
+
current.identity,
|
|
4709
|
+
current.storeMarker,
|
|
4710
|
+
anchor,
|
|
4711
|
+
event,
|
|
4712
|
+
);
|
|
4713
|
+
witnessedStates.push(currentWitness);
|
|
4714
|
+
state.witnessPublished = true;
|
|
4715
|
+
this.#invokeCrashHook("after-witness", {
|
|
4716
|
+
anchorDigest: anchor.anchorDigest,
|
|
4717
|
+
eventDigest: event.eventDigest,
|
|
4718
|
+
witnessDigest: currentWitness.witnessDigest,
|
|
4719
|
+
});
|
|
4720
|
+
this.#replaceHead(anchorBytes);
|
|
4721
|
+
this.#invokeCrashHook("after-head", {
|
|
4722
|
+
anchorDigest: anchor.anchorDigest,
|
|
4723
|
+
eventDigest: event.eventDigest,
|
|
4724
|
+
});
|
|
4725
|
+
}
|
|
4619
4726
|
|
|
4620
4727
|
const persisted = this.#loadState({
|
|
4621
4728
|
allowInitialize: false,
|
|
4622
4729
|
incremental: true,
|
|
4623
4730
|
});
|
|
4624
|
-
const
|
|
4625
|
-
const
|
|
4731
|
+
const sequenceStart = state.events[0].sequence;
|
|
4732
|
+
const persistedEvents = persisted.events.slice(sequenceStart - 1);
|
|
4733
|
+
const finalAnchor = planned.at(-1).anchor;
|
|
4626
4734
|
if (
|
|
4627
|
-
|
|
4628
|
-
|
|
4629
|
-
|
|
4735
|
+
persistedEvents.length !== state.events.length ||
|
|
4736
|
+
persistedEvents.some(
|
|
4737
|
+
(event, index) =>
|
|
4738
|
+
event.eventDigest !== state.events[index].eventDigest,
|
|
4739
|
+
) ||
|
|
4740
|
+
persisted.head.anchorDigest !== finalAnchor.anchorDigest
|
|
4630
4741
|
) {
|
|
4631
4742
|
throw ledgerError(
|
|
4632
4743
|
"CC_EVOLUTION_LEDGER_WRITE_FAILED",
|
|
4633
|
-
"event was not recovered under the authenticated HEAD",
|
|
4744
|
+
"event batch was not recovered under the authenticated HEAD",
|
|
4634
4745
|
);
|
|
4635
4746
|
}
|
|
4636
|
-
state.
|
|
4637
|
-
|
|
4638
|
-
|
|
4639
|
-
|
|
4640
|
-
|
|
4747
|
+
state.receipts = persistedEvents.map((event, index) =>
|
|
4748
|
+
this.#issueReceipt(
|
|
4749
|
+
{ ...persisted, witness: witnessedStates[index] },
|
|
4750
|
+
event,
|
|
4751
|
+
planned[index].anchor,
|
|
4752
|
+
batch
|
|
4753
|
+
? "authenticated-witness-batch-cas"
|
|
4754
|
+
: "authenticated-witness-cas",
|
|
4755
|
+
),
|
|
4641
4756
|
);
|
|
4642
|
-
|
|
4757
|
+
state.receipt = state.receipts.at(-1);
|
|
4758
|
+
if (!batch) return state.receipt;
|
|
4759
|
+
return deepFreeze({
|
|
4760
|
+
anchorDigest: finalAnchor.anchorDigest,
|
|
4761
|
+
authenticated: true,
|
|
4762
|
+
committed: true,
|
|
4763
|
+
durable: true,
|
|
4764
|
+
eventCount: state.events.length,
|
|
4765
|
+
eventDigests: state.events.map((event) => event.eventDigest),
|
|
4766
|
+
eventIds: state.events.map((event) => event.eventId),
|
|
4767
|
+
eventReceipts: state.receipts,
|
|
4768
|
+
headDigest: state.event.eventDigest,
|
|
4769
|
+
readbackVerified: true,
|
|
4770
|
+
schema: EVOLUTION_LEDGER_BATCH_RECEIPT_SCHEMA,
|
|
4771
|
+
sequenceEnd: state.event.sequence,
|
|
4772
|
+
sequenceStart,
|
|
4773
|
+
witnessed: true,
|
|
4774
|
+
witnessDigest: currentWitness.witnessDigest,
|
|
4775
|
+
});
|
|
4643
4776
|
});
|
|
4644
4777
|
} catch (cause) {
|
|
4645
4778
|
if (state.witnessAttempted || state.receipt) {
|
|
@@ -4650,7 +4783,16 @@ export class EvolutionLedger {
|
|
|
4650
4783
|
cause,
|
|
4651
4784
|
commitState: "unknown",
|
|
4652
4785
|
eventDigest: state.event?.eventDigest || null,
|
|
4653
|
-
eventId:
|
|
4786
|
+
eventId:
|
|
4787
|
+
state.event?.eventId ||
|
|
4788
|
+
safeOwnDataValue(safeInputs.at(-1), "eventId"),
|
|
4789
|
+
...(batch
|
|
4790
|
+
? {
|
|
4791
|
+
eventIds: safeInputs.map((entry) =>
|
|
4792
|
+
safeOwnDataValue(entry, "eventId"),
|
|
4793
|
+
),
|
|
4794
|
+
}
|
|
4795
|
+
: {}),
|
|
4654
4796
|
witnessPublished: state.witnessPublished,
|
|
4655
4797
|
},
|
|
4656
4798
|
);
|
|
@@ -4665,7 +4807,9 @@ export class EvolutionLedger {
|
|
|
4665
4807
|
{
|
|
4666
4808
|
cause,
|
|
4667
4809
|
commitState: "not-committed",
|
|
4668
|
-
eventId:
|
|
4810
|
+
eventId: batch
|
|
4811
|
+
? safeInputs.map((entry) => safeOwnDataValue(entry, "eventId"))[0]
|
|
4812
|
+
: safeOwnDataValue(safeInputs[0], "eventId"),
|
|
4669
4813
|
},
|
|
4670
4814
|
);
|
|
4671
4815
|
}
|