@mikeargento/bitgraph-audit 0.1.0

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 (108) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +11 -0
  3. package/dist/anchors.d.ts +31 -0
  4. package/dist/anchors.d.ts.map +1 -0
  5. package/dist/anchors.js +116 -0
  6. package/dist/anchors.js.map +1 -0
  7. package/dist/anomalies.d.ts +42 -0
  8. package/dist/anomalies.d.ts.map +1 -0
  9. package/dist/anomalies.js +642 -0
  10. package/dist/anomalies.js.map +1 -0
  11. package/dist/attestation.d.ts +20 -0
  12. package/dist/attestation.d.ts.map +1 -0
  13. package/dist/attestation.js +795 -0
  14. package/dist/attestation.js.map +1 -0
  15. package/dist/audit.d.ts +19 -0
  16. package/dist/audit.d.ts.map +1 -0
  17. package/dist/audit.js +116 -0
  18. package/dist/audit.js.map +1 -0
  19. package/dist/authority.d.ts +37 -0
  20. package/dist/authority.d.ts.map +1 -0
  21. package/dist/authority.js +126 -0
  22. package/dist/authority.js.map +1 -0
  23. package/dist/aws-nitro-root-ca.d.ts +24 -0
  24. package/dist/aws-nitro-root-ca.d.ts.map +1 -0
  25. package/dist/aws-nitro-root-ca.js +44 -0
  26. package/dist/aws-nitro-root-ca.js.map +1 -0
  27. package/dist/cli.d.ts +3 -0
  28. package/dist/cli.d.ts.map +1 -0
  29. package/dist/cli.js +257 -0
  30. package/dist/cli.js.map +1 -0
  31. package/dist/contents-hash.d.ts +30 -0
  32. package/dist/contents-hash.d.ts.map +1 -0
  33. package/dist/contents-hash.js +73 -0
  34. package/dist/contents-hash.js.map +1 -0
  35. package/dist/export.d.ts +64 -0
  36. package/dist/export.d.ts.map +1 -0
  37. package/dist/export.js +192 -0
  38. package/dist/export.js.map +1 -0
  39. package/dist/index.d.ts +31 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +17 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/ingest.d.ts +36 -0
  44. package/dist/ingest.d.ts.map +1 -0
  45. package/dist/ingest.js +828 -0
  46. package/dist/ingest.js.map +1 -0
  47. package/dist/reconstruct.d.ts +40 -0
  48. package/dist/reconstruct.d.ts.map +1 -0
  49. package/dist/reconstruct.js +400 -0
  50. package/dist/reconstruct.js.map +1 -0
  51. package/dist/report-json.d.ts +3 -0
  52. package/dist/report-json.d.ts.map +1 -0
  53. package/dist/report-json.js +290 -0
  54. package/dist/report-json.js.map +1 -0
  55. package/dist/report-md.d.ts +3 -0
  56. package/dist/report-md.d.ts.map +1 -0
  57. package/dist/report-md.js +853 -0
  58. package/dist/report-md.js.map +1 -0
  59. package/dist/rlp.d.ts +37 -0
  60. package/dist/rlp.d.ts.map +1 -0
  61. package/dist/rlp.js +120 -0
  62. package/dist/rlp.js.map +1 -0
  63. package/dist/tar.d.ts +47 -0
  64. package/dist/tar.d.ts.map +1 -0
  65. package/dist/tar.js +483 -0
  66. package/dist/tar.js.map +1 -0
  67. package/dist/temporal.d.ts +55 -0
  68. package/dist/temporal.d.ts.map +1 -0
  69. package/dist/temporal.js +461 -0
  70. package/dist/temporal.js.map +1 -0
  71. package/dist/types.d.ts +1389 -0
  72. package/dist/types.d.ts.map +1 -0
  73. package/dist/types.js +3 -0
  74. package/dist/types.js.map +1 -0
  75. package/dist/validity.d.ts +21 -0
  76. package/dist/validity.d.ts.map +1 -0
  77. package/dist/validity.js +86 -0
  78. package/dist/validity.js.map +1 -0
  79. package/dist/verify-tiers.d.ts +11 -0
  80. package/dist/verify-tiers.d.ts.map +1 -0
  81. package/dist/verify-tiers.js +120 -0
  82. package/dist/verify-tiers.js.map +1 -0
  83. package/dist/witness.d.ts +25 -0
  84. package/dist/witness.d.ts.map +1 -0
  85. package/dist/witness.js +308 -0
  86. package/dist/witness.js.map +1 -0
  87. package/package.json +42 -0
  88. package/src/anchors.ts +168 -0
  89. package/src/anomalies.ts +773 -0
  90. package/src/attestation.ts +878 -0
  91. package/src/audit.ts +136 -0
  92. package/src/authority.ts +165 -0
  93. package/src/aws-nitro-root-ca.ts +47 -0
  94. package/src/cli.ts +284 -0
  95. package/src/contents-hash.ts +95 -0
  96. package/src/export.ts +278 -0
  97. package/src/index.ts +122 -0
  98. package/src/ingest.ts +967 -0
  99. package/src/reconstruct.ts +491 -0
  100. package/src/report-json.ts +331 -0
  101. package/src/report-md.ts +1067 -0
  102. package/src/rlp.ts +142 -0
  103. package/src/tar.ts +587 -0
  104. package/src/temporal.ts +629 -0
  105. package/src/types.ts +1528 -0
  106. package/src/validity.ts +90 -0
  107. package/src/verify-tiers.ts +137 -0
  108. package/src/witness.ts +407 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024-2026 Mike Argento
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,11 @@
1
+ # @mikeargento/bitgraph-audit
2
+
3
+ An Audit Bundle is a portable collection of BitGraph proofs, optionally accompanied by the original artifact bytes, anchor witness material, and a manifest, packaged as a directory, a `.tar`, or a `.tar.gz`. The premise: the operator's database is not the evidence. BitGraph proofs are self-contained objects, and this package lets an independent reader take a bundle, verify whatever evidence it contains fully offline, and reconstruct the causal record without asking the operator which history to trust. The on-disk format is specified in [docs/BUNDLE-FORMAT.md](https://github.com/mikeargento/bitgraph/blob/main/docs/BUNDLE-FORMAT.md); both this consumer and the bitgraph.ing exporter conform to it.
4
+
5
+ The tool reports exactly what the evidence supports, nothing more. Incomplete input produces an incomplete reconstruction: missing proofs surface as unexplained counter positions and broken predecessor links, which means the supplied evidence cannot reconstruct those positions, not that the authority failed to create them. Divergence between valid objects is presented, never resolved; the reader adjudicates. Proofs without their artifact bytes pass through the bytes-free integrity checks and are reported as artifact-unavailable, never as fully verified. Wall-clock bounds appear only when independently verifiable offline evidence (a locally reconstructed Ethereum block header) is present in the bundle. There is no network access at runtime of any kind.
6
+
7
+ Exactly one proof schema is supported: `bitgraph/1`. The legacy `occ/1` schema is pre-release beta data and is permanently out of scope; proof-shaped files with any other version are rejected at ingest with the stable code `unsupported-version`. All verification semantics come from `@mikeargento/bitgraph-verify` (MIT), the same verifier anyone can run against a single proof. The `bitgraph-audit` CLI runs the whole pipeline (ingest, verification tiers, causal reconstruction, anomaly classification, authority analysis, anchor identification, witness verification, temporal bounds, offline attestation validation) and writes `audit-report.json` and `audit-report.md`; `runAudit()` is the one-call library entry point, and every stage is also exported individually. See [docs/HOW-TO-AUDIT.md](https://github.com/mikeargento/bitgraph/blob/main/docs/HOW-TO-AUDIT.md) for the recipient walkthrough and [docs/BUNDLE-FORMAT.md](https://github.com/mikeargento/bitgraph/blob/main/docs/BUNDLE-FORMAT.md) for the on-disk format.
8
+
9
+ ## License
10
+
11
+ MIT. See LICENSE.
@@ -0,0 +1,31 @@
1
+ /**
2
+ * bitgraph-audit anchor identification (G5)
3
+ *
4
+ * Ethereum anchors are ordinary chain members minted by the anchor
5
+ * service: same counter sequence, same prevB64 links, same signing key as
6
+ * every other proof on the chain. What makes a proof an anchor is the
7
+ * SIGNED attribution:
8
+ *
9
+ * - attribution.name === "Ethereum Anchor" is the discriminator.
10
+ * - attribution.message carries the Ethereum block hash string.
11
+ * - attribution.title carries the block number, only inside the signed
12
+ * Etherscan URL.
13
+ * - artifact.digestB64 is SHA-256 over the block-hash STRING.
14
+ *
15
+ * The unsigned metadata.type === "ethereum-anchor" is corroboration only:
16
+ * agreement and disagreement are recorded, and metadata alone never makes
17
+ * a proof an anchor. The unsigned metadata.anchor block timestamp is
18
+ * never read; wall-clock evidence comes exclusively from verified anchor
19
+ * witnesses (witness.ts). No wall-clock time is ever derived from a block
20
+ * number.
21
+ *
22
+ * Run after verifyObservedProofs so the records carry the run
23
+ * verification status; identification itself reads only the signed body.
24
+ */
25
+ import type { AnchorIdentification, IngestResult } from "./types.js";
26
+ /**
27
+ * Identify anchor proofs among the observed proofs. Read-only and
28
+ * deterministic (observation order).
29
+ */
30
+ export declare function identifyAnchors(ingest: IngestResult): AnchorIdentification;
31
+ //# sourceMappingURL=anchors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anchors.d.ts","sourceRoot":"","sources":["../src/anchors.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EACV,oBAAoB,EAGpB,YAAY,EAEb,MAAM,YAAY,CAAC;AAapB;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,oBAAoB,CAsF1E"}
@@ -0,0 +1,116 @@
1
+ // Copyright (c) 2024-2026 Mike Argento. Licensed under the MIT License. See LICENSE.
2
+ const ANCHOR_ATTRIBUTION_NAME = "Ethereum Anchor";
3
+ const ANCHOR_METADATA_TYPE = "ethereum-anchor";
4
+ /**
5
+ * Strict Etherscan block URL, the exact form the anchor service signs
6
+ * (packages/hosted/src/bitcoin-anchor.ts): https://etherscan.io/block/{n}.
7
+ * Anything else is reported unparseable and the block number treated as
8
+ * absent, never guessed.
9
+ */
10
+ const ETHERSCAN_BLOCK_URL = /^https:\/\/etherscan\.io\/block\/([0-9]+)$/;
11
+ /**
12
+ * Identify anchor proofs among the observed proofs. Read-only and
13
+ * deterministic (observation order).
14
+ */
15
+ export function identifyAnchors(ingest) {
16
+ const anchors = [];
17
+ const metadataOnlyProofHashes = [];
18
+ const findings = [];
19
+ for (const proof of ingest.proofs) {
20
+ const attributionName = readAttributionField(proof, "name");
21
+ const metadataType = readMetadataType(proof);
22
+ const signedAnchor = attributionName === ANCHOR_ATTRIBUTION_NAME;
23
+ if (!signedAnchor) {
24
+ if (metadataType === ANCHOR_METADATA_TYPE) {
25
+ // Unsigned claim with no signed backing: recorded, never trusted.
26
+ metadataOnlyProofHashes.push(proof.proofHash);
27
+ findings.push({
28
+ code: "anchor-metadata-only-claim",
29
+ ...pathOf(proof),
30
+ message: "unsigned metadata.type claims ethereum-anchor, but the signed attribution does not " +
31
+ "identify this proof as an anchor. Metadata is advisory and unsigned; the proof is " +
32
+ "not treated as an anchor.",
33
+ details: { proofHash: proof.proofHash },
34
+ });
35
+ }
36
+ continue;
37
+ }
38
+ // Corroboration between the signed discriminator and the unsigned
39
+ // metadata. Only a present-but-different type disagrees; an absent
40
+ // type is simply absent corroboration.
41
+ const corroboration = metadataType === ANCHOR_METADATA_TYPE
42
+ ? "agrees"
43
+ : metadataType === undefined
44
+ ? "absent"
45
+ : "disagrees";
46
+ if (corroboration === "disagrees") {
47
+ findings.push({
48
+ code: "anchor-metadata-disagreement",
49
+ ...pathOf(proof),
50
+ message: `signed attribution identifies an Ethereum anchor, but unsigned metadata.type is ` +
51
+ `${JSON.stringify(metadataType)}. The signed field governs; the disagreement is recorded.`,
52
+ details: { proofHash: proof.proofHash, metadataType: metadataType },
53
+ });
54
+ }
55
+ const blockHash = readAttributionField(proof, "message");
56
+ const title = readAttributionField(proof, "title");
57
+ const blockNumber = title !== undefined ? (ETHERSCAN_BLOCK_URL.exec(title)?.[1] ?? undefined) : undefined;
58
+ if (blockNumber === undefined) {
59
+ findings.push({
60
+ code: "anchor-title-unparseable",
61
+ ...pathOf(proof),
62
+ message: title === undefined
63
+ ? "anchor proof carries no signed attribution.title; the signed block number is absent"
64
+ : "anchor attribution.title does not parse as an Etherscan block URL; the signed block number is treated as absent",
65
+ details: {
66
+ proofHash: proof.proofHash,
67
+ ...(title !== undefined ? { title } : {}),
68
+ },
69
+ });
70
+ }
71
+ const verification = proof.verification;
72
+ anchors.push({
73
+ proofHash: proof.proofHash,
74
+ ...(proof.epochId !== undefined ? { epochId: proof.epochId } : {}),
75
+ chainId: proof.chainId,
76
+ ...(proof.counter !== undefined ? { counter: proof.counter } : {}),
77
+ ...(proof.slotCounter !== undefined ? { slotCounter: proof.slotCounter } : {}),
78
+ ...(blockHash !== undefined ? { blockHash } : {}),
79
+ ...(blockNumber !== undefined ? { blockNumber } : {}),
80
+ metadataCorroboration: corroboration,
81
+ ...(verification !== undefined
82
+ ? {
83
+ verificationTier: verification.tier,
84
+ verificationStatus: verification.status,
85
+ ...(verification.reason !== undefined ? { verificationReason: verification.reason } : {}),
86
+ }
87
+ : {}),
88
+ });
89
+ }
90
+ return { anchors, metadataOnlyProofHashes, findings };
91
+ }
92
+ // ---------------------------------------------------------------------------
93
+ // Field readers (tolerant: structural problems belong to the verification
94
+ // dimension, not to anchor identification)
95
+ // ---------------------------------------------------------------------------
96
+ function readAttributionField(proof, field) {
97
+ const attribution = proof.proof["attribution"];
98
+ if (attribution === null || typeof attribution !== "object" || Array.isArray(attribution)) {
99
+ return undefined;
100
+ }
101
+ const value = attribution[field];
102
+ return typeof value === "string" ? value : undefined;
103
+ }
104
+ function readMetadataType(proof) {
105
+ const metadata = proof.proof["metadata"];
106
+ if (metadata === null || typeof metadata !== "object" || Array.isArray(metadata)) {
107
+ return undefined;
108
+ }
109
+ const value = metadata["type"];
110
+ return typeof value === "string" ? value : undefined;
111
+ }
112
+ function pathOf(proof) {
113
+ const path = proof.sources[0]?.path;
114
+ return path !== undefined ? { path } : {};
115
+ }
116
+ //# sourceMappingURL=anchors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anchors.js","sourceRoot":"","sources":["../src/anchors.ts"],"names":[],"mappings":"AAAA,qFAAqF;AAmCrF,MAAM,uBAAuB,GAAG,iBAAiB,CAAC;AAClD,MAAM,oBAAoB,GAAG,iBAAiB,CAAC;AAE/C;;;;;GAKG;AACH,MAAM,mBAAmB,GAAG,4CAA4C,CAAC;AAEzE;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,MAAoB;IAClD,MAAM,OAAO,GAAmB,EAAE,CAAC;IACnC,MAAM,uBAAuB,GAAa,EAAE,CAAC;IAC7C,MAAM,QAAQ,GAAmB,EAAE,CAAC;IAEpC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClC,MAAM,eAAe,GAAG,oBAAoB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC5D,MAAM,YAAY,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC7C,MAAM,YAAY,GAAG,eAAe,KAAK,uBAAuB,CAAC;QAEjE,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,IAAI,YAAY,KAAK,oBAAoB,EAAE,CAAC;gBAC1C,kEAAkE;gBAClE,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;gBAC9C,QAAQ,CAAC,IAAI,CAAC;oBACZ,IAAI,EAAE,4BAA4B;oBAClC,GAAG,MAAM,CAAC,KAAK,CAAC;oBAChB,OAAO,EACL,qFAAqF;wBACrF,oFAAoF;wBACpF,2BAA2B;oBAC7B,OAAO,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE;iBACxC,CAAC,CAAC;YACL,CAAC;YACD,SAAS;QACX,CAAC;QAED,kEAAkE;QAClE,mEAAmE;QACnE,uCAAuC;QACvC,MAAM,aAAa,GACjB,YAAY,KAAK,oBAAoB;YACnC,CAAC,CAAE,QAAkB;YACrB,CAAC,CAAC,YAAY,KAAK,SAAS;gBAC1B,CAAC,CAAE,QAAkB;gBACrB,CAAC,CAAE,WAAqB,CAAC;QAC/B,IAAI,aAAa,KAAK,WAAW,EAAE,CAAC;YAClC,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,8BAA8B;gBACpC,GAAG,MAAM,CAAC,KAAK,CAAC;gBAChB,OAAO,EACL,kFAAkF;oBAClF,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,2DAA2D;gBAC5F,OAAO,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,YAAY,EAAE,YAAsB,EAAE;aAC9E,CAAC,CAAC;QACL,CAAC;QAED,MAAM,SAAS,GAAG,oBAAoB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QACzD,MAAM,KAAK,GAAG,oBAAoB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACnD,MAAM,WAAW,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC1G,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC9B,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,0BAA0B;gBAChC,GAAG,MAAM,CAAC,KAAK,CAAC;gBAChB,OAAO,EACL,KAAK,KAAK,SAAS;oBACjB,CAAC,CAAC,qFAAqF;oBACvF,CAAC,CAAC,iHAAiH;gBACvH,OAAO,EAAE;oBACP,SAAS,EAAE,KAAK,CAAC,SAAS;oBAC1B,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAC1C;aACF,CAAC,CAAC;QACL,CAAC;QAED,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;QACxC,OAAO,CAAC,IAAI,CAAC;YACX,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,GAAG,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAClE,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,GAAG,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAClE,GAAG,CAAC,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9E,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjD,GAAG,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrD,qBAAqB,EAAE,aAAa;YACpC,GAAG,CAAC,YAAY,KAAK,SAAS;gBAC5B,CAAC,CAAC;oBACE,gBAAgB,EAAE,YAAY,CAAC,IAAI;oBACnC,kBAAkB,EAAE,YAAY,CAAC,MAAM;oBACvC,GAAG,CAAC,YAAY,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAC1F;gBACH,CAAC,CAAC,EAAE,CAAC;SACR,CAAC,CAAC;IACL,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,uBAAuB,EAAE,QAAQ,EAAE,CAAC;AACxD,CAAC;AAED,8EAA8E;AAC9E,0EAA0E;AAC1E,2CAA2C;AAC3C,8EAA8E;AAE9E,SAAS,oBAAoB,CAC3B,KAAoB,EACpB,KAAmC;IAEnC,MAAM,WAAW,GAAI,KAAK,CAAC,KAA4C,CAAC,aAAa,CAAC,CAAC;IACvF,IAAI,WAAW,KAAK,IAAI,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;QAC1F,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,KAAK,GAAI,WAAuC,CAAC,KAAK,CAAC,CAAC;IAC9D,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACvD,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAoB;IAC5C,MAAM,QAAQ,GAAI,KAAK,CAAC,KAA4C,CAAC,UAAU,CAAC,CAAC;IACjF,IAAI,QAAQ,KAAK,IAAI,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACjF,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,KAAK,GAAI,QAAoC,CAAC,MAAM,CAAC,CAAC;IAC5D,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACvD,CAAC;AAED,SAAS,MAAM,CAAC,KAAoB;IAClC,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;IACpC,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * bitgraph-audit anomaly classification
3
+ *
4
+ * Classifies the reconstructed record with stable machine-readable codes
5
+ * and builds divergence records for every conflict between valid proofs.
6
+ *
7
+ * The G2 two-position rule governs the gap logic: every proof consumes TWO
8
+ * counter positions, its slotCounter N and its commit counter M with
9
+ * N < M (usually M = N + 1, but the enclave guarantees only the strict
10
+ * inequality, and concurrent slot allocation can interleave). A position
11
+ * within a partition's observed [min, max] range is EXPLAINED when it
12
+ * appears as any observed proof's commit counter OR any observed proof's
13
+ * slotCounter. Only unexplained positions are reported, always as
14
+ * unexplained from the supplied evidence (a proof absent from the bundle
15
+ * OR a slot that was allocated but never committed, indistinguishable
16
+ * offline), never as asserted authority failure. Anchor proofs are
17
+ * ordinary chain members; their positions count normally.
18
+ *
19
+ * Dimension discipline: verification status and chain topology stay
20
+ * separate throughout. Topology anomalies are computed over all observed
21
+ * members regardless of verification outcome (with statuses reported
22
+ * alongside), a verifier failure is never reinterpreted as a chain
23
+ * anomaly, and a chain observation never changes a verification result.
24
+ * Divergence parties, however, must be valid: conflicts are declared
25
+ * between valid proofs only (per their definitions), and cryptographically
26
+ * invalid proofs appear as observed context, never as competing branches.
27
+ *
28
+ * Run after verifyObservedProofs and reconstructChains. Isolated validity
29
+ * rechecks reset the verify package's module-level epoch link state (see
30
+ * validity.ts).
31
+ */
32
+ import type { AnomalyReport, IngestResult, ReconstructionResult } from "./types.js";
33
+ /**
34
+ * Classify anomalies and build divergence records over a reconstructed
35
+ * bundle. Read-only over its inputs. Deterministic: anomalies follow
36
+ * partition order, then a fixed per-partition analysis order (gaps,
37
+ * counter collisions, slot collisions, cross-kind position reuse,
38
+ * predecessor reuse, chain breaks, multiple genesis, slot order), then
39
+ * epoch link anomalies.
40
+ */
41
+ export declare function classifyAnomalies(ingest: IngestResult, reconstruction: ReconstructionResult): Promise<AnomalyReport>;
42
+ //# sourceMappingURL=anomalies.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anomalies.d.ts","sourceRoot":"","sources":["../src/anomalies.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EACV,aAAa,EAMb,YAAY,EAGZ,oBAAoB,EAErB,MAAM,YAAY,CAAC;AAcpB;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,YAAY,EACpB,cAAc,EAAE,oBAAoB,GACnC,OAAO,CAAC,aAAa,CAAC,CAyBxB"}