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/SDK.md
ADDED
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
# verifyhash SDK — the stable, semver-guarded public API
|
|
2
|
+
|
|
3
|
+
`require("verifyhash")` gives a downstream program the **exact same** functions the `vh` CLI runs — no
|
|
4
|
+
fork, no second implementation. `index.js` is a *thin, identity re-export* of the already-built,
|
|
5
|
+
already-tested core (proven by `test/sdk.index.test.js`): every symbol below is the same function object
|
|
6
|
+
the corresponding `cli/…` module exports, so a seal built with `sdk.buildSeal(...)` verifies (`ACCEPTED`)
|
|
7
|
+
with `sdk.verifySeal(...)` and a one-byte tamper is `REJECTED` — identical to `vh evidence seal` /
|
|
8
|
+
`vh evidence verify`.
|
|
9
|
+
|
|
10
|
+
This file is the **canonical reference for the SDK's public surface**, and it is machine-checked: the
|
|
11
|
+
[machine-checked surface descriptor](#machine-checked-surface-semver--abi-contract) below is *generated*
|
|
12
|
+
from the live `index.js` exports by [`scripts/gen-sdk-surface.cjs`](../scripts/gen-sdk-surface.cjs) and
|
|
13
|
+
byte-matched against them by [`test/sdk.contract.test.js`](../test/sdk.contract.test.js), so it cannot
|
|
14
|
+
silently drift from the code.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Stability & semver policy
|
|
19
|
+
|
|
20
|
+
The **ABI** re-exported from `index.js` **is** the package's stability contract. The guard pins the
|
|
21
|
+
contract a downstream program *actually integrates against* — not just symbol names, but the three things
|
|
22
|
+
whose silent drift would break a consumer without a loud rename:
|
|
23
|
+
|
|
24
|
+
- **Anything listed below is PUBLIC.** Removing it, renaming it, or moving it between namespaces is a
|
|
25
|
+
**breaking change** and requires a **semver-major** version bump. So is changing its *kind*
|
|
26
|
+
(e.g. a `function` becoming a `string`).
|
|
27
|
+
- **Function arity is pinned** (`name : function/<arity>`). Adding a *required* parameter to an exported
|
|
28
|
+
function — e.g. `verifySeal(seal, entries)` → `verifySeal(seal, entries, opts)` — changes its **call
|
|
29
|
+
signature** and is a breaking change, even though the name and kind are unchanged.
|
|
30
|
+
- **Frozen wire values are pinned** (`name : string="…"` / `number=…`). The seal **kind tag**
|
|
31
|
+
(`seal.KIND`), the **schema versions** (`seal.SCHEMA_VERSION`, `receipts.SCHEMA_VERSION`), the receipt
|
|
32
|
+
kind tags, and the `TRUST_NOTE` are constants a consumer hard-codes or branches on; bumping one is a
|
|
33
|
+
wire-format change, so the pin catches it. (A schema bump 1→2 keeps `number` as the kind — a name-only
|
|
34
|
+
guard would miss it; this one does not.)
|
|
35
|
+
- **The `verifySeal` result shape is pinned** (`#verifySeal.result : <sorted keys>`). A consumer
|
|
36
|
+
destructures `{ verdict, accepted, changed, … }`; dropping or renaming a result key is a breaking
|
|
37
|
+
change to the return contract, and the descriptor's behavioral tail catches it.
|
|
38
|
+
- **Adding a new symbol** is a minor (backward-compatible) change.
|
|
39
|
+
- A **patch/minor** release may freely change a symbol's *behavior-preserving internals* or bump the
|
|
40
|
+
version string. The version is the **one** value intentionally left un-pinned: `apiVersion` is rendered
|
|
41
|
+
by *kind only* (`string`, never its value), so a version bump alone never trips the guard.
|
|
42
|
+
- **`apiVersion`** mirrors `package.json`'s `version` field and is the single source of truth for the
|
|
43
|
+
surface's semver number. It is a `string`.
|
|
44
|
+
- **Deep `cli/*` internals are NOT part of the stable surface.** Only what `index.js` re-exports (and what
|
|
45
|
+
the `exports` map in `package.json` resolves) is guaranteed. Reaching into `verifyhash/cli/...` is
|
|
46
|
+
reaching into unstable, internal code that may change in any release without a major bump — the
|
|
47
|
+
`exports` map deliberately blocks importing those subpaths by name.
|
|
48
|
+
|
|
49
|
+
### Changing the surface (one command)
|
|
50
|
+
|
|
51
|
+
The machine-checked descriptor is **generated, never hand-edited**. When you deliberately change the
|
|
52
|
+
surface:
|
|
53
|
+
|
|
54
|
+
```sh
|
|
55
|
+
npm run sdk:surface -- --write # regenerate the descriptor block in this file from index.js
|
|
56
|
+
npm run sdk:surface -- --check # CI drift gate: exit 1 if this doc has drifted from the exports
|
|
57
|
+
npm run sdk:surface # print the current descriptor to stdout
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Then paste the regenerated block into the `EXPECTED_SURFACE` pin in
|
|
61
|
+
[`test/sdk.contract.test.js`](../test/sdk.contract.test.js) in the **same commit**. The contract test
|
|
62
|
+
fails loudly if this document, that pin, and the live `index.js` exports ever disagree — keeping doc ==
|
|
63
|
+
pin == code.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## The public surface
|
|
68
|
+
|
|
69
|
+
Grouped for humans. Every function is the **identity** re-export of its `cli/…` source; the flat
|
|
70
|
+
top-level names (`buildSeal`, `verifySeal`, …) are the same objects as the grouped ones (`seal.buildSeal`,
|
|
71
|
+
`seal.verifySeal`, …), provided for convenience.
|
|
72
|
+
|
|
73
|
+
### Top level
|
|
74
|
+
|
|
75
|
+
| Symbol | Kind | Meaning |
|
|
76
|
+
| --- | --- | --- |
|
|
77
|
+
| `apiVersion` | string | Semver version of this public surface; mirrors `package.json` `version`. |
|
|
78
|
+
| `seal` | namespace | The evidence-seal SDK (see below). |
|
|
79
|
+
| `signed` | namespace | The SIGNED / vendor-pinned verify SDK — the embedded twin of `vh evidence verify-signed` (see below). |
|
|
80
|
+
| `receipts` | namespace | The anchor/claim receipt codec + manifest diff (see below). |
|
|
81
|
+
| `hashing` | namespace | The keccak/Merkle hashing primitives (see below). |
|
|
82
|
+
|
|
83
|
+
The flat convenience re-exports at the top level are exactly the members of the four namespaces:
|
|
84
|
+
`buildSeal`, `validateSeal`, `serializeSeal`, `readSeal`, `verifySeal`, `PacketSealError` (from `seal`);
|
|
85
|
+
`signSealWith`, `validateSignedSeal`, `verifySignedSeal`, `verifySignedSealAttestation`, `recoverSigner`,
|
|
86
|
+
`verifySignedAttestation` (from `signed`);
|
|
87
|
+
`buildReceipt`, `buildAnchorReceipt`, `writeReceipt`, `readReceipt`, `diffManifest` (from `receipts`);
|
|
88
|
+
`hashBytes`, `hashFile`, `hashEntries`, `hashDir`, `hashPath`, `buildTree` (from `hashing`).
|
|
89
|
+
|
|
90
|
+
### `seal` — build / verify a tamper-evident evidence seal
|
|
91
|
+
|
|
92
|
+
| Symbol | Kind | Meaning |
|
|
93
|
+
| --- | --- | --- |
|
|
94
|
+
| `seal.KIND` | string | The seal document kind tag. |
|
|
95
|
+
| `seal.SCHEMA_VERSION` | number | The seal schema version. |
|
|
96
|
+
| `seal.TRUST_NOTE` | string | The one-line trust-boundary note carried in every seal. |
|
|
97
|
+
| `seal.buildSeal` | function | `buildSeal(entries)` → seal object, from a flat `{ relPath, bytes }` list. |
|
|
98
|
+
| `seal.validateSeal` | function | `validateSeal(seal)` → throws on structural / root-mismatch problems. |
|
|
99
|
+
| `seal.serializeSeal` | function | `serializeSeal(seal)` → canonical, byte-deterministic JSON. |
|
|
100
|
+
| `seal.readSeal` | function | `readSeal(jsonOrObject)` → parsed + strictly validated seal. |
|
|
101
|
+
| `seal.verifySeal` | function | `verifySeal(seal, entries)` → `{ verdict, accepted, … }`; RE-DERIVES the root. |
|
|
102
|
+
| `seal.PacketSealError` | function | The error class the generic seal core throws (advanced / custom products). |
|
|
103
|
+
|
|
104
|
+
### `signed` — verify a SIGNED / vendor-address-pinned seal in-process
|
|
105
|
+
|
|
106
|
+
The embedded twin of `vh evidence verify-signed`: identity re-exports of the already-shipped, CLI-run
|
|
107
|
+
signed-verify functions, so an embedder verifies a **signed, address-pinned** seal in-process with **no
|
|
108
|
+
shell-out** to the `vh` binary — the same code path, so it accepts / rejects byte-identically.
|
|
109
|
+
|
|
110
|
+
| Symbol | Kind | Meaning |
|
|
111
|
+
| --- | --- | --- |
|
|
112
|
+
| `signed.KIND` | string | The signed-seal container kind tag (`vh.evidence-seal-signed`). |
|
|
113
|
+
| `signed.TRUST_NOTE` | string | The one-line signed-verify trust-boundary note (a signature proves WHO vouched, not WHEN). |
|
|
114
|
+
| `signed.signSealWith` | function | `signSealWith(seal, signer)` → a signed-seal container WRAPPING the canonical seal bytes. |
|
|
115
|
+
| `signed.validateSignedSeal` | function | `validateSignedSeal(container)` → strict structural validation of a signed container. |
|
|
116
|
+
| `signed.verifySignedSeal` | function | `verifySignedSeal({container, expectedSigner, expectedCanonical})` → the PURE core verdict (recover signer; optional pin/bind). |
|
|
117
|
+
| `signed.verifySignedSealAttestation` | function | `verifySignedSealAttestation({container, expectedSigner, dir})` → the strict signed-verify the CLI runs (`--signer` / `--dir`). |
|
|
118
|
+
| `signed.recoverSigner` | function | `recoverSigner(container)` → the address the signature recovers to (offline, key-free). |
|
|
119
|
+
| `signed.verifySignedAttestation` | function | The generic, product-agnostic signed-attestation verifier the evidence path is bound to. |
|
|
120
|
+
|
|
121
|
+
**Trust boundary (signed path).** A valid signature proves the holder of `signer`'s key **vouched for
|
|
122
|
+
THIS sealed packet** — it is **NOT** a trusted timestamp ("signed since T" rides the human-owned trust-root,
|
|
123
|
+
[STRATEGY.md](../STRATEGY.md) P-3) and **NOT** a legal opinion. Verification is offline / key-free: it
|
|
124
|
+
recovers a **public** address from the signature, holds no private key, and contacts nothing. Pin the
|
|
125
|
+
`expectedSigner` to the vendor address you trust out-of-band (e.g. a published `vh identity` card).
|
|
126
|
+
|
|
127
|
+
### `receipts` — anchor/claim receipt codec + path-bound manifest diff
|
|
128
|
+
|
|
129
|
+
| Symbol | Kind | Meaning |
|
|
130
|
+
| --- | --- | --- |
|
|
131
|
+
| `receipts.SCHEMA_VERSION` | number | The receipt schema version. |
|
|
132
|
+
| `receipts.CLAIM_RECEIPT_KIND` | string | Kind tag for a commit–reveal claim receipt. |
|
|
133
|
+
| `receipts.ANCHOR_RECEIPT_KIND` | string | Kind tag for a one-shot anchor receipt. |
|
|
134
|
+
| `receipts.buildReceipt` | function | Build a claim receipt. |
|
|
135
|
+
| `receipts.buildAnchorReceipt` | function | Build an anchor receipt. |
|
|
136
|
+
| `receipts.writeReceipt` | function | Serialize a receipt to disk (canonical form). |
|
|
137
|
+
| `receipts.readReceipt` | function | Read + strictly validate a receipt. |
|
|
138
|
+
| `receipts.diffManifest` | function | Path-bound diff of two manifests (ADDED / REMOVED / CHANGED). |
|
|
139
|
+
|
|
140
|
+
### `hashing` — the keccak / Merkle primitives every seal + receipt is built on
|
|
141
|
+
|
|
142
|
+
| Symbol | Kind | Meaning |
|
|
143
|
+
| --- | --- | --- |
|
|
144
|
+
| `hashing.hashBytes` | function | Hash a byte buffer. |
|
|
145
|
+
| `hashing.hashFile` | function | Hash a file on disk. |
|
|
146
|
+
| `hashing.hashEntries` | function | Hash a list of `{ relPath, bytes }` entries. |
|
|
147
|
+
| `hashing.hashDir` | function | Hash a directory tree. |
|
|
148
|
+
| `hashing.hashPath` | function | Hash a file-or-directory path. |
|
|
149
|
+
| `hashing.buildTree` | function | Build the Merkle tree over leaves. |
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Machine-checked surface (semver / ABI contract)
|
|
154
|
+
|
|
155
|
+
The block below is the **canonical ABI descriptor** of the entire exported surface — one `path : abi` line
|
|
156
|
+
per symbol, where `abi` is:
|
|
157
|
+
|
|
158
|
+
- `function/<arity>` for a function (the trailing number is its **parameter count** — part of the call
|
|
159
|
+
signature);
|
|
160
|
+
- `<kind>=<value>` for a frozen constant (`string="…"`, `number=…`) — the exact **wire value** a consumer
|
|
161
|
+
hard-codes (`apiVersion` is the sole exception: rendered `string`, value un-pinned, so a version bump is
|
|
162
|
+
free);
|
|
163
|
+
- `namespace` for a grouped object; and a trailing `#verifySeal.result : <sorted keys>` line pinning the
|
|
164
|
+
**result shape** a consumer destructures from `verifySeal`.
|
|
165
|
+
|
|
166
|
+
[`scripts/gen-sdk-surface.cjs`](../scripts/gen-sdk-surface.cjs) generates this exact block from the live
|
|
167
|
+
`index.js` exports (`npm run sdk:surface -- --write`), and [`test/sdk.contract.test.js`](../test/sdk.contract.test.js)
|
|
168
|
+
asserts it BYTE-MATCHES both this document and the frozen pin in the test. If you change the surface, the
|
|
169
|
+
test prints the drifted line so you can regenerate this block and update the pin together.
|
|
170
|
+
|
|
171
|
+
<!-- SDK-SURFACE:BEGIN (generated by scripts/gen-sdk-surface.cjs — run `npm run sdk:surface -- --write`) -->
|
|
172
|
+
```text
|
|
173
|
+
PacketSealError : function/1
|
|
174
|
+
apiVersion : string
|
|
175
|
+
buildAnchorReceipt : function/1
|
|
176
|
+
buildReceipt : function/1
|
|
177
|
+
buildSeal : function/1
|
|
178
|
+
buildTree : function/1
|
|
179
|
+
diffManifest : function/2
|
|
180
|
+
hashBytes : function/1
|
|
181
|
+
hashDir : function/1
|
|
182
|
+
hashEntries : function/1
|
|
183
|
+
hashFile : function/1
|
|
184
|
+
hashPath : function/1
|
|
185
|
+
hashing : namespace
|
|
186
|
+
hashing.buildTree : function/1
|
|
187
|
+
hashing.hashBytes : function/1
|
|
188
|
+
hashing.hashDir : function/1
|
|
189
|
+
hashing.hashEntries : function/1
|
|
190
|
+
hashing.hashFile : function/1
|
|
191
|
+
hashing.hashPath : function/1
|
|
192
|
+
readReceipt : function/1
|
|
193
|
+
readSeal : function/1
|
|
194
|
+
receipts : namespace
|
|
195
|
+
receipts.ANCHOR_RECEIPT_KIND : string="verifyhash.anchor-receipt"
|
|
196
|
+
receipts.CLAIM_RECEIPT_KIND : string="verifyhash.claim-receipt"
|
|
197
|
+
receipts.SCHEMA_VERSION : number=4
|
|
198
|
+
receipts.buildAnchorReceipt : function/1
|
|
199
|
+
receipts.buildReceipt : function/1
|
|
200
|
+
receipts.diffManifest : function/2
|
|
201
|
+
receipts.readReceipt : function/1
|
|
202
|
+
receipts.writeReceipt : function/2
|
|
203
|
+
recoverSigner : function/1
|
|
204
|
+
seal : namespace
|
|
205
|
+
seal.KIND : string="vh.evidence-seal"
|
|
206
|
+
seal.PacketSealError : function/1
|
|
207
|
+
seal.SCHEMA_VERSION : number=1
|
|
208
|
+
seal.TRUST_NOTE : string="This evidence seal is TAMPER-EVIDENT + OFFLINE-RECOMPUTABLE, NOT a trusted timestamp. Its Merkle `root` commits to the full set of (relPath, content) pairs in the directory: any edit, rename, add, or remove changes the root, and verify RE-DERIVES the root from the bytes you hold and LOCALIZES the change to the exact file (MATCH / CHANGED / MISSING / UNEXPECTED). It does NOT prove WHEN the sealing happened (\"sealed at T\" rides the human-owned signing/timestamp trust-root, STRATEGY.md P-3) and it is NOT a legal opinion. The packet is an UNTRUSTED transport container: verify never trusts the packet's own stored hashes."
|
|
209
|
+
seal.buildSeal : function/1
|
|
210
|
+
seal.readSeal : function/1
|
|
211
|
+
seal.serializeSeal : function/1
|
|
212
|
+
seal.validateSeal : function/1
|
|
213
|
+
seal.verifySeal : function/2
|
|
214
|
+
serializeSeal : function/1
|
|
215
|
+
signSealWith : function/2
|
|
216
|
+
signed : namespace
|
|
217
|
+
signed.KIND : string="vh.evidence-seal-signed"
|
|
218
|
+
signed.TRUST_NOTE : string="A valid signature proves the HOLDER OF `signer`'s key vouched for THIS evidence seal (the embedded root + the full set of (relPath, content) pairs). It does NOT by itself prove a trustworthy TIMESTAMP: \"sealed/vouched since a date T\" still needs the human-owned signing/timestamp trust-root (needs-human, P-3). It is NOT a legal opinion. This evidence seal is TAMPER-EVIDENT + OFFLINE-RECOMPUTABLE, NOT a trusted timestamp. Its Merkle `root` commits to the full set of (relPath, content) pairs in the directory: any edit, rename, add, or remove changes the root, and verify RE-DERIVES the root from the bytes you hold and LOCALIZES the change to the exact file (MATCH / CHANGED / MISSING / UNEXPECTED). It does NOT prove WHEN the sealing happened (\"sealed at T\" rides the human-owned signing/timestamp trust-root, STRATEGY.md P-3) and it is NOT a legal opinion. The packet is an UNTRUSTED transport container: verify never trusts the packet's own stored hashes."
|
|
219
|
+
signed.recoverSigner : function/1
|
|
220
|
+
signed.signSealWith : function/2
|
|
221
|
+
signed.validateSignedSeal : function/1
|
|
222
|
+
signed.verifySignedAttestation : function/1
|
|
223
|
+
signed.verifySignedSeal : function/1
|
|
224
|
+
signed.verifySignedSealAttestation : function/1
|
|
225
|
+
validateSeal : function/1
|
|
226
|
+
validateSignedSeal : function/1
|
|
227
|
+
verifySeal : function/2
|
|
228
|
+
verifySignedAttestation : function/1
|
|
229
|
+
verifySignedSeal : function/1
|
|
230
|
+
verifySignedSealAttestation : function/1
|
|
231
|
+
writeReceipt : function/2
|
|
232
|
+
#verifySeal.result : accepted,changed,counts,matched,missing,recomputedRoot,rootMatches,sealedRoot,unexpected,verdict
|
|
233
|
+
```
|
|
234
|
+
<!-- SDK-SURFACE:END -->
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## Consume the verifier over HTTP (`vh serve-verify`)
|
|
239
|
+
|
|
240
|
+
The SDK verifies **in-process**. For a CI pipeline or another microservice that would rather **POST a seal
|
|
241
|
+
and read an ACCEPT/REJECT** — the *"CI plugin that imports rather than shells out"* — verifyhash ships a
|
|
242
|
+
tiny, dependency-free (Node-core `http` only) **verify service**:
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
vh serve-verify [--port <n>] [--host <h>] # default 127.0.0.1:4180, loopback-only, verify-only
|
|
246
|
+
# POST /verify -> JSON verdict on a CI-mappable status (200 ACCEPTED / 422 REJECTED / 400 bad request)
|
|
247
|
+
# GET /healthz -> { ok: true, ... }
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
It reuses the **same** `verifySeal` / `verifySignedSeal` cores documented above — no fork. It is
|
|
251
|
+
**verify-only** (never signs, holds no key, writes nothing) and binds **loopback** by default; exposing it
|
|
252
|
+
publicly is a **human** deploy step (STRATEGY.md **P-9**). The request/response schema, the full status
|
|
253
|
+
mapping, and the trust boundary are documented in **[docs/VERIFY-SERVICE.md](./VERIFY-SERVICE.md)**.
|
|
254
|
+
|
|
255
|
+
Drop it in with:
|
|
256
|
+
|
|
257
|
+
- a dependency-free client — [`examples/verify-service-client.js`](../examples/verify-service-client.js)
|
|
258
|
+
(boots the service, POSTs a clean seal → ACCEPT, then a tampered one → REJECT, exits 0);
|
|
259
|
+
- a shell CI gate — [`verifier/ci/verify-service.generic.sh`](../verifier/ci/verify-service.generic.sh);
|
|
260
|
+
- a GitHub Actions gate — [`verifier/ci/verify-service.github-actions.yml`](../verifier/ci/verify-service.github-actions.yml).
|
|
261
|
+
|
|
262
|
+
## Verify continuously over time (`vh journal`)
|
|
263
|
+
|
|
264
|
+
The SDK and the service both answer *"do these bytes match RIGHT NOW?"* and exit. To prove an artifact has
|
|
265
|
+
verified **continuously across runs**, verifyhash ships an **append-only, hash-chained integrity journal**:
|
|
266
|
+
each run appends one verify verdict, and the log is **itself tamper-evident** — a deleted / edited /
|
|
267
|
+
reordered / inserted past entry **breaks the chain** and `vh journal verify` **localizes the first break**.
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
vh journal append <artifact> --to <journalfile> [--dir <d>] [--ts <ISO>] # record ONE verdict (additive)
|
|
271
|
+
vh journal verify <journalfile> # PASS / BROKEN / DRIFTED
|
|
272
|
+
# exit 0 PASS (unbroken + every observation ACCEPTED) / 3 broken-or-drifted / 2 usage / 1 IO
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
It reuses the **same** keccak/Merkle hashing documented above — no fork, no new crypto — and the core
|
|
276
|
+
(`cli/journal.js`) is **pure** (no disk I/O, no socket, no key). The `ts` on each entry is **self-asserted**
|
|
277
|
+
(the verifier's own wall clock), **NOT a trusted timestamp** — the journal never claims *"unaltered since date
|
|
278
|
+
T"* on its own; that claim rides the human-owned trust-root (STRATEGY.md **P-3**). The schema, the chain
|
|
279
|
+
guarantee, the 0/3 contract, and the full honesty boundary are documented in
|
|
280
|
+
**[docs/INTEGRITY-JOURNAL.md](./INTEGRITY-JOURNAL.md)**.
|
|
281
|
+
|
|
282
|
+
The journal also carries **transparency-log proofs** (RFC-6962 / Certificate-Transparency lineage):
|
|
283
|
+
`vh journal tree-head` publishes a `{ size, root }` head, `prove-inclusion` / `prove-consistency` emit
|
|
284
|
+
compact proof artifacts, and `vh journal check-proof` verifies them **offline** (no journal, no key, no
|
|
285
|
+
network — though today via the **producer package**, not the standalone, zero-dependency `verifier/` bundle a
|
|
286
|
+
seal enjoys) — the head is **self-asserted** until a P-3 trust-root signs it. See
|
|
287
|
+
[docs/INTEGRITY-JOURNAL.md](./INTEGRITY-JOURNAL.md) § "Transparency-log proofs (publish a tree head;
|
|
288
|
+
auditors verify offline)".
|
|
289
|
+
|
|
290
|
+
Drop it in with:
|
|
291
|
+
|
|
292
|
+
- a dependency-free runnable step — [`examples/journal-ci.js`](../examples/journal-ci.js)
|
|
293
|
+
(appends two hash-chained entries, verifies an unbroken chain, exits 0);
|
|
294
|
+
- a shell CI gate — [`verifier/ci/journal.generic.sh`](../verifier/ci/journal.generic.sh);
|
|
295
|
+
- a GitHub Actions gate — [`verifier/ci/journal.github-actions.yml`](../verifier/ci/journal.github-actions.yml).
|
|
296
|
+
|
|
297
|
+
## Trust boundary (unchanged from the CLI — the SDK adds nothing)
|
|
298
|
+
|
|
299
|
+
A seal proves **tamper-evidence + offline re-compute** ("these exact bytes are what was sealed"), NOT a
|
|
300
|
+
trusted timestamp and NOT who authored the bytes. `verifySeal` re-derives the Merkle root from the bytes
|
|
301
|
+
**you** supply — never the seal's own stored hashes. See [docs/TRUST-BOUNDARIES.md](./TRUST-BOUNDARIES.md).
|