@mikeargento/bitgraph-audit 0.8.0 → 0.10.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.
- package/README.md +8 -2
- package/dist/audit.d.ts +9 -6
- package/dist/audit.d.ts.map +1 -1
- package/dist/audit.js +34 -8
- package/dist/audit.js.map +1 -1
- package/dist/ceilings.d.ts.map +1 -1
- package/dist/ceilings.js +1 -0
- package/dist/ceilings.js.map +1 -1
- package/dist/cli.js +109 -21
- package/dist/cli.js.map +1 -1
- package/dist/exports.d.ts +39 -0
- package/dist/exports.d.ts.map +1 -0
- package/dist/exports.js +374 -0
- package/dist/exports.js.map +1 -0
- package/dist/floors.d.ts +23 -0
- package/dist/floors.d.ts.map +1 -0
- package/dist/floors.js +203 -0
- package/dist/floors.js.map +1 -0
- package/dist/index.d.ts +6 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/ingest.d.ts +2 -0
- package/dist/ingest.d.ts.map +1 -1
- package/dist/ingest.js +193 -19
- package/dist/ingest.js.map +1 -1
- package/dist/report-json.d.ts.map +1 -1
- package/dist/report-json.js +30 -0
- package/dist/report-json.js.map +1 -1
- package/dist/report-md.d.ts.map +1 -1
- package/dist/report-md.js +315 -25
- package/dist/report-md.js.map +1 -1
- package/dist/temporal.d.ts +12 -0
- package/dist/temporal.d.ts.map +1 -1
- package/dist/temporal.js +245 -41
- package/dist/temporal.js.map +1 -1
- package/dist/types.d.ts +348 -7
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -2
- package/src/__tests__/base-floor.test.ts +405 -0
- package/src/audit.ts +36 -8
- package/src/ceilings.ts +1 -0
- package/src/cli.ts +117 -22
- package/src/exports.ts +482 -0
- package/src/floors.ts +242 -0
- package/src/index.ts +20 -0
- package/src/ingest.ts +207 -18
- package/src/report-json.ts +30 -0
- package/src/report-md.ts +353 -29
- package/src/temporal.ts +279 -48
- package/src/types.ts +341 -6
package/src/types.ts
CHANGED
|
@@ -123,6 +123,13 @@ export type AnomalyCode =
|
|
|
123
123
|
| "attestation-measurement-mismatch"
|
|
124
124
|
/** A validated attestation document's user_data is not bound to this proof's canonical proof hash. */
|
|
125
125
|
| "attestation-user-data-mismatch"
|
|
126
|
+
// --- Exports (bitgraph-export/1) ---
|
|
127
|
+
/** A file declares format "bitgraph-export/1" but lacks an export's structure (a proof object and tree.rootDocument). Not checked; fails the audit (exit bit 1). */
|
|
128
|
+
| "export-malformed"
|
|
129
|
+
/** A file declares a bitgraph-export format other than "bitgraph-export/1". Not checked; fails the audit (exit bit 1), as an unsupported proof version does. */
|
|
130
|
+
| "export-unsupported-format"
|
|
131
|
+
/** A file opens an export object but is larger than the audit's cap for one export's JSON (IngestLimits.maxExportJsonBytes). Not checked; fails the audit (exit bit 1). */
|
|
132
|
+
| "export-too-large"
|
|
126
133
|
| (string & {});
|
|
127
134
|
|
|
128
135
|
/**
|
|
@@ -335,6 +342,19 @@ export interface AnchorWitnessFile {
|
|
|
335
342
|
witness: Record<string, unknown>;
|
|
336
343
|
}
|
|
337
344
|
|
|
345
|
+
/**
|
|
346
|
+
* A floor header file (bitgraph-floor-header/1):
|
|
347
|
+
* { version, chain: "base", evmChainId: 8453, blockNumber, blockHash, blockTimestamp, header }
|
|
348
|
+
* where header is the block's RLP as 0x hex. Only the header bytes are
|
|
349
|
+
* evidence: they are checked by keccak-256 against the floor a proof signs,
|
|
350
|
+
* and the other fields are a convenience for readers.
|
|
351
|
+
*/
|
|
352
|
+
export interface FloorHeaderFile {
|
|
353
|
+
path: string;
|
|
354
|
+
fileSha256Hex: string;
|
|
355
|
+
json: Record<string, unknown>;
|
|
356
|
+
}
|
|
357
|
+
|
|
338
358
|
// ---------------------------------------------------------------------------
|
|
339
359
|
// Manifest
|
|
340
360
|
// ---------------------------------------------------------------------------
|
|
@@ -406,8 +426,12 @@ export interface IngestCounts {
|
|
|
406
426
|
artifacts: number;
|
|
407
427
|
/** Anchor witness files. */
|
|
408
428
|
witnesses: number;
|
|
429
|
+
/** Floor header files (bitgraph-floor-header/1). Absent when there are none. */
|
|
430
|
+
floorHeaders?: number;
|
|
409
431
|
/** Ceiling files (bitgraph-ceiling/1) and ceiling status notes (bitgraph-ceiling-status/1). */
|
|
410
432
|
ceilings?: number;
|
|
433
|
+
/** Export-shaped files (format "bitgraph-export/..."), checked or rejected. */
|
|
434
|
+
exports?: number;
|
|
411
435
|
/** Container entries skipped for unsafe paths. */
|
|
412
436
|
skippedUnsafePaths: number;
|
|
413
437
|
}
|
|
@@ -437,6 +461,14 @@ export interface IngestLimits {
|
|
|
437
461
|
* declaring a larger size aborts ingest before any allocation.
|
|
438
462
|
*/
|
|
439
463
|
maxMetadataEntryBytes: number;
|
|
464
|
+
/**
|
|
465
|
+
* Ceiling on one export's JSON (bitgraph-export/1), for every container,
|
|
466
|
+
* directories included. Other JSON candidates stop at 8 MiB; an entry that
|
|
467
|
+
* opens an export object may run to this size (the owner's export of a
|
|
468
|
+
* large tree lists every leaf). A larger export is reported
|
|
469
|
+
* (export-too-large) and not checked. Default 192 MiB.
|
|
470
|
+
*/
|
|
471
|
+
maxExportJsonBytes?: number;
|
|
440
472
|
}
|
|
441
473
|
|
|
442
474
|
/**
|
|
@@ -469,10 +501,21 @@ export interface IngestResult {
|
|
|
469
501
|
artifacts: ArtifactRecord[];
|
|
470
502
|
/** Anchor witness files in observation order. */
|
|
471
503
|
witnesses: AnchorWitnessFile[];
|
|
504
|
+
/**
|
|
505
|
+
* Floor header files (bitgraph-floor-header/1): the header of a Base block
|
|
506
|
+
* a proof signs as its floor, the way the carrier/3 unpacker writes it.
|
|
507
|
+
* Evidence, never artifacts. Optional so older embedders' IngestResults still type.
|
|
508
|
+
*/
|
|
509
|
+
floorHeaders?: FloorHeaderFile[];
|
|
472
510
|
/** Ceiling files (bitgraph-ceiling/1) in observation order. Optional so older embedders' IngestResults still type. */
|
|
473
511
|
ceilings?: CeilingFile[];
|
|
474
512
|
/** Ceiling status notes (bitgraph-ceiling-status/1): a package saying why a ceiling is absent. */
|
|
475
513
|
ceilingStatuses?: CeilingFile[];
|
|
514
|
+
/**
|
|
515
|
+
* Export-shaped files (format "bitgraph-export/..."), in observation order.
|
|
516
|
+
* Evidence, never artifacts. Optional so older embedders' IngestResults still type.
|
|
517
|
+
*/
|
|
518
|
+
exports?: ExportFile[];
|
|
476
519
|
/** Present when a root manifest.json entry existed. */
|
|
477
520
|
manifest?: ManifestReport;
|
|
478
521
|
|
|
@@ -646,9 +689,13 @@ export interface EpochAnchorBound {
|
|
|
646
689
|
* anchor evidence. "not-before": they came after it. Always one-sided.
|
|
647
690
|
*/
|
|
648
691
|
kind: "not-after" | "not-before";
|
|
649
|
-
/** Canonical hash of the anchor proof providing the bound. */
|
|
692
|
+
/** Canonical hash of the anchor proof providing the bound (for a Base floor, the proof that signs it). */
|
|
650
693
|
anchorProofHash: string;
|
|
651
|
-
/**
|
|
694
|
+
/** Absent for an anchor bound; "signed-floor" when the representative bound is a Base floor a proof signs. */
|
|
695
|
+
source?: "signed-floor";
|
|
696
|
+
/** Absent for Ethereum; "base" when the representative bound is a Base block. */
|
|
697
|
+
chain?: "base";
|
|
698
|
+
/** Block number (decimal string): the anchored Ethereum block, or the Base floor block. */
|
|
652
699
|
blockNumber?: string;
|
|
653
700
|
/** Ethereum block hash from the signed attribution message. */
|
|
654
701
|
blockHash?: string;
|
|
@@ -1050,8 +1097,17 @@ export interface AnchorWitnessAnalysis {
|
|
|
1050
1097
|
* "counter-order" only the commit counters order them. This relies on
|
|
1051
1098
|
* the authority's per-chain counter discipline rather
|
|
1052
1099
|
* than verifiable hash links, and is marked weaker.
|
|
1100
|
+
* "signed-floor" the bounded proof itself signs the floor block
|
|
1101
|
+
* (commit.slotFloor, a Base block, enclave v10). Nothing
|
|
1102
|
+
* stands between the proof and the block: it is the
|
|
1103
|
+
* proof's own signed field. Not weaker.
|
|
1104
|
+
*
|
|
1105
|
+
* A Base floor bound reaches other proofs only the way an anchor bound
|
|
1106
|
+
* does: through a verified hash-link path ("chain-link") or by counter
|
|
1107
|
+
* order ("counter-order"), and only as a NOT-BEFORE. A floor never yields a
|
|
1108
|
+
* not-after: a later proof's floor block can predate this proof.
|
|
1053
1109
|
*/
|
|
1054
|
-
export type BoundEvidence = "chain-link" | "counter-order";
|
|
1110
|
+
export type BoundEvidence = "chain-link" | "counter-order" | "signed-floor";
|
|
1055
1111
|
|
|
1056
1112
|
/**
|
|
1057
1113
|
* One one-sided temporal bound on a segment, derived from a verified
|
|
@@ -1081,7 +1137,27 @@ export type BoundEvidence = "chain-link" | "counter-order";
|
|
|
1081
1137
|
*/
|
|
1082
1138
|
export interface SegmentBound {
|
|
1083
1139
|
kind: "not-before" | "not-after";
|
|
1140
|
+
/**
|
|
1141
|
+
* The proof that supplies the bound: the anchor proof, or for a Base floor
|
|
1142
|
+
* (source "signed-floor") the proof that signs the floor block.
|
|
1143
|
+
*/
|
|
1084
1144
|
anchorProofHash: string;
|
|
1145
|
+
/**
|
|
1146
|
+
* Absent for an anchor bound (an Ethereum anchor proof with a verified
|
|
1147
|
+
* witness, every bound before enclave v10). "signed-floor": the Base block a
|
|
1148
|
+
* proof signs as commit.slotFloor (enclave v10). Always a not-before.
|
|
1149
|
+
*/
|
|
1150
|
+
source?: "signed-floor";
|
|
1151
|
+
/** Absent for Ethereum (every anchor bound); "base" for a Base floor. */
|
|
1152
|
+
chain?: "base";
|
|
1153
|
+
/**
|
|
1154
|
+
* Base floors only: where the block time comes from. "header": a header in
|
|
1155
|
+
* the bundle hashes to the signed block and carries the signed number and
|
|
1156
|
+
* time. "signed": no header for the block is in the bundle; the time is the
|
|
1157
|
+
* one the proof signs (on Base mainnet's schedule for its number), and
|
|
1158
|
+
* confirming the block needs a Base lookup.
|
|
1159
|
+
*/
|
|
1160
|
+
timeSource?: "header" | "signed";
|
|
1085
1161
|
/** Block number confirmed by the verified witness header (decimal string). */
|
|
1086
1162
|
blockNumber?: string;
|
|
1087
1163
|
/** Locally recomputed block hash (0x + 64 lowercase hex). */
|
|
@@ -1175,6 +1251,52 @@ export interface AnchorOrderedPair {
|
|
|
1175
1251
|
note: string;
|
|
1176
1252
|
}
|
|
1177
1253
|
|
|
1254
|
+
/**
|
|
1255
|
+
* A Base floor one proof signs (commit.slotFloor, enclave v10), as the
|
|
1256
|
+
* temporal pass read it. Listed only for Base floors: an Ethereum floor
|
|
1257
|
+
* (commit.slotAnchor) is read through the anchor proofs, as before.
|
|
1258
|
+
*/
|
|
1259
|
+
export interface SignedFloorRecord {
|
|
1260
|
+
proofHash: string;
|
|
1261
|
+
chain: "base";
|
|
1262
|
+
blockNumber: number;
|
|
1263
|
+
/** 0x-prefixed lowercase hex, as signed. */
|
|
1264
|
+
blockHash: string;
|
|
1265
|
+
/** Unix seconds, as signed. */
|
|
1266
|
+
blockTimestamp: number;
|
|
1267
|
+
/** "checked": a header in the bundle hashes to the signed block (headerPath names it). "not-carried": none is here. */
|
|
1268
|
+
header: "checked" | "not-carried";
|
|
1269
|
+
/** Bundle path of the header that was checked (a floor header file, a ceiling file or an export). */
|
|
1270
|
+
headerPath?: string;
|
|
1271
|
+
/** "not-before": the floor bounds the proof. "withheld": it does not, for withheldReason. */
|
|
1272
|
+
bound: "not-before" | "withheld";
|
|
1273
|
+
withheldReason?: string;
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
/** Problem codes of the floor stage. Every one sets exit bit 2. */
|
|
1277
|
+
export type FloorProblemCode =
|
|
1278
|
+
/** The proof signs two floors (commit.slotAnchor and commit.slotFloor): ambiguous, bounds nothing. */
|
|
1279
|
+
| "floor-ambiguous"
|
|
1280
|
+
/** commit.slotFloor does not name Base mainnet, or lacks a 32-byte hash, a number or a time. */
|
|
1281
|
+
| "floor-malformed"
|
|
1282
|
+
/** The signed Base floor time is not Base mainnet's schedule for the signed block number. */
|
|
1283
|
+
| "floor-off-schedule"
|
|
1284
|
+
/** A floor header file names a block a proof signs, and does not match it (hash, number, time or chain). */
|
|
1285
|
+
| "floor-header-mismatch"
|
|
1286
|
+
/** A floor header file is unreadable or not a Base header. */
|
|
1287
|
+
| "floor-header-malformed"
|
|
1288
|
+
/** A floor header file hashes to a block no proof in the bundle signs as its floor. */
|
|
1289
|
+
| "floor-header-unmatched";
|
|
1290
|
+
|
|
1291
|
+
export interface FloorProblem {
|
|
1292
|
+
code: FloorProblemCode;
|
|
1293
|
+
/** The proof concerned, when there is one. */
|
|
1294
|
+
proofHash?: string;
|
|
1295
|
+
/** The bundle path concerned (a proof file or a floor header file). */
|
|
1296
|
+
path?: string;
|
|
1297
|
+
message: string;
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1178
1300
|
/** Output of the temporal bounds pass. */
|
|
1179
1301
|
export interface TemporalAnalysis {
|
|
1180
1302
|
/** Per-partition segments with their bounds, deterministically ordered. */
|
|
@@ -1185,6 +1307,10 @@ export interface TemporalAnalysis {
|
|
|
1185
1307
|
verifiedAnchorProofHashes: string[];
|
|
1186
1308
|
/** Identified anchors with no verified witness: they still establish causal order, but confer no wall-clock evidence. Sorted. */
|
|
1187
1309
|
unverifiedAnchorProofHashes: string[];
|
|
1310
|
+
/** Base floors the proofs sign (enclave v10), in observation order. Absent when no proof signs one. */
|
|
1311
|
+
signedFloors?: SignedFloorRecord[];
|
|
1312
|
+
/** Floor problems (exit bit 2). Absent when there are none. */
|
|
1313
|
+
floorProblems?: FloorProblem[];
|
|
1188
1314
|
}
|
|
1189
1315
|
|
|
1190
1316
|
// ---------------------------------------------------------------------------
|
|
@@ -1314,6 +1440,8 @@ export interface AuditOptions {
|
|
|
1314
1440
|
trustedRootCaDer?: Uint8Array;
|
|
1315
1441
|
/** Ceilings in time: the declared writer, the chain, and an optional Base RPC for the one online check. */
|
|
1316
1442
|
ceilings?: import("./ceilings.js").CeilingAuditOptions;
|
|
1443
|
+
/** Exports (bitgraph-export/1): extra spec hashes, PCR0 pins, and optional lookups for embedders that allow network. */
|
|
1444
|
+
exports?: import("./exports.js").ExportAuditOptions;
|
|
1317
1445
|
}
|
|
1318
1446
|
|
|
1319
1447
|
/**
|
|
@@ -1351,9 +1479,11 @@ export interface CeilingCheck {
|
|
|
1351
1479
|
*/
|
|
1352
1480
|
status: "verified" | "failed" | "pending" | "unmatched";
|
|
1353
1481
|
reason?: string;
|
|
1354
|
-
/** One line for people, e.g. "Ceiling: Base block N at hh:mm:ss UTC
|
|
1482
|
+
/** One line for people, e.g. "Ceiling: included in Base block N at hh:mm:ss UTC. ..."; it never claims settlement the file does not prove. */
|
|
1355
1483
|
label?: string;
|
|
1356
1484
|
window?: {
|
|
1485
|
+
/** "base" when the floor block (the one the proof signs) is a Base block; absent for Ethereum or no floor. */
|
|
1486
|
+
floorChain?: "base";
|
|
1357
1487
|
floorBlock: number | null;
|
|
1358
1488
|
floorTime: number | null;
|
|
1359
1489
|
ceilingChainId: number;
|
|
@@ -1406,6 +1536,166 @@ export interface CeilingAnalysis {
|
|
|
1406
1536
|
statuses: Array<{ path: string; status: string; note: string }>;
|
|
1407
1537
|
}
|
|
1408
1538
|
|
|
1539
|
+
// ---------------------------------------------------------------------------
|
|
1540
|
+
// Exports (bitgraph-export/1)
|
|
1541
|
+
// ---------------------------------------------------------------------------
|
|
1542
|
+
|
|
1543
|
+
/**
|
|
1544
|
+
* An export-shaped file as found in the bundle: a JSON object whose format
|
|
1545
|
+
* field starts with "bitgraph-export/". Found by structure, never by name.
|
|
1546
|
+
* Evidence, never an artifact.
|
|
1547
|
+
*/
|
|
1548
|
+
export interface ExportFile {
|
|
1549
|
+
path: string;
|
|
1550
|
+
fileSha256Hex: string;
|
|
1551
|
+
/** The format the file declares. */
|
|
1552
|
+
format: string;
|
|
1553
|
+
/**
|
|
1554
|
+
* ok: a bitgraph-export/1 document (bitgraph-verify's parseExport accepts it).
|
|
1555
|
+
* malformed: declares bitgraph-export/1 but lacks a proof object or tree.rootDocument.
|
|
1556
|
+
* unsupported-format: declares another bitgraph-export version.
|
|
1557
|
+
* too-large: opens an export object but is larger than the audit's export JSON cap; not parsed (json is empty).
|
|
1558
|
+
*/
|
|
1559
|
+
status: "ok" | "malformed" | "unsupported-format" | "too-large";
|
|
1560
|
+
json: Record<string, unknown>;
|
|
1561
|
+
/** Canonical hash of the proof the export carries, when that proof joined the proof analysis (a proof-shaped bitgraph/1 object). */
|
|
1562
|
+
proofHash?: string;
|
|
1563
|
+
}
|
|
1564
|
+
|
|
1565
|
+
/** One claim exactly as bitgraph-verify's verifyExport states it. */
|
|
1566
|
+
export interface ExportClaimRecord {
|
|
1567
|
+
/** Stable id, dotted: "proof.signature", "tree.member", "bytes.floor", "ceiling.base", "confirmed.floor" ... */
|
|
1568
|
+
id: string;
|
|
1569
|
+
name: string;
|
|
1570
|
+
result: "TRUE" | "FALSE" | "UNDETERMINED" | "NOT_CARRIED";
|
|
1571
|
+
/** What the result rests on (the primitive or the evidence), empty when nothing was checked. */
|
|
1572
|
+
restsOn: string;
|
|
1573
|
+
detail: string;
|
|
1574
|
+
/** offline: recomputed from the bytes in hand. confirmed: from the caller's own chain lookups (never made by the CLI). */
|
|
1575
|
+
level: "offline" | "confirmed";
|
|
1576
|
+
}
|
|
1577
|
+
|
|
1578
|
+
/** The three time claims as verifyExport establishes them. Never merged; a null field was not established. */
|
|
1579
|
+
export interface ExportTimes {
|
|
1580
|
+
/**
|
|
1581
|
+
* The committed bytes were finished after this block (the proof's signed
|
|
1582
|
+
* floor block, its header checked by hash), on its chain: chain absent is
|
|
1583
|
+
* Ethereum (an anchor floor, commit.slotAnchor), "base" a Base floor
|
|
1584
|
+
* (commit.slotFloor, enclave v10). Absent rather than "ethereum" so reports
|
|
1585
|
+
* on older exports stay byte-identical.
|
|
1586
|
+
*/
|
|
1587
|
+
floor: { chain?: "base"; blockNumber: number; blockHash: string; blockTimestamp: number } | null;
|
|
1588
|
+
/** The record existed by this Base block, at its time. Provisional until the block is checked against Base (offline, always provisional). */
|
|
1589
|
+
ceilingBase: { blockNumber: number; blockHash: string; blockTimestamp: number; provisional: boolean } | null;
|
|
1590
|
+
/** The record existed by this Ethereum block (through Base's output root; needs no trust in Base). */
|
|
1591
|
+
ceilingEthereum: { blockNumber: number; blockHash: string; blockTimestamp: number } | null;
|
|
1592
|
+
}
|
|
1593
|
+
|
|
1594
|
+
/** A file in the bundle that an export covers, matched by SHA-256 against a leaf's digests. */
|
|
1595
|
+
export interface ExportCoveredFile {
|
|
1596
|
+
/** SHA-256 of the file, lowercase hex. */
|
|
1597
|
+
sha256Hex: string;
|
|
1598
|
+
/** Every bundle path holding these bytes. */
|
|
1599
|
+
paths: string[];
|
|
1600
|
+
byteLength: number;
|
|
1601
|
+
/** The leaf it matched, in tree order: the first leaf whose committed or original digest is the file's, as verifyExport picks it. */
|
|
1602
|
+
leafIndex: number | null;
|
|
1603
|
+
/** That leaf's placement: "as-is", "trailer/1", "container/1" or "container/2". */
|
|
1604
|
+
placement: string | null;
|
|
1605
|
+
/**
|
|
1606
|
+
* committed-bytes: the file is the leaf's committed bytes (its artifact digest).
|
|
1607
|
+
* original: the file is the original the committed bytes were made from (its origin digest).
|
|
1608
|
+
* as-is: the leaf records the file exactly as it is (the two digests are the same).
|
|
1609
|
+
*/
|
|
1610
|
+
matchedAs: "committed-bytes" | "original" | "as-is";
|
|
1611
|
+
/** The name an owner's export lists for that leaf. Unsigned and informational. */
|
|
1612
|
+
nameInExport?: string;
|
|
1613
|
+
}
|
|
1614
|
+
|
|
1615
|
+
/** A claim of one run that is not common to every run of its export, with its place in verifyExport's order. */
|
|
1616
|
+
export interface ExportOwnClaim extends ExportClaimRecord {
|
|
1617
|
+
/** Index of this claim in the run's whole claim list, in verifyExport's order. */
|
|
1618
|
+
position: number;
|
|
1619
|
+
}
|
|
1620
|
+
|
|
1621
|
+
/**
|
|
1622
|
+
* One verifyExport run: with one covered file, or once without a file when
|
|
1623
|
+
* the bundle holds none. The run's whole claim list, in verifyExport's
|
|
1624
|
+
* order, is the export's common claims (ExportCheck.claims) with this run's
|
|
1625
|
+
* own claims put back at their positions: exportRunClaims(check, run).
|
|
1626
|
+
* verifyExport's reasons are that list's FALSE and UNDETERMINED claims, and
|
|
1627
|
+
* its time claims are the export's (ExportCheck.times): they do not depend
|
|
1628
|
+
* on the file.
|
|
1629
|
+
*/
|
|
1630
|
+
export interface ExportRun {
|
|
1631
|
+
/** The covered file this run checked; null for the run without a file. */
|
|
1632
|
+
file: ExportCoveredFile | null;
|
|
1633
|
+
/** verifyExport's verdict over its offline claims. */
|
|
1634
|
+
verdict: "TRUE" | "FALSE" | "UNDETERMINED";
|
|
1635
|
+
/** This run's claims that differ from the export's common claims (in practice the ones about its file: tree.member, bytes.member, bytes.floor). */
|
|
1636
|
+
claims: ExportOwnClaim[];
|
|
1637
|
+
/** The member the run established (index, count, placement, digests), when it did. */
|
|
1638
|
+
member: { index: number; count: number; placement: string; artifactHex: string; originHex: string } | null;
|
|
1639
|
+
/**
|
|
1640
|
+
* What the floor covers for this run's file, read from its claims: content
|
|
1641
|
+
* (the committed bytes carry the commitment, so they were finished after the
|
|
1642
|
+
* floor block; an original inside them is not dated by it), record (an as-is
|
|
1643
|
+
* leaf: the record was made after the floor block, the bytes themselves are
|
|
1644
|
+
* not dated), or null (the file was not established as a member, or no file
|
|
1645
|
+
* was checked).
|
|
1646
|
+
*/
|
|
1647
|
+
floorCovers: "content" | "record" | null;
|
|
1648
|
+
/** verifyExport's plain-language reading, written from its claims. */
|
|
1649
|
+
reading: string;
|
|
1650
|
+
}
|
|
1651
|
+
|
|
1652
|
+
/** One export file, checked. */
|
|
1653
|
+
export interface ExportCheck {
|
|
1654
|
+
path: string;
|
|
1655
|
+
fileSha256Hex: string;
|
|
1656
|
+
format: string;
|
|
1657
|
+
/** checked: verifyExport ran. malformed / unsupported-format / too-large: rejected at ingest, not checked (exit bit 1). */
|
|
1658
|
+
status: "checked" | "malformed" | "unsupported-format" | "too-large";
|
|
1659
|
+
/** Why the file was not checked. */
|
|
1660
|
+
reason?: string;
|
|
1661
|
+
/** member: carries one member's evidence (tree.member). owner: carries the whole list (tree.leaves). root-only: neither. */
|
|
1662
|
+
kind?: "member" | "owner" | "root-only";
|
|
1663
|
+
/** Canonical hash of the export's proof, which also appears in the proof analysis. */
|
|
1664
|
+
proofHash?: string;
|
|
1665
|
+
/**
|
|
1666
|
+
* The audit's judgment of the export: FALSE when any run's verdict is FALSE
|
|
1667
|
+
* or any claim of any run is FALSE (a confirmed claim included, from an
|
|
1668
|
+
* embedder's lookup); else UNDETERMINED when any run is; else TRUE. A FALSE
|
|
1669
|
+
* export fails the audit (exit bit 1), as a bad proof does.
|
|
1670
|
+
*/
|
|
1671
|
+
verdict: "TRUE" | "FALSE" | "UNDETERMINED";
|
|
1672
|
+
/** Ids of the claims that are FALSE in any run, in first-seen order. */
|
|
1673
|
+
failedClaims: string[];
|
|
1674
|
+
/** The three time claims, never merged. They do not depend on the file, so every run states the same; read from the first. */
|
|
1675
|
+
times: ExportTimes;
|
|
1676
|
+
/** The claims every run states alike (same id, result, level, restsOn and detail), in verifyExport's order. With one run, all of its claims. */
|
|
1677
|
+
claims: ExportClaimRecord[];
|
|
1678
|
+
/** Files in the bundle this export covers, sorted by first path. */
|
|
1679
|
+
files: ExportCoveredFile[];
|
|
1680
|
+
/** One run per covered file (in the order of files), or one run without a file when the bundle holds none. */
|
|
1681
|
+
runs: ExportRun[];
|
|
1682
|
+
/**
|
|
1683
|
+
* How the per-file runs of an owner's export were made. as-given: verifyExport
|
|
1684
|
+
* on the export itself, once per file. member-from-list: the owner's list was
|
|
1685
|
+
* checked once (claim tree.leaves TRUE), then each file's member evidence was
|
|
1686
|
+
* derived from it exactly as verifyExport derives it, verifyExport ran on that
|
|
1687
|
+
* member form, and the list claim was put back in its place; the runs equal
|
|
1688
|
+
* the as-given runs, without rebuilding the whole tree once per file.
|
|
1689
|
+
*/
|
|
1690
|
+
runMode?: "as-given" | "member-from-list";
|
|
1691
|
+
/** Covered files not checked one by one: only when an owner's list fails and the per-file budget ran out, or a file could not be re-read. */
|
|
1692
|
+
unchecked?: Array<{ file: ExportCoveredFile; reason: string }>;
|
|
1693
|
+
}
|
|
1694
|
+
|
|
1695
|
+
export interface ExportAnalysis {
|
|
1696
|
+
checks: ExportCheck[];
|
|
1697
|
+
}
|
|
1698
|
+
|
|
1409
1699
|
export interface AuditResult {
|
|
1410
1700
|
runMetadata: AuditRunMetadata;
|
|
1411
1701
|
ingest: IngestResult;
|
|
@@ -1419,6 +1709,8 @@ export interface AuditResult {
|
|
|
1419
1709
|
attestations: AttestationAnalysis;
|
|
1420
1710
|
/** Ceilings in time on Base. Absent from results made before this stage existed. */
|
|
1421
1711
|
ceilings?: CeilingAnalysis;
|
|
1712
|
+
/** Exports (bitgraph-export/1), each checked with verifyExport per covered file. Absent from results made before this stage existed. */
|
|
1713
|
+
exports?: ExportAnalysis;
|
|
1422
1714
|
}
|
|
1423
1715
|
|
|
1424
1716
|
/**
|
|
@@ -1426,7 +1718,13 @@ export interface AuditResult {
|
|
|
1426
1718
|
*
|
|
1427
1719
|
* bit 1 (value 1): verification failures. Set when any proof's canonical
|
|
1428
1720
|
* checks failed at either tier, or any proof-shaped input was rejected
|
|
1429
|
-
* as an unsupported version
|
|
1721
|
+
* as an unsupported version, or any export (bitgraph-export/1) has a
|
|
1722
|
+
* FALSE claim (its verdict is FALSE), or an export-shaped file was
|
|
1723
|
+
* rejected as malformed or of an unsupported format. An export's
|
|
1724
|
+
* attestation claims are part of its verdict: an export is checked as
|
|
1725
|
+
* one self-contained object, as a carrier is. NOT_CARRIED claims (a
|
|
1726
|
+
* pending ceiling, the covered file absent) never fail an export.
|
|
1727
|
+
* artifact-unavailable is NOT a failure: a
|
|
1430
1728
|
* proof without artifact bytes passes or fails on its bytes-free checks
|
|
1431
1729
|
* alone, unless a supplied trust policy makes those checks fail (for
|
|
1432
1730
|
* example requireSlot), in which case its status is "failed" and it
|
|
@@ -1440,7 +1738,9 @@ export interface AuditResult {
|
|
|
1440
1738
|
* witness failed its offline verification (a witness-* code: RLP or
|
|
1441
1739
|
* header malformation, block-hash mismatch, digest-binding mismatch,
|
|
1442
1740
|
* block-number mismatch, an invalid candidate anchor, or an unmatched
|
|
1443
|
-
* witness)
|
|
1741
|
+
* witness), or any floor problem (a floor-* code: a proof signing two
|
|
1742
|
+
* floors, a malformed or off-schedule Base floor, a floor header that
|
|
1743
|
+
* contradicts the signed floor or matches none). Benign findings are reported but never set exit bits: ingest
|
|
1444
1744
|
* advisories (duplicate copies, manifest advisories, unsafe paths,
|
|
1445
1745
|
* embedded proofHash mismatches) and informational anchor findings
|
|
1446
1746
|
* (anchor-metadata-disagreement, anchor-metadata-only-claim,
|
|
@@ -1615,6 +1915,35 @@ export interface ReportSummary {
|
|
|
1615
1915
|
segmentsLowerBounded: number;
|
|
1616
1916
|
segmentsUpperBounded: number;
|
|
1617
1917
|
segmentsUnanchored: number;
|
|
1918
|
+
/**
|
|
1919
|
+
* Base floors (enclave v10), as counts. Present only when a proof signs a
|
|
1920
|
+
* Base floor or a floor problem was found, so older reports are unchanged.
|
|
1921
|
+
*/
|
|
1922
|
+
baseFloors?: {
|
|
1923
|
+
/** Proofs that sign a Base floor (commit.slotFloor). */
|
|
1924
|
+
signed: number;
|
|
1925
|
+
/** Of those, floors that bound their proof not-before. */
|
|
1926
|
+
bounding: number;
|
|
1927
|
+
/** Of those, floors whose header the bundle carries, checked against the signed block. */
|
|
1928
|
+
headersChecked: number;
|
|
1929
|
+
/** Floors not used as a bound (see SignedFloorRecord.withheldReason). */
|
|
1930
|
+
withheld: number;
|
|
1931
|
+
/** Floor problems (exit bit 2). */
|
|
1932
|
+
problems: number;
|
|
1933
|
+
};
|
|
1934
|
+
};
|
|
1935
|
+
/** Exports (bitgraph-export/1), as counts. Present only when the bundle carries export-shaped files. */
|
|
1936
|
+
exports?: {
|
|
1937
|
+
/** Export-shaped files found. */
|
|
1938
|
+
files: number;
|
|
1939
|
+
/** Exports checked, by the audit's verdict. */
|
|
1940
|
+
verdictTrue: number;
|
|
1941
|
+
verdictFalse: number;
|
|
1942
|
+
verdictUndetermined: number;
|
|
1943
|
+
/** Export-shaped files rejected (malformed or an unsupported format). */
|
|
1944
|
+
rejected: number;
|
|
1945
|
+
/** verifyExport runs made with a covered file from the bundle. */
|
|
1946
|
+
coveredFilesChecked: number;
|
|
1618
1947
|
};
|
|
1619
1948
|
exit: ExitFlags;
|
|
1620
1949
|
}
|
|
@@ -1662,6 +1991,8 @@ export interface AuditJsonReport {
|
|
|
1662
1991
|
};
|
|
1663
1992
|
/** Ceilings in time on Base (bitgraph-ceiling/1). Absent when the bundle carries none. */
|
|
1664
1993
|
ceilings?: import("./types.js").CeilingAnalysis;
|
|
1994
|
+
/** Exports (bitgraph-export/1), one entry per export file in observation order. Absent when the bundle carries none. */
|
|
1995
|
+
exports?: ExportAnalysis;
|
|
1665
1996
|
attestations: {
|
|
1666
1997
|
records: ProofAttestationRecord[];
|
|
1667
1998
|
counts: AttestationAnalysis["counts"];
|
|
@@ -1677,6 +2008,10 @@ export interface AuditJsonReport {
|
|
|
1677
2008
|
segments: TemporalSegment[];
|
|
1678
2009
|
verifiedAnchorProofHashes: string[];
|
|
1679
2010
|
unverifiedAnchorProofHashes: string[];
|
|
2011
|
+
/** Base floors the proofs sign (enclave v10). Absent when there are none. */
|
|
2012
|
+
signedFloors?: SignedFloorRecord[];
|
|
2013
|
+
/** Floor problems (exit bit 2). Absent when there are none. */
|
|
2014
|
+
floorProblems?: FloorProblem[];
|
|
1680
2015
|
};
|
|
1681
2016
|
summary: ReportSummary;
|
|
1682
2017
|
}
|