@mikeargento/bitgraph 1.1.0 → 1.1.1

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 (144) hide show
  1. package/README.md +49 -40
  2. package/dist/__tests__/audit-anchors.test.d.ts +2 -0
  3. package/dist/__tests__/audit-anchors.test.d.ts.map +1 -0
  4. package/dist/__tests__/audit-anchors.test.js +152 -0
  5. package/dist/__tests__/audit-anchors.test.js.map +1 -0
  6. package/dist/__tests__/audit-anomalies.test.d.ts +2 -0
  7. package/dist/__tests__/audit-anomalies.test.d.ts.map +1 -0
  8. package/dist/__tests__/audit-anomalies.test.js +663 -0
  9. package/dist/__tests__/audit-anomalies.test.js.map +1 -0
  10. package/dist/__tests__/audit-attestation.test.d.ts +2 -0
  11. package/dist/__tests__/audit-attestation.test.d.ts.map +1 -0
  12. package/dist/__tests__/audit-attestation.test.js +403 -0
  13. package/dist/__tests__/audit-attestation.test.js.map +1 -0
  14. package/dist/__tests__/audit-bench-smoke.test.d.ts +2 -0
  15. package/dist/__tests__/audit-bench-smoke.test.d.ts.map +1 -0
  16. package/dist/__tests__/audit-bench-smoke.test.js +87 -0
  17. package/dist/__tests__/audit-bench-smoke.test.js.map +1 -0
  18. package/dist/__tests__/audit-boundary.test.d.ts +20 -0
  19. package/dist/__tests__/audit-boundary.test.d.ts.map +1 -0
  20. package/dist/__tests__/audit-boundary.test.js +84 -0
  21. package/dist/__tests__/audit-boundary.test.js.map +1 -0
  22. package/dist/__tests__/audit-cli.test.d.ts +2 -0
  23. package/dist/__tests__/audit-cli.test.d.ts.map +1 -0
  24. package/dist/__tests__/audit-cli.test.js +239 -0
  25. package/dist/__tests__/audit-cli.test.js.map +1 -0
  26. package/dist/__tests__/audit-dependencies.test.d.ts +2 -0
  27. package/dist/__tests__/audit-dependencies.test.d.ts.map +1 -0
  28. package/dist/__tests__/audit-dependencies.test.js +116 -0
  29. package/dist/__tests__/audit-dependencies.test.js.map +1 -0
  30. package/dist/__tests__/audit-fixtures.d.ts +265 -0
  31. package/dist/__tests__/audit-fixtures.d.ts.map +1 -0
  32. package/dist/__tests__/audit-fixtures.js +511 -0
  33. package/dist/__tests__/audit-fixtures.js.map +1 -0
  34. package/dist/__tests__/audit-ingest.test.d.ts +2 -0
  35. package/dist/__tests__/audit-ingest.test.d.ts.map +1 -0
  36. package/dist/__tests__/audit-ingest.test.js +473 -0
  37. package/dist/__tests__/audit-ingest.test.js.map +1 -0
  38. package/dist/__tests__/audit-memory-ingest.test.d.ts +12 -0
  39. package/dist/__tests__/audit-memory-ingest.test.d.ts.map +1 -0
  40. package/dist/__tests__/audit-memory-ingest.test.js +120 -0
  41. package/dist/__tests__/audit-memory-ingest.test.js.map +1 -0
  42. package/dist/__tests__/audit-property.test.d.ts +2 -0
  43. package/dist/__tests__/audit-property.test.d.ts.map +1 -0
  44. package/dist/__tests__/audit-property.test.js +771 -0
  45. package/dist/__tests__/audit-property.test.js.map +1 -0
  46. package/dist/__tests__/audit-real-fixtures.test.d.ts +2 -0
  47. package/dist/__tests__/audit-real-fixtures.test.d.ts.map +1 -0
  48. package/dist/__tests__/audit-real-fixtures.test.js +132 -0
  49. package/dist/__tests__/audit-real-fixtures.test.js.map +1 -0
  50. package/dist/__tests__/audit-real-live.test.d.ts +2 -0
  51. package/dist/__tests__/audit-real-live.test.d.ts.map +1 -0
  52. package/dist/__tests__/audit-real-live.test.js +107 -0
  53. package/dist/__tests__/audit-real-live.test.js.map +1 -0
  54. package/dist/__tests__/audit-reconstruct.test.d.ts +2 -0
  55. package/dist/__tests__/audit-reconstruct.test.d.ts.map +1 -0
  56. package/dist/__tests__/audit-reconstruct.test.js +287 -0
  57. package/dist/__tests__/audit-reconstruct.test.js.map +1 -0
  58. package/dist/__tests__/audit-report.test.d.ts +2 -0
  59. package/dist/__tests__/audit-report.test.d.ts.map +1 -0
  60. package/dist/__tests__/audit-report.test.js +186 -0
  61. package/dist/__tests__/audit-report.test.js.map +1 -0
  62. package/dist/__tests__/audit-roundtrip.test.d.ts +2 -0
  63. package/dist/__tests__/audit-roundtrip.test.d.ts.map +1 -0
  64. package/dist/__tests__/audit-roundtrip.test.js +368 -0
  65. package/dist/__tests__/audit-roundtrip.test.js.map +1 -0
  66. package/dist/__tests__/audit-temporal.test.d.ts +2 -0
  67. package/dist/__tests__/audit-temporal.test.d.ts.map +1 -0
  68. package/dist/__tests__/audit-temporal.test.js +364 -0
  69. package/dist/__tests__/audit-temporal.test.js.map +1 -0
  70. package/dist/__tests__/audit-tiers.test.d.ts +2 -0
  71. package/dist/__tests__/audit-tiers.test.d.ts.map +1 -0
  72. package/dist/__tests__/audit-tiers.test.js +282 -0
  73. package/dist/__tests__/audit-tiers.test.js.map +1 -0
  74. package/dist/__tests__/audit-witness-real.test.d.ts +19 -0
  75. package/dist/__tests__/audit-witness-real.test.d.ts.map +1 -0
  76. package/dist/__tests__/audit-witness-real.test.js +82 -0
  77. package/dist/__tests__/audit-witness-real.test.js.map +1 -0
  78. package/dist/__tests__/audit-witness.test.d.ts +2 -0
  79. package/dist/__tests__/audit-witness.test.d.ts.map +1 -0
  80. package/dist/__tests__/audit-witness.test.js +308 -0
  81. package/dist/__tests__/audit-witness.test.js.map +1 -0
  82. package/dist/__tests__/chain-hash-anchor.test.d.ts +22 -0
  83. package/dist/__tests__/chain-hash-anchor.test.d.ts.map +1 -0
  84. package/dist/__tests__/chain-hash-anchor.test.js +55 -0
  85. package/dist/__tests__/chain-hash-anchor.test.js.map +1 -0
  86. package/dist/__tests__/declared-proof-fixture.d.ts +66 -0
  87. package/dist/__tests__/declared-proof-fixture.d.ts.map +1 -0
  88. package/dist/__tests__/declared-proof-fixture.js +66 -0
  89. package/dist/__tests__/declared-proof-fixture.js.map +1 -0
  90. package/dist/__tests__/mock-proof-fixture.d.ts +15 -0
  91. package/dist/__tests__/mock-proof-fixture.d.ts.map +1 -0
  92. package/dist/__tests__/mock-proof-fixture.js +34 -0
  93. package/dist/__tests__/mock-proof-fixture.js.map +1 -0
  94. package/dist/__tests__/proof-hash-regression.test.js +4 -43
  95. package/dist/__tests__/proof-hash-regression.test.js.map +1 -1
  96. package/dist/__tests__/proof-hash.test.js +3 -21
  97. package/dist/__tests__/proof-hash.test.js.map +1 -1
  98. package/dist/__tests__/proof-integrity.test.d.ts +2 -0
  99. package/dist/__tests__/proof-integrity.test.d.ts.map +1 -0
  100. package/dist/__tests__/proof-integrity.test.js +426 -0
  101. package/dist/__tests__/proof-integrity.test.js.map +1 -0
  102. package/dist/__tests__/realistic-proof-fixture.d.ts +56 -0
  103. package/dist/__tests__/realistic-proof-fixture.d.ts.map +1 -0
  104. package/dist/__tests__/realistic-proof-fixture.js +57 -0
  105. package/dist/__tests__/realistic-proof-fixture.js.map +1 -0
  106. package/dist/__tests__/verifier.test.js +74 -0
  107. package/dist/__tests__/verifier.test.js.map +1 -1
  108. package/package.json +10 -5
  109. package/src/__tests__/audit-anchors.test.ts +188 -0
  110. package/src/__tests__/audit-anomalies.test.ts +815 -0
  111. package/src/__tests__/audit-attestation.test.ts +529 -0
  112. package/src/__tests__/audit-bench-smoke.test.ts +108 -0
  113. package/src/__tests__/audit-boundary.test.ts +96 -0
  114. package/src/__tests__/audit-cli.test.ts +288 -0
  115. package/src/__tests__/audit-dependencies.test.ts +141 -0
  116. package/src/__tests__/audit-fixtures.ts +736 -0
  117. package/src/__tests__/audit-ingest.test.ts +575 -0
  118. package/src/__tests__/audit-memory-ingest.test.ts +140 -0
  119. package/src/__tests__/audit-property.test.ts +892 -0
  120. package/src/__tests__/audit-real-fixtures.test.ts +153 -0
  121. package/src/__tests__/audit-real-live.test.ts +128 -0
  122. package/src/__tests__/audit-reconstruct.test.ts +353 -0
  123. package/src/__tests__/audit-report.test.ts +222 -0
  124. package/src/__tests__/audit-roundtrip.test.ts +464 -0
  125. package/src/__tests__/audit-temporal.test.ts +446 -0
  126. package/src/__tests__/audit-tiers.test.ts +343 -0
  127. package/src/__tests__/audit-witness-real.test.ts +92 -0
  128. package/src/__tests__/audit-witness.test.ts +345 -0
  129. package/src/__tests__/chain-hash-anchor.test.ts +67 -0
  130. package/src/__tests__/declared-proof-fixture.ts +65 -0
  131. package/src/__tests__/mock-proof-fixture.ts +36 -0
  132. package/src/__tests__/proof-hash-regression.test.ts +4 -44
  133. package/src/__tests__/proof-hash.test.ts +3 -22
  134. package/src/__tests__/proof-integrity.test.ts +541 -0
  135. package/src/__tests__/real-fixtures/anchor-after-112762.json +47 -0
  136. package/src/__tests__/real-fixtures/anchor-with-ethereum-112758.json +47 -0
  137. package/src/__tests__/real-fixtures/live-proof-0.json +42 -0
  138. package/src/__tests__/real-fixtures/live-proof-1.json +43 -0
  139. package/src/__tests__/real-fixtures/live-proof-2.json +43 -0
  140. package/src/__tests__/real-fixtures/successor-112760.json +38 -0
  141. package/src/__tests__/real-fixtures/witness-25525146.json +6 -0
  142. package/src/__tests__/real-fixtures/witness-25525147.json +6 -0
  143. package/src/__tests__/realistic-proof-fixture.ts +57 -0
  144. package/src/__tests__/verifier.test.ts +83 -0
@@ -0,0 +1,287 @@
1
+ // Copyright (c) Mike Argento. All rights reserved. See LICENSE.
2
+ /**
3
+ * Tests for @mikeargento/bitgraph-audit causal reconstruction:
4
+ * partitioning per (signer key, epochId, chainId), chain components from
5
+ * prevB64 hash links, genesis and terminal identification, counter
6
+ * evidence, and epoch relationships (epochLink lineage edges, hard-edge
7
+ * ordering, observed-but-unordered epochs).
8
+ */
9
+ import { describe, test, after } from "node:test";
10
+ import * as assert from "node:assert/strict";
11
+ import { rm } from "node:fs/promises";
12
+ import { classifyAnomalies, ingestBundle, reconstructChains, verifyObservedProofs, } from "@mikeargento/bitgraph-audit";
13
+ import { sha256 } from "@noble/hashes/sha256";
14
+ import { b64, healthyPairs, makeConstructorProof, makeCounterChain, makeEpochLinkProof, makeKey, makeTempDir, proofJson, utf8, writeBundleDir, } from "./audit-fixtures.js";
15
+ const tempDirs = [];
16
+ after(async () => {
17
+ for (const dir of tempDirs) {
18
+ await rm(dir, { recursive: true, force: true });
19
+ }
20
+ });
21
+ async function auditBundle(files) {
22
+ const dir = await makeTempDir("bitgraph-audit-reconstruct-");
23
+ tempDirs.push(dir);
24
+ await writeBundleDir(dir, files);
25
+ const ingest = await ingestBundle(dir);
26
+ await verifyObservedProofs(ingest);
27
+ const reconstruction = await reconstructChains(ingest);
28
+ const report = await classifyAnomalies(ingest, reconstruction);
29
+ return { ingest, reconstruction, report };
30
+ }
31
+ // ---------------------------------------------------------------------------
32
+ // The critical regression: a healthy chain is clean
33
+ // ---------------------------------------------------------------------------
34
+ describe("reconstruct: healthy slot/commit chain", () => {
35
+ test("one partition, one component, zero anomalies, zero unexplained positions", async () => {
36
+ const chain = await makeCounterChain({
37
+ epochId: "epoch-healthy",
38
+ chainId: "bitgraph:main",
39
+ pairs: healthyPairs(4), // slot 1/commit 2 ... slot 7/commit 8
40
+ });
41
+ const { ingest, reconstruction, report } = await auditBundle({
42
+ "proofs/p0.json": proofJson(chain.proofs[0].proof),
43
+ "proofs/p1.json": proofJson(chain.proofs[1].proof),
44
+ "proofs/p2.json": proofJson(chain.proofs[2].proof),
45
+ "proofs/p3.json": proofJson(chain.proofs[3].proof),
46
+ });
47
+ assert.equal(ingest.proofs.length, 4);
48
+ assert.equal(reconstruction.partitions.length, 1);
49
+ const partition = reconstruction.partitions[0];
50
+ assert.deepEqual(partition.key, {
51
+ publicKeyB64: chain.key.publicKeyB64,
52
+ epochId: "epoch-healthy",
53
+ chainId: "bitgraph:main",
54
+ });
55
+ assert.equal(partition.components.length, 1);
56
+ const component = partition.components[0];
57
+ assert.deepEqual(component.memberProofHashes, chain.proofs.map((p) => p.proofHash), "link order must follow the hash chain from genesis to terminal");
58
+ assert.deepEqual(component.genesisProofHashes, [chain.proofs[0].proofHash]);
59
+ assert.deepEqual(component.terminalProofHashes, [chain.proofs[3].proofHash]);
60
+ assert.deepEqual(component.brokenLinkProofHashes, []);
61
+ assert.equal(component.hasCounterEvidence, true);
62
+ assert.deepEqual(component.positionRange, { min: "1", max: "8" });
63
+ // THE critical regression: a healthy slot/commit chain produces NO
64
+ // unexplained positions and no anomalies of any kind.
65
+ assert.deepEqual(report.anomalies, []);
66
+ assert.deepEqual(report.divergences, []);
67
+ });
68
+ test("reconstruction is link-driven: file order and counters are not the mechanism", async () => {
69
+ const chain = await makeCounterChain({
70
+ epochId: "epoch-shuffled",
71
+ pairs: healthyPairs(3),
72
+ });
73
+ // Write files in an order that reverses the causal order.
74
+ const { reconstruction } = await auditBundle({
75
+ "a-last.json": proofJson(chain.proofs[2].proof),
76
+ "b-middle.json": proofJson(chain.proofs[1].proof),
77
+ "c-first.json": proofJson(chain.proofs[0].proof),
78
+ });
79
+ const component = reconstruction.partitions[0].components[0];
80
+ assert.deepEqual(component.memberProofHashes, chain.proofs.map((p) => p.proofHash));
81
+ });
82
+ test("a counterless link chain still reconstructs as one component", async () => {
83
+ const chain = await makeCounterChain({
84
+ epochId: "epoch-no-counters",
85
+ pairs: [{}, {}, {}], // epochId only: hash links are the only evidence
86
+ });
87
+ const { reconstruction, report } = await auditBundle({
88
+ "p0.json": proofJson(chain.proofs[0].proof),
89
+ "p1.json": proofJson(chain.proofs[1].proof),
90
+ "p2.json": proofJson(chain.proofs[2].proof),
91
+ });
92
+ const partition = reconstruction.partitions[0];
93
+ assert.equal(partition.components.length, 1);
94
+ const component = partition.components[0];
95
+ assert.deepEqual(component.memberProofHashes, chain.proofs.map((p) => p.proofHash));
96
+ assert.equal(component.hasCounterEvidence, false);
97
+ assert.equal(component.positionRange, undefined);
98
+ assert.deepEqual(report.anomalies, []);
99
+ });
100
+ });
101
+ // ---------------------------------------------------------------------------
102
+ // Partitioning
103
+ // ---------------------------------------------------------------------------
104
+ describe("reconstruct: partitioning", () => {
105
+ test("two independent lineages are never merged", async () => {
106
+ const chainA = await makeCounterChain({ epochId: "epoch-A", pairs: healthyPairs(2) });
107
+ const chainB = await makeCounterChain({ epochId: "epoch-B", pairs: healthyPairs(2) });
108
+ const { reconstruction, report } = await auditBundle({
109
+ "a0.json": proofJson(chainA.proofs[0].proof),
110
+ "a1.json": proofJson(chainA.proofs[1].proof),
111
+ "b0.json": proofJson(chainB.proofs[0].proof),
112
+ "b1.json": proofJson(chainB.proofs[1].proof),
113
+ });
114
+ assert.equal(reconstruction.partitions.length, 2);
115
+ const keys = reconstruction.partitions.map((p) => p.key.publicKeyB64).sort();
116
+ assert.deepEqual(keys, [chainA.key.publicKeyB64, chainB.key.publicKeyB64].sort());
117
+ // Same counters on both chains, yet no collisions: counters are
118
+ // partition-local.
119
+ assert.deepEqual(report.anomalies, []);
120
+ assert.deepEqual(report.divergences, []);
121
+ });
122
+ test("same signer and epoch on different chainIds are separate partitions (G6)", async () => {
123
+ const key = await makeKey();
124
+ const main = await makeCounterChain({
125
+ key,
126
+ epochId: "epoch-multichain",
127
+ chainId: "bitgraph:main",
128
+ pairs: healthyPairs(2),
129
+ payloadPrefix: "main",
130
+ });
131
+ const globalChain = await makeCounterChain({
132
+ key,
133
+ epochId: "epoch-multichain",
134
+ pairs: healthyPairs(2), // no chainId: normalized "global"
135
+ payloadPrefix: "global",
136
+ });
137
+ const { reconstruction, report } = await auditBundle({
138
+ "m0.json": proofJson(main.proofs[0].proof),
139
+ "m1.json": proofJson(main.proofs[1].proof),
140
+ "g0.json": proofJson(globalChain.proofs[0].proof),
141
+ "g1.json": proofJson(globalChain.proofs[1].proof),
142
+ });
143
+ assert.equal(reconstruction.partitions.length, 2);
144
+ assert.deepEqual(reconstruction.partitions.map((p) => p.key.chainId).sort(), ["bitgraph:main", "global"]);
145
+ assert.deepEqual(report.anomalies, []);
146
+ });
147
+ test("chainless proofs stay outside partitions as observed-but-unchained", async () => {
148
+ const chain = await makeCounterChain({ epochId: "epoch-with-stray", pairs: healthyPairs(2) });
149
+ const chainless = await makeConstructorProof(); // no counter, no epochId
150
+ const { ingest, reconstruction, report } = await auditBundle({
151
+ "p0.json": proofJson(chain.proofs[0].proof),
152
+ "p1.json": proofJson(chain.proofs[1].proof),
153
+ "stray.json": proofJson(chainless.proof),
154
+ });
155
+ assert.equal(ingest.proofs.length, 3);
156
+ assert.equal(reconstruction.partitions.length, 1);
157
+ assert.equal(reconstruction.partitions[0].memberProofHashes.length, 2);
158
+ const strayHash = ingest.proofs.find((p) => p.chainless).proofHash;
159
+ assert.deepEqual(reconstruction.unchainedProofHashes, [strayHash]);
160
+ // Observed-but-unchained is not an anomaly.
161
+ assert.deepEqual(report.anomalies, []);
162
+ });
163
+ test("a proof with chain fields but no signer key is unpartitioned", async () => {
164
+ const broken = JSON.stringify({
165
+ version: "bitgraph/1",
166
+ artifact: { hashAlg: "sha256", digestB64: b64(sha256(utf8("broken-payload"))) },
167
+ commit: { nonceB64: "AAAA", counter: "2", epochId: "epoch-broken" },
168
+ signer: { publicKeyB64: 42, signatureB64: "AAAA" },
169
+ });
170
+ const { ingest, reconstruction } = await auditBundle({ "broken.json": broken });
171
+ assert.equal(ingest.proofs.length, 1);
172
+ assert.equal(reconstruction.partitions.length, 0);
173
+ assert.deepEqual(reconstruction.unpartitionedProofHashes, [ingest.proofs[0].proofHash]);
174
+ // The verification dimension reports the structural failure.
175
+ assert.equal(ingest.proofs[0].verification.status, "failed");
176
+ });
177
+ });
178
+ // ---------------------------------------------------------------------------
179
+ // Missing proofs split components
180
+ // ---------------------------------------------------------------------------
181
+ describe("reconstruct: missing middle proof", () => {
182
+ test("splits the partition into two components with the break identified", async () => {
183
+ const chain = await makeCounterChain({ epochId: "epoch-gap", pairs: healthyPairs(3) });
184
+ // Omit the middle proof (slot 3 / commit 4).
185
+ const { reconstruction } = await auditBundle({
186
+ "p0.json": proofJson(chain.proofs[0].proof),
187
+ "p2.json": proofJson(chain.proofs[2].proof),
188
+ });
189
+ const partition = reconstruction.partitions[0];
190
+ assert.equal(partition.components.length, 2);
191
+ const [first, second] = partition.components;
192
+ assert.deepEqual(first.memberProofHashes, [chain.proofs[0].proofHash]);
193
+ assert.deepEqual(first.genesisProofHashes, [chain.proofs[0].proofHash]);
194
+ assert.deepEqual(first.terminalProofHashes, [chain.proofs[0].proofHash]);
195
+ assert.deepEqual(second.memberProofHashes, [chain.proofs[2].proofHash]);
196
+ assert.deepEqual(second.genesisProofHashes, []);
197
+ assert.deepEqual(second.brokenLinkProofHashes, [chain.proofs[2].proofHash]);
198
+ });
199
+ });
200
+ // ---------------------------------------------------------------------------
201
+ // Epoch relationships
202
+ // ---------------------------------------------------------------------------
203
+ describe("reconstruct: epoch relationships", () => {
204
+ test("a valid epochLink produces a hard lineage edge and linked ordering", async () => {
205
+ const chainA = await makeCounterChain({ epochId: "epoch-lineage-A", pairs: healthyPairs(2) });
206
+ const terminalA = chainA.proofs[1];
207
+ const genesisB = await makeEpochLinkProof({
208
+ prevEpochId: "epoch-lineage-A",
209
+ prevCounter: terminalA.proof.commit.counter,
210
+ prevProofHashB64: terminalA.chainHash,
211
+ prevPublicKeyB64: chainA.key.publicKeyB64,
212
+ toEpochId: "epoch-lineage-B",
213
+ counter: "2",
214
+ slotCounter: "1",
215
+ });
216
+ const { reconstruction, report } = await auditBundle({
217
+ "a0.json": proofJson(chainA.proofs[0].proof),
218
+ "a1.json": proofJson(terminalA.proof),
219
+ "b-genesis.json": proofJson(genesisB.proof),
220
+ });
221
+ const { edges, epochs, orderedPairs } = reconstruction.epochRelationships;
222
+ assert.equal(edges.length, 1);
223
+ const edge = edges[0];
224
+ assert.equal(edge.resolution, "matched");
225
+ assert.equal(edge.fromEpochId, "epoch-lineage-A");
226
+ assert.equal(edge.toEpochId, "epoch-lineage-B");
227
+ assert.equal(edge.predecessorProofHash, terminalA.proofHash);
228
+ assert.equal(edge.metadataConsistent, true);
229
+ assert.equal(edge.referencedProofIsTerminal, true);
230
+ assert.equal(edge.viaProofValid, true);
231
+ assert.equal(edge.predecessorValid, true);
232
+ assert.equal(edge.hardEdge, true);
233
+ assert.deepEqual(orderedPairs, [
234
+ { beforeEpochId: "epoch-lineage-A", afterEpochId: "epoch-lineage-B" },
235
+ ]);
236
+ const epochA = epochs.find((e) => e.epochId === "epoch-lineage-A");
237
+ const epochB = epochs.find((e) => e.epochId === "epoch-lineage-B");
238
+ assert.equal(epochA.ordering, "linked");
239
+ assert.equal(epochB.ordering, "linked");
240
+ assert.deepEqual(epochA.linkedSuccessorEpochIds, ["epoch-lineage-B"]);
241
+ assert.deepEqual(epochB.linkedPredecessorEpochIds, ["epoch-lineage-A"]);
242
+ // The extension point stays untouched by reconstruction.
243
+ assert.equal(epochA.anchorBounds, undefined);
244
+ // Valid lineage is not an anomaly.
245
+ assert.deepEqual(report.anomalies, []);
246
+ assert.deepEqual(report.divergences, []);
247
+ });
248
+ test("a dangling epochLink yields no hard edge and no ordering", async () => {
249
+ const genesis = await makeEpochLinkProof({
250
+ prevEpochId: "epoch-never-observed",
251
+ prevCounter: "10",
252
+ prevProofHashB64: b64(sha256(utf8("terminal-never-observed"))),
253
+ toEpochId: "epoch-dangling-B",
254
+ counter: "2",
255
+ slotCounter: "1",
256
+ });
257
+ const { reconstruction } = await auditBundle({
258
+ "b-genesis.json": proofJson(genesis.proof),
259
+ });
260
+ const { edges, epochs, orderedPairs } = reconstruction.epochRelationships;
261
+ assert.equal(edges.length, 1);
262
+ assert.equal(edges[0].resolution, "dangling");
263
+ assert.equal(edges[0].hardEdge, false);
264
+ assert.deepEqual(orderedPairs, []);
265
+ assert.equal(epochs.find((e) => e.epochId === "epoch-dangling-B").ordering, "observed-but-unordered");
266
+ });
267
+ test("epochs with no lineage evidence are observed-but-unordered, never divergence", async () => {
268
+ const chainA = await makeCounterChain({ epochId: "epoch-solo-A", pairs: healthyPairs(2) });
269
+ const chainB = await makeCounterChain({ epochId: "epoch-solo-B", pairs: healthyPairs(2) });
270
+ const { reconstruction, report } = await auditBundle({
271
+ "a0.json": proofJson(chainA.proofs[0].proof),
272
+ "a1.json": proofJson(chainA.proofs[1].proof),
273
+ "b0.json": proofJson(chainB.proofs[0].proof),
274
+ "b1.json": proofJson(chainB.proofs[1].proof),
275
+ });
276
+ const { epochs, edges, orderedPairs } = reconstruction.epochRelationships;
277
+ assert.equal(edges.length, 0);
278
+ assert.deepEqual(orderedPairs, []);
279
+ for (const epoch of epochs) {
280
+ assert.equal(epoch.ordering, "observed-but-unordered");
281
+ }
282
+ // Concurrent-or-unordered is never divergence.
283
+ assert.deepEqual(report.divergences, []);
284
+ assert.deepEqual(report.anomalies, []);
285
+ });
286
+ });
287
+ //# sourceMappingURL=audit-reconstruct.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-reconstruct.test.js","sourceRoot":"","sources":["../../src/__tests__/audit-reconstruct.test.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAEhE;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACtC,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EACL,GAAG,EACH,YAAY,EACZ,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,OAAO,EACP,WAAW,EACX,SAAS,EACT,IAAI,EACJ,cAAc,GACf,MAAM,qBAAqB,CAAC;AAE7B,MAAM,QAAQ,GAAa,EAAE,CAAC;AAE9B,KAAK,CAAC,KAAK,IAAI,EAAE;IACf,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAClD,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,KAAK,UAAU,WAAW,CAAC,KAA0C;IAKnE,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,6BAA6B,CAAC,CAAC;IAC7D,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnB,MAAM,cAAc,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACjC,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,CAAC;IACvC,MAAM,oBAAoB,CAAC,MAAM,CAAC,CAAC;IACnC,MAAM,cAAc,GAAG,MAAM,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC/D,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,CAAC;AAC5C,CAAC;AAED,8EAA8E;AAC9E,oDAAoD;AACpD,8EAA8E;AAE9E,QAAQ,CAAC,wCAAwC,EAAE,GAAG,EAAE;IACtD,IAAI,CAAC,0EAA0E,EAAE,KAAK,IAAI,EAAE;QAC1F,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC;YACnC,OAAO,EAAE,eAAe;YACxB,OAAO,EAAE,eAAe;YACxB,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,sCAAsC;SAC/D,CAAC,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,MAAM,WAAW,CAAC;YAC3D,gBAAgB,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC;YACnD,gBAAgB,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC;YACnD,gBAAgB,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC;YACnD,gBAAgB,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC;SACpD,CAAC,CAAC;QAEH,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACtC,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAClD,MAAM,SAAS,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC,CAAE,CAAC;QAChD,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,EAAE;YAC9B,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,YAAY;YACpC,OAAO,EAAE,eAAe;YACxB,OAAO,EAAE,eAAe;SACzB,CAAC,CAAC;QAEH,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC7C,MAAM,SAAS,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC,CAAE,CAAC;QAC3C,MAAM,CAAC,SAAS,CACd,SAAS,CAAC,iBAAiB,EAC3B,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EACpC,gEAAgE,CACjE,CAAC;QACF,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,kBAAkB,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,SAAS,CAAC,CAAC,CAAC;QAC7E,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,mBAAmB,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,SAAS,CAAC,CAAC,CAAC;QAC9E,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC;QACtD,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC;QACjD,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,aAAa,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;QAElE,mEAAmE;QACnE,sDAAsD;QACtD,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QACvC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,8EAA8E,EAAE,KAAK,IAAI,EAAE;QAC9F,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC;YACnC,OAAO,EAAE,gBAAgB;YACzB,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC;SACvB,CAAC,CAAC;QACH,0DAA0D;QAC1D,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,WAAW,CAAC;YAC3C,aAAa,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC;YAChD,eAAe,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC;YAClD,cAAc,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC;SAClD,CAAC,CAAC;QACH,MAAM,SAAS,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC,CAAE,CAAC,UAAU,CAAC,CAAC,CAAE,CAAC;QAC/D,MAAM,CAAC,SAAS,CACd,SAAS,CAAC,iBAAiB,EAC3B,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CACrC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC9E,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC;YACnC,OAAO,EAAE,mBAAmB;YAC5B,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,iDAAiD;SACvE,CAAC,CAAC;QACH,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,MAAM,WAAW,CAAC;YACnD,SAAS,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC;YAC5C,SAAS,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC;YAC5C,SAAS,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC;SAC7C,CAAC,CAAC;QACH,MAAM,SAAS,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC,CAAE,CAAC;QAChD,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC7C,MAAM,SAAS,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC,CAAE,CAAC;QAC3C,MAAM,CAAC,SAAS,CACd,SAAS,CAAC,iBAAiB,EAC3B,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CACrC,CAAC;QACF,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC;QAClD,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;QACjD,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,8EAA8E;AAC9E,eAAe;AACf,8EAA8E;AAE9E,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACzC,IAAI,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACtF,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACtF,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,MAAM,WAAW,CAAC;YACnD,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC;YAC7C,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC;YAC7C,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC;YAC7C,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC;SAC9C,CAAC,CAAC;QAEH,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAClD,MAAM,IAAI,GAAG,cAAc,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7E,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAClF,gEAAgE;QAChE,mBAAmB;QACnB,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QACvC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,0EAA0E,EAAE,KAAK,IAAI,EAAE;QAC1F,MAAM,GAAG,GAAG,MAAM,OAAO,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC;YAClC,GAAG;YACH,OAAO,EAAE,kBAAkB;YAC3B,OAAO,EAAE,eAAe;YACxB,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC;YACtB,aAAa,EAAE,MAAM;SACtB,CAAC,CAAC;QACH,MAAM,WAAW,GAAG,MAAM,gBAAgB,CAAC;YACzC,GAAG;YACH,OAAO,EAAE,kBAAkB;YAC3B,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,kCAAkC;YAC1D,aAAa,EAAE,QAAQ;SACxB,CAAC,CAAC;QACH,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,MAAM,WAAW,CAAC;YACnD,SAAS,EAAE,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC;YAC3C,SAAS,EAAE,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC;YAC3C,SAAS,EAAE,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC;YAClD,SAAS,EAAE,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC;SACnD,CAAC,CAAC;QAEH,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAClD,MAAM,CAAC,SAAS,CACd,cAAc,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAC1D,CAAC,eAAe,EAAE,QAAQ,CAAC,CAC5B,CAAC;QACF,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,oEAAoE,EAAE,KAAK,IAAI,EAAE;QACpF,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC9F,MAAM,SAAS,GAAG,MAAM,oBAAoB,EAAE,CAAC,CAAC,yBAAyB;QACzE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,MAAM,WAAW,CAAC;YAC3D,SAAS,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC;YAC5C,SAAS,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC;YAC5C,YAAY,EAAE,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC;SACzC,CAAC,CAAC;QAEH,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACtC,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAClD,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAE,CAAC,iBAAiB,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACxE,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAE,CAAC,SAAS,CAAC;QACpE,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,oBAAoB,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;QACnE,4CAA4C;QAC5C,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC9E,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC;YAC5B,OAAO,EAAE,YAAY;YACrB,QAAQ,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE;YAC/E,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,cAAc,EAAE;YACnE,MAAM,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE;SACnD,CAAC,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,WAAW,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC,CAAC;QAChF,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACtC,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAClD,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,wBAAwB,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,SAAS,CAAC,CAAC,CAAC;QACzF,6DAA6D;QAC7D,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,YAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,8EAA8E;AAC9E,kCAAkC;AAClC,8EAA8E;AAE9E,QAAQ,CAAC,mCAAmC,EAAE,GAAG,EAAE;IACjD,IAAI,CAAC,oEAAoE,EAAE,KAAK,IAAI,EAAE;QACpF,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACvF,6CAA6C;QAC7C,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,WAAW,CAAC;YAC3C,SAAS,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC;YAC5C,SAAS,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC;SAC7C,CAAC,CAAC;QAEH,MAAM,SAAS,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC,CAAE,CAAC;QAChD,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC7C,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,UAAU,CAAC;QAC7C,MAAM,CAAC,SAAS,CAAC,KAAM,CAAC,iBAAiB,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,SAAS,CAAC,CAAC,CAAC;QACzE,MAAM,CAAC,SAAS,CAAC,KAAM,CAAC,kBAAkB,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,SAAS,CAAC,CAAC,CAAC;QAC1E,MAAM,CAAC,SAAS,CAAC,KAAM,CAAC,mBAAmB,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,SAAS,CAAC,CAAC,CAAC;QAC3E,MAAM,CAAC,SAAS,CAAC,MAAO,CAAC,iBAAiB,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,SAAS,CAAC,CAAC,CAAC;QAC1E,MAAM,CAAC,SAAS,CAAC,MAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;QACjD,MAAM,CAAC,SAAS,CAAC,MAAO,CAAC,qBAAqB,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IAChF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,8EAA8E;AAC9E,sBAAsB;AACtB,8EAA8E;AAE9E,QAAQ,CAAC,kCAAkC,EAAE,GAAG,EAAE;IAChD,IAAI,CAAC,oEAAoE,EAAE,KAAK,IAAI,EAAE;QACpF,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,EAAE,OAAO,EAAE,iBAAiB,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC9F,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC;YACxC,WAAW,EAAE,iBAAiB;YAC9B,WAAW,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,OAAiB;YACrD,gBAAgB,EAAE,SAAS,CAAC,SAAS;YACrC,gBAAgB,EAAE,MAAM,CAAC,GAAG,CAAC,YAAY;YACzC,SAAS,EAAE,iBAAiB;YAC5B,OAAO,EAAE,GAAG;YACZ,WAAW,EAAE,GAAG;SACjB,CAAC,CAAC;QAEH,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,MAAM,WAAW,CAAC;YACnD,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC;YAC7C,SAAS,EAAE,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC;YACrC,gBAAgB,EAAE,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC;SAC5C,CAAC,CAAC;QAEH,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,cAAc,CAAC,kBAAkB,CAAC;QAC1E,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC9B,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;QACvB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QACzC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAClD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;QAChD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;QAC7D,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC;QAC5C,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,yBAAyB,EAAE,IAAI,CAAC,CAAC;QACnD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;QACvC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;QAC1C,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAElC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE;YAC7B,EAAE,aAAa,EAAE,iBAAiB,EAAE,YAAY,EAAE,iBAAiB,EAAE;SACtE,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,iBAAiB,CAAE,CAAC;QACpE,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,iBAAiB,CAAE,CAAC;QACpE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACxC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,uBAAuB,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACtE,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,yBAAyB,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACxE,yDAAyD;QACzD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;QAE7C,mCAAmC;QACnC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QACvC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;QAC1E,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC;YACvC,WAAW,EAAE,sBAAsB;YACnC,WAAW,EAAE,IAAI;YACjB,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC,CAAC;YAC9D,SAAS,EAAE,kBAAkB;YAC7B,OAAO,EAAE,GAAG;YACZ,WAAW,EAAE,GAAG;SACjB,CAAC,CAAC;QACH,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,WAAW,CAAC;YAC3C,gBAAgB,EAAE,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC;SAC3C,CAAC,CAAC;QAEH,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,cAAc,CAAC,kBAAkB,CAAC;QAC1E,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC9B,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QAC/C,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QACxC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;QACnC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,kBAAkB,CAAE,CAAC,QAAQ,EAAE,wBAAwB,CAAC,CAAC;IACzG,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,8EAA8E,EAAE,KAAK,IAAI,EAAE;QAC9F,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC3F,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC3F,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,MAAM,WAAW,CAAC;YACnD,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC;YAC7C,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC;YAC7C,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC;YAC7C,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC;SAC9C,CAAC,CAAC;QAEH,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,cAAc,CAAC,kBAAkB,CAAC;QAC1E,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC9B,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;QACnC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,wBAAwB,CAAC,CAAC;QACzD,CAAC;QACD,+CAA+C;QAC/C,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QACzC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=audit-report.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-report.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/audit-report.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,186 @@
1
+ // Copyright (c) Mike Argento. All rights reserved. See LICENSE.
2
+ /**
3
+ * Tests for the Phase 4d audit orchestrator and report generators:
4
+ * runAudit end-to-end over the standard mixed bundle, JSON report with
5
+ * stable codes and correct counts, deterministic double-run equality
6
+ * (runMetadata stripped), executive-summary language in the brief's
7
+ * style (two-position gap wording, no-winner divergence wording), and
8
+ * zero em dash characters in all generated output.
9
+ */
10
+ import { describe, it, before, after } from "node:test";
11
+ import * as assert from "node:assert/strict";
12
+ import { rm } from "node:fs/promises";
13
+ import { buildJsonReport, buildMarkdownReport, computeExitFlags, runAudit, } from "@mikeargento/bitgraph-audit";
14
+ import { makeStandardAuditBundle } from "./audit-fixtures.js";
15
+ const EM_DASH = "—";
16
+ describe("audit orchestrator and reports: standard mixed bundle", () => {
17
+ let bundle;
18
+ let result;
19
+ let report;
20
+ let markdown;
21
+ before(async () => {
22
+ bundle = await makeStandardAuditBundle();
23
+ result = await runAudit(bundle.dir);
24
+ report = buildJsonReport(result);
25
+ markdown = buildMarkdownReport(result);
26
+ });
27
+ after(async () => {
28
+ await rm(bundle.dir, { recursive: true, force: true });
29
+ });
30
+ it("runs the full pipeline end-to-end", () => {
31
+ assert.equal(result.ingest.container, "directory");
32
+ assert.equal(result.runMetadata.bundlePath, bundle.dir);
33
+ assert.equal(typeof result.runMetadata.toolVersion, "string");
34
+ assert.ok(result.runMetadata.startedAt.includes("T"));
35
+ // Two partitions: the main chain and the anchor's own epoch.
36
+ assert.equal(result.reconstruction.partitions.length, 2);
37
+ // Verification tiers.
38
+ assert.equal(result.verification.verified, bundle.expected.verified);
39
+ assert.equal(result.verification.failed, bundle.expected.failed);
40
+ assert.equal(result.verification.artifactUnavailable, bundle.expected.artifactUnavailable);
41
+ assert.equal(result.verification.chainless, bundle.expected.chainless);
42
+ // Chain anomalies: gap, break, fork.
43
+ const codes = result.anomalies.anomalies.map((a) => a.code).sort();
44
+ assert.deepEqual(codes, [
45
+ "chain-break-missing",
46
+ "predecessor-reuse",
47
+ "unexplained-counter-positions",
48
+ ]);
49
+ assert.equal(result.anomalies.divergences.length, 1);
50
+ assert.equal(result.anomalies.divergences[0]?.kind, "predecessor-reuse");
51
+ const partyHashes = result.anomalies.divergences[0]?.parties.map((p) => p.proofHash).sort();
52
+ assert.deepEqual(partyHashes, [bundle.forkAProofHash, bundle.forkBProofHash].sort());
53
+ // The gap is exactly the dropped proof's two positions (slot 3, commit 4).
54
+ const gap = result.anomalies.anomalies.find((a) => a.code === "unexplained-counter-positions");
55
+ assert.deepEqual((gap?.details).positions, ["3", "4"]);
56
+ // Authority analysis is quiet; attestation records exist without documents.
57
+ assert.equal(result.authorities.anomalies.length, 0);
58
+ assert.equal(result.attestations.records.length, 6);
59
+ assert.equal(result.attestations.counts.proofsWithDocument, 0);
60
+ // The anchor was identified and its witness verified with the header timestamp.
61
+ assert.deepEqual(result.temporal.verifiedAnchorProofHashes, [bundle.anchorProofHash]);
62
+ const outcome = result.witnesses.outcomes.find((o) => o.verified);
63
+ assert.equal(outcome?.anchorProofHash, bundle.anchorProofHash);
64
+ assert.equal(outcome?.timestamp, bundle.blockTimestamp);
65
+ assert.equal(outcome?.blockNumber, String(bundle.blockNumber));
66
+ // Exit flags: unsupported-version sets bit 1, anomalies set bit 2.
67
+ assert.deepEqual(computeExitFlags(result), {
68
+ verificationFailures: true,
69
+ chainAnomaliesOrDivergences: true,
70
+ code: 3,
71
+ });
72
+ });
73
+ it("JSON report carries the schema version, stable codes, and correct counts", () => {
74
+ assert.equal(report.reportSchemaVersion, "bitgraph-audit-report/2");
75
+ assert.equal(report.toolVersion, result.runMetadata.toolVersion);
76
+ assert.equal(report.runMetadata.nondeterministic, true);
77
+ assert.equal(report.input.counts.observed, bundle.expected.observed);
78
+ assert.equal(report.input.counts.proofFiles, bundle.expected.proofFiles);
79
+ assert.equal(report.input.counts.exactDuplicates, bundle.expected.exactDuplicates);
80
+ assert.equal(report.input.counts.semanticDuplicates, bundle.expected.semanticDuplicates);
81
+ assert.equal(report.input.counts.unsupportedVersion, bundle.expected.unsupportedVersion);
82
+ assert.equal(report.input.counts.verified, bundle.expected.verified);
83
+ assert.equal(report.input.counts.failed, bundle.expected.failed);
84
+ assert.equal(report.input.counts.artifactUnavailable, bundle.expected.artifactUnavailable);
85
+ assert.equal(report.input.counts.chainless, bundle.expected.chainless);
86
+ // Machine consumers key on stable codes, never prose.
87
+ const codes = report.anomalies.map((a) => a.code);
88
+ for (const expected of [
89
+ "unsupported-version",
90
+ "exact-duplicate",
91
+ "semantic-duplicate",
92
+ "unexplained-counter-positions",
93
+ "chain-break-missing",
94
+ "predecessor-reuse",
95
+ ]) {
96
+ assert.ok(codes.includes(expected), `anomaly list includes ${expected}`);
97
+ }
98
+ assert.equal(report.anomalies.length, 6);
99
+ assert.deepEqual(report.summary.anomalyCountsByCode, {
100
+ "chain-break-missing": 1,
101
+ "exact-duplicate": 1,
102
+ "predecessor-reuse": 1,
103
+ "semantic-duplicate": 1,
104
+ "unexplained-counter-positions": 1,
105
+ "unsupported-version": 1,
106
+ });
107
+ // Per-proof records: sorted by canonical hash, compact fields only.
108
+ const hashes = report.proofs.map((p) => p.proofHash);
109
+ assert.deepEqual(hashes, [...hashes].sort());
110
+ assert.equal(report.proofs.length, bundle.expected.observed);
111
+ assert.ok(!("proof" in report.proofs[0]), "raw proof objects never serialized");
112
+ // The stored-form copy is cross-checked, never trusted. Its embedded
113
+ // proofHash matched, so no mismatch escalation and no finding; the
114
+ // record keeps the first observed copy's "absent" status per ingest
115
+ // semantics (only a mismatch on any copy escalates).
116
+ const genesis = report.proofs.find((p) => p.proofHash === bundle.chainProofHashes[0]);
117
+ assert.notEqual(genesis?.embeddedProofHash, "mismatch");
118
+ assert.ok(!codes.includes("proofhash-mismatch"));
119
+ assert.equal(genesis?.sources.length, 3);
120
+ assert.equal(genesis?.verificationStatus, "verified");
121
+ // Partition intactness: main chain broken, anchor partition intact.
122
+ assert.equal(report.partitions.length, 2);
123
+ const mainPartition = report.partitions.find((p) => p.key.epochId === bundle.epochId);
124
+ const anchorPartition = report.partitions.find((p) => p.key.epochId === bundle.anchorEpochId);
125
+ assert.equal(mainPartition?.intact, false);
126
+ assert.equal(mainPartition?.components.length, 2);
127
+ assert.equal(anchorPartition?.intact, true);
128
+ assert.equal(report.summary.chainIntact, false);
129
+ assert.equal(report.summary.partitionsIntact, 1);
130
+ // Epoch relationships: two epochs, no ordering evidence between them.
131
+ assert.equal(report.summary.epochsObserved, 2);
132
+ assert.equal(report.epochRelationships.unorderedPairs.length, 1);
133
+ assert.equal(report.epochRelationships.orderedPairs.length, 0);
134
+ // Rejected input listed with path and offending version string.
135
+ assert.equal(report.unsupportedVersions.length, 1);
136
+ assert.equal(report.unsupportedVersions[0]?.path, bundle.unsupportedPath);
137
+ assert.equal(report.unsupportedVersions[0]?.version, "occ/1");
138
+ // Temporal summary: the anchor's own segment is lower-bounded, the rest unanchored.
139
+ assert.equal(report.summary.temporal.anchorsIdentified, 1);
140
+ assert.equal(report.summary.temporal.anchorsWithVerifiedWitness, 1);
141
+ assert.ok(report.summary.temporal.segmentsLowerBounded >= 1);
142
+ assert.ok(report.summary.temporal.segmentsUnanchored >= 1);
143
+ // Exit flags mirrored into the summary.
144
+ assert.deepEqual(report.summary.exit, {
145
+ verificationFailures: true,
146
+ chainAnomaliesOrDivergences: true,
147
+ code: 3,
148
+ });
149
+ });
150
+ it("is deterministic across runs once runMetadata is stripped", async () => {
151
+ const resultA = await runAudit(bundle.dir);
152
+ const resultB = await runAudit(bundle.dir);
153
+ const reportA = buildJsonReport(resultA);
154
+ const reportB = buildJsonReport(resultB);
155
+ const { runMetadata: metaA, ...restA } = reportA;
156
+ const { runMetadata: metaB, ...restB } = reportB;
157
+ assert.deepEqual(restA, restB);
158
+ assert.equal(JSON.stringify(restA), JSON.stringify(restB));
159
+ // The markdown differs only in the wall-clock start time.
160
+ const mdA = buildMarkdownReport(resultA).replaceAll(metaA.startedAt, "STARTED_AT");
161
+ const mdB = buildMarkdownReport(resultB).replaceAll(metaB.startedAt, "STARTED_AT");
162
+ assert.equal(mdA, mdB);
163
+ });
164
+ it("markdown executive summary uses the brief's gap and divergence language", () => {
165
+ assert.ok(markdown.includes("# BitGraph Audit Report"));
166
+ // G2 gap language: two-position wording, honest absence claim.
167
+ assert.ok(markdown.includes("neither commit positions nor referenced slot positions"));
168
+ assert.ok(markdown.includes("does not, by itself, prove"));
169
+ // Divergence: no winner is ever chosen.
170
+ assert.ok(markdown.includes("does not choose between them"));
171
+ // Rejected legacy input listed with its path and version string.
172
+ assert.ok(markdown.includes(bundle.unsupportedPath));
173
+ assert.ok(markdown.includes("occ/1"));
174
+ // Chain intactness stated per partition.
175
+ assert.ok(markdown.includes("Chain intact: no"));
176
+ assert.ok(markdown.includes("Chain intact: yes"));
177
+ });
178
+ it("contains zero em dash characters in the markdown and the JSON", () => {
179
+ assert.ok(!markdown.includes(EM_DASH), "markdown contains no em dashes");
180
+ const json = JSON.stringify(report, null, 2);
181
+ assert.ok(!json.includes(EM_DASH), "JSON report contains no em dashes");
182
+ // The report never leaks signatures or raw proof bodies.
183
+ assert.ok(!json.includes('"signatureB64"'));
184
+ });
185
+ });
186
+ //# sourceMappingURL=audit-report.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-report.test.js","sourceRoot":"","sources":["../../src/__tests__/audit-report.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=audit-roundtrip.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-roundtrip.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/audit-roundtrip.test.ts"],"names":[],"mappings":""}