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.
Files changed (154) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +883 -0
  3. package/cli/abi/ContributionRegistry.json +881 -0
  4. package/cli/agent.js +2173 -0
  5. package/cli/anchor-artifact.js +853 -0
  6. package/cli/anchor.js +400 -0
  7. package/cli/claim.js +881 -0
  8. package/cli/core/agent-commit.js +448 -0
  9. package/cli/core/agent-session.js +598 -0
  10. package/cli/core/anchor-binding.js +663 -0
  11. package/cli/core/attestation.js +580 -0
  12. package/cli/core/evidence-plans.js +495 -0
  13. package/cli/core/fixtures/evidence-plans/baseline.json +19 -0
  14. package/cli/core/fulfill-intake.js +1082 -0
  15. package/cli/core/go-live-preflight.js +481 -0
  16. package/cli/core/license.js +534 -0
  17. package/cli/core/manifest.js +243 -0
  18. package/cli/core/packetseal.js +591 -0
  19. package/cli/core/registryArtifact.js +49 -0
  20. package/cli/core/revocation.js +539 -0
  21. package/cli/core/rfc3161.js +389 -0
  22. package/cli/core/timestamp.js +482 -0
  23. package/cli/core/trust-asof.js +479 -0
  24. package/cli/dataset.js +2950 -0
  25. package/cli/evidence.js +2227 -0
  26. package/cli/fulfill-webhook-http.js +438 -0
  27. package/cli/git.js +220 -0
  28. package/cli/hash.js +550 -0
  29. package/cli/identity.js +1072 -0
  30. package/cli/journal-cli.js +1110 -0
  31. package/cli/journal-log.js +454 -0
  32. package/cli/journal.js +334 -0
  33. package/cli/lineage.js +447 -0
  34. package/cli/list.js +287 -0
  35. package/cli/parcel.js +1509 -0
  36. package/cli/proof.js +578 -0
  37. package/cli/prove.js +300 -0
  38. package/cli/receipt.js +631 -0
  39. package/cli/registry.js +331 -0
  40. package/cli/reputation.js +344 -0
  41. package/cli/revocation.js +495 -0
  42. package/cli/serve-verify-http.js +298 -0
  43. package/cli/serve-verify.js +333 -0
  44. package/cli/show.js +339 -0
  45. package/cli/verify.js +383 -0
  46. package/cli/vh.js +3927 -0
  47. package/docs/ADOPT.md +183 -0
  48. package/docs/ADOPTION.json +11 -0
  49. package/docs/AGENTTRACE.md +247 -0
  50. package/docs/ANCHORING.md +167 -0
  51. package/docs/AUDIT.md +55 -0
  52. package/docs/CONFORMANCE.md +107 -0
  53. package/docs/DATALEDGER.md +638 -0
  54. package/docs/DECIDE.md +47 -0
  55. package/docs/DECISIONS-PENDING.md +27 -0
  56. package/docs/DEPLOY-PUBLIC-SITE.md +301 -0
  57. package/docs/ENGINE-LEDGER.json +12 -0
  58. package/docs/EVIDENCE.md +519 -0
  59. package/docs/GO-LIVE.md +66 -0
  60. package/docs/IDENTITY.md +123 -0
  61. package/docs/INDEPENDENT-VERIFICATION.md +377 -0
  62. package/docs/INTEGRITY-JOURNAL.md +337 -0
  63. package/docs/KEY-LIFECYCLE.md +179 -0
  64. package/docs/LICENSING.md +46 -0
  65. package/docs/LINEAGE.md +307 -0
  66. package/docs/LOOP-AUDIT-2026-07-03.json +580 -0
  67. package/docs/LOOP-HARDENING-PLAN.md +44 -0
  68. package/docs/MERKLE-LEAVES.md +113 -0
  69. package/docs/METRICS.jsonl +31 -0
  70. package/docs/MORNING.md +204 -0
  71. package/docs/PILOT.md +444 -0
  72. package/docs/PROOFPARCEL.md +227 -0
  73. package/docs/PROOFS.md +262 -0
  74. package/docs/RECEIPTS.md +341 -0
  75. package/docs/REPUTATION.md +158 -0
  76. package/docs/SDK.md +301 -0
  77. package/docs/STRATEGY-ARCHIVE.md +5055 -0
  78. package/docs/SUPERVISOR-RUNBOOK.md +52 -0
  79. package/docs/TRUST-BOUNDARIES.md +335 -0
  80. package/docs/TRUSTLEDGER.md +1976 -0
  81. package/docs/USAGE-BUDGET.json +121 -0
  82. package/docs/VERIFY-SERVICE.md +168 -0
  83. package/index.js +160 -0
  84. package/package.json +41 -0
  85. package/trustledger/build-standalone.js +796 -0
  86. package/trustledger/cli.js +3179 -0
  87. package/trustledger/close.js +391 -0
  88. package/trustledger/corpus.js +159 -0
  89. package/trustledger/dist/BUILD-PROVENANCE.json +99 -0
  90. package/trustledger/dist/trustledger-standalone.html +6197 -0
  91. package/trustledger/dist/trustledger-standalone.html.sha256 +1 -0
  92. package/trustledger/door-core.js +442 -0
  93. package/trustledger/fixtures/bank.csv +7 -0
  94. package/trustledger/fixtures/bank.malformed.csv +3 -0
  95. package/trustledger/fixtures/bank.noalias.csv +5 -0
  96. package/trustledger/fixtures/bank.ofx +34 -0
  97. package/trustledger/fixtures/bank.real.csv +5 -0
  98. package/trustledger/fixtures/corpus/_shared/prior-close.json +22 -0
  99. package/trustledger/fixtures/corpus/bank-book-mismatch--benign-twin/inputs.json +14 -0
  100. package/trustledger/fixtures/corpus/bank-book-mismatch--benign-twin/meta.json +7 -0
  101. package/trustledger/fixtures/corpus/bank-book-mismatch--out-of-trust/inputs.json +14 -0
  102. package/trustledger/fixtures/corpus/bank-book-mismatch--out-of-trust/meta.json +7 -0
  103. package/trustledger/fixtures/corpus/continuity-break--benign-twin/inputs.json +15 -0
  104. package/trustledger/fixtures/corpus/continuity-break--benign-twin/meta.json +7 -0
  105. package/trustledger/fixtures/corpus/continuity-break--out-of-trust/inputs.json +15 -0
  106. package/trustledger/fixtures/corpus/continuity-break--out-of-trust/meta.json +7 -0
  107. package/trustledger/fixtures/corpus/negative-tenant-ledger--benign-twin/inputs.json +13 -0
  108. package/trustledger/fixtures/corpus/negative-tenant-ledger--benign-twin/meta.json +7 -0
  109. package/trustledger/fixtures/corpus/negative-tenant-ledger--out-of-trust/inputs.json +13 -0
  110. package/trustledger/fixtures/corpus/negative-tenant-ledger--out-of-trust/meta.json +7 -0
  111. package/trustledger/fixtures/corpus/owner-overdraw--benign-twin/inputs.json +15 -0
  112. package/trustledger/fixtures/corpus/owner-overdraw--benign-twin/meta.json +7 -0
  113. package/trustledger/fixtures/corpus/owner-overdraw--out-of-trust/inputs.json +15 -0
  114. package/trustledger/fixtures/corpus/owner-overdraw--out-of-trust/meta.json +7 -0
  115. package/trustledger/fixtures/corpus/security-deposit-segregation--benign-twin/inputs.json +16 -0
  116. package/trustledger/fixtures/corpus/security-deposit-segregation--benign-twin/meta.json +7 -0
  117. package/trustledger/fixtures/corpus/security-deposit-segregation--out-of-trust/inputs.json +13 -0
  118. package/trustledger/fixtures/corpus/security-deposit-segregation--out-of-trust/meta.json +7 -0
  119. package/trustledger/fixtures/corpus/subledger-out-of-balance--benign-twin/inputs.json +13 -0
  120. package/trustledger/fixtures/corpus/subledger-out-of-balance--benign-twin/meta.json +7 -0
  121. package/trustledger/fixtures/corpus/subledger-out-of-balance--out-of-trust/inputs.json +13 -0
  122. package/trustledger/fixtures/corpus/subledger-out-of-balance--out-of-trust/meta.json +7 -0
  123. package/trustledger/fixtures/e2e/bank.aliased.csv +4 -0
  124. package/trustledger/fixtures/e2e/bank.csv +4 -0
  125. package/trustledger/fixtures/e2e/bank.nsf.csv +4 -0
  126. package/trustledger/fixtures/e2e/quickbooks.csv +6 -0
  127. package/trustledger/fixtures/e2e/quickbooks.nsf.csv +8 -0
  128. package/trustledger/fixtures/e2e/rentroll.csv +6 -0
  129. package/trustledger/fixtures/e2e/rentroll.nsf.csv +8 -0
  130. package/trustledger/fixtures/e2e/rentroll.short.csv +5 -0
  131. package/trustledger/fixtures/plans/baseline.json +25 -0
  132. package/trustledger/fixtures/plans/price-binding.example.json +27 -0
  133. package/trustledger/fixtures/policy/ambiguous-deposit-example.json +12 -0
  134. package/trustledger/fixtures/policy/baseline.json +19 -0
  135. package/trustledger/fixtures/policy/ca-example.json +12 -0
  136. package/trustledger/fixtures/policy/negative-tenant-ledger-example.json +12 -0
  137. package/trustledger/fixtures/policy/owner-overdraw-example.json +12 -0
  138. package/trustledger/fixtures/quickbooks.csv +7 -0
  139. package/trustledger/fixtures/quickbooks.real.csv +5 -0
  140. package/trustledger/fixtures/rentroll.csv +6 -0
  141. package/trustledger/fixtures/rentroll.real.csv +4 -0
  142. package/trustledger/ingest.js +1163 -0
  143. package/trustledger/lib/policy-bundled-loader.js +44 -0
  144. package/trustledger/lib/sha256-vendored.js +227 -0
  145. package/trustledger/license.js +563 -0
  146. package/trustledger/match.js +551 -0
  147. package/trustledger/plans.js +551 -0
  148. package/trustledger/policy.js +398 -0
  149. package/trustledger/public/index.html +512 -0
  150. package/trustledger/reconcile.js +1486 -0
  151. package/trustledger/report.js +887 -0
  152. package/trustledger/seal.js +854 -0
  153. package/trustledger/server.js +391 -0
  154. package/trustledger/valueproof.js +350 -0
@@ -0,0 +1,44 @@
1
+ # Loop-hardening batch 2 — engine patches (apply at the next park point)
2
+
3
+ Source: `docs/LOOP-AUDIT-2026-07-03.json` (7-reviewer audit). Batch 1 (gates, launch chokepoint,
4
+ runbook, decision sheet, adoption signal) shipped as commit `1272ffe`. Batch 2 edits
5
+ `build-loop.workflow.js` and MUST be applied only when no run is active (a live run's Architect can
6
+ swap the engine file and clobber edits). Re-gate with `node scripts/pre-run-gate.cjs` after applying.
7
+
8
+ Ordered by priority:
9
+
10
+ 1. **Mechanical test gate (verification P1).** Add a per-task `test-runner` agent (haiku, effort low):
11
+ sole job = run TEST_CMD, return `{exitCode, passing, failing, tail}` via schema. The DRIVER then
12
+ requires `verdict.pass && verdict.testsPass && runner.exitCode === 0` to commit. Add a
13
+ validate-driver invariant pinning the `runner.exitCode === 0` conjunct in executable code. This makes
14
+ suite-green a mechanical fact, not an LLM claim, and lets the Verifier skip re-running the full suite
15
+ itself (its job becomes acceptance-criteria judgment + targeted probes) — likely net CHEAPER.
16
+ 2. **Panel width by blast radius (economics P1).** Default 3 reviewers; full panel only when
17
+ `build.filesChanged` touches `contracts/`, `cli/core/`, `verifier/`, `trustledger/`, or the engine.
18
+ Keep the dissenter-only re-score.
19
+ 3. **Per-run spend cap (economics P1).** In the main loop: break with `endReason:'run-cap'` when
20
+ `budget.spent() > RUN_CAP_TOKENS` (start 8M; tune from ledger). Bounds run MAGNITUDE, which the 2h
21
+ cooldown does not.
22
+ 4. **Dissent preservation (verification P2).** Trigger the rework path when ANY reviewer scores <=2,
23
+ not only when the median <=3. minUsefulness already lands in METRICS.
24
+ 5. **Single telemetry read (engine P2).** Preflight agent returns the METRICS tail + computed
25
+ qualityStall in its schema; the driver injects both into strategist/manager/architect prompts.
26
+ Kills 3 duplicate file-reads + two prose re-derivations of the same arithmetic per run.
27
+ 6. **Reporter -> haiku (engine P1, cheap now; true driver-write when the harness exposes file I/O).**
28
+ Its job is a verbatim append of a driver-computed line + a short MORNING.md.
29
+ 7. **Adoption-aware Strategist (strategy P0).** Strategist prompt reads `docs/ADOPTION.json`:
30
+ while all adoption numbers are zero — NO new verticals/epics; only distribution tasks (npm publish
31
+ prep, funnel, pilot materials), hardening tasks (this plan), or `newTasks: []` (explicitly a
32
+ rewarded outcome, not a failure). Reviewer prompts: novelty with zero adoption scores LOW.
33
+ 8. **Preflight self-heal (verification P2).** Preflight runs `scripts/archive-direction.cjs` + fixture
34
+ refresh BEFORE any build, so a Strategist append can never redden the suite mid-run
35
+ (STRATEGY.md sits ~500 bytes from the size-guard cliff).
36
+ 9. **Prompt dedup (engine P3).** qualityStall guidance collapsed to one sentence; VISION trimmed to the
37
+ guardrails agents act on.
38
+ 10. **Agent timeout probe (engine P1).** Test whether `setTimeout` exists in the workflow sandbox; if
39
+ yes, wrap agent() calls in a deadline race (timeout == failed attempt, same path as a throw). If
40
+ not available, document the limitation here and rely on the run-cap.
41
+
42
+ Also at the same park point (non-engine): add the corresponding BACKLOG epic so the loop continues the
43
+ remainder itself (checkpointing/partial-run METRICS, engine-writes-own-ledger-row when file I/O exists,
44
+ prev.js archive rotation), and launch the next run with `args: {maxTasks: 4}` while adoption is zero.
@@ -0,0 +1,113 @@
1
+ # What the verifyhash directory root commits to
2
+
3
+ This is the canonical spec for how `vh hash <dir>` / `hashDir()` (cli/hash.js) build a directory's
4
+ Merkle root and exactly what that root proves. It is the reference for T-0.1 (domain separation)
5
+ and T-0.2 (path binding).
6
+
7
+ ## TL;DR
8
+
9
+ The directory root commits to the **full set of `(relative-path, content)` pairs** in the tree —
10
+ both the file **names/locations** and the file **bytes**. Two directories produce the same root
11
+ **iff** they contain the identical set of files, at the identical relative paths, with identical
12
+ content. Therefore:
13
+
14
+ - editing a single byte of any file changes the root (content binding),
15
+ - **renaming** a file (same bytes, new name) changes the root (path binding),
16
+ - **moving** a file to another directory (same bytes, new relPath) changes the root,
17
+ - adding or removing a file changes the root,
18
+ - the root does **not** depend on filesystem enumeration order or on the host OS path separator.
19
+
20
+ ## Leaf construction (two layers)
21
+
22
+ Each file `F` at relative path `relPath` with bytes `B` produces a tree leaf in two stages.
23
+
24
+ 1. **Content digest** — the bare keccak256 of the file's bytes (this is also what `vh hash <file>`
25
+ prints and what `anchor()` stores for a single file):
26
+
27
+ ```
28
+ c = keccak256(B)
29
+ ```
30
+
31
+ 2. **Path-bound leaf** (T-0.2) — bind the relative path into the leaf so the root commits to names:
32
+
33
+ ```
34
+ pathLeaf = keccak256( DIR_LEAF_DOMAIN ‖ relPath ‖ 0x00 ‖ c )
35
+ ```
36
+
37
+ - `DIR_LEAF_DOMAIN = keccak256("verifyhash/dir-leaf/v1")` is a fixed 32-byte `domainPrefix`. It
38
+ isolates a directory leaf in its own value space so it can never collide with a bare content
39
+ digest, a single-file anchor, or a leaf from a future scheme. Bump the `v1` suffix if the
40
+ encoding ever changes, to keep old and new roots disjoint.
41
+ - `relPath` is normalized to forward slashes (POSIX), so a repo hashed on Windows and on Linux
42
+ yields the same root.
43
+ - The single `0x00` separator sits between the variable-length `relPath` and the fixed-length
44
+ 32-byte `c`. Because `c` is always exactly 32 bytes, there is exactly one way to split any
45
+ `pathLeaf` preimage back into `(relPath, c)` — two different `(relPath, content)` pairs can
46
+ never alias to the same leaf via boundary ambiguity.
47
+
48
+ `pathLeaf` is the value the on-chain `verifyLeaf(root, contentHash, proof)` is handed as its
49
+ `contentHash` argument (NOT the bare digest `c`).
50
+
51
+ 3. **Domain-tagged tree leaf** (T-0.1) — `verifyLeaf` then re-tags `pathLeaf` with the leaf domain
52
+ tag to form the actual bottom-of-tree value, keeping leaves and interior nodes in disjoint value
53
+ spaces (second-preimage resistance):
54
+
55
+ ```
56
+ treeLeaf = keccak256( LEAF_TAG ‖ pathLeaf ) // LEAF_TAG = 0x00
57
+ nodeHash(a,b) = keccak256( NODE_TAG ‖ min(a,b) ‖ max(a,b) ) // NODE_TAG = 0x01, sorted pair
58
+ ```
59
+
60
+ The CLI and the contract use byte-identical conventions, so a root produced by `vh hash <dir>` is
61
+ exactly the root `verifyLeaf` reconstructs from a `pathLeaf` + Merkle proof. The contract did not
62
+ change for T-0.2: path binding lives entirely in the value the CLI feeds to `verifyLeaf`.
63
+
64
+ ## Tree shape
65
+
66
+ Leaves are **sorted by their `pathLeaf` value** before the tree is built, so the root is
67
+ independent of enumeration/creation order. Odd (lone) nodes are paired with themselves
68
+ (`nodeHash(node, node)`) rather than promoted, giving every leaf a full-depth proof.
69
+
70
+ ## Which files become leaves: filesystem walk vs. `--git`
71
+
72
+ The leaf/tree formulas above are unchanged regardless of how the file SET is chosen — `--git` reuses
73
+ the identical `pathLeaf` / `leafHash` / `nodeHash` convention. Only the enumeration differs:
74
+
75
+ - **`vh hash <dir>` (default)** walks the filesystem and makes a leaf for every regular file it finds,
76
+ including untracked files (`node_modules/`, `.env`, build artifacts, editor scratch). The root then
77
+ depends on whatever happens to be in the work tree.
78
+ - **`vh hash <dir> --git [--ref <ref>]`** makes a leaf for EXACTLY the files git tracks at that commit
79
+ (`git ls-tree -r`, default `HEAD`), reading each file's bytes from the work tree. Untracked files
80
+ are ignored, so the root is reproducible across clones of the same commit. The git path is the
81
+ `relPath` bound into each leaf, so renaming a tracked file still changes the root. See
82
+ `cli/git.js` (`repoRoot` / `resolveCommit` / `listTrackedFiles`) and `test/cli.hash.git.test.js`.
83
+
84
+ Because `--git` only changes which files become leaves (never how a leaf is hashed), every caveat in
85
+ [`docs/TRUST-BOUNDARIES.md`](TRUST-BOUNDARIES.md) still applies verbatim: the on-chain record attests
86
+ only to the resulting `contentHash`/root, and the receipt's `git` provenance (commit + scope) is an
87
+ **untrusted hint** that records *how* the tracked set was enumerated, never a second proof (see
88
+ [`docs/RECEIPTS.md`](RECEIPTS.md)).
89
+
90
+ ## What the root does NOT commit to
91
+
92
+ - File mode/permissions, mtimes, or other filesystem metadata (only path + bytes).
93
+ - Empty directories (only files become leaves).
94
+ - Symlinks / sockets / fifos are skipped (they have no stable content hash).
95
+
96
+ ## Consequences for `vh prove`
97
+
98
+ `vh prove <file> --root <dir>` builds the file's `pathLeaf` and Merkle proof. The proof binds the
99
+ file to **its location** in the repo: the same bytes at a different path produce a different leaf and
100
+ do not verify. A renamed or moved file's old proof no longer folds to the new root.
101
+
102
+ ## Tests
103
+
104
+ See `test/cli.hash.test.js`:
105
+ - "RENAMING a file changes the root …" and "MOVING a file …" prove path binding,
106
+ - "a renamed file's OLD proof no longer verifies on-chain against the new root" proves it end to end
107
+ against the deployed `ContributionRegistry.verifyLeaf`,
108
+ - "pathLeaf matches the explicit keccak256(domain ‖ relPath ‖ 0x00 ‖ content) formula" pins the
109
+ encoding.
110
+
111
+
112
+ ---
113
+ <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>
@@ -0,0 +1,31 @@
1
+ {"ts":"2026-06-23T07:10:34Z","verified":4,"blocked":0,"rework":0,"newlyPlanned":4,"teamChanges":1}
2
+ {"ts":"2026-06-23T08:24:31Z","verified":4,"blocked":0,"rework":1,"newlyPlanned":3,"teamChanges":1}
3
+ {"ts":"2026-06-23T09:46:00Z","verified":4,"blocked":0,"rework":0,"newlyPlanned":3,"teamChanges":0,"avgUsefulness":4.5,"minUsefulness":4}
4
+ {"ts":"2026-06-23T12:19:33Z","verified":4,"blocked":0,"rework":0,"newlyPlanned":5,"teamChanges":1,"avgUsefulness":4,"minUsefulness":4}
5
+ {"ts":"2026-06-23T14:04:21Z","verified":4,"blocked":0,"rework":1,"newlyPlanned":3,"teamChanges":0,"avgUsefulness":3.75,"minUsefulness":3}
6
+ {"ts":"2026-06-23T18:23:33Z","verified":4,"blocked":0,"rework":1,"newlyPlanned":0,"teamChanges":1,"avgUsefulness":4.25,"minUsefulness":4,"humanGated":3}
7
+ {"ts":"2026-06-23T19:32:12Z","verified":4,"blocked":0,"rework":2,"newlyPlanned":6,"teamChanges":0,"avgUsefulness":4,"minUsefulness":4,"humanGated":3}
8
+ {"ts":"2026-06-23T20:26:43Z","verified":4,"blocked":0,"rework":0,"newlyPlanned":3,"teamChanges":0,"avgUsefulness":4,"minUsefulness":4,"humanGated":3}
9
+ {"ts":"2026-06-23T21:28:20Z","verified":4,"blocked":0,"rework":1,"newlyPlanned":3,"teamChanges":0,"avgUsefulness":4,"minUsefulness":4,"humanGated":4}
10
+ {"ts":"2026-06-23T22:40:52Z","verified":4,"blocked":0,"rework":0,"reworkReverted":0,"newlyPlanned":6,"teamChanges":1,"avgUsefulness":4,"minUsefulness":4,"humanGated":3}
11
+ {"ts":"2026-06-24T01:13:54Z","verified":4,"blocked":0,"rework":0,"reworkReverted":0,"newlyPlanned":2,"teamChanges":0,"avgUsefulness":4,"minUsefulness":4,"humanGated":4,"endReason":"iters"}
12
+ {"ts":"2026-06-24T02:36:25Z","verified":4,"blocked":0,"rework":3,"reworkReverted":0,"newlyPlanned":0,"teamChanges":3,"avgUsefulness":4,"minUsefulness":4,"humanGated":3,"endReason":"iters"}
13
+ {"ts":"2026-06-24T03:54:45Z","verified":4,"blocked":0,"rework":1,"reworkReverted":0,"newlyPlanned":6,"teamChanges":0,"avgUsefulness":3.75,"minUsefulness":3,"humanGated":3,"endReason":"iters"}
14
+ {"ts":"2026-06-24T05:13:13Z","verified":4,"blocked":0,"rework":1,"reworkReverted":0,"newlyPlanned":4,"teamChanges":0,"avgUsefulness":3.75,"minUsefulness":3,"humanGated":3,"endReason":"iters"}
15
+ {"ts":"2026-06-24T07:23:34Z","verified":4,"blocked":0,"rework":3,"reworkReverted":0,"newlyPlanned":3,"teamChanges":2,"avgUsefulness":3.5,"minUsefulness":3,"humanGated":3,"endReason":"iters"}
16
+ {"ts":"2026-06-24T08:37:00Z","verified":4,"blocked":0,"rework":2,"reworkReverted":0,"newlyPlanned":0,"teamChanges":2,"avgUsefulness":3.75,"minUsefulness":3,"humanGated":3,"endReason":"iters"}
17
+ {"ts":"2026-06-24T12:33:58Z","verified":4,"blocked":0,"rework":2,"reworkReverted":0,"newlyPlanned":6,"teamChanges":2,"avgUsefulness":3.75,"minUsefulness":3,"humanGated":5,"endReason":"iters"}
18
+ {"ts":"2026-06-24T15:43:39Z","verified":4,"blocked":0,"rework":0,"reworkReverted":0,"newlyPlanned":6,"teamChanges":1,"avgUsefulness":3,"minUsefulness":3,"humanGated":3,"endReason":"iters"}
19
+ {"ts":"2026-06-24T17:16:28Z","verified":4,"blocked":0,"rework":1,"reworkReverted":0,"newlyPlanned":3,"teamChanges":1,"avgUsefulness":4,"minUsefulness":4,"humanGated":3,"endReason":"iters"}
20
+ {"ts":"2026-06-24T20:18:25Z","verified":8,"blocked":0,"rework":1,"reworkReverted":0,"newlyPlanned":7,"teamChanges":0,"avgUsefulness":4,"minUsefulness":4,"humanGated":3,"endReason":"iters"}
21
+ {"ts":"2026-06-25T02:18:30Z","verified":8,"blocked":0,"rework":2,"reworkReverted":0,"newlyPlanned":9,"teamChanges":1,"avgUsefulness":3.25,"minUsefulness":2,"humanGated":4,"endReason":"iters"}
22
+ {"ts":"2026-06-25T08:02:04Z","verified":8,"blocked":0,"rework":2,"reworkReverted":1,"newlyPlanned":9,"teamChanges":1,"avgUsefulness":3.75,"minUsefulness":3,"humanGated":3,"endReason":"iters"}
23
+ {"ts":"2026-06-25T13:21:35Z","verified":8,"blocked":0,"rework":1,"reworkReverted":0,"newlyPlanned":6,"teamChanges":0,"avgUsefulness":3.75,"minUsefulness":3,"humanGated":3,"endReason":"iters"}
24
+ {"ts":"2026-06-25T20:02:12Z","verified":7,"blocked":1,"rework":3,"reworkReverted":0,"newlyPlanned":9,"teamChanges":1,"avgUsefulness":4,"minUsefulness":4,"humanGated":3,"endReason":"iters"}
25
+ {"ts":"2026-06-26T01:01:34Z","verified":8,"blocked":0,"blockedReasons":"","rework":1,"reworkReverted":0,"newlyPlanned":6,"teamChanges":0,"avgUsefulness":3.88,"minUsefulness":3,"humanGated":3,"endReason":"iters"}
26
+ {"ts":"2026-06-26T06:12:11Z","verified":8,"blocked":0,"blockedReasons":"","rework":1,"reworkReverted":0,"newlyPlanned":8,"teamChanges":1,"avgUsefulness":3.63,"minUsefulness":2,"humanGated":3,"endReason":"iters"}
27
+ {"ts":"2026-06-26T13:57:52Z","verified":8,"blocked":0,"blockedReasons":"","rework":5,"reworkReverted":0,"newlyPlanned":6,"teamChanges":1,"avgUsefulness":3.75,"minUsefulness":3,"humanGated":3,"endReason":"iters"}
28
+ {"ts":"2026-06-26T19:24:52Z","verified":4,"blocked":0,"blockedReasons":"","rework":4,"reworkReverted":0,"newlyPlanned":3,"teamChanges":2,"avgUsefulness":2.5,"minUsefulness":2,"humanGated":3,"endReason":"frontier"}
29
+ {"ts":"2026-07-01T07:24:30Z","verified":8,"blocked":0,"blockedReasons":"","rework":5,"reworkReverted":2,"newlyPlanned":8,"teamChanges":0,"avgUsefulness":3.38,"minUsefulness":2,"panelSize":5,"humanGated":3,"endReason":"iters"}
30
+ {"ts":"2026-07-02T08:25:29Z","verified":8,"blocked":0,"blockedReasons":"","rework":3,"reworkReverted":1,"newlyPlanned":3,"teamChanges":1,"avgUsefulness":3.88,"minUsefulness":3,"panelSize":5,"humanGated":3,"endReason":"iters","fableFirstShots":8,"fableFirstShotVerified":8}
31
+ {"ts":"2026-07-02T18:51:39Z","verified":8,"blocked":0,"blockedReasons":"","rework":4,"reworkReverted":0,"newlyPlanned":9,"teamChanges":2,"avgUsefulness":4.13,"minUsefulness":4,"panelSize":5,"humanGated":3,"endReason":"iters","fableFirstShots":8,"fableFirstShotVerified":8}
@@ -0,0 +1,204 @@
1
+ # verifyhash — Morning Report
2
+
3
+ _Generated 2026-07-02T18:51Z (UTC). Snapshot of the latest autonomous loop run. Read STRATEGY.md for the *why*._
4
+
5
+ ## At a glance
6
+
7
+ | verified | blocked | rework | rework reverted | newly planned | team changes | avg usefulness | min usefulness | panel | human-gated |
8
+ |---------:|--------:|-------:|----------------:|--------------:|-------------:|---------------:|---------------:|------:|------------:|
9
+ | 8 | 0 | 4 | 0 | 9 | 2 | 4.13 | 4 | 5 | 3 |
10
+
11
+ The headline: **the loop stopped building more product mechanism and spent the whole run on the funnel and
12
+ one genuinely new vertical.** The `qualityStall` flag fired again (avg window `3.63→3.75→2.5→3.38→3.88`)
13
+ and `humanGated` has been pinned at **3** for ~20 runs, so the Strategist pivoted the build target off
14
+ "9th primitive" and onto three things a stuck go-to-market actually runs through: a **zero-install,
15
+ in-browser Evidence verifier** (EPIC-66), a **drift-guarded one-command release packet for the live
16
+ verifyhash.com** (EPIC-67), and a **brand-new income vertical, AGENTTRACE** (EPIC-68), built entirely by
17
+ re-purposing the shipped-but-dormant RFC-6962 Merkle-log core rather than inventing new crypto. Eight
18
+ tasks verified, zero blocked. Usefulness recovered strongly to **avg 4.13 / min 4** (per-task
19
+ 4,5,4,4,4,4,4,4) — the best recent run. End reason: `iters` (hit the iteration cap). No pushes, no deploys.
20
+ The gated FABLE-5 first-shot trial again went **8/8** (`fableFirstShots:8`, `fableFirstShotVerified:8`).
21
+
22
+ ## What got built / committed this run
23
+
24
+ Run commit window: everything after `42a0626` (the previous run's `chore(run)` record) up to HEAD
25
+ (`71354b8`). Eight verified tasks across three epics.
26
+
27
+ ### EPIC-66 — link-shaped first contact for the EVIDENCE vertical (the funnel, half 1)
28
+
29
+ Closes the asymmetry where the FIRST commercial target (Evidence, per P-8) still needed Node in its first
30
+ 60 seconds while TrustLedger already had a zero-install browser app.
31
+
32
+ - **T-66.1 (VERIFIED)** — Gave the verifier an **in-memory file-source seam with zero behavior change**:
33
+ a pure `verifyArtifactFromBytes({...})` entry so the same verify cores that read packets from disk now
34
+ verify from caller-supplied bytes (`{relPath: Uint8Array}`), no `fs`/`path`/`os`/`process` reachable on
35
+ that path, missing/extra/mismatch/wrong-vendor/tampered-sig verdicts derived from the map. Existing CLI
36
+ disk path stays byte-identical; every existing verifier test passes unedited.
37
+ - **T-66.2 (VERIFIED)** — Emitted the deterministic single-file **`verifier/dist/verify-vh-standalone.html`
38
+ with the 60-second challenge built in** (new `verifier/build-standalone-html.js`, mirroring the proven
39
+ byte-stable bundler discipline). Drag-and-drop a `*.vhevidence.json` + files → same verdict + per-file
40
+ tamper localization the CLI prints; a "load the sample" click → ACCEPT; edit one demo byte in-page →
41
+ REJECT naming the file; the honest boundary is visible on the page. **No-network enforced**: the emitted
42
+ file contains none of `fetch`/`XMLHttpRequest`/`WebSocket`/`EventSource`/`sendBeacon`/dynamic `import(`.
43
+ Two builds byte-identical; committed dist `--check`-pinned; a `vm`-evaluated engine block asserts verdicts
44
+ byte-identical to the in-tree T-66.1 path.
45
+ - **T-66.3 (VERIFIED)** — Wired the link-shaped path into the funnel honestly: a "No Node? Do it in your
46
+ browser" path at the top of `challenge/README.md`, pointers from ADOPT/PILOT/INDEPENDENT-VERIFICATION/
47
+ verifier READMEs, and a docs-rot test pinning the flow + grepping that **no P-3…P-9 human step was
48
+ deleted or relaxed** (STRATEGY.md left untouched — it sits near its byte budget and `docs/DECIDE.md` is
49
+ generated from P-8).
50
+
51
+ ### EPIC-67 — make the live verifyhash.com refresh one-command + drift-guarded (the funnel, half 2)
52
+
53
+ verifyhash.com is the project's ONLY deployed outward asset and was invisible to the repo (webroot
54
+ gitignored, landing page unversioned, live site known to have drifted from the build).
55
+
56
+ - **T-67.1 (VERIFIED)** — Shipped the deterministic **site-release assembler** (`scripts/site-release.js`,
57
+ node-core only, never writes outside the repo) + a tracked, schema-validated **allowlist publish set**
58
+ (`site/publish-set.json`), brought the landing page under version control (`site/index.html`), snapshotted
59
+ what was actually deployed on 2026-06-26 (`site/DEPLOYED.json`, the drift baseline), and committed a
60
+ byte-pinned `RELEASE-MANIFEST.json`. Allowlist-only assembly makes the runbook's "must NEVER be served"
61
+ rule **structural**.
62
+ - **T-67.2 (VERIFIED)** — Made **drift visible and the refresh decision-ready**: `--diff` prints a per-file
63
+ ADDED/CHANGED/REMOVED/UNCHANGED table + a one-line staleness verdict (exit 0 either way — staleness is a
64
+ human signal, not a CI failure; exit 3 only on a malformed snapshot), `--mark-deployed` closes the loop
65
+ after upload, and a standing test pins the SIGNAL chain (any later `verifier/dist`/docs/landing change
66
+ without a re-release turns the suite RED) while a stale `DEPLOYED.json` never fails the suite. Boundary
67
+ stated verbatim: the loop assembles + diffs INSIDE the repo only; uploading is the human-owned **P-11** step.
68
+
69
+ ### EPIC-68 — AGENTTRACE: a NEW income vertical on shipped primitives (`vh agent`)
70
+
71
+ Tamper-evident, selectively-disclosable, independently-verifiable **AI-agent session records**
72
+ (`*.vhagent.json`) — for the 2026 record-keeping / audit / incident-forensics buyer (EU AI Act
73
+ Art. 12/19/26) that observability tracing (operator-editable after the fact) does not serve. The
74
+ resume-adding criterion's "genuinely new unsaturated axis" clause is met (`grep -in agent BACKLOG.md` →
75
+ zero prior work). **Zero new primitives or crypto**: its load-bearing engine is the shipped-but-dormant
76
+ ordered RFC-6962 Merkle-log core (`cli/journal-log.js`, T-63.1) — this either makes that asset pay or it
77
+ stays parked.
78
+
79
+ - **T-68.1 (VERIFIED)** — Pure `cli/core/agent-session.js` (no `fs`/network/key/clock, no new dependency):
80
+ canonical closed-set event schema with strict named rejects; **the redaction-safe leaf** — a full event
81
+ and its redacted twin (payload replaced by its keccak commitment) derive the **byte-identical leaf**, so
82
+ redacting any subset changes neither leaves nor root; `sessionHead` via `treeHead` reused verbatim
83
+ (position-bound, no sorting); single-event inclusion proofs + `verifyGrowth` append-only consistency
84
+ between a mid-session checkpoint and the final head.
85
+ - **T-68.2 (VERIFIED)** — The `vh agent` CLI surface (`seal`/`verify`/`redact`/`prove`/`verify-proof`/
86
+ `checkpoint`/`verify-growth`). `--sign` reuses the SAME attestation envelope + fail-closed `license.js`
87
+ gate as `vh evidence seal`, keyed to a new **DRAFT `agent_signed` capability** (no price set — pricing
88
+ stays P-7). Unsigned seal/verify/prove/redact are FREE; REJECT names the first offending event `seq`.
89
+ **No new needs-human step** — the human's one existing go-live flip sells this vertical in the same motion.
90
+ - **T-68.3 (VERIFIED)** — Independent + zero-install verification: added `verifyAgentSeal` to the verifier's
91
+ auto-detection on BOTH the disk path and the in-memory T-66.1 path (deep-equal verdicts), re-derived from
92
+ the verifier's OWN dependency-free libs (no import from `cli/`), inlined a demo agent session (one redacted
93
+ `tool_call`), and rebuilt the committed standalone JS+HTML bundles so the same emailed/linked page also
94
+ verifies a dropped `*.vhagent.json` (demo → ACCEPT, one-byte in-page tamper → REJECT naming the seq).
95
+
96
+ **Rework** fired on **4** tasks this run; **0 reverted** — all 8 still landed VERIFIED. The one remaining
97
+ EPIC-68 child, **T-68.4** (docs/AGENTTRACE.md + a real transcript-mapping example + docs-rot test), is
98
+ `TODO` on the frontier.
99
+
100
+ ## Usefulness — read the shape, not just the average
101
+
102
+ Avg **4.13** / min **4** (per-task 4,5,4,4,4,4,4,4) — the strongest recent run and a clear lift off the
103
+ ~3.6 plateau. The single 5 went to the genuinely novel AGENTTRACE work; the two orbit-shaped tasks
104
+ (T-66.3 funnel-link, T-67.2 site-drift) scored a borderline-but-defensible 4 (both widen the free→paid
105
+ funnel / add byte-pinned release discipline). The Manager read the two 4s as run noise, not a trend.
106
+
107
+ ## Decisions made
108
+
109
+ - **Pivot the build target off "more product mechanism" and onto the funnel (Strategist notes (m)/(n)).**
110
+ `qualityStall` fired again and `humanGated` has been stuck at 3 for ~20 runs, so the loop refused to add a
111
+ 9th primitive and instead built the distribution shape the stuck P-8 ask runs through (EPIC-66/67) plus a
112
+ new vertical that re-purposes a dormant asset (EPIC-68).
113
+ - **Open the new vertical by RE-PURPOSING, not inventing.** AGENTTRACE is the first product whose engine is
114
+ the shipped RFC-6962 log core (T-63.1) — file-SET seals structurally cannot express an ordered,
115
+ grow-over-time, redactable session. **EPIC-64 (witness/equivocation) stays PARKED; the primitive freeze
116
+ and resume-adding criterion remain in force.**
117
+ - **Strictly additive + in-guardrails.** No new dependency, no new crypto, free verify surface only (paid
118
+ `--sign` reuses the existing fail-closed license gate), no new `needs-human` item, and the honest boundary
119
+ carried in-band from day one: a packet proves the log was NOT altered after sealing and what any disclosed
120
+ event said — NOT that the log faithfully records what the agent did (garbage-in), NOT a trusted timestamp
121
+ without P-3.
122
+
123
+ ## Work invented (newly planned: 9)
124
+
125
+ Nine new tasks across the three new epics: EPIC-66 (T-66.1/.2/.3), EPIC-67 (T-67.1/.2), and EPIC-68
126
+ (T-68.1/.2/.3/.4). Eight shipped and verified this same run; **T-68.4** (AGENTTRACE docs + a real
127
+ transcript-mapping example) remains on the frontier as the single open item.
128
+
129
+ ## Team changes (2)
130
+
131
+ **Manager MODIFIED two things — no panel growth (stays 5 reviewers + 5 builder profiles).** The new
132
+ AGENTTRACE surface introduced three novel make-or-break properties with no standing owner
133
+ (redaction-safe-leaf equivalence, redaction-as-withholding privacy, append-only-growth soundness):
134
+
135
+ 1. **MODIFIED reviewer TrustIntegrity** — appended a tight 7-pillar AGENTTRACE clause onto its existing
136
+ seal / Merkle-root re-derivation competency (redaction-safe leaf; redaction truly drops payload bytes;
137
+ `verifyGrowth` rejects rewritten history; signature-wraps-head + fail-closed `agent_signed` gate with the
138
+ free tier open; order/determinism + strict named rejects; honest boundary; verbatim reuse of
139
+ `journal-log`/`hash`/`attestation`).
140
+ 2. **MODIFIED the falsepass persona** — added agent-session redaction/growth false-PASSes to its explicit
141
+ hunting list.
142
+
143
+ Rationale: TrustIntegrity is the natural owner (already owns seal/root re-derivation), so the Manager closed
144
+ the gap at **zero panel growth** rather than adding a 6th reviewer at the working size of 5. A false-PASS in
145
+ agent redaction (a leaked withheld payload) or in `verifyGrowth` (an accepted rewritten history) is a silent
146
+ evidentiary make-or-break defect no standing lens would have caught.
147
+
148
+ ## What's blocked
149
+
150
+ Nothing is software-blocked (`blocked: 0`). The standing constraint is human, not technical: **3 human-gated
151
+ items** (unchanged for ~20 runs). Both verticals (Evidence + TrustLedger), the new AGENTTRACE vertical, the
152
+ embeddable SDK, the HTTP verify-service, the integrity/transparency journal, and now the zero-install browser
153
+ Evidence verifier are all built and locally tested. The dam is purely commercial/relational.
154
+
155
+ ## Needs-human (from STRATEGY.md)
156
+
157
+ - **P-8 — CONSOLIDATED GO-TO-MARKET ASK: land ONE design partner and run the pilot.** The single human action
158
+ that de-risks P-3, P-5, P-6, and P-7 at once, and this run made its first-contact step **cheaper**: the
159
+ 60-second cold-prospect challenge is now a single browser link (`verify-vh-standalone.html`), no Node. The
160
+ loop has BUILT and locally TESTED the entire deliverable (an offline, ephemeral-key pilot kit); identifying
161
+ a partner, provisioning a real vendor key, setting a price, and running the pilot are human actions that
162
+ MUST NOT be auto-executed. The one-screen version lives in [`docs/DECIDE.md`](DECIDE.md):
163
+ 1. **Pick the lighter-gated vertical FIRST: EVIDENCE (P-7), not TrustLedger (P-5)** — no CPA/legal/per-state
164
+ liability layer; only a vendor key, a price, and one partner.
165
+ 2. **One concrete first target this week:** an incident-response / digital-forensics team OR an
166
+ e-discovery / audit-workpaper shop — buyers for whom "this is the exact file set, byte-for-byte
167
+ unaltered, and here is who produced it" is contractually expensive.
168
+ 3. **3-step first contact (no slide deck):** (a) `vh identity publish` once the vendor key exists; (b) hand
169
+ them the zero-install cold-prospect challenge; (c) if they lean in, run
170
+ `node pilot/run-pilot.js --certificate <path>` on THEIR own folder → a forwardable
171
+ `*.vhevidence.json` their security team verifies independently.
172
+ 4. **Time box:** 3–5 prospects over ~2 weeks. Success = ONE who keeps using the free verify/challenge
173
+ weekly OR agrees to a paid pilot. Zero after the box → the signal is "wrong buyer archetype" →
174
+ switch to the TrustLedger broker channel, NOT "build more product."
175
+ - **P-11 — REFRESH the live verifyhash.com publish set (~10-min recurring, deploy-gated).** The live site
176
+ serves stale pinned bytes; EPIC-67 makes the drift mechanical. The refresh now collapses to: (1)
177
+ `node scripts/site-release.js --diff` (read what the live site is missing); (2) `node scripts/site-release.js`
178
+ then upload `public/` per the REPLACE-mode runbook; (3) `--mark-deployed` + commit so the next `--diff` is
179
+ truthful. The loop NEVER uploads or touches `/var/www` — the upload is human-owned. As soon as this lands,
180
+ the site becomes the 60-second in-browser tamper challenge P-8's first contact can send as ONE link.
181
+ - **P-9 — Embeddable SDK distribution + pricing.** The `verifyhash` library surface (signed + unsigned verify)
182
+ is built and contract-pinned; publishing to a registry and pricing the embed/usage stay human steps.
183
+ - **P-10 — Transparency-log distribution (materially LOWER-gated than the pilot).** A public-good append-only
184
+ log + paid enterprise witness/monitor SLAs. Note: the enterprise witness/equivocation tier (EPIC-64) is
185
+ currently **PARKED** pending real demand, so P-10's paid tier is on hold until a customer pulls it.
186
+ - P-1..P-7 unchanged (D-2 token framing, mainnet deploy, DataLedger trust-root, and the per-product
187
+ go-to-market gates); AGENTTRACE's paid `--sign` sells under the SAME existing P-7 key/price/partner steps —
188
+ it adds no new gate.
189
+
190
+ **Revenue integrity (unchanged):** income is a subscription / license / meter for delivered software value;
191
+ the license is an ACCESS credential, NOT a token/coin/NFT, not tradeable, not an appreciating asset. The
192
+ loop ships only the mechanism + ephemeral test keys and must NEVER provision a real key, set a price, contact
193
+ a prospect, host, take payment, or run the pilot itself.
194
+
195
+ ## The honest read
196
+
197
+ Disciplined run. With its own panel flagging a quality stall and the go-to-market dam stuck for ~20 runs, the
198
+ loop did the two highest-leverage non-product things available: it made its first-contact funnel a
199
+ send-one-link browser page (removing the Node install from the Evidence pitch), and it made the one deployed
200
+ asset — verifyhash.com — mechanically know when it's stale. Then it opened a genuinely new buyer (AI-agent
201
+ audit/compliance) without inventing anything, by finally putting the dormant Merkle-log core to work. The
202
+ single highest-leverage HUMAN move is unchanged and now cheaper: **pick one Evidence design partner and send
203
+ them the browser challenge this week (`docs/DECIDE.md`), and re-deploy verifyhash.com so that link is live
204
+ (`P-11`).**