@mikeargento/bitgraph 1.9.1 → 1.9.2

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 (239) hide show
  1. package/package.json +9 -6
  2. package/dist/__tests__/audit-anchors.test.d.ts +0 -2
  3. package/dist/__tests__/audit-anchors.test.d.ts.map +0 -1
  4. package/dist/__tests__/audit-anchors.test.js +0 -152
  5. package/dist/__tests__/audit-anchors.test.js.map +0 -1
  6. package/dist/__tests__/audit-anomalies.test.d.ts +0 -2
  7. package/dist/__tests__/audit-anomalies.test.d.ts.map +0 -1
  8. package/dist/__tests__/audit-anomalies.test.js +0 -663
  9. package/dist/__tests__/audit-anomalies.test.js.map +0 -1
  10. package/dist/__tests__/audit-attestation.test.d.ts +0 -2
  11. package/dist/__tests__/audit-attestation.test.d.ts.map +0 -1
  12. package/dist/__tests__/audit-attestation.test.js +0 -403
  13. package/dist/__tests__/audit-attestation.test.js.map +0 -1
  14. package/dist/__tests__/audit-bench-smoke.test.d.ts +0 -2
  15. package/dist/__tests__/audit-bench-smoke.test.d.ts.map +0 -1
  16. package/dist/__tests__/audit-bench-smoke.test.js +0 -87
  17. package/dist/__tests__/audit-bench-smoke.test.js.map +0 -1
  18. package/dist/__tests__/audit-boundary.test.d.ts +0 -20
  19. package/dist/__tests__/audit-boundary.test.d.ts.map +0 -1
  20. package/dist/__tests__/audit-boundary.test.js +0 -84
  21. package/dist/__tests__/audit-boundary.test.js.map +0 -1
  22. package/dist/__tests__/audit-cli.test.d.ts +0 -2
  23. package/dist/__tests__/audit-cli.test.d.ts.map +0 -1
  24. package/dist/__tests__/audit-cli.test.js +0 -239
  25. package/dist/__tests__/audit-cli.test.js.map +0 -1
  26. package/dist/__tests__/audit-dependencies.test.d.ts +0 -2
  27. package/dist/__tests__/audit-dependencies.test.d.ts.map +0 -1
  28. package/dist/__tests__/audit-dependencies.test.js +0 -116
  29. package/dist/__tests__/audit-dependencies.test.js.map +0 -1
  30. package/dist/__tests__/audit-fixtures.d.ts +0 -265
  31. package/dist/__tests__/audit-fixtures.d.ts.map +0 -1
  32. package/dist/__tests__/audit-fixtures.js +0 -511
  33. package/dist/__tests__/audit-fixtures.js.map +0 -1
  34. package/dist/__tests__/audit-ingest.test.d.ts +0 -2
  35. package/dist/__tests__/audit-ingest.test.d.ts.map +0 -1
  36. package/dist/__tests__/audit-ingest.test.js +0 -473
  37. package/dist/__tests__/audit-ingest.test.js.map +0 -1
  38. package/dist/__tests__/audit-memory-ingest.test.d.ts +0 -12
  39. package/dist/__tests__/audit-memory-ingest.test.d.ts.map +0 -1
  40. package/dist/__tests__/audit-memory-ingest.test.js +0 -135
  41. package/dist/__tests__/audit-memory-ingest.test.js.map +0 -1
  42. package/dist/__tests__/audit-property.test.d.ts +0 -2
  43. package/dist/__tests__/audit-property.test.d.ts.map +0 -1
  44. package/dist/__tests__/audit-property.test.js +0 -771
  45. package/dist/__tests__/audit-property.test.js.map +0 -1
  46. package/dist/__tests__/audit-real-fixtures.test.d.ts +0 -2
  47. package/dist/__tests__/audit-real-fixtures.test.d.ts.map +0 -1
  48. package/dist/__tests__/audit-real-fixtures.test.js +0 -132
  49. package/dist/__tests__/audit-real-fixtures.test.js.map +0 -1
  50. package/dist/__tests__/audit-real-live.test.d.ts +0 -2
  51. package/dist/__tests__/audit-real-live.test.d.ts.map +0 -1
  52. package/dist/__tests__/audit-real-live.test.js +0 -107
  53. package/dist/__tests__/audit-real-live.test.js.map +0 -1
  54. package/dist/__tests__/audit-reconstruct.test.d.ts +0 -2
  55. package/dist/__tests__/audit-reconstruct.test.d.ts.map +0 -1
  56. package/dist/__tests__/audit-reconstruct.test.js +0 -287
  57. package/dist/__tests__/audit-reconstruct.test.js.map +0 -1
  58. package/dist/__tests__/audit-report.test.d.ts +0 -2
  59. package/dist/__tests__/audit-report.test.d.ts.map +0 -1
  60. package/dist/__tests__/audit-report.test.js +0 -186
  61. package/dist/__tests__/audit-report.test.js.map +0 -1
  62. package/dist/__tests__/audit-roundtrip.test.d.ts +0 -2
  63. package/dist/__tests__/audit-roundtrip.test.d.ts.map +0 -1
  64. package/dist/__tests__/audit-roundtrip.test.js +0 -368
  65. package/dist/__tests__/audit-roundtrip.test.js.map +0 -1
  66. package/dist/__tests__/audit-temporal.test.d.ts +0 -2
  67. package/dist/__tests__/audit-temporal.test.d.ts.map +0 -1
  68. package/dist/__tests__/audit-temporal.test.js +0 -364
  69. package/dist/__tests__/audit-temporal.test.js.map +0 -1
  70. package/dist/__tests__/audit-tiers.test.d.ts +0 -2
  71. package/dist/__tests__/audit-tiers.test.d.ts.map +0 -1
  72. package/dist/__tests__/audit-tiers.test.js +0 -282
  73. package/dist/__tests__/audit-tiers.test.js.map +0 -1
  74. package/dist/__tests__/audit-witness-real.test.d.ts +0 -19
  75. package/dist/__tests__/audit-witness-real.test.d.ts.map +0 -1
  76. package/dist/__tests__/audit-witness-real.test.js +0 -82
  77. package/dist/__tests__/audit-witness-real.test.js.map +0 -1
  78. package/dist/__tests__/audit-witness.test.d.ts +0 -2
  79. package/dist/__tests__/audit-witness.test.d.ts.map +0 -1
  80. package/dist/__tests__/audit-witness.test.js +0 -308
  81. package/dist/__tests__/audit-witness.test.js.map +0 -1
  82. package/dist/__tests__/canonical.test.d.ts +0 -2
  83. package/dist/__tests__/canonical.test.d.ts.map +0 -1
  84. package/dist/__tests__/canonical.test.js +0 -162
  85. package/dist/__tests__/canonical.test.js.map +0 -1
  86. package/dist/__tests__/chain-hash-anchor.test.d.ts +0 -22
  87. package/dist/__tests__/chain-hash-anchor.test.d.ts.map +0 -1
  88. package/dist/__tests__/chain-hash-anchor.test.js +0 -55
  89. package/dist/__tests__/chain-hash-anchor.test.js.map +0 -1
  90. package/dist/__tests__/commit-service.integration.test.d.ts +0 -2
  91. package/dist/__tests__/commit-service.integration.test.d.ts.map +0 -1
  92. package/dist/__tests__/commit-service.integration.test.js +0 -95
  93. package/dist/__tests__/commit-service.integration.test.js.map +0 -1
  94. package/dist/__tests__/constructor.test.d.ts +0 -2
  95. package/dist/__tests__/constructor.test.d.ts.map +0 -1
  96. package/dist/__tests__/constructor.test.js +0 -267
  97. package/dist/__tests__/constructor.test.js.map +0 -1
  98. package/dist/__tests__/declared-proof-fixture.d.ts +0 -66
  99. package/dist/__tests__/declared-proof-fixture.d.ts.map +0 -1
  100. package/dist/__tests__/declared-proof-fixture.js +0 -66
  101. package/dist/__tests__/declared-proof-fixture.js.map +0 -1
  102. package/dist/__tests__/fuse-inline.test.d.ts +0 -2
  103. package/dist/__tests__/fuse-inline.test.d.ts.map +0 -1
  104. package/dist/__tests__/fuse-inline.test.js +0 -181
  105. package/dist/__tests__/fuse-inline.test.js.map +0 -1
  106. package/dist/__tests__/fuse-placement.test.d.ts +0 -2
  107. package/dist/__tests__/fuse-placement.test.d.ts.map +0 -1
  108. package/dist/__tests__/fuse-placement.test.js +0 -31
  109. package/dist/__tests__/fuse-placement.test.js.map +0 -1
  110. package/dist/__tests__/fuse-roundtrip.test.d.ts +0 -2
  111. package/dist/__tests__/fuse-roundtrip.test.d.ts.map +0 -1
  112. package/dist/__tests__/fuse-roundtrip.test.js +0 -241
  113. package/dist/__tests__/fuse-roundtrip.test.js.map +0 -1
  114. package/dist/__tests__/fuse-sdk.test.d.ts +0 -2
  115. package/dist/__tests__/fuse-sdk.test.d.ts.map +0 -1
  116. package/dist/__tests__/fuse-sdk.test.js +0 -117
  117. package/dist/__tests__/fuse-sdk.test.js.map +0 -1
  118. package/dist/__tests__/fuse-set-sdk.test.d.ts +0 -2
  119. package/dist/__tests__/fuse-set-sdk.test.d.ts.map +0 -1
  120. package/dist/__tests__/fuse-set-sdk.test.js +0 -721
  121. package/dist/__tests__/fuse-set-sdk.test.js.map +0 -1
  122. package/dist/__tests__/fuse-set.test.d.ts +0 -2
  123. package/dist/__tests__/fuse-set.test.d.ts.map +0 -1
  124. package/dist/__tests__/fuse-set.test.js +0 -889
  125. package/dist/__tests__/fuse-set.test.js.map +0 -1
  126. package/dist/__tests__/fuse-set2.test.d.ts +0 -2
  127. package/dist/__tests__/fuse-set2.test.d.ts.map +0 -1
  128. package/dist/__tests__/fuse-set2.test.js +0 -294
  129. package/dist/__tests__/fuse-set2.test.js.map +0 -1
  130. package/dist/__tests__/fuse-vectors.test.d.ts +0 -2
  131. package/dist/__tests__/fuse-vectors.test.d.ts.map +0 -1
  132. package/dist/__tests__/fuse-vectors.test.js +0 -175
  133. package/dist/__tests__/fuse-vectors.test.js.map +0 -1
  134. package/dist/__tests__/fuse-verify.test.d.ts +0 -2
  135. package/dist/__tests__/fuse-verify.test.d.ts.map +0 -1
  136. package/dist/__tests__/fuse-verify.test.js +0 -250
  137. package/dist/__tests__/fuse-verify.test.js.map +0 -1
  138. package/dist/__tests__/hello-world.test.d.ts +0 -2
  139. package/dist/__tests__/hello-world.test.d.ts.map +0 -1
  140. package/dist/__tests__/hello-world.test.js +0 -9
  141. package/dist/__tests__/hello-world.test.js.map +0 -1
  142. package/dist/__tests__/mock-proof-fixture.d.ts +0 -15
  143. package/dist/__tests__/mock-proof-fixture.d.ts.map +0 -1
  144. package/dist/__tests__/mock-proof-fixture.js +0 -34
  145. package/dist/__tests__/mock-proof-fixture.js.map +0 -1
  146. package/dist/__tests__/policy-enforcement.test.d.ts +0 -2
  147. package/dist/__tests__/policy-enforcement.test.d.ts.map +0 -1
  148. package/dist/__tests__/policy-enforcement.test.js +0 -188
  149. package/dist/__tests__/policy-enforcement.test.js.map +0 -1
  150. package/dist/__tests__/proof-hash-regression.test.d.ts +0 -2
  151. package/dist/__tests__/proof-hash-regression.test.d.ts.map +0 -1
  152. package/dist/__tests__/proof-hash-regression.test.js +0 -95
  153. package/dist/__tests__/proof-hash-regression.test.js.map +0 -1
  154. package/dist/__tests__/proof-hash.test.d.ts +0 -2
  155. package/dist/__tests__/proof-hash.test.d.ts.map +0 -1
  156. package/dist/__tests__/proof-hash.test.js +0 -116
  157. package/dist/__tests__/proof-hash.test.js.map +0 -1
  158. package/dist/__tests__/proof-integrity.test.d.ts +0 -2
  159. package/dist/__tests__/proof-integrity.test.d.ts.map +0 -1
  160. package/dist/__tests__/proof-integrity.test.js +0 -454
  161. package/dist/__tests__/proof-integrity.test.js.map +0 -1
  162. package/dist/__tests__/realistic-proof-fixture.d.ts +0 -56
  163. package/dist/__tests__/realistic-proof-fixture.d.ts.map +0 -1
  164. package/dist/__tests__/realistic-proof-fixture.js +0 -57
  165. package/dist/__tests__/realistic-proof-fixture.js.map +0 -1
  166. package/dist/__tests__/run.test.d.ts +0 -2
  167. package/dist/__tests__/run.test.d.ts.map +0 -1
  168. package/dist/__tests__/run.test.js +0 -178
  169. package/dist/__tests__/run.test.js.map +0 -1
  170. package/dist/__tests__/verifier.test.d.ts +0 -2
  171. package/dist/__tests__/verifier.test.d.ts.map +0 -1
  172. package/dist/__tests__/verifier.test.js +0 -531
  173. package/dist/__tests__/verifier.test.js.map +0 -1
  174. package/dist/canonical.d.ts +0 -54
  175. package/dist/canonical.d.ts.map +0 -1
  176. package/dist/canonical.js +0 -119
  177. package/dist/canonical.js.map +0 -1
  178. package/dist/proof-hash.d.ts +0 -9
  179. package/dist/proof-hash.d.ts.map +0 -1
  180. package/dist/proof-hash.js +0 -75
  181. package/dist/proof-hash.js.map +0 -1
  182. package/dist/types.d.ts +0 -705
  183. package/dist/types.d.ts.map +0 -1
  184. package/dist/types.js +0 -3
  185. package/dist/types.js.map +0 -1
  186. package/dist/verifier.d.ts +0 -27
  187. package/dist/verifier.d.ts.map +0 -1
  188. package/dist/verifier.js +0 -844
  189. package/dist/verifier.js.map +0 -1
  190. package/src/__tests__/audit-anchors.test.ts +0 -188
  191. package/src/__tests__/audit-anomalies.test.ts +0 -815
  192. package/src/__tests__/audit-attestation.test.ts +0 -529
  193. package/src/__tests__/audit-bench-smoke.test.ts +0 -108
  194. package/src/__tests__/audit-boundary.test.ts +0 -96
  195. package/src/__tests__/audit-cli.test.ts +0 -288
  196. package/src/__tests__/audit-dependencies.test.ts +0 -141
  197. package/src/__tests__/audit-fixtures.ts +0 -736
  198. package/src/__tests__/audit-ingest.test.ts +0 -575
  199. package/src/__tests__/audit-memory-ingest.test.ts +0 -156
  200. package/src/__tests__/audit-property.test.ts +0 -892
  201. package/src/__tests__/audit-real-fixtures.test.ts +0 -153
  202. package/src/__tests__/audit-real-live.test.ts +0 -128
  203. package/src/__tests__/audit-reconstruct.test.ts +0 -353
  204. package/src/__tests__/audit-report.test.ts +0 -222
  205. package/src/__tests__/audit-roundtrip.test.ts +0 -464
  206. package/src/__tests__/audit-temporal.test.ts +0 -446
  207. package/src/__tests__/audit-tiers.test.ts +0 -343
  208. package/src/__tests__/audit-witness-real.test.ts +0 -92
  209. package/src/__tests__/audit-witness.test.ts +0 -345
  210. package/src/__tests__/canonical.test.ts +0 -253
  211. package/src/__tests__/chain-hash-anchor.test.ts +0 -67
  212. package/src/__tests__/commit-service.integration.test.ts +0 -117
  213. package/src/__tests__/constructor.test.ts +0 -340
  214. package/src/__tests__/declared-proof-fixture.ts +0 -65
  215. package/src/__tests__/fuse-inline.test.ts +0 -211
  216. package/src/__tests__/fuse-placement.test.ts +0 -32
  217. package/src/__tests__/fuse-roundtrip.test.ts +0 -243
  218. package/src/__tests__/fuse-sdk.test.ts +0 -142
  219. package/src/__tests__/fuse-set-sdk.test.ts +0 -852
  220. package/src/__tests__/fuse-set.test.ts +0 -1027
  221. package/src/__tests__/fuse-set2.test.ts +0 -343
  222. package/src/__tests__/fuse-vectors.test.ts +0 -218
  223. package/src/__tests__/fuse-verify.test.ts +0 -278
  224. package/src/__tests__/hello-world.test.ts +0 -10
  225. package/src/__tests__/mock-proof-fixture.ts +0 -36
  226. package/src/__tests__/policy-enforcement.test.ts +0 -226
  227. package/src/__tests__/proof-hash-regression.test.ts +0 -107
  228. package/src/__tests__/proof-hash.test.ts +0 -129
  229. package/src/__tests__/proof-integrity.test.ts +0 -576
  230. package/src/__tests__/real-fixtures/anchor-after-112762.json +0 -47
  231. package/src/__tests__/real-fixtures/anchor-with-ethereum-112758.json +0 -47
  232. package/src/__tests__/real-fixtures/live-proof-0.json +0 -42
  233. package/src/__tests__/real-fixtures/live-proof-1.json +0 -43
  234. package/src/__tests__/real-fixtures/live-proof-2.json +0 -43
  235. package/src/__tests__/real-fixtures/successor-112760.json +0 -38
  236. package/src/__tests__/real-fixtures/witness-25525146.json +0 -6
  237. package/src/__tests__/real-fixtures/witness-25525147.json +0 -6
  238. package/src/__tests__/realistic-proof-fixture.ts +0 -57
  239. package/src/__tests__/verifier.test.ts +0 -624
@@ -1,343 +0,0 @@
1
- // Copyright (c) Argento Computing Inc. All rights reserved. See LICENSE.
2
-
3
- /**
4
- * Tests for @mikeargento/bitgraph-audit verification tiers: full
5
- * verification when artifact bytes are present (canonical verify()),
6
- * bytes-free integrity when they are absent (verifyProofIntegrity()),
7
- * exact failure reasons, VerificationPolicy passthrough, and per-run
8
- * epoch link state reset.
9
- */
10
-
11
- import { describe, test, before, after } from "node:test";
12
- import * as assert from "node:assert/strict";
13
- import { rm, writeFile } from "node:fs/promises";
14
- import { join } from "node:path";
15
- import { computeProofHash } from "@mikeargento/bitgraph-verify";
16
- import type { BitGraphProof } from "@mikeargento/bitgraph-verify";
17
- import { ingestBundle, verifyObservedProofs } from "@mikeargento/bitgraph-audit";
18
- import {
19
- b64,
20
- makeChainIdProof,
21
- makeConstructorProof,
22
- makeEpochLinkProof,
23
- makeTar,
24
- makeTempDir,
25
- proofJson,
26
- utf8,
27
- writeBundleDir,
28
- } from "./audit-fixtures.js";
29
- import { sha256 } from "@noble/hashes/sha256";
30
-
31
- const tempDirs: string[] = [];
32
-
33
- async function newBundleDir(): Promise<string> {
34
- const dir = await makeTempDir("bitgraph-audit-tiers-");
35
- tempDirs.push(dir);
36
- return dir;
37
- }
38
-
39
- after(async () => {
40
- for (const dir of tempDirs) {
41
- await rm(dir, { recursive: true, force: true });
42
- }
43
- });
44
-
45
- let fxProof!: BitGraphProof;
46
- let fxBytes!: Uint8Array;
47
- let fxHash!: string;
48
-
49
- before(async () => {
50
- const made = await makeConstructorProof();
51
- fxProof = made.proof;
52
- fxBytes = made.bytes;
53
- fxHash = computeProofHash(fxProof);
54
- });
55
-
56
- function clone(proof: BitGraphProof): BitGraphProof {
57
- return JSON.parse(JSON.stringify(proof)) as BitGraphProof;
58
- }
59
-
60
- // ---------------------------------------------------------------------------
61
- // Tier routing
62
- // ---------------------------------------------------------------------------
63
-
64
- describe("audit tiers: artifact present", () => {
65
- test("full verification through canonical verify(), status verified", async () => {
66
- const dir = await newBundleDir();
67
- await writeBundleDir(dir, {
68
- "proofs/p.json": proofJson(fxProof),
69
- "media/original.bin": fxBytes,
70
- });
71
-
72
- const ingest = await ingestBundle(dir);
73
- const summary = await verifyObservedProofs(ingest);
74
-
75
- assert.deepEqual(summary, {
76
- total: 1,
77
- verified: 1,
78
- failed: 0,
79
- artifactUnavailable: 0,
80
- chainless: 1,
81
- });
82
- const verification = ingest.proofs[0]!.verification!;
83
- assert.equal(verification.tier, "full");
84
- assert.equal(verification.status, "verified");
85
- assert.equal(verification.artifactPath, "media/original.bin");
86
- assert.equal(verification.reason, undefined);
87
- });
88
-
89
- test("tampered signature fails at the full tier with the verifier's exact reason", async () => {
90
- const tampered = clone(fxProof);
91
- const sigBytes = Buffer.from(tampered.signer.signatureB64, "base64");
92
- sigBytes[0] = (sigBytes[0]! + 1) % 256;
93
- tampered.signer.signatureB64 = sigBytes.toString("base64");
94
-
95
- const dir = await newBundleDir();
96
- await writeBundleDir(dir, {
97
- "proofs/p.json": proofJson(tampered),
98
- "media/original.bin": fxBytes,
99
- });
100
-
101
- const ingest = await ingestBundle(dir);
102
- const summary = await verifyObservedProofs(ingest);
103
-
104
- assert.equal(summary.failed, 1);
105
- const verification = ingest.proofs[0]!.verification!;
106
- assert.equal(verification.tier, "full");
107
- assert.equal(verification.status, "failed");
108
- assert.equal(verification.reason, "signature verification failed: signature does not match");
109
- });
110
-
111
- test("full verification works through a tar container (bytes re-streamed)", async () => {
112
- const dir = await newBundleDir();
113
- const tar = makeTar([
114
- { name: "proofs/p.json", content: proofJson(fxProof) },
115
- { name: "media/original.bin", content: fxBytes },
116
- ]);
117
- const tarPath = join(dir, "bundle.tar");
118
- await writeFile(tarPath, tar);
119
-
120
- const ingest = await ingestBundle(tarPath);
121
- const summary = await verifyObservedProofs(ingest);
122
- assert.equal(summary.verified, 1);
123
- assert.equal(ingest.proofs[0]!.verification!.tier, "full");
124
- });
125
-
126
- test("a proof with a signed chainId verifies fully (unknown-field tolerance end to end)", async () => {
127
- const made = await makeChainIdProof({ chainId: "bitgraph:main", counter: "2", epochId: "epoch-c" });
128
- const dir = await newBundleDir();
129
- await writeBundleDir(dir, {
130
- "p.json": proofJson(made.proof),
131
- "artifact.bin": made.bytes,
132
- });
133
-
134
- const ingest = await ingestBundle(dir);
135
- const summary = await verifyObservedProofs(ingest);
136
- assert.equal(summary.verified, 1);
137
- assert.equal(ingest.proofs[0]!.chainId, "bitgraph:main");
138
- });
139
- });
140
-
141
- describe("audit tiers: artifact absent", () => {
142
- test("integrity tier records artifact-unavailable, never verified", async () => {
143
- const dir = await newBundleDir();
144
- await writeBundleDir(dir, {
145
- "proofs/p.json": proofJson(fxProof),
146
- });
147
-
148
- const ingest = await ingestBundle(dir);
149
- const summary = await verifyObservedProofs(ingest);
150
-
151
- assert.deepEqual(summary, {
152
- total: 1,
153
- verified: 0,
154
- failed: 0,
155
- artifactUnavailable: 1,
156
- chainless: 1,
157
- });
158
- const verification = ingest.proofs[0]!.verification!;
159
- assert.equal(verification.tier, "integrity");
160
- assert.equal(verification.status, "artifact-unavailable");
161
- assert.equal(verification.artifactPath, undefined);
162
- });
163
-
164
- test("a decoy file named like the artifact does not bind (matching is content-addressed)", async () => {
165
- const dir = await newBundleDir();
166
- await writeBundleDir(dir, {
167
- "proofs/p.json": proofJson(fxProof),
168
- // Named to look like the artifact, but the bytes hash differently.
169
- "artifacts/original.bin": utf8("not the committed bytes"),
170
- });
171
-
172
- const ingest = await ingestBundle(dir);
173
- const summary = await verifyObservedProofs(ingest);
174
- assert.equal(summary.artifactUnavailable, 1);
175
- assert.equal(summary.verified, 0);
176
- assert.equal(ingest.proofs[0]!.verification!.tier, "integrity");
177
- });
178
-
179
- test("a corrupted artifact digest fails integrity with the verifier's exact reason", async () => {
180
- // Flip the committed digest to some other 32-byte value. Content
181
- // addressing then finds no artifact (the original bytes no longer
182
- // match), and the signature check fails because the digest sits
183
- // inside the signed body.
184
- const corrupted = clone(fxProof);
185
- corrupted.artifact.digestB64 = b64(sha256(utf8("some other content")));
186
-
187
- const dir = await newBundleDir();
188
- await writeBundleDir(dir, {
189
- "proofs/p.json": proofJson(corrupted),
190
- "media/original.bin": fxBytes,
191
- });
192
-
193
- const ingest = await ingestBundle(dir);
194
- const summary = await verifyObservedProofs(ingest);
195
-
196
- assert.equal(summary.failed, 1);
197
- assert.equal(summary.verified, 0);
198
- const verification = ingest.proofs[0]!.verification!;
199
- assert.equal(verification.tier, "integrity");
200
- assert.equal(verification.status, "failed");
201
- assert.equal(verification.reason, "signature verification failed: signature does not match");
202
- // The genuine artifact bytes did not bind to the corrupted digest.
203
- assert.equal(
204
- ingest.artifacts.find((a) => a.paths.includes("media/original.bin"))!.matchedProofHashes.length,
205
- 0
206
- );
207
- });
208
- });
209
-
210
- // ---------------------------------------------------------------------------
211
- // Deduplication and exclusion interplay
212
- // ---------------------------------------------------------------------------
213
-
214
- describe("audit tiers: unique verification", () => {
215
- test("semantic duplicates are verified once, as one observed proof", async () => {
216
- const dir = await newBundleDir();
217
- await writeBundleDir(dir, {
218
- "compact.json": JSON.stringify(fxProof),
219
- "pretty.json": JSON.stringify(fxProof, null, 2),
220
- "media/original.bin": fxBytes,
221
- });
222
-
223
- const ingest = await ingestBundle(dir);
224
- const summary = await verifyObservedProofs(ingest);
225
- assert.equal(summary.total, 1);
226
- assert.equal(summary.verified, 1);
227
- assert.equal(ingest.proofs[0]!.sources.length, 2);
228
- });
229
-
230
- test("unsupported-version files are excluded from verification entirely", async () => {
231
- const dir = await newBundleDir();
232
- await writeBundleDir(dir, {
233
- "legacy.json": JSON.stringify({
234
- version: "occ/1",
235
- artifact: { hashAlg: "sha256", digestB64: b64(sha256(fxBytes)) },
236
- commit: { nonceB64: "AAAA" },
237
- signer: { publicKeyB64: "AAAA", signatureB64: "AAAA" },
238
- }),
239
- "good.json": proofJson(fxProof),
240
- });
241
-
242
- const ingest = await ingestBundle(dir);
243
- const summary = await verifyObservedProofs(ingest);
244
- assert.equal(summary.total, 1);
245
- assert.equal(ingest.counts.unsupportedVersion, 1);
246
- });
247
- });
248
-
249
- // ---------------------------------------------------------------------------
250
- // Policy passthrough
251
- // ---------------------------------------------------------------------------
252
-
253
- describe("audit tiers: VerificationPolicy passthrough", () => {
254
- test("trustAnchors constraints are applied by the canonical verifier", async () => {
255
- const dir = await newBundleDir();
256
- await writeBundleDir(dir, {
257
- "proofs/p.json": proofJson(fxProof),
258
- "media/original.bin": fxBytes,
259
- });
260
-
261
- const ingest = await ingestBundle(dir);
262
- const summary = await verifyObservedProofs(ingest, {
263
- trustAnchors: { allowedMeasurements: ["some-other-measurement"] },
264
- });
265
-
266
- assert.equal(summary.failed, 1);
267
- const verification = ingest.proofs[0]!.verification!;
268
- assert.equal(verification.status, "failed");
269
- assert.match(verification.reason ?? "", /is not in the allowed set/);
270
- });
271
-
272
- test("a satisfied policy leaves the proof verified", async () => {
273
- const dir = await newBundleDir();
274
- await writeBundleDir(dir, {
275
- "proofs/p.json": proofJson(fxProof),
276
- "media/original.bin": fxBytes,
277
- });
278
-
279
- const ingest = await ingestBundle(dir);
280
- const summary = await verifyObservedProofs(ingest, {
281
- trustAnchors: { allowedMeasurements: [fxProof.environment.measurement] },
282
- });
283
- assert.equal(summary.verified, 1);
284
- });
285
- });
286
-
287
- // ---------------------------------------------------------------------------
288
- // Epoch link state
289
- // ---------------------------------------------------------------------------
290
-
291
- describe("audit tiers: epoch link state", () => {
292
- const predecessor = {
293
- prevEpochId: "epoch-predecessor",
294
- prevCounter: "42",
295
- prevProofHashB64: b64(sha256(utf8("terminal-proof-of-predecessor"))),
296
- };
297
-
298
- test("within one run, a second consumption of the same predecessor is a detected fork", async () => {
299
- const first = await makeEpochLinkProof({ ...predecessor, toEpochId: "epoch-successor-a" });
300
- const second = await makeEpochLinkProof({ ...predecessor, toEpochId: "epoch-successor-b" });
301
-
302
- const dir = await newBundleDir();
303
- // Observation order is deterministic (sorted directory walk):
304
- // a-genesis before b-genesis.
305
- await writeBundleDir(dir, {
306
- "a-genesis.json": proofJson(first.proof),
307
- "b-genesis.json": proofJson(second.proof),
308
- });
309
-
310
- const ingest = await ingestBundle(dir);
311
- const summary = await verifyObservedProofs(ingest);
312
-
313
- assert.equal(summary.total, 2);
314
- assert.equal(summary.artifactUnavailable, 1);
315
- assert.equal(summary.failed, 1);
316
- const a = ingest.proofs.find((p) => p.sources[0]!.path === "a-genesis.json")!;
317
- const b = ingest.proofs.find((p) => p.sources[0]!.path === "b-genesis.json")!;
318
- assert.equal(a.verification!.status, "artifact-unavailable");
319
- assert.equal(b.verification!.status, "failed");
320
- assert.match(b.verification!.reason ?? "", /FORK DETECTED/);
321
- assert.equal(a.hasEpochLink, true);
322
- });
323
-
324
- test("state is reset per run: a fresh audit is not poisoned by a previous one", async () => {
325
- const runOne = await makeEpochLinkProof({ ...predecessor, toEpochId: "epoch-successor-x" });
326
- const dirOne = await newBundleDir();
327
- await writeBundleDir(dirOne, { "genesis-x.json": proofJson(runOne.proof) });
328
- const ingestOne = await ingestBundle(dirOne);
329
- const summaryOne = await verifyObservedProofs(ingestOne);
330
- assert.equal(summaryOne.failed, 0);
331
-
332
- // A different successor consumes the same predecessor in a separate
333
- // bundle. Within one run that would be a fork; across runs the state
334
- // must have been reset, so this verifies cleanly.
335
- const runTwo = await makeEpochLinkProof({ ...predecessor, toEpochId: "epoch-successor-y" });
336
- const dirTwo = await newBundleDir();
337
- await writeBundleDir(dirTwo, { "genesis-y.json": proofJson(runTwo.proof) });
338
- const ingestTwo = await ingestBundle(dirTwo);
339
- const summaryTwo = await verifyObservedProofs(ingestTwo);
340
- assert.equal(summaryTwo.failed, 0);
341
- assert.equal(summaryTwo.artifactUnavailable, 1);
342
- });
343
- });
@@ -1,92 +0,0 @@
1
- /**
2
- * End-to-end: block-header witnesses produced by the exporter make an anchor's
3
- * Ethereum time claim verifiable FULLY OFFLINE, and the audit accepts them.
4
- *
5
- * The two witness fixtures were produced by the same header-RLP encoder the
6
- * website export uses (website/src/lib/eth-header.ts), for the two real
7
- * Ethereum blocks the whitepaper bundle's anchors signed: 25525146 (the before
8
- * anchor, block of commit 112758) and 25525147 (the after anchor, block of
9
- * commit 112762). Each was self-checked at generation time: keccak256(headerRlp)
10
- * equals the block hash.
11
- *
12
- * This test bundles the three real proofs plus the two witnesses and confirms
13
- * the audit's zero-network witness procedure verifies both, so the exporter's
14
- * output and the verifier's expectations actually meet. Before this feature the
15
- * anchors carried a block hash but no header, so the timestamp could only be
16
- * resolved online; now the bundle stands alone.
17
- */
18
-
19
- import { describe, it, before, after } from "node:test";
20
- import * as assert from "node:assert/strict";
21
- import { mkdtemp, mkdir, writeFile, rm, readFile } from "node:fs/promises";
22
- import { tmpdir } from "node:os";
23
- import { join } from "node:path";
24
- import { fileURLToPath } from "node:url";
25
- import { runAudit, buildJsonReport, computeExitFlags, type AuditResult } from "@mikeargento/bitgraph-audit";
26
- import { computeProofHash, type BitGraphProof } from "@mikeargento/bitgraph-verify";
27
-
28
- function safe(value: string): string {
29
- return value.replace(/[^A-Za-z0-9]/g, "_");
30
- }
31
- async function fixture(name: string): Promise<Record<string, unknown>> {
32
- const url = new URL(`../../src/__tests__/real-fixtures/${name}`, import.meta.url);
33
- return JSON.parse(await readFile(fileURLToPath(url), "utf8"));
34
- }
35
-
36
- describe("audit: real block-header witnesses verify offline", () => {
37
- let dir: string;
38
- let result: AuditResult;
39
-
40
- before(async () => {
41
- const proofs = await Promise.all([
42
- fixture("anchor-with-ethereum-112758.json"),
43
- fixture("successor-112760.json"),
44
- fixture("anchor-after-112762.json"),
45
- ]);
46
-
47
- dir = await mkdtemp(join(tmpdir(), "bitgraph-audit-witness-"));
48
- for (const proof of proofs) {
49
- const commit = proof.commit as { epochId: string; counter: string };
50
- const epochDir = join(dir, "proofs", safe(commit.epochId));
51
- await mkdir(epochDir, { recursive: true });
52
- await writeFile(
53
- join(epochDir, `${commit.counter}-${safe(computeProofHash(proof as unknown as BitGraphProof))}.json`),
54
- JSON.stringify(proof)
55
- );
56
- }
57
- // Witnesses discovered by shape; path is conventional only.
58
- const witnessDir = join(dir, "witnesses");
59
- await mkdir(witnessDir, { recursive: true });
60
- for (const block of [25525146, 25525147]) {
61
- const w = await fixture(`witness-${block}.json`);
62
- await writeFile(join(witnessDir, `${block}.json`), JSON.stringify(w));
63
- }
64
- result = await runAudit(dir);
65
- });
66
-
67
- after(async () => {
68
- if (dir !== undefined) await rm(dir, { recursive: true, force: true });
69
- });
70
-
71
- it("ingests both witnesses and verifies both against the signed anchor hashes", () => {
72
- const report = buildJsonReport(result);
73
- assert.equal(report.input.counts.witnesses, 2);
74
- assert.equal(report.summary.temporal.anchorsWithVerifiedWitness, 2);
75
- });
76
-
77
- it("lower-bounds the whitepaper's causal segment and records its following anchor", () => {
78
- const report = buildJsonReport(result);
79
- // Both bounding anchors now carry a verified offline timestamp, so the
80
- // segment holding the whitepaper commit is bracketed (upper AND lower).
81
- assert.equal(report.summary.temporal.segmentsWithFollowingAnchor, 1);
82
- assert.equal(report.summary.temporal.segmentsUnanchored, 0);
83
- });
84
-
85
- it("exits clean (code 0): witnesses only add evidence, never failure", () => {
86
- assert.deepEqual(computeExitFlags(result), {
87
- verificationFailures: false,
88
- chainAnomaliesOrDivergences: false,
89
- code: 0,
90
- });
91
- });
92
- });