# Word Of Clout — ASTRA-R4 Public Artifact Set

Round-four reply to Astra. **PHASE 1 OF 2 — the machinery freeze.** This set
ships the r4 verifier (R4-2 signed-delivery-manifest + R4-3 current-mode
evaluator + R4-4/R4-5 canonicalization), the conformance fixture, the trust
stores, the canonicalization recipe v1.1, and the frozen hash-chained export.
The **int1-signed delivery manifest** and the **LIVE successor record
(mo-dental-013494@3)** land with two host-side one-line commands (§Phase 2
below) — the production signing key is root-held and never moves into any
repo. Until then this directory is the machinery freeze, not the round-4
package.

- **Requirements:** Node.js ≥ 20. No network. No dependencies.
- **Generation freeze:** machinery commit `76db5fbc` (R4-2 + R4-3 + the 30-leg
  regression suite), frozen 2026-09-13T14:45:00Z. The phase-2 shipping commit
  is named in the round-4 cover note.
- **The machine-checked regression set** lives in the repo:
  `scripts/astra-r4-verifier.test.ts` — 30 legs, every one through this public
  CLI (spawned, never internals).

## What changed from r3 — the reviewer's five failure families, closed

| Rank | r3 finding | r4 closure | Exit codes |
|---|---|---|---|
| 1 | CLI never enforced issuer eligibility (I01/I02/I03/I05 all exited 0) | the `--record` path runs THE ONE eligibility evaluator: revoked → 4 · not-yet-valid / clock-before-validity → 4 · not in the supplied store / no store → 3; signature-only is an explicit separate mode | 3, 4 |
| 2 | Export completeness not authenticated (I12/I13/I14 recomputed everything green) | `delivery.manifest.json` is SIGNED by int1 and binds every package file's sha256, the export chain (whole-file digest + line count + chain head), every record's canonical digest, and the snapshot reference — supplied with real signature bytes or explicitly not-supplied with a signed reason, never descriptive text. Drop a line, swap a record, rebuild checksums, remove the snapshot reference: each fails | 7, 1 |
| 3 | No current-use evaluation (I04/I15 at 2027-01-01 passed) | `--current` mode: evaluation time (default now, `--at`), EXACT subject/proposition scope, live deadlines on every in-scope proposition (the license-expiry cap is inside the signed `next_required_by`), and an authenticated checkpoint that binds the record. Historical integrity remains separate and inspectable — the same record passes historical at the same clock | 5, 6, 7 |
| 4 | Manifest hash depended on representation (I16) | canonicalization v1.1: `dependency_manifest_sha256` re-derives under `stableStringify` — key order is never a reconstruction dependency. Hard check in `--current` (exit 1, named); superseded-recipe history stays verifiable in `--record` mode with a labeled non-blocking note | 1, note |
| 5 | Own `__proto__` survived verification (I10) | null-prototype accumulator in `stableStringify`: a smuggled own `__proto__` key AFFECTS the canonical bytes → the signature breaks | 1 |

**Claims still not exercised** (the reviewer's table, answered honestly):
wrong subject/predicate is now exercised — NEG-11 (exit 6). The authorization
witness and re-derivable source evidence remain capability gaps; they are
the engagement package's job (the mock engagement under
`engagement-mock/` follows phase 2), not this set's claim.

## Exit-code contract (one table, every mode, no two failures render alike)

| exit | meaning |
|---|---|
| 0 | verified + recognized + eligible (and in `--current`: in scope, deadlines live, checkpoint-bound) |
| 1 | signature fails (record OR delivery manifest; includes own-`__proto__` smuggle and internal digest mismatch in current mode) |
| 2 | usage |
| 3 | issuer/signer not in the trust store — and without `--well-known`, a verifying signature alone is NOT authorization |
| 4 | recognized but ineligible (revoked / not yet valid / clock before validity) |
| 5 | STALE — current mode: an in-scope proposition's `next_required_by` is past the evaluation time |
| 6 | SCOPE MISMATCH — the record is not the requested subject/proposition |
| 7 | DELIVERY/CHECKPOINT FAILURE — manifest signature, binding, coverage, or chain broken; record not bound in the supplied checkpoint |

## Quick start — the first command a stranger runs

```
node verifier.mjs --record fixture.json --sig fixture.sig --well-known issuer-trust.json
# → VERIFIED + RECOGNIZED + ELIGIBLE — exit 0
```

That is the whole entry: a synthetic record, checked end-to-end — signature,
issuer recognition, eligibility — in one command, no network, no dependencies.
Everything below (the inventory, the exit-code contract, the negative cases,
the live-record legs) is the same CLI with different inputs. If this is your
first run, run it from this directory and expect `exit 0`.

## Files

| file | what it is |
|---|---|
| `README.md` | this file |
| `verifier.mjs` | the r4 standalone verifier (commit `76db5fbc` embedded) |
| `fixture.json` / `fixture.sig` | synthetic conformance record (Example Dental, LLC — invented subject, invented values; never a customer), fixture-key signed |
| `issuer-trust.json` | trust stores as enforced live: PRODUCTION = int1 only; FIXTURE separate and labeled |
| `canonicalization.md` | recipe v1.1 (the I16-corrected dependency-manifest digest + the null-proto law), cross-repo pin `ba62f43f…` |
| `export.jsonl` | frozen hash-chained export (phase 1: fixture + canonicalization freezes; the live record line lands in phase 2) |
| `record-mo-dental-013494@3.json` / `.sig` | *(phase 2)* the LIVE successor record + int1 detached signature |
| `delivery.manifest.json` | *(phase 2)* the int1-SIGNED delivery manifest binding every file above |
| `SHA256SUMS` | *(phase 2)* regenerated over the completed set |

## Commands

```
# phase-1 self-run (observed at freeze, exit 0):
node verifier.mjs --record fixture.json --sig fixture.sig --well-known issuer-trust.json

# issuer eligibility (rank 1): craft a well-known marking the key revoked →
node verifier.mjs --record fixture.json --sig fixture.sig --well-known your-revoked.json   # exit 4

# current mode (rank 3): requires the authenticated checkpoint →
node verifier.mjs --current --record record-mo-dental-013494@3.json \
                  --sig record-mo-dental-013494@3.sig \
                  --subject '<the record's exact subject line>' \
                  --delivery-manifest delivery.manifest.json \
                  --well-known issuer-trust.json
# wrong subject → exit 6 · deadline past at --at → exit 5 · older intact bundle at current mode → exit 5

# delivery verification (rank 2): tamper with ANY bound file, then →
node verifier.mjs --delivery-manifest delivery.manifest.json          # exit 7, the file named
```

## The negative cases — TRUE labels (r3's three relabeled, three new)

| # | true shape | result |
|---|---|---|
| NEG-6 | **Tampering** — an edited interior line breaks the whole-file digest and the `prev_sha256` chain (r3's label claimed "replay"; it never replayed an intact bundle) | rejected |
| NEG-7 | **Key status** — revoked / future `valid_from` / clock before validity (r3's label claimed "deadline/clock/revocation"; no record deadline was evaluated) | exit 4 |
| NEG-8 | **Unknown-key recognition refusal** (r3's label claimed "missing authorization"; no authorization witness was ever supplied) | exit 3 |
| NEG-9 | **Intact older-bundle replay at current mode** — a complete, previously valid bundle whose deadlines are past at the evaluation time. Bounded honestly: an intact older bundle whose deadlines are still live IS current evidence; offline currentness is relative to the supplied authenticated checkpoint — this CLI cannot discover an unseen newer head | exit 5 |
| NEG-10 | **Deadline expiry at current mode** — evaluation time past an in-scope `next_required_by` (the license-expiry cap binds: it is inside the signed data) | exit 5 |
| NEG-11 | **Wrong-scope request** — an intact, valid receipt for subject A presented against a request for B | exit 6 |

All eleven shapes run in the committed regression suite through this exact
CLI (`scripts/astra-r4-verifier.test.ts`, 30 legs, woc commit `76db5fbc`).

## Phase 2 — the two host-side one-liners (Tani; the key never moves)

```
# 1. export the LIVE successor from the kernel ledger (host mongosh):
mongosh "$KERNEL_APP_URI" --quiet --eval 'const d=db.getSiblingDB("woc_kernel").published_records.findOne({id:"mo-dental-013494@3"}); delete d._id; print(JSON.stringify(d,null,2))' > public/verify/astra-r4/record-mo-dental-013494@3.json

# 2. sign + freeze the completed package (int1 detached sig, export line 3, the
#    int1-signed delivery manifest binding every file, SHA256SUMS regenerated):
node scripts/r4-freeze-phase2.mjs --signing-key <INT1_KEY_PATH> \
     --snapshot-sha256 3736f976430224ab7ea3341c52e65de7f13f655050dac63cd807b16515830ec7 \
     --commit-id <this commit's sha>
```

Expected phase-2 output: the record's canonical sha256 (compare against
`514e3718…`'s record — the @3 successor carries the v1.1-recipe dependency
manifest), export line 3 appended, `delivery.manifest.json` written with the
int1 signature, SHA256SUMS regenerated; then `node verifier.mjs
--delivery-manifest delivery.manifest.json` exits 0 and the set is the
round-4 package.

**The snapshot reference** (`snapshot_reference.snapshot_sha256` inside the
signed manifest) pins the root-held int1-signed host snapshot — the
completeness anchor. The referenced bytes are archived root-side, are NOT
publicly served, and can be produced under engagement terms.