verifyhash 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.
- package/LICENSE +201 -0
- package/README.md +883 -0
- package/cli/abi/ContributionRegistry.json +881 -0
- package/cli/agent.js +2173 -0
- package/cli/anchor-artifact.js +853 -0
- package/cli/anchor.js +400 -0
- package/cli/claim.js +881 -0
- package/cli/core/agent-commit.js +448 -0
- package/cli/core/agent-session.js +598 -0
- package/cli/core/anchor-binding.js +663 -0
- package/cli/core/attestation.js +580 -0
- package/cli/core/evidence-plans.js +495 -0
- package/cli/core/fixtures/evidence-plans/baseline.json +19 -0
- package/cli/core/fulfill-intake.js +1082 -0
- package/cli/core/go-live-preflight.js +481 -0
- package/cli/core/license.js +534 -0
- package/cli/core/manifest.js +243 -0
- package/cli/core/packetseal.js +591 -0
- package/cli/core/registryArtifact.js +49 -0
- package/cli/core/revocation.js +539 -0
- package/cli/core/rfc3161.js +389 -0
- package/cli/core/timestamp.js +482 -0
- package/cli/core/trust-asof.js +479 -0
- package/cli/dataset.js +2950 -0
- package/cli/evidence.js +2227 -0
- package/cli/fulfill-webhook-http.js +438 -0
- package/cli/git.js +220 -0
- package/cli/hash.js +550 -0
- package/cli/identity.js +1072 -0
- package/cli/journal-cli.js +1110 -0
- package/cli/journal-log.js +454 -0
- package/cli/journal.js +334 -0
- package/cli/lineage.js +447 -0
- package/cli/list.js +287 -0
- package/cli/parcel.js +1509 -0
- package/cli/proof.js +578 -0
- package/cli/prove.js +300 -0
- package/cli/receipt.js +631 -0
- package/cli/registry.js +331 -0
- package/cli/reputation.js +344 -0
- package/cli/revocation.js +495 -0
- package/cli/serve-verify-http.js +298 -0
- package/cli/serve-verify.js +333 -0
- package/cli/show.js +339 -0
- package/cli/verify.js +383 -0
- package/cli/vh.js +3927 -0
- package/docs/ADOPT.md +183 -0
- package/docs/ADOPTION.json +11 -0
- package/docs/AGENTTRACE.md +247 -0
- package/docs/ANCHORING.md +167 -0
- package/docs/AUDIT.md +55 -0
- package/docs/CONFORMANCE.md +107 -0
- package/docs/DATALEDGER.md +638 -0
- package/docs/DECIDE.md +47 -0
- package/docs/DECISIONS-PENDING.md +27 -0
- package/docs/DEPLOY-PUBLIC-SITE.md +301 -0
- package/docs/ENGINE-LEDGER.json +12 -0
- package/docs/EVIDENCE.md +519 -0
- package/docs/GO-LIVE.md +66 -0
- package/docs/IDENTITY.md +123 -0
- package/docs/INDEPENDENT-VERIFICATION.md +377 -0
- package/docs/INTEGRITY-JOURNAL.md +337 -0
- package/docs/KEY-LIFECYCLE.md +179 -0
- package/docs/LICENSING.md +46 -0
- package/docs/LINEAGE.md +307 -0
- package/docs/LOOP-AUDIT-2026-07-03.json +580 -0
- package/docs/LOOP-HARDENING-PLAN.md +44 -0
- package/docs/MERKLE-LEAVES.md +113 -0
- package/docs/METRICS.jsonl +31 -0
- package/docs/MORNING.md +204 -0
- package/docs/PILOT.md +444 -0
- package/docs/PROOFPARCEL.md +227 -0
- package/docs/PROOFS.md +262 -0
- package/docs/RECEIPTS.md +341 -0
- package/docs/REPUTATION.md +158 -0
- package/docs/SDK.md +301 -0
- package/docs/STRATEGY-ARCHIVE.md +5055 -0
- package/docs/SUPERVISOR-RUNBOOK.md +52 -0
- package/docs/TRUST-BOUNDARIES.md +335 -0
- package/docs/TRUSTLEDGER.md +1976 -0
- package/docs/USAGE-BUDGET.json +121 -0
- package/docs/VERIFY-SERVICE.md +168 -0
- package/index.js +160 -0
- package/package.json +41 -0
- package/trustledger/build-standalone.js +796 -0
- package/trustledger/cli.js +3179 -0
- package/trustledger/close.js +391 -0
- package/trustledger/corpus.js +159 -0
- package/trustledger/dist/BUILD-PROVENANCE.json +99 -0
- package/trustledger/dist/trustledger-standalone.html +6197 -0
- package/trustledger/dist/trustledger-standalone.html.sha256 +1 -0
- package/trustledger/door-core.js +442 -0
- package/trustledger/fixtures/bank.csv +7 -0
- package/trustledger/fixtures/bank.malformed.csv +3 -0
- package/trustledger/fixtures/bank.noalias.csv +5 -0
- package/trustledger/fixtures/bank.ofx +34 -0
- package/trustledger/fixtures/bank.real.csv +5 -0
- package/trustledger/fixtures/corpus/_shared/prior-close.json +22 -0
- package/trustledger/fixtures/corpus/bank-book-mismatch--benign-twin/inputs.json +14 -0
- package/trustledger/fixtures/corpus/bank-book-mismatch--benign-twin/meta.json +7 -0
- package/trustledger/fixtures/corpus/bank-book-mismatch--out-of-trust/inputs.json +14 -0
- package/trustledger/fixtures/corpus/bank-book-mismatch--out-of-trust/meta.json +7 -0
- package/trustledger/fixtures/corpus/continuity-break--benign-twin/inputs.json +15 -0
- package/trustledger/fixtures/corpus/continuity-break--benign-twin/meta.json +7 -0
- package/trustledger/fixtures/corpus/continuity-break--out-of-trust/inputs.json +15 -0
- package/trustledger/fixtures/corpus/continuity-break--out-of-trust/meta.json +7 -0
- package/trustledger/fixtures/corpus/negative-tenant-ledger--benign-twin/inputs.json +13 -0
- package/trustledger/fixtures/corpus/negative-tenant-ledger--benign-twin/meta.json +7 -0
- package/trustledger/fixtures/corpus/negative-tenant-ledger--out-of-trust/inputs.json +13 -0
- package/trustledger/fixtures/corpus/negative-tenant-ledger--out-of-trust/meta.json +7 -0
- package/trustledger/fixtures/corpus/owner-overdraw--benign-twin/inputs.json +15 -0
- package/trustledger/fixtures/corpus/owner-overdraw--benign-twin/meta.json +7 -0
- package/trustledger/fixtures/corpus/owner-overdraw--out-of-trust/inputs.json +15 -0
- package/trustledger/fixtures/corpus/owner-overdraw--out-of-trust/meta.json +7 -0
- package/trustledger/fixtures/corpus/security-deposit-segregation--benign-twin/inputs.json +16 -0
- package/trustledger/fixtures/corpus/security-deposit-segregation--benign-twin/meta.json +7 -0
- package/trustledger/fixtures/corpus/security-deposit-segregation--out-of-trust/inputs.json +13 -0
- package/trustledger/fixtures/corpus/security-deposit-segregation--out-of-trust/meta.json +7 -0
- package/trustledger/fixtures/corpus/subledger-out-of-balance--benign-twin/inputs.json +13 -0
- package/trustledger/fixtures/corpus/subledger-out-of-balance--benign-twin/meta.json +7 -0
- package/trustledger/fixtures/corpus/subledger-out-of-balance--out-of-trust/inputs.json +13 -0
- package/trustledger/fixtures/corpus/subledger-out-of-balance--out-of-trust/meta.json +7 -0
- package/trustledger/fixtures/e2e/bank.aliased.csv +4 -0
- package/trustledger/fixtures/e2e/bank.csv +4 -0
- package/trustledger/fixtures/e2e/bank.nsf.csv +4 -0
- package/trustledger/fixtures/e2e/quickbooks.csv +6 -0
- package/trustledger/fixtures/e2e/quickbooks.nsf.csv +8 -0
- package/trustledger/fixtures/e2e/rentroll.csv +6 -0
- package/trustledger/fixtures/e2e/rentroll.nsf.csv +8 -0
- package/trustledger/fixtures/e2e/rentroll.short.csv +5 -0
- package/trustledger/fixtures/plans/baseline.json +25 -0
- package/trustledger/fixtures/plans/price-binding.example.json +27 -0
- package/trustledger/fixtures/policy/ambiguous-deposit-example.json +12 -0
- package/trustledger/fixtures/policy/baseline.json +19 -0
- package/trustledger/fixtures/policy/ca-example.json +12 -0
- package/trustledger/fixtures/policy/negative-tenant-ledger-example.json +12 -0
- package/trustledger/fixtures/policy/owner-overdraw-example.json +12 -0
- package/trustledger/fixtures/quickbooks.csv +7 -0
- package/trustledger/fixtures/quickbooks.real.csv +5 -0
- package/trustledger/fixtures/rentroll.csv +6 -0
- package/trustledger/fixtures/rentroll.real.csv +4 -0
- package/trustledger/ingest.js +1163 -0
- package/trustledger/lib/policy-bundled-loader.js +44 -0
- package/trustledger/lib/sha256-vendored.js +227 -0
- package/trustledger/license.js +563 -0
- package/trustledger/match.js +551 -0
- package/trustledger/plans.js +551 -0
- package/trustledger/policy.js +398 -0
- package/trustledger/public/index.html +512 -0
- package/trustledger/reconcile.js +1486 -0
- package/trustledger/report.js +887 -0
- package/trustledger/seal.js +854 -0
- package/trustledger/server.js +391 -0
- package/trustledger/valueproof.js +350 -0
package/docs/PILOT.md
ADDED
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
# The verifyhash Pilot — a buyer-facing runbook
|
|
2
|
+
|
|
3
|
+
This is the runbook a prospective **design partner** (and their security team) follows to run the
|
|
4
|
+
verifyhash pilot kit, see the two sellable journeys work end to end, and understand — precisely — what
|
|
5
|
+
each artifact **proves**, what it **does not**, and **where they independently verify it**. It is
|
|
6
|
+
written so a **non-author** can follow it without reading the source, and so a partner can explain it
|
|
7
|
+
to a colleague.
|
|
8
|
+
|
|
9
|
+
Nothing in this pilot touches a real key, a timestamp authority, an RPC endpoint, or any network. It
|
|
10
|
+
runs **offline** and writes **only** to a throwaway workspace.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## 1. What you are evaluating
|
|
15
|
+
|
|
16
|
+
verifyhash turns "a set of files, byte-for-byte unaltered, and who vouched for them" into a
|
|
17
|
+
**tamper-evident, independently-verifiable artifact**. The pilot drives the **two** journeys we sell:
|
|
18
|
+
|
|
19
|
+
- **Evidence packets** — seal a folder of compliance / audit / incident / hand-off files into one
|
|
20
|
+
`*.vhevidence.json`, hand it to a counterparty, and let them confirm offline that it is exactly the
|
|
21
|
+
set you sealed (and who signed it).
|
|
22
|
+
- **TrustLedger reconciliation seals** — reconcile a bank statement, a ledger export, and a rent roll
|
|
23
|
+
into a dated audit packet, then seal it so an examiner can confirm **byte-for-byte** that this is the
|
|
24
|
+
exact packet the tool produced.
|
|
25
|
+
|
|
26
|
+
Both ride the **same** provenance core and the **same** independent verifier, so confidence in one
|
|
27
|
+
transfers to the other.
|
|
28
|
+
|
|
29
|
+
> A third, packet-shaped journey — **AgentTrace** agent-session evidence (`vh agent`: seal an ordered
|
|
30
|
+
> AI-agent session log into one tamper-evident, selectively-redactable `*.vhagent.json`) — rides that
|
|
31
|
+
> same core and the same independent verifier, though this kit's script does not drive it. Its
|
|
32
|
+
> buyer-facing spec, honest trust boundary (log unaltered since seal; NOT what the agent actually did;
|
|
33
|
+
> not a trusted timestamp without **P-3**), and a committed map → seal → redact → verify → prove
|
|
34
|
+
> example are in [`AGENTTRACE.md`](AGENTTRACE.md) and
|
|
35
|
+
> [`../examples/agent-session/`](../examples/agent-session/).
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## 2. Run the kit (zero setup)
|
|
40
|
+
|
|
41
|
+
From a checkout of the repository (run `npm install` once):
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
node pilot/run-pilot.js
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
You should see two labelled sections — `VERTICAL A — EVIDENCE` and `VERTICAL B — RECONCILE` — each
|
|
48
|
+
listing `[PASS]` checks, then a single final line:
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
VERDICT: PASS — N/N checks passed (evidence + reconcile).
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
The process exits **0** on an all-PASS run (CI-gateable). It writes its artifacts to a fresh OS temp
|
|
55
|
+
directory; set `PILOT_OUT=<dir>` to choose where, or `PILOT_KEEP=1` to keep the workspace so you can
|
|
56
|
+
open the produced files. It **never** writes into the repository, and the committed sample inputs are
|
|
57
|
+
**read-only** — the tamper step always hits a throwaway copy.
|
|
58
|
+
|
|
59
|
+
### Run it on YOUR OWN folder (the question every partner asks first)
|
|
60
|
+
|
|
61
|
+
The default run above seals the committed sample. To watch the **exact same** journey — license-gated
|
|
62
|
+
`--sign` → independent `verify-vh` ACCEPT → TAMPER → REJECT — run against **your own** evidence folder,
|
|
63
|
+
point the evidence vertical at it in **one command**:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
node pilot/run-pilot.js --evidence-dir /path/to/your/folder
|
|
67
|
+
# …or, equivalently, via the environment:
|
|
68
|
+
PILOT_EVIDENCE_DIR=/path/to/your/folder node pilot/run-pilot.js
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**The kit does NOT modify your files.** It **copies** your folder into the throwaway workspace and seals,
|
|
72
|
+
verifies, and tampers **only the copy**; your originals are **read-only** and are never written, renamed,
|
|
73
|
+
or deleted (their bytes and mtimes are unchanged after the run — this is asserted by the test suite). If
|
|
74
|
+
the folder is **missing, empty, or unreadable**, the kit **hard-errors with a clear message before it
|
|
75
|
+
seals anything** — never a misleading PASS over no data. On a valid folder you get the same single
|
|
76
|
+
`VERDICT: PASS` line, computed on *your* data.
|
|
77
|
+
|
|
78
|
+
Folder size doesn't matter: the demo mints an **ephemeral, throwaway** license that grants the full paid
|
|
79
|
+
evidence surface (`evidence_signed` + `evidence_unlimited`), so a realistic evidence/audit folder with
|
|
80
|
+
dozens of files runs to the same all-PASS verdict — you are never gated by the free-sample size in the
|
|
81
|
+
pilot. (In production, sealing more than the free sample is the paid tier; here the demo license simply
|
|
82
|
+
unlocks it for you so you can watch the whole journey on your real data.)
|
|
83
|
+
|
|
84
|
+
> Operator quick reference (knobs, file map, how it can't rot):
|
|
85
|
+
> [`pilot/README.md`](../pilot/README.md).
|
|
86
|
+
|
|
87
|
+
### The link-shaped first contact (evidence vertical — one page in their browser, no Node)
|
|
88
|
+
|
|
89
|
+
The very first touch does not even need a terminal — on either side. Send the prospect **one committed
|
|
90
|
+
file**, [`../verifier/dist/verify-vh-standalone.html`](../verifier/dist/verify-vh-standalone.html)
|
|
91
|
+
(it is also in the verifyhash.com site publish set — `site/publish-set.json`; uploading the assembled
|
|
92
|
+
webroot to the live site remains the standing human-owned deploy step). They double-click it and the
|
|
93
|
+
page opens in their browser with the **60-second challenge built in**: click **"Load the sample packet
|
|
94
|
+
& verify"** (**ACCEPT**), change ONE character of the editable sample file on the page, re-verify
|
|
95
|
+
(**REJECT** — the page names the file changed) — then drag a REAL sealed packet + its files in for the
|
|
96
|
+
same verdict + per-file tamper localization the CLI prints. The privacy claim is verifiable, not a
|
|
97
|
+
promise: the file contains **no network API at all**, so their bytes never leave their machine — the
|
|
98
|
+
browser **devtools Network tab** stays empty. The boundary is §5's, unchanged and stated on the page
|
|
99
|
+
itself; for CI/production gating use the node standalone (`verify-vh-standalone.js`) — the §4 merge
|
|
100
|
+
gate, not the browser page, is what lives in a pipeline. The guided walkthrough (browser path first,
|
|
101
|
+
node path as the CI-shaped variant) is [`../challenge/README.md`](../challenge/README.md).
|
|
102
|
+
|
|
103
|
+
### Evaluate it with ZERO install first (the 10-second no-clone path)
|
|
104
|
+
|
|
105
|
+
Before you check out the repo at all, you can drive the **whole** evidence journey — seal → hand-off →
|
|
106
|
+
verify — from **two self-contained files**, with **no clone, no `npm install`, no account, no key** on
|
|
107
|
+
either side. Save [`../verifier/dist/seal-vh-standalone.js`](../verifier/dist/seal-vh-standalone.js) and
|
|
108
|
+
[`../verifier/dist/verify-vh-standalone.js`](../verifier/dist/verify-vh-standalone.js) (each depends on
|
|
109
|
+
nothing but Node core), then:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# 1. Seal up to 25 of YOUR OWN files into one tamper-evident packet:
|
|
113
|
+
node seal-vh-standalone.js /path/to/your/folder -o packet.vhevidence.json # exit 0 = sealed
|
|
114
|
+
|
|
115
|
+
# 2. Hand packet.vhevidence.json + the folder to a counterparty; they run the FREE verifier:
|
|
116
|
+
node verify-vh-standalone.js packet.vhevidence.json --dir /path/to/your/folder # 0 = verifies, 3 = REJECTED
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
That is the same organic loop a real counterparty would run, on your own data, before any sales call. The
|
|
120
|
+
free seal proves **tamper-evidence + offline-recompute** — and **NOT** a trusted "sealed at T" (that still
|
|
121
|
+
requires **P-3** — see §5). The free seal is **UNSIGNED** and **capped at 25 files**; **SIGNING** (so a
|
|
122
|
+
counterparty can pin you with `--vendor`) and **UNLIMITED** sealing are the PAID upgrade —
|
|
123
|
+
`vh evidence seal --sign` / the `evidence_unlimited` entitlement. Full round-trip in
|
|
124
|
+
[`../verifier/README.md`](../verifier/README.md) §0a and
|
|
125
|
+
[`INDEPENDENT-VERIFICATION.md`](INDEPENDENT-VERIFICATION.md) §0a. The `node pilot/run-pilot.js` kit above
|
|
126
|
+
is the deeper, license-gated evaluation; this zero-install loop is the fastest first taste.
|
|
127
|
+
|
|
128
|
+
### Zero-install: the offline app (TrustLedger — email them ONE file)
|
|
129
|
+
|
|
130
|
+
The TrustLedger vertical has an even shorter zero-install path — **no terminal at all, on either
|
|
131
|
+
side**. You **email ONE file** to the design partner (or hand it over on a USB stick):
|
|
132
|
+
[`../trustledger/dist/trustledger-standalone.html`](../trustledger/dist/trustledger-standalone.html).
|
|
133
|
+
The partner **double-clicks** it — it opens as an ordinary page in their browser — then **drags their
|
|
134
|
+
REAL exports** onto the page's three file inputs (the **bank statement**, the **QuickBooks trust
|
|
135
|
+
ledger**, and the **rent roll**; the same in-page "Check this file" inspect/map onboarding fixes a
|
|
136
|
+
file that won't load), and **reads the same tie-out report** the installed product produces: the
|
|
137
|
+
PASS/FAIL verdict, the three balances, the exceptions, and the downloadable HTML + CSV audit packet.
|
|
138
|
+
|
|
139
|
+
Run **month-1**'s three files, then **month-2**'s — **two INDEPENDENT monthly tie-outs on real
|
|
140
|
+
data**, a FREE, zero-install willingness-to-pay signal that the recurring monthly product ties out on
|
|
141
|
+
the partner's own exports (part of the sharpened P-5 ask's "run their REAL month-1 + month-2 files"
|
|
142
|
+
step). The offline app runs **each month independently** — its UI has only the three file pickers, so
|
|
143
|
+
the **machine-checked continuity roll-forward** (month-1's signed close carried into month 2 with **no
|
|
144
|
+
`CONTINUITY_BREAK`**, via `--emit-close` / `--prior-close`) is **not** in the offline app; it stays an
|
|
145
|
+
**installed-CLI** capability. The engine inlined in the file is pinned **byte-identical** to the
|
|
146
|
+
installed one — *including* on exactly that two-month **prior-close** clean roll-forward at the
|
|
147
|
+
**payload level**, which proves the bundle's *engine* supports the roll-forward, not that the app's UI
|
|
148
|
+
delivers it ([`../test/trustledger.standalone.test.js`](../test/trustledger.standalone.test.js)).
|
|
149
|
+
|
|
150
|
+
The privacy claim — the #1 objection with live trust-account data — is **honest and verifiable, not
|
|
151
|
+
a promise**: the page makes **NO network request**, because the file **contains no network API at
|
|
152
|
+
all** (no `fetch(`, no `XMLHttpRequest`, no `WebSocket`/`EventSource`/`sendBeacon`, no dynamic
|
|
153
|
+
`import(`) — **check the browser devtools Network tab yourself**: it stays empty, so the partner's
|
|
154
|
+
trust-account data **never leaves their machine**. A recipient can confirm the received file is the
|
|
155
|
+
published one with `sha256sum -c trustledger-standalone.html.sha256`.
|
|
156
|
+
|
|
157
|
+
The honesty boundary, stated plainly: the offline app is the FREE funnel tier — per-state policy
|
|
158
|
+
tables, sealing, and licensing/fulfillment run in the installed product, and P-5's CPA/counsel
|
|
159
|
+
review, vendor-key provisioning, pricing, and publishing steps remain HUMAN-OWNED and UNCHANGED (no
|
|
160
|
+
new needs-human item, no relaxed gate). Requesting a paid surface in the offline app yields the
|
|
161
|
+
**same named `license_required` refusal** the web door gives — the gate is reused, never weakened.
|
|
162
|
+
The deeper spec is in [`TRUSTLEDGER.md`](TRUSTLEDGER.md) › *Zero-install: the offline app*.
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## 3. What each artifact proves — and where you independently verify it
|
|
167
|
+
|
|
168
|
+
The pilot produces three kinds of artifact. For each, here is the claim it carries and **how a partner
|
|
169
|
+
checks it themselves, without trusting us**.
|
|
170
|
+
|
|
171
|
+
### 3a. The evidence packet (`*.vhevidence.json`)
|
|
172
|
+
|
|
173
|
+
- **What it proves.** This exact set of files, byte-for-byte. The packet is a content-addressed
|
|
174
|
+
keccak Merkle root over `(relPath, content)` pairs, optionally wrapped in an EIP-191 signature that
|
|
175
|
+
binds **who** vouched (the operator key).
|
|
176
|
+
- **Where you verify it independently.** Run the standalone verifier on the bytes you were handed:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
node verifier/verify-vh.js --dir <evidence-folder> --vendor <0xOperatorAddress> <packet>.vhevidence.json
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Exit **0** = the folder matches the packet and the signature recovers to the address you pinned;
|
|
183
|
+
exit **3** = REJECTED, and the output **localizes** which file CHANGED / MISSING / UNEXPECTED. The
|
|
184
|
+
verifier is in its own [`verifier/`](../verifier/) tree with near-zero dependencies (`js-sha3`
|
|
185
|
+
only — **no** `ethers`, **no** `hardhat`), so you are not installing our producer stack to check our
|
|
186
|
+
claim. **Zero-install option:** for a counterparty who was handed only a packet, save the single
|
|
187
|
+
self-contained file [`verifier/dist/verify-vh-standalone.js`](../verifier/dist/verify-vh-standalone.js)
|
|
188
|
+
(optionally check its published `verify-vh-standalone.js.sha256`) and run
|
|
189
|
+
`node verify-vh-standalone.js <packet> --vendor <0xOperator>` — no clone, no `npm install`, no account;
|
|
190
|
+
it is byte-for-byte the same verifier and proves the same **tamper-evidence + signer-pin**, NOT a
|
|
191
|
+
trusted "sealed at T" (that still requires **P-3**). See [`verifier/README.md`](../verifier/README.md)
|
|
192
|
+
§0 and [`INDEPENDENT-VERIFICATION.md`](INDEPENDENT-VERIFICATION.md) §0.
|
|
193
|
+
- **And confirm the VERIFIER itself rejects what it should** — run the adversarial conformance corpus
|
|
194
|
+
(`node challenge/corpus/run-corpus.js`, exit 0 = every poisoned input REJECTED by every shipped
|
|
195
|
+
verifier) in place of trusting our claim; it proves REJECT of every *enumerated* tamper class (NOT the
|
|
196
|
+
absence of unknown ones, and a REJECT is tamper-evidence NOT a trusted timestamp without **P-3**). See
|
|
197
|
+
[`CONFORMANCE.md`](CONFORMANCE.md).
|
|
198
|
+
|
|
199
|
+
### 3b. The TrustLedger reconciliation seal
|
|
200
|
+
|
|
201
|
+
- **What it proves.** The three balances tied out to a single PASS/FAIL on a stated date, and the
|
|
202
|
+
sealed packet (sources + every emitted file + the verdict/role header) is byte-for-byte the packet
|
|
203
|
+
the tool produced — any edit, rename, add, or removed input REJECTS.
|
|
204
|
+
- **Where you verify it independently.** The **same** verifier re-derives the keccak root from the
|
|
205
|
+
source bytes you hold:
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
node verifier/verify-vh.js --dir <reconcile-folder> <reconciliation-...-seal>.json
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Exit **0** = the root re-derives from the bytes on disk; exit **3** = REJECTED, localized to the
|
|
212
|
+
changed source. (The pilot's reconciliation seal is **unsigned**, so you do not pin `--vendor` for
|
|
213
|
+
it — an unsigned artifact cannot be signer-pinned.)
|
|
214
|
+
|
|
215
|
+
- **And confirm the GATE itself is correct — run this in place of trusting our disclaimer.** A seal proves
|
|
216
|
+
the packet is byte-for-byte unaltered; it does **not** tell you whether a **FAIL really means out of
|
|
217
|
+
trust**. To confirm the reconciliation **gate** is correct — that it FAILs the canonical trust-account
|
|
218
|
+
frauds and PASSes their benign twins — run the committed **correctness corpus**, one read-only command,
|
|
219
|
+
no setup:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
vh trust corpus # exit 0 = CORPUS OK (every scenario matches); exit 3 = CORPUS DRIFT
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
It drives a committed library of out-of-trust scenarios (an un-segregated security deposit, a
|
|
226
|
+
sub-ledger out of balance, a negative individual ledger, an owner over-draw, a bank-short mismatch, a
|
|
227
|
+
broken roll-forward) **and** their benign near-twins through the **same** engine path the real
|
|
228
|
+
`reconcile` exit uses, and prints a per-scenario table (control, expected vs **actual** verdict,
|
|
229
|
+
`OK`/`MISMATCH`) plus the trust-law **principle** under each row. This is what a CPA or broker **runs**
|
|
230
|
+
to confirm the gate is correct **in place of trusting our disclaimer** (see
|
|
231
|
+
[`TRUSTLEDGER.md`](TRUSTLEDGER.md) › *The correctness corpus*). It **confirms the gate's behaviour** —
|
|
232
|
+
it does **NOT** certify a jurisdiction or constitute legal advice; for TrustLedger a PASS does **not**
|
|
233
|
+
imply legal compliance, the broker remains the responsible legal custodian, and that meaning stays
|
|
234
|
+
CPA/counsel-reviewed under **P-5** (§5).
|
|
235
|
+
|
|
236
|
+
### 3c. The licence (`*.vhlicense.json`)
|
|
237
|
+
|
|
238
|
+
- **What it proves.** It is the **access credential** that unlocks the paid surface (`evidence
|
|
239
|
+
seal --sign`, `reconcile --seal`). It is signed by the vendor key and verified offline; a wrong,
|
|
240
|
+
expired, or under-entitled licence is a **hard refuse**, never a silent downgrade. The pilot proves
|
|
241
|
+
this gate is **real** by showing the paid surface refused with **no** licence and refused again with
|
|
242
|
+
a licence pinned to the **wrong** vendor.
|
|
243
|
+
- **What it is NOT.** Not a token, not tradeable, not an appreciating asset. Income is a subscription
|
|
244
|
+
/ licence for delivered software value — the credential is just the key to the door.
|
|
245
|
+
|
|
246
|
+
### 3d. The pilot result certificate — your SHAREABLE deliverable (`--certificate`)
|
|
247
|
+
|
|
248
|
+
When you run the pilot on your own folder (§2), the terminal `VERDICT: PASS` is the proof *on your
|
|
249
|
+
machine*. To turn "the demo passed on my machine" into a **forwardable, tamper-evident record** your
|
|
250
|
+
security and procurement teams can check for themselves, add one flag and the kit seals the run into a
|
|
251
|
+
portable `*.vhevidence.json` **certificate**:
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
node pilot/run-pilot.js --evidence-dir /path/to/your/folder --certificate ./pilot-result.vhevidence.json
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
This writes two things alongside each other — the certificate `pilot-result.vhevidence.json` and its
|
|
258
|
+
companion `pilot-result.files/` directory (the sealed result bytes). **Forward both together.** Anyone
|
|
259
|
+
you hand them to verifies the certificate **independently**, with **no clone, no `npm install`, no
|
|
260
|
+
account, no key**, using the zero-install single-file verifier
|
|
261
|
+
[`../verifier/dist/verify-vh-standalone.js`](../verifier/dist/verify-vh-standalone.js):
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
# they save verify-vh-standalone.js, then run it on the bytes you forwarded:
|
|
265
|
+
node verify-vh-standalone.js --dir ./pilot-result.files ./pilot-result.vhevidence.json # exit 0 = ACCEPT, 3 = REJECT
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Exit **0** = the certificate's keccak root re-derives from the bytes on disk — the result record is
|
|
269
|
+
exactly what the pilot produced; exit **3** = REJECTED, localized to the byte that changed. The kit
|
|
270
|
+
prints the precise verify command (and, for a signed certificate, the operator address to pin with
|
|
271
|
+
`--vendor`) after the verdict line. That is what turns a one-off demo into a record your team can carry
|
|
272
|
+
into a procurement review and confirm without trusting you — or us.
|
|
273
|
+
|
|
274
|
+
**Then READ the verdict out of the bytes you just verified — the certificate is a self-contained
|
|
275
|
+
procurement record, not just a checksum.** The whole point of a forwardable certificate is that the
|
|
276
|
+
reviewer who confirmed exit `0` does **not** then have to take a sales claim about *what the run checked*
|
|
277
|
+
on faith: the **machine-readable result record** — `verdict`, the `passed`/`total` counts, and the full
|
|
278
|
+
**labelled checklist** of every gate the pilot exercised — lives **inside** `pilot-result.files/pilot-result.json`,
|
|
279
|
+
which is the **exact byte stream the keccak root commits to**. So once verify-vh ACCEPTs, the contents of
|
|
280
|
+
that file are *part of what was proven unaltered*. Read the headline with one Node-only line (no extra
|
|
281
|
+
install, no `jq` needed):
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
# the same file the certificate's root commits to — its contents are part of what you just verified:
|
|
285
|
+
node -e 'const r=require("./pilot-result.files/pilot-result.json"); console.log(r.verdict+" — "+r.passed+"/"+r.total+" checks; evidenceSource="+r.evidenceSource)'
|
|
286
|
+
# → PASS — 24/24 checks; evidenceSource=partner
|
|
287
|
+
|
|
288
|
+
# and read the FULL labelled checklist of what was actually exercised (open it, or list the labels):
|
|
289
|
+
node -e 'require("./pilot-result.files/pilot-result.json").checks.forEach(c=>console.log((c.ok?"[PASS] ":"[FAIL] ")+c.label))'
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
`evidenceSource` reads `partner` when the pilot ran on the partner's **own** folder (§2) and `canned` on
|
|
293
|
+
the committed sample — so a procurement reviewer can see at a glance whether the forwarded certificate was
|
|
294
|
+
produced on real data or the demo set, **from the verified bytes themselves**. (`jq -r '.verdict' pilot-result.files/pilot-result.json`
|
|
295
|
+
works identically if your reviewer prefers it.) This is the leverage of the certificate over a bare
|
|
296
|
+
PASS/FAIL screenshot: the verdict, the counts, and the precise list of checks are a tamper-evident,
|
|
297
|
+
forwardable **artifact** a security/procurement team reads and re-confirms on its own — the screenshot is
|
|
298
|
+
not.
|
|
299
|
+
|
|
300
|
+
**The HONEST boundary (read this before you forward it).** The certificate proves WHAT the pilot run
|
|
301
|
+
checked and that the result bytes are unaltered — it is tamper-evidence over the run record, NOT a
|
|
302
|
+
trusted "the pilot ran at time T" without P-3, and NOT a legal/compliance verdict. The pilot signs
|
|
303
|
+
with **ephemeral throwaway keys only**, so any date inside the record is self-asserted input, not an
|
|
304
|
+
independent attestation of *when* — a trusted "ran at time T" still requires the human-owned trust-root
|
|
305
|
+
of **P-3** (§5). And it is tamper-evidence over a run record, not an opinion: it makes no legal or
|
|
306
|
+
compliance claim (for TrustLedger a PASS does not imply legal compliance — that meaning stays
|
|
307
|
+
CPA/counsel-reviewed under **P-5**, §5).
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
## 4. Wire it into your pipeline (this is how the pilot lives in your release process)
|
|
312
|
+
|
|
313
|
+
A pilot you run once is a demo; a pilot that **lives in your CI** is a dependency. The same independent
|
|
314
|
+
`verify-vh` you ran by hand in §3 drops into your build as a **merge gate**: the moment a sealed
|
|
315
|
+
artifact is tampered, forged, or signed by the wrong key, the build goes **red** and the merge is
|
|
316
|
+
**blocked**. You do not install our producer stack to do this — the gate runs the standalone verifier
|
|
317
|
+
(`js-sha3` only, **no** `ethers`, **no** `hardhat`).
|
|
318
|
+
|
|
319
|
+
We ship the snippet so this is **one paste**, not a project. A non-author wires it in like so:
|
|
320
|
+
|
|
321
|
+
1. Copy [`../verifier/ci/verify-vh.generic.sh`](../verifier/ci/verify-vh.generic.sh) into your repo (a
|
|
322
|
+
portable `set -e` shell gate for GitLab CI, CircleCI, Jenkins, a Makefile recipe, or a git hook), or
|
|
323
|
+
drop [`../verifier/ci/verify-vh.github-actions.yml`](../verifier/ci/verify-vh.github-actions.yml) at
|
|
324
|
+
`.github/workflows/verify-vh.yml` for GitHub Actions.
|
|
325
|
+
2. Add **three lines** to the pipeline step that runs it — the producer address you pin out-of-band, the
|
|
326
|
+
artifact(s) or release manifest, and the call:
|
|
327
|
+
|
|
328
|
+
```bash
|
|
329
|
+
export VH_VENDOR=0xYOUR_PRODUCERS_SIGNER_ADDRESS # pinned out-of-band
|
|
330
|
+
export VH_MANIFEST=release.manifest # or VH_ARTIFACTS="dist/packet.vhevidence.json"
|
|
331
|
+
./verifier/ci/verify-vh.generic.sh # exit 0 = green/merge; non-zero = red/blocked
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
3. Read the gate: a **green** check *means* every sealed artifact still matches the bytes the producer
|
|
335
|
+
signed (exit `0`). A **red** gate *means* a `3` (REJECTED — a sealed byte changed / wrong signer,
|
|
336
|
+
localized to the offending artifact and file), a `2` (usage error), or a `1` (an artifact could not
|
|
337
|
+
even be read) — and your merge is **blocked** until it is resolved. A non-zero verdict never slips
|
|
338
|
+
through as a silent pass.
|
|
339
|
+
|
|
340
|
+
**The boundary stays explicit even in CI: verification is FREE, sealing is PAID.** The gate above — and
|
|
341
|
+
every `verify-vh` invocation — costs nothing and needs no licence; anyone may verify forever, offline.
|
|
342
|
+
The licence (§3c) gates only the **paid sealing surface** (`evidence seal --sign`, `reconcile --seal`)
|
|
343
|
+
on the **producer** side. So your pipeline can gate on our proofs without buying anything; what your
|
|
344
|
+
counterparty pays for is the right to **produce** sealed artifacts, not your right to **check** them.
|
|
345
|
+
|
|
346
|
+
The shipped snippets are **examples the loop never runs**, but their exact gate command is mechanically
|
|
347
|
+
tested ([`../test/verifier.ci-snippet.test.js`](../test/verifier.ci-snippet.test.js)): it must exit `0`
|
|
348
|
+
on a good release and `3` on a tampered one, so the snippet you copy is known-good, not aspirational.
|
|
349
|
+
The deeper spec is in [`../verifier/README.md`](../verifier/README.md) §2b and
|
|
350
|
+
[`INDEPENDENT-VERIFICATION.md`](INDEPENDENT-VERIFICATION.md) §4b.
|
|
351
|
+
|
|
352
|
+
> **And that is where the pilot ends:** not at "it worked once on a demo," but wired into your release
|
|
353
|
+
> process, failing your build the day someone hands you a seal that no longer matches its bytes.
|
|
354
|
+
|
|
355
|
+
---
|
|
356
|
+
|
|
357
|
+
## 5. The honest trust boundary (read this before you rely on anything)
|
|
358
|
+
|
|
359
|
+
The pilot is deliberately conservative about what it claims:
|
|
360
|
+
|
|
361
|
+
- **It proves tamper-evidence + offline-recompute + signer-pin.** "These are exactly those files" and
|
|
362
|
+
"this address vouched for them" — both checkable by you, offline, with the independent verifier.
|
|
363
|
+
- **It does NOT prove a trusted timestamp.** There is **no trusted "sealed on date T" without P-3.**
|
|
364
|
+
A trustworthy "existed by date T" requires a **human-owned trust-root** — a self-managed signing
|
|
365
|
+
key, an independent RFC-3161 timestamp authority, or an on-chain anchor — which is **P-3** in
|
|
366
|
+
[`STRATEGY.md`](../STRATEGY.md). The pilot uses **ephemeral throwaway keys only**, so it asserts
|
|
367
|
+
nothing about *when*; any date you see in a licence window or report is self-asserted input, not an
|
|
368
|
+
independent attestation.
|
|
369
|
+
- **It is NOT a legal or compliance opinion.** The evidence packet makes no domain claim beyond
|
|
370
|
+
tamper-evidence; for TrustLedger, a PASS does **not** imply legal compliance (that meaning is
|
|
371
|
+
CPA/counsel-reviewed — P-5).
|
|
372
|
+
- **The pilot ends at the explicit human handoff** and overclaims nothing. The handoff (provision a
|
|
373
|
+
real key / TSA, choose a price, run the partner) is the human go-to-market ask, consolidated as
|
|
374
|
+
**P-8** below.
|
|
375
|
+
|
|
376
|
+
This boundary is not a footnote — it is the product. We sell verifiable *tamper-evidence and
|
|
377
|
+
provenance*, and we are explicit that *trusted time* is a separate, human-owned upgrade.
|
|
378
|
+
|
|
379
|
+
---
|
|
380
|
+
|
|
381
|
+
## 6. The single go-to-market ask (P-8)
|
|
382
|
+
|
|
383
|
+
Everything above is **built, tested, and green**. The one thing the loop cannot do — and the one thing
|
|
384
|
+
a human must — is **land a design partner and run a pilot**. That precondition was scattered across
|
|
385
|
+
four proposals (P-3 trust-root, P-5 TrustLedger legal/CPA/design-partner, P-6 TrustLedger licence
|
|
386
|
+
delivery + pricing, P-7 evidence vertical go-to-market). It is now **consolidated into one
|
|
387
|
+
decision-ready ask, P-8**, in [`STRATEGY.md`](../STRATEGY.md) → *Proposals — needs-human*, whose
|
|
388
|
+
**deliverable is this very kit**. Read P-8 to see the precise human steps and how running this pilot
|
|
389
|
+
de-risks all four gates at once.
|
|
390
|
+
|
|
391
|
+
The first artifact that ask sends a cold prospect can now be **link-shaped**: the browser challenge
|
|
392
|
+
page in §2 — one file, `verify-vh-standalone.html`, no Node, no install, nothing to type — with the
|
|
393
|
+
node standalone as the CI-shaped follow-up. That changes the *first contact*, not the ask: every human
|
|
394
|
+
step above stays human-owned and unchanged.
|
|
395
|
+
|
|
396
|
+
### The pilot success contract (the measured WTP instrument)
|
|
397
|
+
|
|
398
|
+
A pilot that ends at "the partner liked it" leaves the money question — **"is this worth paying for ON MY
|
|
399
|
+
data?"** — to a relational hunch. The TrustLedger pilot's success contract is therefore a **measured**
|
|
400
|
+
one, run on the partner's **own already-closed period**: **`vh trust value-proof`**. The partner runs a
|
|
401
|
+
month they **already reconciled by hand and signed off**, and the command compares the **same** reconcile
|
|
402
|
+
gate against that manual close and prints **one of three outcomes**, exit-coded so the pilot can read the
|
|
403
|
+
result without interpretation:
|
|
404
|
+
|
|
405
|
+
```bash
|
|
406
|
+
vh trust value-proof <bank> <ledger> <rentroll> --period <label>
|
|
407
|
+
# exit 3 = out_of_trust_missed — the dollars the gate caught that the manual close LET THROUGH (the WTP case)
|
|
408
|
+
# exit 4 = data_gap_only — fix-my-data-and-re-run; NOT (yet) evidence the money is gone
|
|
409
|
+
# exit 0 = clean_confirmed — a signed, independent confirmation of a clean trust account
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
Every count and dollar figure is read **verbatim** off the period's reconciliation — the **same**
|
|
413
|
+
numbers `vh trust reconcile --json` shows — so the value-proof is the **same** verdict path the paying
|
|
414
|
+
broker's licensed gate runs, not a narrower one. The deeper spec is in
|
|
415
|
+
[`TRUSTLEDGER.md`](TRUSTLEDGER.md) › *The value-proof*. This is the **measured** form of P-5 #3's
|
|
416
|
+
two-month WTP validation: it turns "their willingness to keep using it is the WTP signal" into a dollar
|
|
417
|
+
figure a broker reads on **their own** month.
|
|
418
|
+
|
|
419
|
+
> **The value-proof COMPARES the gate to the manual close — it does NOT certify a jurisdiction or
|
|
420
|
+
> constitute legal advice.** It quantifies what the gate found that the broker's manual close did not; it
|
|
421
|
+
> does not certify that any state's trust-fund rules are satisfied and is not legal/accounting/audit
|
|
422
|
+
> advice. The standing TrustLedger pilot posture is unchanged: a **PASS does not imply legal compliance**,
|
|
423
|
+
> the broker remains the **responsible legal custodian**, and that meaning stays CPA/counsel-reviewed
|
|
424
|
+
> under **P-5**.
|
|
425
|
+
|
|
426
|
+
---
|
|
427
|
+
|
|
428
|
+
## 7. Why this is trustworthy to run
|
|
429
|
+
|
|
430
|
+
- **Offline + no key + no network.** No real private key is ever created, held, persisted, read, or
|
|
431
|
+
echoed; every key in the run is an in-process `Wallet.createRandom()`. No socket is opened.
|
|
432
|
+
- **Read-only of your inputs.** Whether you run the canned sample or `--evidence-dir <your folder>`, the
|
|
433
|
+
source is read-only; the kit copies it and every seal/tamper hits the copy. Your originals are never
|
|
434
|
+
written, renamed, or deleted. And even on your own data the boundary is unchanged: the seal proves
|
|
435
|
+
**tamper-evidence + signer-pin**, NOT a trusted "sealed at T" (that still requires **P-3**).
|
|
436
|
+
- **Cannot silently rot.** The journey is gated by
|
|
437
|
+
[`test/pilot.evidence.test.js`](../test/pilot.evidence.test.js) +
|
|
438
|
+
[`test/pilot.reconcile.test.js`](../test/pilot.reconcile.test.js), and this runbook's claims are
|
|
439
|
+
gated by [`test/pilot.docs.test.js`](../test/pilot.docs.test.js), all under the project's unchanged
|
|
440
|
+
`npx hardhat test`. If the behaviour or the claims drift, the suite fails.
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
---
|
|
444
|
+
<sub>© 2026 verifyhash.com · Licensed under Apache-2.0 (SPDX-License-Identifier: Apache-2.0) — see the [LICENSE](https://verifyhash.com/LICENSE) and [NOTICE](https://verifyhash.com/NOTICE) served with this file.</sub>
|