@sanning/proof 0.6.0 → 0.8.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 +1 -1
- package/dist/chain.d.ts +99 -0
- package/dist/chain.js +389 -0
- package/dist/cli.js +42 -2
- package/dist/evidence.d.ts +148 -0
- package/dist/evidence.js +603 -70
- package/dist/index.d.ts +4 -2
- package/dist/index.js +22 -1
- package/dist/verifier.js +46 -7
- package/package.json +1 -1
- package/src/chain.ts +500 -0
- package/src/cli.ts +50 -1
- package/src/evidence.ts +813 -74
- package/src/index.ts +46 -0
- package/src/verifier.ts +49 -7
- package/vectors/chain-reading.json +293 -0
package/src/cli.ts
CHANGED
|
@@ -21,6 +21,8 @@ import { fileURLToPath } from "node:url";
|
|
|
21
21
|
|
|
22
22
|
import { isAgentProofSpec, verifyAgentProofBundle } from "./agent-proof.js";
|
|
23
23
|
import type { AgentProofResult } from "./agent-proof.js";
|
|
24
|
+
import { CHAIN_READING_SCOPE, readChains, renderChainFinding } from "./chain.js";
|
|
25
|
+
import type { ChainReading } from "./chain.js";
|
|
24
26
|
import { composeExport } from "./compose.js";
|
|
25
27
|
import type { ComposeExportOptions } from "./compose.js";
|
|
26
28
|
import { utf8 } from "./crypto.js";
|
|
@@ -167,7 +169,12 @@ export async function runCli(argv: string[], io: Cli): Promise<number> {
|
|
|
167
169
|
...(content ? { content } : {}),
|
|
168
170
|
...(io.fetchImpl ? { fetchImpl: io.fetchImpl } : {}),
|
|
169
171
|
});
|
|
170
|
-
|
|
172
|
+
// Read the chains from the SAME parsed bundle the verifier saw. Findings are
|
|
173
|
+
// evidence about the records in front of us, not a verdict: they are printed
|
|
174
|
+
// and they never move `exit`, because a chain is not a completeness proof and
|
|
175
|
+
// an exit code is exactly the kind of thing people read as one.
|
|
176
|
+
const chains = await readChains(parsed);
|
|
177
|
+
const exit = reportEvidence(result, bundlePath, gateways, io, chains);
|
|
171
178
|
// Coverage is reported only once the bundle parsed far enough to have events
|
|
172
179
|
// to compare against; over a MALFORMED bundle there is nothing to say.
|
|
173
180
|
if (logs && result.status !== "malformed") reportLogsCoverage(logs, result, io);
|
|
@@ -664,6 +671,7 @@ function reportEvidence(
|
|
|
664
671
|
path: string,
|
|
665
672
|
gateways: string[],
|
|
666
673
|
io: Cli,
|
|
674
|
+
chains: ChainReading,
|
|
667
675
|
): number {
|
|
668
676
|
if (result.status === "malformed") {
|
|
669
677
|
io.err(paint("MALFORMED", R) + ` ${path}`);
|
|
@@ -708,6 +716,8 @@ function reportEvidence(
|
|
|
708
716
|
}
|
|
709
717
|
}
|
|
710
718
|
|
|
719
|
+
reportChains(chains, io);
|
|
720
|
+
|
|
711
721
|
if (result.export) {
|
|
712
722
|
reportExport(result.export, io);
|
|
713
723
|
}
|
|
@@ -725,6 +735,45 @@ function reportEvidence(
|
|
|
725
735
|
return mapStatusToExit(result.status, result.errors);
|
|
726
736
|
}
|
|
727
737
|
|
|
738
|
+
/**
|
|
739
|
+
* The chain block: what following each record's pointer to the record before it
|
|
740
|
+
* showed, over the records THIS bundle presents.
|
|
741
|
+
*
|
|
742
|
+
* Three deliberate choices, all of them about not overclaiming.
|
|
743
|
+
*
|
|
744
|
+
* 1. It prints the chains it READ, not just the findings. "3 chains, nothing to
|
|
745
|
+
* report" and silence are different statements, and a reader that quietly
|
|
746
|
+
* matched no records at all would produce the second one while covering
|
|
747
|
+
* nothing.
|
|
748
|
+
* 2. It prints the scope sentence whenever it read a chain, findings or not.
|
|
749
|
+
* "Delete an event and the next pointer dangles" is true; "so the bundle is
|
|
750
|
+
* complete" does not follow, and two customer-facing documents had already
|
|
751
|
+
* made that leap. The limit travels with the result or it gets dropped.
|
|
752
|
+
* 3. It does not touch the exit code. Findings are evidence; the exit code is
|
|
753
|
+
* the verdict surface, and the pinned 0/1/2/3 contract stays exactly what it
|
|
754
|
+
* was. A dangling link is something for a person to look at, not a machine
|
|
755
|
+
* decision this check is entitled to make.
|
|
756
|
+
*/
|
|
757
|
+
function reportChains(reading: ChainReading, io: Cli): void {
|
|
758
|
+
if (reading.chains.length === 0) return;
|
|
759
|
+
|
|
760
|
+
io.out("");
|
|
761
|
+
io.out(paint(" Event chains", DIM));
|
|
762
|
+
for (const c of reading.chains) {
|
|
763
|
+
const where = c.namespace === undefined ? "record" : `${c.namespace} metadata`;
|
|
764
|
+
io.out(
|
|
765
|
+
paint(
|
|
766
|
+
` ${c.chainKey} ${count(c.events, "record", "records")} present (linked in ${where})`,
|
|
767
|
+
DIM,
|
|
768
|
+
),
|
|
769
|
+
);
|
|
770
|
+
}
|
|
771
|
+
for (const f of reading.findings) {
|
|
772
|
+
io.out(paint(` ! ${renderChainFinding(f, "this bundle")}`, Y));
|
|
773
|
+
}
|
|
774
|
+
io.out(paint(` ${CHAIN_READING_SCOPE}`, DIM));
|
|
775
|
+
}
|
|
776
|
+
|
|
728
777
|
// Render the export-specific block (evidence-export.md §5): source-bundle
|
|
729
778
|
// linkage, cached-vs-recomputed verdict agreement, and each embedded operator
|
|
730
779
|
// attestation (RSA-PSS sig · operator-address binding · data_hash binding).
|