@longarc/mdash 3.1.1 → 3.1.3
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 +86 -23
- package/SECURITY.md +254 -0
- package/dist/accountability/engine.d.ts +27 -0
- package/dist/accountability/engine.d.ts.map +1 -0
- package/dist/accountability/engine.js +148 -0
- package/dist/accountability/engine.js.map +1 -0
- package/dist/accountability/types.d.ts +46 -0
- package/dist/accountability/types.d.ts.map +1 -0
- package/dist/accountability/types.js +8 -0
- package/dist/accountability/types.js.map +1 -0
- package/dist/checkpoint/engine.d.ts +2 -2
- package/dist/checkpoint/engine.d.ts.map +1 -1
- package/dist/checkpoint/engine.js +5 -1
- package/dist/checkpoint/engine.js.map +1 -1
- package/dist/context/compose.d.ts +62 -0
- package/dist/context/compose.d.ts.map +1 -0
- package/dist/context/compose.js +286 -0
- package/dist/context/compose.js.map +1 -0
- package/dist/context/crypto/hash.d.ts +100 -0
- package/dist/context/crypto/hash.d.ts.map +1 -0
- package/dist/context/crypto/hash.js +248 -0
- package/dist/context/crypto/hash.js.map +1 -0
- package/dist/context/crypto/hmac.d.ts +80 -0
- package/dist/context/crypto/hmac.d.ts.map +1 -0
- package/dist/context/crypto/hmac.js +192 -0
- package/dist/context/crypto/hmac.js.map +1 -0
- package/dist/context/crypto/index.d.ts +7 -0
- package/dist/context/crypto/index.d.ts.map +1 -0
- package/dist/context/crypto/index.js +7 -0
- package/dist/context/crypto/index.js.map +1 -0
- package/dist/context/engine-v3.0-backup.d.ts +197 -0
- package/dist/context/engine-v3.0-backup.d.ts.map +1 -0
- package/dist/context/engine-v3.0-backup.js +392 -0
- package/dist/context/engine-v3.0-backup.js.map +1 -0
- package/dist/context/engine.d.ts +2 -2
- package/dist/context/engine.d.ts.map +1 -1
- package/dist/context/engine.js +2 -2
- package/dist/context/engine.js.map +1 -1
- package/dist/context/fragment.d.ts +99 -0
- package/dist/context/fragment.d.ts.map +1 -0
- package/dist/context/fragment.js +316 -0
- package/dist/context/fragment.js.map +1 -0
- package/dist/context/index.d.ts +99 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +180 -0
- package/dist/context/index.js.map +1 -0
- package/dist/context/provenance.d.ts +80 -0
- package/dist/context/provenance.d.ts.map +1 -0
- package/dist/context/provenance.js +294 -0
- package/dist/context/provenance.js.map +1 -0
- package/dist/context/resolve.d.ts +106 -0
- package/dist/context/resolve.d.ts.map +1 -0
- package/dist/context/resolve.js +440 -0
- package/dist/context/resolve.js.map +1 -0
- package/dist/context/store.d.ts +156 -0
- package/dist/context/store.d.ts.map +1 -0
- package/dist/context/store.js +396 -0
- package/dist/context/store.js.map +1 -0
- package/dist/context/types.d.ts +463 -0
- package/dist/context/types.d.ts.map +1 -0
- package/dist/context/types.js +94 -0
- package/dist/context/types.js.map +1 -0
- package/dist/context/utils/atomic.d.ts +76 -0
- package/dist/context/utils/atomic.d.ts.map +1 -0
- package/dist/context/utils/atomic.js +159 -0
- package/dist/context/utils/atomic.js.map +1 -0
- package/dist/context/utils/credit.d.ts +65 -0
- package/dist/context/utils/credit.d.ts.map +1 -0
- package/dist/context/utils/credit.js +164 -0
- package/dist/context/utils/credit.js.map +1 -0
- package/dist/context/utils/index.d.ts +13 -0
- package/dist/context/utils/index.d.ts.map +1 -0
- package/dist/context/utils/index.js +13 -0
- package/dist/context/utils/index.js.map +1 -0
- package/dist/context/utils/utility.d.ts +63 -0
- package/dist/context/utils/utility.d.ts.map +1 -0
- package/dist/context/utils/utility.js +141 -0
- package/dist/context/utils/utility.js.map +1 -0
- package/dist/core/commitment.d.ts +26 -3
- package/dist/core/commitment.d.ts.map +1 -1
- package/dist/core/commitment.js +45 -7
- package/dist/core/commitment.js.map +1 -1
- package/dist/core/crypto.d.ts +2 -0
- package/dist/core/crypto.d.ts.map +1 -1
- package/dist/core/crypto.js +12 -0
- package/dist/core/crypto.js.map +1 -1
- package/dist/index.d.ts +11 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +35 -10
- package/dist/index.js.map +1 -1
- package/dist/mcca/engine.d.ts.map +1 -1
- package/dist/mcca/engine.js +5 -4
- package/dist/mcca/engine.js.map +1 -1
- package/dist/physics/engine.d.ts +3 -2
- package/dist/physics/engine.d.ts.map +1 -1
- package/dist/physics/engine.js +37 -3
- package/dist/physics/engine.js.map +1 -1
- package/dist/provenance/api-handler.d.ts +45 -0
- package/dist/provenance/api-handler.d.ts.map +1 -0
- package/dist/provenance/api-handler.js +223 -0
- package/dist/provenance/api-handler.js.map +1 -0
- package/dist/provenance/api-types.d.ts +108 -0
- package/dist/provenance/api-types.d.ts.map +1 -0
- package/dist/provenance/api-types.js +9 -0
- package/dist/provenance/api-types.js.map +1 -0
- package/dist/provenance/index.d.ts +6 -0
- package/dist/provenance/index.d.ts.map +1 -0
- package/dist/provenance/index.js +3 -0
- package/dist/provenance/index.js.map +1 -0
- package/dist/provenance/provenance-engine.d.ts +63 -0
- package/dist/provenance/provenance-engine.d.ts.map +1 -0
- package/dist/provenance/provenance-engine.js +311 -0
- package/dist/provenance/provenance-engine.js.map +1 -0
- package/dist/provenance/types.d.ts +193 -0
- package/dist/provenance/types.d.ts.map +1 -0
- package/dist/provenance/types.js +9 -0
- package/dist/provenance/types.js.map +1 -0
- package/dist/tee/engine.d.ts.map +1 -1
- package/dist/tee/engine.js +14 -0
- package/dist/tee/engine.js.map +1 -1
- package/dist/warrant/engine.d.ts +24 -1
- package/dist/warrant/engine.d.ts.map +1 -1
- package/dist/warrant/engine.js +76 -1
- package/dist/warrant/engine.js.map +1 -1
- package/dist/zk/engine.d.ts.map +1 -1
- package/dist/zk/engine.js +7 -4
- package/dist/zk/engine.js.map +1 -1
- package/docs/SECURITY-PATCHES.md +170 -0
- package/package.json +17 -5
- package/src/__tests__/accountability.test.ts +308 -0
- package/src/__tests__/l1-verification-modes.test.ts +424 -0
- package/src/__tests__/phase1.benchmark.test.ts +94 -0
- package/src/__tests__/phase1.test.ts +0 -77
- package/src/__tests__/phase2-4.benchmark.test.ts +60 -0
- package/src/__tests__/phase2-4.test.ts +1 -52
- package/src/__tests__/provenance/api-handler.test.ts +356 -0
- package/src/__tests__/provenance/provenance-engine.test.ts +628 -0
- package/src/__tests__/sa-2026-008.test.ts +45 -0
- package/src/__tests__/sa-2026-009.test.ts +86 -0
- package/src/__tests__/sa-2026-010.test.ts +72 -0
- package/src/__tests__/sa-2026-012.test.ts +65 -0
- package/src/__tests__/sa-2026-nfc.test.ts +40 -0
- package/src/__tests__/security.test.ts +786 -0
- package/src/accountability/engine.ts +230 -0
- package/src/accountability/types.ts +58 -0
- package/src/checkpoint/engine.ts +6 -2
- package/src/context/__tests__/caret-v0.2.0.test.ts +860 -0
- package/src/context/__tests__/integration.test.ts +356 -0
- package/src/context/compose.ts +388 -0
- package/src/context/crypto/hash.ts +277 -0
- package/src/context/crypto/hmac.ts +253 -0
- package/src/context/crypto/index.ts +29 -0
- package/src/context/engine-v3.0-backup.ts +598 -0
- package/src/context/engine.ts +2 -2
- package/src/context/fragment.ts +454 -0
- package/src/context/index.ts +427 -0
- package/src/context/provenance.ts +380 -0
- package/src/context/resolve.ts +581 -0
- package/src/context/store.ts +503 -0
- package/src/context/types.ts +679 -0
- package/src/context/utils/atomic.ts +207 -0
- package/src/context/utils/credit.ts +224 -0
- package/src/context/utils/index.ts +13 -0
- package/src/context/utils/utility.ts +200 -0
- package/src/core/commitment.ts +130 -68
- package/src/core/crypto.ts +13 -0
- package/src/index.ts +62 -10
- package/src/mcca/engine.ts +5 -4
- package/src/physics/engine.ts +42 -5
- package/src/provenance/api-handler.ts +248 -0
- package/src/provenance/api-types.ts +112 -0
- package/src/provenance/index.ts +19 -0
- package/src/provenance/provenance-engine.ts +387 -0
- package/src/provenance/types.ts +211 -0
- package/src/tee/engine.ts +16 -0
- package/src/warrant/engine.ts +89 -1
- package/src/zk/engine.ts +8 -4
- package/tsconfig.json +1 -1
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mdash v3.1 — AccountabilityEngine
|
|
3
|
+
*
|
|
4
|
+
* Unified consumer API: warrants + commitments in one class.
|
|
5
|
+
* Composes CommitmentEngine (attestation) and WarrantEngine (warrant lifecycle).
|
|
6
|
+
*
|
|
7
|
+
* Consumer story: import { AccountabilityEngine } from '@longarc/mdash'
|
|
8
|
+
* One class, full accountability lifecycle.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { CommitmentEngine } from '../core/commitment.js';
|
|
12
|
+
import type { Commitment } from '../core/commitment.js';
|
|
13
|
+
import { WarrantEngine } from '../warrant/engine.js';
|
|
14
|
+
import type { WarrantId } from '../core/crypto.js';
|
|
15
|
+
import type {
|
|
16
|
+
WarrantPermissions,
|
|
17
|
+
Violation,
|
|
18
|
+
ViolationType,
|
|
19
|
+
ActionResult,
|
|
20
|
+
AuditRecord,
|
|
21
|
+
AuditSummary,
|
|
22
|
+
} from './types.js';
|
|
23
|
+
|
|
24
|
+
interface ManagedWarrant {
|
|
25
|
+
agentId: string;
|
|
26
|
+
permissions: WarrantPermissions;
|
|
27
|
+
issuedAt: number;
|
|
28
|
+
status: 'ACTIVE' | 'EXPIRED' | 'REVOKED';
|
|
29
|
+
executionCount: number;
|
|
30
|
+
infraWarrantId: WarrantId;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export class AccountabilityEngine {
|
|
34
|
+
private commitmentEngine: CommitmentEngine;
|
|
35
|
+
private warrantEngine: WarrantEngine;
|
|
36
|
+
private managedWarrants: Map<string, ManagedWarrant> = new Map();
|
|
37
|
+
private auditLog: AuditRecord[] = [];
|
|
38
|
+
private actionCounters: Map<string, number> = new Map();
|
|
39
|
+
|
|
40
|
+
constructor() {
|
|
41
|
+
this.commitmentEngine = new CommitmentEngine();
|
|
42
|
+
this.warrantEngine = new WarrantEngine(this.commitmentEngine);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async initialize(sealKey: string): Promise<void> {
|
|
46
|
+
await this.commitmentEngine.initialize(sealKey);
|
|
47
|
+
await this.warrantEngine.initialize(sealKey);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async issueWarrant(agentId: string, permissions: WarrantPermissions): Promise<void> {
|
|
51
|
+
// Create a crypto-sealed infrastructure warrant via WarrantEngine
|
|
52
|
+
const speculative = await this.warrantEngine.createSpeculative({
|
|
53
|
+
agent_id: agentId,
|
|
54
|
+
policy_id: 'accountability-default',
|
|
55
|
+
tier: 'T1',
|
|
56
|
+
constraints: {
|
|
57
|
+
maxCalls: permissions.maxExecutions,
|
|
58
|
+
},
|
|
59
|
+
duration_ms: permissions.ttlMs,
|
|
60
|
+
issued_by: 'accountability-engine',
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// Activate immediately — consumer warrants are active on issuance
|
|
64
|
+
const activated = await this.warrantEngine.activate(speculative.id);
|
|
65
|
+
|
|
66
|
+
this.managedWarrants.set(agentId, {
|
|
67
|
+
agentId,
|
|
68
|
+
permissions,
|
|
69
|
+
issuedAt: Date.now(),
|
|
70
|
+
status: 'ACTIVE',
|
|
71
|
+
executionCount: 0,
|
|
72
|
+
infraWarrantId: activated.id,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
revokeWarrant(agentId: string): void {
|
|
77
|
+
const managed = this.managedWarrants.get(agentId);
|
|
78
|
+
if (!managed) return;
|
|
79
|
+
|
|
80
|
+
managed.status = 'REVOKED';
|
|
81
|
+
|
|
82
|
+
// Best-effort infrastructure-level revocation (fire-and-forget)
|
|
83
|
+
this.warrantEngine
|
|
84
|
+
.revoke(managed.infraWarrantId, 'Consumer API revocation', {
|
|
85
|
+
type: 'system',
|
|
86
|
+
id: 'accountability-engine',
|
|
87
|
+
})
|
|
88
|
+
.catch(() => {
|
|
89
|
+
// Infra warrant may have already expired from cache — local state is authoritative
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async executeAction(
|
|
94
|
+
agentId: string,
|
|
95
|
+
action: string,
|
|
96
|
+
params: unknown,
|
|
97
|
+
): Promise<ActionResult> {
|
|
98
|
+
const managed = this.managedWarrants.get(agentId);
|
|
99
|
+
|
|
100
|
+
// No warrant issued for this agent
|
|
101
|
+
if (!managed) {
|
|
102
|
+
return this.deny(agentId, action, 'NO_WARRANT', `No warrant found for agent '${agentId}'`);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Check infrastructure-level revocation (propagates across caches)
|
|
106
|
+
if (this.warrantEngine.isRevoked(managed.infraWarrantId)) {
|
|
107
|
+
managed.status = 'REVOKED';
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Revoked
|
|
111
|
+
if (managed.status === 'REVOKED') {
|
|
112
|
+
return this.deny(
|
|
113
|
+
agentId, action, 'WARRANT_REVOKED',
|
|
114
|
+
`Warrant for agent '${agentId}' has been revoked`,
|
|
115
|
+
managed.infraWarrantId,
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Expired
|
|
120
|
+
if (Date.now() - managed.issuedAt > managed.permissions.ttlMs) {
|
|
121
|
+
managed.status = 'EXPIRED';
|
|
122
|
+
return this.deny(
|
|
123
|
+
agentId, action, 'WARRANT_EXPIRED',
|
|
124
|
+
`Warrant for agent '${agentId}' has expired`,
|
|
125
|
+
managed.infraWarrantId,
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Execution limit
|
|
130
|
+
if (
|
|
131
|
+
managed.permissions.maxExecutions !== undefined &&
|
|
132
|
+
managed.executionCount >= managed.permissions.maxExecutions
|
|
133
|
+
) {
|
|
134
|
+
return this.deny(
|
|
135
|
+
agentId, action, 'EXECUTION_LIMIT_REACHED',
|
|
136
|
+
`Agent '${agentId}' has reached execution limit of ${managed.permissions.maxExecutions}`,
|
|
137
|
+
managed.infraWarrantId,
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Forbidden action (explicit deny takes precedence)
|
|
142
|
+
if (managed.permissions.forbiddenActions.includes(action)) {
|
|
143
|
+
return this.deny(
|
|
144
|
+
agentId, action, 'FORBIDDEN_ACTION',
|
|
145
|
+
`Action '${action}' is explicitly forbidden for agent '${agentId}'`,
|
|
146
|
+
managed.infraWarrantId,
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Not in allowed list
|
|
151
|
+
if (!managed.permissions.allowedActions.includes(action)) {
|
|
152
|
+
return this.deny(
|
|
153
|
+
agentId, action, 'UNAUTHORIZED_ACTION',
|
|
154
|
+
`Action '${action}' is not in the allowed list for agent '${agentId}'`,
|
|
155
|
+
managed.infraWarrantId,
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// ── AUTHORIZED — commit attestation ──
|
|
160
|
+
|
|
161
|
+
managed.executionCount++;
|
|
162
|
+
|
|
163
|
+
const count = (this.actionCounters.get(agentId) || 0) + 1;
|
|
164
|
+
this.actionCounters.set(agentId, count);
|
|
165
|
+
const commitId = `${agentId}-action-${count}`;
|
|
166
|
+
|
|
167
|
+
const commitment = await this.commitmentEngine.commit(
|
|
168
|
+
{ agentId, action, params, timestamp: Date.now() },
|
|
169
|
+
commitId,
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
const verified = await this.commitmentEngine.verify(commitment);
|
|
173
|
+
|
|
174
|
+
this.auditLog.push({
|
|
175
|
+
type: 'ATTESTED_ACTION',
|
|
176
|
+
agentId,
|
|
177
|
+
action,
|
|
178
|
+
timestamp: Date.now(),
|
|
179
|
+
commitId,
|
|
180
|
+
contentHash: commitment.content_hash,
|
|
181
|
+
verified,
|
|
182
|
+
warrantId: managed.infraWarrantId,
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
return { executed: true, commitment, verified };
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
getAuditSummary(): AuditSummary {
|
|
189
|
+
const authorized = this.auditLog.filter(r => r.type === 'ATTESTED_ACTION').length;
|
|
190
|
+
const denied = this.auditLog.filter(r => r.type !== 'ATTESTED_ACTION').length;
|
|
191
|
+
return {
|
|
192
|
+
total: this.auditLog.length,
|
|
193
|
+
authorized,
|
|
194
|
+
denied,
|
|
195
|
+
log: [...this.auditLog],
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
async verifyCommitment(commitment: Commitment): Promise<boolean> {
|
|
200
|
+
return this.commitmentEngine.verify(commitment);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
private deny(
|
|
204
|
+
agentId: string,
|
|
205
|
+
action: string,
|
|
206
|
+
type: ViolationType,
|
|
207
|
+
detail: string,
|
|
208
|
+
warrantId?: WarrantId,
|
|
209
|
+
): ActionResult {
|
|
210
|
+
const violation: Violation = {
|
|
211
|
+
type,
|
|
212
|
+
agentId,
|
|
213
|
+
action,
|
|
214
|
+
timestamp: Date.now(),
|
|
215
|
+
detail,
|
|
216
|
+
warrantId,
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
this.auditLog.push({
|
|
220
|
+
type,
|
|
221
|
+
agentId,
|
|
222
|
+
action,
|
|
223
|
+
timestamp: Date.now(),
|
|
224
|
+
detail,
|
|
225
|
+
warrantId,
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
return { executed: false, violation };
|
|
229
|
+
}
|
|
230
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mdash v3.1 — Accountability Engine Types
|
|
3
|
+
*
|
|
4
|
+
* Consumer-facing types for the unified accountability API.
|
|
5
|
+
* Warrants + Commitments in a single lifecycle.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { Commitment } from '../core/commitment.js';
|
|
9
|
+
|
|
10
|
+
export interface WarrantPermissions {
|
|
11
|
+
allowedActions: string[];
|
|
12
|
+
forbiddenActions: string[];
|
|
13
|
+
ttlMs: number;
|
|
14
|
+
maxExecutions?: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type ViolationType =
|
|
18
|
+
| 'FORBIDDEN_ACTION'
|
|
19
|
+
| 'UNAUTHORIZED_ACTION'
|
|
20
|
+
| 'WARRANT_EXPIRED'
|
|
21
|
+
| 'WARRANT_REVOKED'
|
|
22
|
+
| 'EXECUTION_LIMIT_REACHED'
|
|
23
|
+
| 'NO_WARRANT';
|
|
24
|
+
|
|
25
|
+
export interface Violation {
|
|
26
|
+
type: ViolationType;
|
|
27
|
+
agentId: string;
|
|
28
|
+
action: string;
|
|
29
|
+
timestamp: number;
|
|
30
|
+
detail: string;
|
|
31
|
+
warrantId?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface ActionResult {
|
|
35
|
+
executed: boolean;
|
|
36
|
+
commitment?: Commitment;
|
|
37
|
+
verified?: boolean;
|
|
38
|
+
violation?: Violation;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface AuditRecord {
|
|
42
|
+
type: 'ATTESTED_ACTION' | ViolationType;
|
|
43
|
+
agentId: string;
|
|
44
|
+
action: string;
|
|
45
|
+
timestamp: number;
|
|
46
|
+
commitId?: string;
|
|
47
|
+
contentHash?: string;
|
|
48
|
+
verified?: boolean;
|
|
49
|
+
detail?: string;
|
|
50
|
+
warrantId?: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface AuditSummary {
|
|
54
|
+
total: number;
|
|
55
|
+
authorized: number;
|
|
56
|
+
denied: number;
|
|
57
|
+
log: AuditRecord[];
|
|
58
|
+
}
|
package/src/checkpoint/engine.ts
CHANGED
|
@@ -23,9 +23,9 @@ import {
|
|
|
23
23
|
hmacSeal,
|
|
24
24
|
hmacVerify,
|
|
25
25
|
deriveKey,
|
|
26
|
-
} from '../core/crypto';
|
|
26
|
+
} from '../core/crypto.js';
|
|
27
27
|
|
|
28
|
-
import { CommitmentEngine } from '../core/commitment';
|
|
28
|
+
import { CommitmentEngine } from '../core/commitment.js';
|
|
29
29
|
|
|
30
30
|
// ============================================================================
|
|
31
31
|
// CHECKPOINT TYPES
|
|
@@ -315,6 +315,10 @@ export class CheckpointEngine {
|
|
|
315
315
|
this.commitmentEngine.commit(checkpoint, commitmentId).then(() => {
|
|
316
316
|
checkpoint.commitment_id = commitmentId;
|
|
317
317
|
checkpoint.status = 'sealed';
|
|
318
|
+
}).catch((error) => {
|
|
319
|
+
// SA-2026-010: Log commitment failures instead of silently swallowing
|
|
320
|
+
checkpoint.status = 'failed';
|
|
321
|
+
console.error(`[Checkpoint] L1 commit failed for ${id}: ${error}`);
|
|
318
322
|
});
|
|
319
323
|
|
|
320
324
|
// Store and index
|