@longarc/mdash 3.1.2 → 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.
Files changed (172) hide show
  1. package/README.md +86 -23
  2. package/SECURITY.md +254 -0
  3. package/dist/accountability/engine.d.ts +27 -0
  4. package/dist/accountability/engine.d.ts.map +1 -0
  5. package/dist/accountability/engine.js +148 -0
  6. package/dist/accountability/engine.js.map +1 -0
  7. package/dist/accountability/types.d.ts +46 -0
  8. package/dist/accountability/types.d.ts.map +1 -0
  9. package/dist/accountability/types.js +8 -0
  10. package/dist/accountability/types.js.map +1 -0
  11. package/dist/checkpoint/engine.d.ts.map +1 -1
  12. package/dist/checkpoint/engine.js +4 -0
  13. package/dist/checkpoint/engine.js.map +1 -1
  14. package/dist/context/compose.d.ts +62 -0
  15. package/dist/context/compose.d.ts.map +1 -0
  16. package/dist/context/compose.js +286 -0
  17. package/dist/context/compose.js.map +1 -0
  18. package/dist/context/crypto/hash.d.ts +100 -0
  19. package/dist/context/crypto/hash.d.ts.map +1 -0
  20. package/dist/context/crypto/hash.js +248 -0
  21. package/dist/context/crypto/hash.js.map +1 -0
  22. package/dist/context/crypto/hmac.d.ts +80 -0
  23. package/dist/context/crypto/hmac.d.ts.map +1 -0
  24. package/dist/context/crypto/hmac.js +192 -0
  25. package/dist/context/crypto/hmac.js.map +1 -0
  26. package/dist/context/crypto/index.d.ts +7 -0
  27. package/dist/context/crypto/index.d.ts.map +1 -0
  28. package/dist/context/crypto/index.js +7 -0
  29. package/dist/context/crypto/index.js.map +1 -0
  30. package/dist/context/engine-v3.0-backup.d.ts +197 -0
  31. package/dist/context/engine-v3.0-backup.d.ts.map +1 -0
  32. package/dist/context/engine-v3.0-backup.js +392 -0
  33. package/dist/context/engine-v3.0-backup.js.map +1 -0
  34. package/dist/context/fragment.d.ts +99 -0
  35. package/dist/context/fragment.d.ts.map +1 -0
  36. package/dist/context/fragment.js +316 -0
  37. package/dist/context/fragment.js.map +1 -0
  38. package/dist/context/index.d.ts +99 -0
  39. package/dist/context/index.d.ts.map +1 -0
  40. package/dist/context/index.js +180 -0
  41. package/dist/context/index.js.map +1 -0
  42. package/dist/context/provenance.d.ts +80 -0
  43. package/dist/context/provenance.d.ts.map +1 -0
  44. package/dist/context/provenance.js +294 -0
  45. package/dist/context/provenance.js.map +1 -0
  46. package/dist/context/resolve.d.ts +106 -0
  47. package/dist/context/resolve.d.ts.map +1 -0
  48. package/dist/context/resolve.js +440 -0
  49. package/dist/context/resolve.js.map +1 -0
  50. package/dist/context/store.d.ts +156 -0
  51. package/dist/context/store.d.ts.map +1 -0
  52. package/dist/context/store.js +396 -0
  53. package/dist/context/store.js.map +1 -0
  54. package/dist/context/types.d.ts +463 -0
  55. package/dist/context/types.d.ts.map +1 -0
  56. package/dist/context/types.js +94 -0
  57. package/dist/context/types.js.map +1 -0
  58. package/dist/context/utils/atomic.d.ts +76 -0
  59. package/dist/context/utils/atomic.d.ts.map +1 -0
  60. package/dist/context/utils/atomic.js +159 -0
  61. package/dist/context/utils/atomic.js.map +1 -0
  62. package/dist/context/utils/credit.d.ts +65 -0
  63. package/dist/context/utils/credit.d.ts.map +1 -0
  64. package/dist/context/utils/credit.js +164 -0
  65. package/dist/context/utils/credit.js.map +1 -0
  66. package/dist/context/utils/index.d.ts +13 -0
  67. package/dist/context/utils/index.d.ts.map +1 -0
  68. package/dist/context/utils/index.js +13 -0
  69. package/dist/context/utils/index.js.map +1 -0
  70. package/dist/context/utils/utility.d.ts +63 -0
  71. package/dist/context/utils/utility.d.ts.map +1 -0
  72. package/dist/context/utils/utility.js +141 -0
  73. package/dist/context/utils/utility.js.map +1 -0
  74. package/dist/core/commitment.d.ts +25 -2
  75. package/dist/core/commitment.d.ts.map +1 -1
  76. package/dist/core/commitment.js +44 -6
  77. package/dist/core/commitment.js.map +1 -1
  78. package/dist/core/crypto.d.ts +2 -0
  79. package/dist/core/crypto.d.ts.map +1 -1
  80. package/dist/core/crypto.js +12 -0
  81. package/dist/core/crypto.js.map +1 -1
  82. package/dist/index.d.ts +11 -6
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +35 -10
  85. package/dist/index.js.map +1 -1
  86. package/dist/mcca/engine.d.ts.map +1 -1
  87. package/dist/mcca/engine.js +5 -4
  88. package/dist/mcca/engine.js.map +1 -1
  89. package/dist/physics/engine.d.ts +1 -0
  90. package/dist/physics/engine.d.ts.map +1 -1
  91. package/dist/physics/engine.js +36 -2
  92. package/dist/physics/engine.js.map +1 -1
  93. package/dist/provenance/api-handler.d.ts +45 -0
  94. package/dist/provenance/api-handler.d.ts.map +1 -0
  95. package/dist/provenance/api-handler.js +223 -0
  96. package/dist/provenance/api-handler.js.map +1 -0
  97. package/dist/provenance/api-types.d.ts +108 -0
  98. package/dist/provenance/api-types.d.ts.map +1 -0
  99. package/dist/provenance/api-types.js +9 -0
  100. package/dist/provenance/api-types.js.map +1 -0
  101. package/dist/provenance/index.d.ts +6 -0
  102. package/dist/provenance/index.d.ts.map +1 -0
  103. package/dist/provenance/index.js +3 -0
  104. package/dist/provenance/index.js.map +1 -0
  105. package/dist/provenance/provenance-engine.d.ts +63 -0
  106. package/dist/provenance/provenance-engine.d.ts.map +1 -0
  107. package/dist/provenance/provenance-engine.js +311 -0
  108. package/dist/provenance/provenance-engine.js.map +1 -0
  109. package/dist/provenance/types.d.ts +193 -0
  110. package/dist/provenance/types.d.ts.map +1 -0
  111. package/dist/provenance/types.js +9 -0
  112. package/dist/provenance/types.js.map +1 -0
  113. package/dist/tee/engine.d.ts.map +1 -1
  114. package/dist/tee/engine.js +14 -0
  115. package/dist/tee/engine.js.map +1 -1
  116. package/dist/warrant/engine.d.ts +24 -1
  117. package/dist/warrant/engine.d.ts.map +1 -1
  118. package/dist/warrant/engine.js +76 -1
  119. package/dist/warrant/engine.js.map +1 -1
  120. package/dist/zk/engine.d.ts.map +1 -1
  121. package/dist/zk/engine.js +7 -4
  122. package/dist/zk/engine.js.map +1 -1
  123. package/docs/SECURITY-PATCHES.md +170 -0
  124. package/package.json +17 -5
  125. package/src/__tests__/accountability.test.ts +308 -0
  126. package/src/__tests__/l1-verification-modes.test.ts +424 -0
  127. package/src/__tests__/phase1.benchmark.test.ts +94 -0
  128. package/src/__tests__/phase1.test.ts +0 -77
  129. package/src/__tests__/phase2-4.benchmark.test.ts +60 -0
  130. package/src/__tests__/phase2-4.test.ts +1 -52
  131. package/src/__tests__/provenance/api-handler.test.ts +356 -0
  132. package/src/__tests__/provenance/provenance-engine.test.ts +628 -0
  133. package/src/__tests__/sa-2026-008.test.ts +45 -0
  134. package/src/__tests__/sa-2026-009.test.ts +86 -0
  135. package/src/__tests__/sa-2026-010.test.ts +72 -0
  136. package/src/__tests__/sa-2026-012.test.ts +65 -0
  137. package/src/__tests__/sa-2026-nfc.test.ts +40 -0
  138. package/src/__tests__/security.test.ts +786 -0
  139. package/src/accountability/engine.ts +230 -0
  140. package/src/accountability/types.ts +58 -0
  141. package/src/checkpoint/engine.ts +4 -0
  142. package/src/context/__tests__/caret-v0.2.0.test.ts +860 -0
  143. package/src/context/__tests__/integration.test.ts +356 -0
  144. package/src/context/compose.ts +388 -0
  145. package/src/context/crypto/hash.ts +277 -0
  146. package/src/context/crypto/hmac.ts +253 -0
  147. package/src/context/crypto/index.ts +29 -0
  148. package/src/context/engine-v3.0-backup.ts +598 -0
  149. package/src/context/fragment.ts +454 -0
  150. package/src/context/index.ts +427 -0
  151. package/src/context/provenance.ts +380 -0
  152. package/src/context/resolve.ts +581 -0
  153. package/src/context/store.ts +503 -0
  154. package/src/context/types.ts +679 -0
  155. package/src/context/utils/atomic.ts +207 -0
  156. package/src/context/utils/credit.ts +224 -0
  157. package/src/context/utils/index.ts +13 -0
  158. package/src/context/utils/utility.ts +200 -0
  159. package/src/core/commitment.ts +129 -67
  160. package/src/core/crypto.ts +13 -0
  161. package/src/index.ts +62 -10
  162. package/src/mcca/engine.ts +5 -4
  163. package/src/physics/engine.ts +40 -3
  164. package/src/provenance/api-handler.ts +248 -0
  165. package/src/provenance/api-types.ts +112 -0
  166. package/src/provenance/index.ts +19 -0
  167. package/src/provenance/provenance-engine.ts +387 -0
  168. package/src/provenance/types.ts +211 -0
  169. package/src/tee/engine.ts +16 -0
  170. package/src/warrant/engine.ts +89 -1
  171. package/src/zk/engine.ts +8 -4
  172. package/tsconfig.json +1 -1
@@ -0,0 +1,308 @@
1
+ /**
2
+ * AccountabilityEngine Test Suite
3
+ *
4
+ * Full lifecycle: issue warrant → check action → commit attestation → verify
5
+ */
6
+
7
+ import { describe, it, expect, beforeEach } from 'vitest';
8
+ import { AccountabilityEngine } from '../accountability/engine.js';
9
+ import type { WarrantPermissions } from '../accountability/types.js';
10
+
11
+ const SEAL_KEY = 'test-seal-key-minimum-32-characters-long';
12
+
13
+ const DEFAULT_PERMISSIONS: WarrantPermissions = {
14
+ allowedActions: ['read', 'write', 'query'],
15
+ forbiddenActions: ['delete', 'drop-table'],
16
+ ttlMs: 60_000,
17
+ };
18
+
19
+ describe('AccountabilityEngine', () => {
20
+ let engine: AccountabilityEngine;
21
+
22
+ beforeEach(async () => {
23
+ engine = new AccountabilityEngine();
24
+ await engine.initialize(SEAL_KEY);
25
+ });
26
+
27
+ // ── Authorization ──
28
+
29
+ it('should execute authorized actions with cryptographic attestation', async () => {
30
+ await engine.issueWarrant('agent-1', DEFAULT_PERMISSIONS);
31
+
32
+ const result = await engine.executeAction('agent-1', 'read', { file: 'data.csv' });
33
+
34
+ expect(result.executed).toBe(true);
35
+ expect(result.commitment).toBeDefined();
36
+ expect(result.commitment!.content_hash).toBeTruthy();
37
+ expect(result.commitment!.seal).toBeTruthy();
38
+ expect(result.verified).toBe(true);
39
+ expect(result.violation).toBeUndefined();
40
+ });
41
+
42
+ it('should verify commitment seals are cryptographically valid', async () => {
43
+ await engine.issueWarrant('agent-1', DEFAULT_PERMISSIONS);
44
+ const result = await engine.executeAction('agent-1', 'read', {});
45
+
46
+ const valid = await engine.verifyCommitment(result.commitment!);
47
+ expect(valid).toBe(true);
48
+ });
49
+
50
+ it('should handle multiple authorized actions with distinct commitments', async () => {
51
+ await engine.issueWarrant('agent-1', DEFAULT_PERMISSIONS);
52
+
53
+ const r1 = await engine.executeAction('agent-1', 'read', { id: 1 });
54
+ const r2 = await engine.executeAction('agent-1', 'write', { id: 2 });
55
+ const r3 = await engine.executeAction('agent-1', 'query', { sql: 'SELECT 1' });
56
+
57
+ expect(r1.executed).toBe(true);
58
+ expect(r2.executed).toBe(true);
59
+ expect(r3.executed).toBe(true);
60
+
61
+ // Each gets a unique commitment
62
+ expect(r1.commitment!.id).not.toBe(r2.commitment!.id);
63
+ expect(r2.commitment!.id).not.toBe(r3.commitment!.id);
64
+ });
65
+
66
+ // ── Denial: Forbidden Actions ──
67
+
68
+ it('should deny forbidden actions with typed violation', async () => {
69
+ await engine.issueWarrant('agent-1', DEFAULT_PERMISSIONS);
70
+
71
+ const result = await engine.executeAction('agent-1', 'delete', { target: 'users' });
72
+
73
+ expect(result.executed).toBe(false);
74
+ expect(result.violation).toBeDefined();
75
+ expect(result.violation!.type).toBe('FORBIDDEN_ACTION');
76
+ expect(result.violation!.agentId).toBe('agent-1');
77
+ expect(result.violation!.action).toBe('delete');
78
+ expect(result.commitment).toBeUndefined();
79
+ });
80
+
81
+ it('should deny forbidden actions even if also in allowed list', async () => {
82
+ // Forbidden takes precedence
83
+ await engine.issueWarrant('agent-1', {
84
+ allowedActions: ['delete'],
85
+ forbiddenActions: ['delete'],
86
+ ttlMs: 60_000,
87
+ });
88
+
89
+ const result = await engine.executeAction('agent-1', 'delete', {});
90
+ expect(result.executed).toBe(false);
91
+ expect(result.violation!.type).toBe('FORBIDDEN_ACTION');
92
+ });
93
+
94
+ // ── Denial: Unauthorized Actions ──
95
+
96
+ it('should deny actions not in the allowed list', async () => {
97
+ await engine.issueWarrant('agent-1', DEFAULT_PERMISSIONS);
98
+
99
+ const result = await engine.executeAction('agent-1', 'execute-shell', { cmd: 'rm -rf /' });
100
+
101
+ expect(result.executed).toBe(false);
102
+ expect(result.violation!.type).toBe('UNAUTHORIZED_ACTION');
103
+ });
104
+
105
+ // ── Denial: No Warrant ──
106
+
107
+ it('should deny actions from agents with no warrant', async () => {
108
+ const result = await engine.executeAction('unknown-agent', 'read', {});
109
+
110
+ expect(result.executed).toBe(false);
111
+ expect(result.violation!.type).toBe('NO_WARRANT');
112
+ expect(result.violation!.agentId).toBe('unknown-agent');
113
+ });
114
+
115
+ // ── Denial: Expired Warrants ──
116
+
117
+ it('should deny actions when warrant has expired', async () => {
118
+ await engine.issueWarrant('agent-1', {
119
+ allowedActions: ['read'],
120
+ forbiddenActions: [],
121
+ ttlMs: 1, // 1ms TTL — will expire immediately
122
+ });
123
+
124
+ // Wait for expiry
125
+ await new Promise(resolve => setTimeout(resolve, 10));
126
+
127
+ const result = await engine.executeAction('agent-1', 'read', {});
128
+
129
+ expect(result.executed).toBe(false);
130
+ expect(result.violation!.type).toBe('WARRANT_EXPIRED');
131
+ });
132
+
133
+ // ── Denial: Revoked Warrants ──
134
+
135
+ it('should deny actions after warrant revocation', async () => {
136
+ await engine.issueWarrant('agent-1', DEFAULT_PERMISSIONS);
137
+
138
+ // Authorized before revocation
139
+ const before = await engine.executeAction('agent-1', 'read', {});
140
+ expect(before.executed).toBe(true);
141
+
142
+ engine.revokeWarrant('agent-1');
143
+
144
+ const after = await engine.executeAction('agent-1', 'read', {});
145
+ expect(after.executed).toBe(false);
146
+ expect(after.violation!.type).toBe('WARRANT_REVOKED');
147
+ });
148
+
149
+ // ── Denial: Execution Limit ──
150
+
151
+ it('should deny actions when execution limit is reached', async () => {
152
+ await engine.issueWarrant('agent-1', {
153
+ allowedActions: ['read'],
154
+ forbiddenActions: [],
155
+ ttlMs: 60_000,
156
+ maxExecutions: 2,
157
+ });
158
+
159
+ const r1 = await engine.executeAction('agent-1', 'read', { n: 1 });
160
+ const r2 = await engine.executeAction('agent-1', 'read', { n: 2 });
161
+ const r3 = await engine.executeAction('agent-1', 'read', { n: 3 });
162
+
163
+ expect(r1.executed).toBe(true);
164
+ expect(r2.executed).toBe(true);
165
+ expect(r3.executed).toBe(false);
166
+ expect(r3.violation!.type).toBe('EXECUTION_LIMIT_REACHED');
167
+ });
168
+
169
+ // ── Audit Trail ──
170
+
171
+ it('should produce correct audit summary', async () => {
172
+ await engine.issueWarrant('agent-1', DEFAULT_PERMISSIONS);
173
+
174
+ await engine.executeAction('agent-1', 'read', {});
175
+ await engine.executeAction('agent-1', 'write', {});
176
+ await engine.executeAction('agent-1', 'delete', {});
177
+ await engine.executeAction('agent-1', 'execute-shell', {});
178
+
179
+ const audit = engine.getAuditSummary();
180
+
181
+ expect(audit.total).toBe(4);
182
+ expect(audit.authorized).toBe(2);
183
+ expect(audit.denied).toBe(2);
184
+ expect(audit.log).toHaveLength(4);
185
+ });
186
+
187
+ it('should include commit details in audit records for attested actions', async () => {
188
+ await engine.issueWarrant('agent-1', DEFAULT_PERMISSIONS);
189
+ await engine.executeAction('agent-1', 'read', { file: 'test.txt' });
190
+
191
+ const audit = engine.getAuditSummary();
192
+ const record = audit.log[0]!;
193
+
194
+ expect(record.type).toBe('ATTESTED_ACTION');
195
+ expect(record.commitId).toBeTruthy();
196
+ expect(record.contentHash).toBeTruthy();
197
+ expect(record.verified).toBe(true);
198
+ expect(record.warrantId).toBeTruthy();
199
+ });
200
+
201
+ it('should include violation details in audit records for denied actions', async () => {
202
+ await engine.issueWarrant('agent-1', DEFAULT_PERMISSIONS);
203
+ await engine.executeAction('agent-1', 'delete', {});
204
+
205
+ const audit = engine.getAuditSummary();
206
+ const record = audit.log[0]!;
207
+
208
+ expect(record.type).toBe('FORBIDDEN_ACTION');
209
+ expect(record.detail).toContain('forbidden');
210
+ expect(record.warrantId).toBeTruthy();
211
+ });
212
+
213
+ // ── Multi-Agent Isolation ──
214
+
215
+ it('should isolate warrants between agents', async () => {
216
+ await engine.issueWarrant('agent-a', {
217
+ allowedActions: ['read'],
218
+ forbiddenActions: ['write'],
219
+ ttlMs: 60_000,
220
+ });
221
+
222
+ await engine.issueWarrant('agent-b', {
223
+ allowedActions: ['write'],
224
+ forbiddenActions: ['read'],
225
+ ttlMs: 60_000,
226
+ });
227
+
228
+ // agent-a can read but not write
229
+ expect((await engine.executeAction('agent-a', 'read', {})).executed).toBe(true);
230
+ expect((await engine.executeAction('agent-a', 'write', {})).executed).toBe(false);
231
+
232
+ // agent-b can write but not read
233
+ expect((await engine.executeAction('agent-b', 'write', {})).executed).toBe(true);
234
+ expect((await engine.executeAction('agent-b', 'read', {})).executed).toBe(false);
235
+ });
236
+
237
+ // ── Full Lifecycle ──
238
+
239
+ it('should support the full lifecycle: issue → execute → deny → revoke → audit', async () => {
240
+ // Issue
241
+ await engine.issueWarrant('lifecycle-agent', {
242
+ allowedActions: ['query-database', 'read-file'],
243
+ forbiddenActions: ['delete-database'],
244
+ ttlMs: 60_000,
245
+ });
246
+
247
+ // Execute authorized
248
+ const authorized = await engine.executeAction('lifecycle-agent', 'query-database', {
249
+ table: 'users',
250
+ limit: 100,
251
+ });
252
+ expect(authorized.executed).toBe(true);
253
+ expect(authorized.verified).toBe(true);
254
+
255
+ // Deny forbidden
256
+ const denied = await engine.executeAction('lifecycle-agent', 'delete-database', {
257
+ target: 'users',
258
+ });
259
+ expect(denied.executed).toBe(false);
260
+ expect(denied.violation!.type).toBe('FORBIDDEN_ACTION');
261
+
262
+ // Revoke
263
+ engine.revokeWarrant('lifecycle-agent');
264
+
265
+ // Deny after revocation
266
+ const postRevoke = await engine.executeAction('lifecycle-agent', 'read-file', {});
267
+ expect(postRevoke.executed).toBe(false);
268
+ expect(postRevoke.violation!.type).toBe('WARRANT_REVOKED');
269
+
270
+ // Audit
271
+ const audit = engine.getAuditSummary();
272
+ expect(audit.authorized).toBe(1);
273
+ expect(audit.denied).toBe(2);
274
+ expect(audit.total).toBe(3);
275
+ });
276
+
277
+ // ── Warrant checks happen BEFORE execution ──
278
+
279
+ it('should check warrant before creating commitment (no partial attestation on denial)', async () => {
280
+ // No warrant — should not create any commitment
281
+ const result = await engine.executeAction('no-warrant-agent', 'read', {});
282
+
283
+ expect(result.executed).toBe(false);
284
+ expect(result.commitment).toBeUndefined();
285
+ expect(result.verified).toBeUndefined();
286
+
287
+ // Audit should have zero attested actions
288
+ const audit = engine.getAuditSummary();
289
+ expect(audit.authorized).toBe(0);
290
+ });
291
+
292
+ // ── Revoking nonexistent warrant is safe ──
293
+
294
+ it('should handle revoking a warrant that does not exist', () => {
295
+ // Should not throw
296
+ expect(() => engine.revokeWarrant('nonexistent-agent')).not.toThrow();
297
+ });
298
+
299
+ // ── Audit starts empty ──
300
+
301
+ it('should return empty audit summary when no actions have been taken', () => {
302
+ const audit = engine.getAuditSummary();
303
+ expect(audit.total).toBe(0);
304
+ expect(audit.authorized).toBe(0);
305
+ expect(audit.denied).toBe(0);
306
+ expect(audit.log).toHaveLength(0);
307
+ });
308
+ });