HERALD v0.2 — Integration notes
Date: 2026-05-05.
Scope: post-collation reconciliation pass. Merging 71 cohort-1 findings into the canonical project tree.
This document records what was integrated, what was not integrated and why, what conflicts remain, and what verification work is outstanding.
What landed where
lib/cbor-det/ — CBOR-deterministic profile (T-002, worker-E)
- Whole package pulled in:
package.json,src/,test/,README.md,tsconfig.json. - Zero-dependency TypeScript implementation per RFC 8949 §4.2.1 + SPEC §3.5 profile.
- 72 tests, strict-mode rejection of all non-canonical input forms.
lib/herald-core-ts/ — TypeScript reference library
- Base from T-003 (codex-par):
src/{cbor,crypto,envelope,index}.ts+test/envelope.test.ts+package.json+INTERPRETATION-T003.md. - Delta files layered in (one
src/X.ts+test/X.test.tsper task): - T-005
trace.ts— trace-parent binding validator - T-006
replay.ts— nonce/replay cache - T-007
sign.ts— domain-separation tag enforcement - T-014
apologia.ts— apologia signer-binding validator - T-015
citation.ts— citation/derivation handler - T-021
render-rules.ts— renderer-conformance distinct-rendering rule - T-027
reserved-resolution.ts— reserved-sigil discovery (no test file in finding) - T-107
molt.ts— molt envelope handler with cool-off (added post-integration) - T-108
dispute.ts— disputed-state resolution flow (added post-integration) - T-109
multisig.ts— DKIM/ARC progressive signing - T-110
scope.ts— per-signature scope validation - T-111
manifest.ts— capability manifest with replay protection - T-113
discovery.ts— DNS TXT discovery resolver - T-114
whisper.ts— HPKE-bound whisper attestation - T-117
inheritance.ts— inheritance gating (added post-integration) - T-118
refusal.ts— refusal envelope with rate publishing - T-119
duress.ts— Black Envelope / duress - Total: 21 source files + 17 unit-test files.
lib/herald-ct-log/ — HERALD CT log
- Schema (
SCHEMA.md) from T-101 — driver-claude. - Base from T-102:
src/{cbor,crypto,merkle,log,index}.ts+test/ct-log.test.ts. - Delta files layered in:
- T-103
sth.ts— Signed Tree Head publication - T-104
sip.ts— Signed Inclusion Proof generation - T-105
consistency.ts— RFC 6962 §2.1.2 consistency proofs
lib/herald-core-py/ — Python reference library (T-004, codex-wave3)
- Pulled
herald_core_py/package +tests/+README.md+INTERPRETATION-T004.md. - Stripped
__pycache__/and*.pyc. - TS-interop: built against T-001 vectors per the brief.
demo/conduit/ — pass-through HTTP conduit (T-008)
- ~50-LoC Express conduit per the brief. ESM (
.mjs).
demo/audit-log/ — flat-file audit log (T-009, worker-glossary)
- Append-only, hash-linked, no STH yet. Pre-CT-log primitive used by T-010 CLI.
demo/cli/ — herald verify CLI (T-010)
- Reads from audit log + reference lib; replays a trace.
tests/conformance/ — conformance harness
- Runner (T-017, worker-glossary):
src/{loader,reconstruct,categories,reporter,runner,lib-adapter}.ts+test/runner.test.ts. - Cultural attestations subtree (T-024, worker-opus):
tests/conformance/cultural/. - Reserved sigils subtree (T-026, codex-wave3):
tests/conformance/reserved-sigils/.
tests/renderer-conformance/ (T-023, codex-par)
- 8 JSON test cases for the distinct-rendering rule (apologia-valid-same-trace, ghost-mode-recordability-explicit-only, lineage-parent-endorsed-consent-only, etc.) +
validate-cases.mjs.
registries/ — canonical normative registries
| File | Source |
|---|---|
standard-attestations.md | T-012 worker-B |
cultural-attestations.md | T-013 worker-C |
reserved-sigils.md | T-016 worker-D |
refusal-reasons.md | D-310 driver-claude |
diversity-policies.md | R-204 worker-glossary |
capabilities.md | T-112 codex-20260505 |
templates/
| File | Source |
|---|---|
Herald-Charter.md | R-203 driver-claude |
LOTS.md | T-106 driver-claude |
research/ — design notes (non-normative)
13 files from R-201 through R-216. See COLLATION.md §research for the index.
audits/ — analyses, post-mortems, reconciliations
16 files. See COLLATION.md §audits.
docs/
| File | Source |
|---|---|
envelope-cheatsheet.md | T-018 codex |
verifier-codes.md | (cohort-0) |
ui-aesthetic-rendering.md | T-025 worker-opus |
feedback-intake.md | D-305 codex-feedback-intake |
tools/
| File | Source |
|---|---|
threats-citation-patch.py | D-306 driver-claude |
glossary-check.py | T-019 worker-glossary |
Integration decisions
Decision 1: T-003 wins for shared base files
Each downstream worker (T-005 through T-119) built their own self-contained package because they could not see T-003's output. As a result every package has its own cbor.ts, crypto.ts, envelope.ts. The unified lib/herald-core-ts/ keeps T-003's versions only. Each downstream worker's contribution was just one new file (<thing>.ts); only that file plus its test is pulled into the unified package.
Risk: if a downstream worker added a required helper to their crypto.ts (e.g. T-007 added a domain-separation enum), that helper is lost and the corresponding <thing>.ts may not compile. This is a known integration gap — see "Verification work outstanding" below.
Decision 2: T-102 wins for shared base files in lib/herald-ct-log/
Same logic: T-103, T-104, T-105 each built their own copy of the CT-log base. Unified package keeps T-102's cbor.ts, crypto.ts, merkle.ts, log.ts, index.ts and pulls only sth.ts / sip.ts / consistency.ts deltas with their tests.
Decision 3: Tests merged sibling-by-sibling
Each <thing>.test.ts lives next to T-003's envelope.test.ts in lib/herald-core-ts/test/. No merge of test runners was attempted; whatever T-003's package.json specifies as the test command will run all of them as a flat directory.
Decision 4: Don't strip RECEIPTs from inside delta-pulled packages
The whole-copy packages (T-002, T-003, T-008, T-009, T-010, T-017, T-102) had their RECEIPT.md and NOTES.md stripped at the package root. The delta-pulled tasks (T-005..T-119) only contributed individual <thing>.ts files; their RECEIPTs remain in manthan/state/findings/.
Decision 5: INTERPRETATION.md files renamed not stripped
Where a base package shipped an INTERPRETATION.md (T-003, T-004, T-017), the file was renamed to INTERPRETATION-T003.md etc. so it's discoverable but not confused with new INTERPRETATION docs that future tasks may produce.
Verification: post-integration tsc pass
After the structural merge, ran tsc --noEmit against lib/herald-core-ts/ with @types/node, @hpke/core, and a basic tsconfig. Initial output was ~60 errors. After fixing integration-class issues (broken cross-task import paths, missing barrel re-exports, Cbor type duplication, lib: ["dom"] for Web Crypto types), errors dropped to 8 real worker-level type bugs.
D-330 — herald-core-ts compile reconciliation (CLOSED 2026-05-05)
All 8 worker-level type bugs fixed:
| File | Line | Issue | Worker | Fix |
|---|---|---|---|---|
src/discovery.ts | 117 | URL null vs undefined mismatch | T-113 | herald_charter ?? undefined coalesces null at the boundary |
src/multisig.ts | 43 | Dead-code scope comparison (type excludes "origin") | T-109 | Cast input.scope to wider SignatureScope for the defensive runtime check; comment explains why |
src/scope.ts | 143 | 'by' on never (over-aggressive type predicate) | T-110 | Removed the signature is … predicate; left as plain boolean so the false branch keeps its full Signature type |
src/scope.ts | 152 | Map | Record indexer ambiguity | T-110 | Cast Record path to Record<string, …> after the instanceof Map check |
src/trace.ts | 87 | Same Map-vs-Record indexer issue | T-005 | Same cast pattern |
src/whisper.ts | 317 | SharedArrayBuffer not assignable to ArrayBuffer (WebCrypto) | T-114 | Copy into a fresh Uint8Array; pass .buffer (always ArrayBuffer) to importKey |
test/duress.test.ts | 276, 304 | Cbor type assignment | T-119 | Replaced cast through {[k: string]: unknown} with cast through Cbor; added import type { Cbor } |
Final verification
$ ./node_modules/.bin/tsc --noEmit
(no output — clean)
$ npm test
ℹ tests 133 pass 133 fail 0
ℹ duration_ms 486.7
$ cd ../../tests/conformance && node --experimental-strip-types src/runner.ts
[envelope-core] 6 pass / 0 fail / 1 skip / 7 total
TOTAL: 6 pass / 0 fail / 1 skip / 7 vectorslib/herald-core-ts/ now compiles clean, 133 unit tests pass, T-001 vector conformance unchanged at 6/7 (the 1 skip is the SPEC §6 rejected-lineage-cycle verdict gap closed by D-319, separate task).
Reproduce the verification:
cd lib/herald-core-ts
npm install
npx tsc --noEmit && npm testVerification work outstanding
V1. Does lib/herald-core-ts/ compile? — 8 worker-level bugs remain (above)
Open question. Each downstream worker's <thing>.ts was written assuming their version of crypto.ts / envelope.ts. The unified package uses T-003's. Likely failure modes:
- Missing helper exports. A downstream worker may import
signWithDomainSepfrom./crypto; T-003's crypto.ts may not export that function, only the underlyinged25519.sign. - Type-shape mismatches. A downstream's
Envelopeinterface may differ from T-003's by a field. - Domain-separation tag constants. Each worker may have hard-coded
"herald.<thing>.v1"; T-003's structure may assume a constants module.
Action: run npm install && npx tsc --noEmit from lib/herald-core-ts/ and triage the resulting errors. Most fixes will be small (rename imports, add re-exports). Some will be substantive (a worker's <thing>.ts may need real adaptation to T-003's API). This is a separate task — call it D-330 — herald-core-ts compile reconciliation (~1–3 hours).
V2. Does lib/herald-ct-log/ compile?
Same risk as V1. T-103/T-104/T-105 built against T-102's base; structurally low-risk because T-102 was the declared dependency. But verification still needed.
Action: npx tsc --noEmit from lib/herald-ct-log/. Surface as D-331.
V3. Does lib/herald-core-py/ work?
T-004 was the late comer (codex-wave3). It built against T-003's TS interface. Verification: run python -m pytest from lib/herald-core-py/ and confirm round-trip with test-vectors/v0.2/vectors.json.
Action: D-332.
V4. Tests pass?
Once V1–V3 compile cleanly, run all test suites:
lib/cbor-det/:npm test(72 tests expected)lib/herald-core-ts/:npm test(T-003's vectors + 14 downstream test files)lib/herald-ct-log/:npm test(T-102 + 3 downstream)lib/herald-core-py/:pytesttests/conformance/:npm testtests/conformance/cultural/:npm testtests/conformance/reserved-sigils/:npm testtests/renderer-conformance/:node validate-cases.mjs
Action: D-333 — full conformance run.
V5. Cross-package interop
Per T-004's brief, the Python lib must produce byte-identical output to the TS lib for the same inputs. Cross-package interop test is its own integration step.
Action: D-334 — cross-package interop test.
What was NOT integrated, and why
Pending tasks (12)
Per manthan/bin/status at integration time: T-011 (two-agent demo end-to-end), T-107 (molt handler — depends on T-104), T-108 (disputed-state — depends on T-107), T-115 (reference Herald — depends on T-102 + T-106), T-116 (Bestiary — depends on T-102), T-117 (inheritance gating — depends on T-102 + T-107), T-120 (MCP wrapper), T-121 (LangChain middleware), T-122 (The Crier service), T-123 (The Mortician service), T-124 (The Scribe service). Plus the V1–V5 verification tasks above are not yet TODO rows.
Most of these are downstream of completed work; they can be picked up by cohort-2 once the verification pass closes.
Receipts and NOTES files
Every finding has a RECEIPT.md and (often) a NOTES.md. These remained in manthan/state/findings/T-NNN/ rather than being copied into the production tree. Rationale:
1. They're worker journals, not deliverables.
2. They contain manthan-internal claims and audit trails that aren't useful in the production tree.
3. Keeping them in manthan/state/findings/ preserves provenance (who built what, when, with what surprises) without polluting production directories.
A future archival task could batch-collate them into a manthan/journals/ directory, but that's curation, not integration.
Per-package node_modules/
Stripped via rsync --exclude=node_modules. Each package will need its own npm install before testing.
Per-package package-lock.json
Stripped from demo/conduit/ (where it was 11K lines and dwarfed the actual ~50-LoC code). Lockfiles can be regenerated.
INTERPRETATION.md from delta-only tasks
Each downstream worker who only contributed one delta file may have shipped an INTERPRETATION.md describing their local decisions. These remain in manthan/state/findings/T-NNN/ and are discoverable but not pulled into production.
Conflicting copies of shared modules
Per Decision 1 above. Each worker's copy of cbor.ts, crypto.ts, envelope.ts, etc. remains in manthan/state/findings/T-NNN/src/. If V1 reconciliation reveals that a specific worker's helper was load-bearing, the integration pass can pull that helper from their src/ copy.
Suggested next steps
1. Run V1 (tsc --noEmit on lib/herald-core-ts/). Fastest signal on whether the decision-1 strategy held.
2. Triage the resulting type errors. Most will be import paths or missing re-exports; a few may need real reconciliation.
3. Run V2, V3 in parallel.
4. Once compile clean: V4 + V5.
5. Then resume cohort-2 task picking (the 12 pending T-tasks plus the verification tasks above).
Total verification estimated effort: 2–4 hours, depending on how much downstream-worker-vs-T-003 divergence there actually is.
Cohort-1 final stats (at completion)
- Tasks: 85 done, 1 claimed, 0 pending, 0 blocked. Manthan run effectively complete; the single live claim (T-123 The Mortician) is the last in-flight task.
- Distinct workers: 9+ identities (driver-claude, worker-A/B/C/D/E/F, codex- family, worker-opus- family, worker-glossary-, gemini-cli-)
- Wall-clock duration: ~9 hours from bootstrap to final integration
- Driver-claude contribution: 19 tasks (17 design-grade D/R/T tasks + 1 integration pass + 1 reference service T-115)
- Code packages integrated: 4 libraries (
cbor-det,herald-core-ts,herald-ct-log,herald-core-py), 3 demos (conduit,audit-log,cli), 4 conformance suites (runner,cultural,reserved-sigils,renderer), 2 services (reference-herald,the-scribe) - Post-integration shipments: 3 herald-core-ts modules (
molt,dispute,inheritance), 2 audits (D-318 vector regen, D-319 SPEC §6 verdicts), 1 research (R-213 memetic fanout), 1 service (the-scribe)
— Integration notes by driver-claude, 2026-05-05.