Full audit of the August 2026 corpus: parcel consistency across both layouts, signal-graph engine correctness, contract conformance, and the state of every deliverable the downstream consumers read.
The engine is correct and the corpus is consistent. The three-region conversion moves no payload: six August days re-emitted from the converted corpus are byte-identical in nodes, edges and counts. All 2,704 parcels pass conformance across both layouts, and all 1,191 reviewed parcels read identically through every reader class. Downstream payloads are present, digest-consistent and internally agreeing.
Seven defects found, all bounded. One was fixed and mutation-proven during this audit; the rest are reported with owners rather than silently patched. None blocks the daily run.
The corpus holds two parcel layouts at once. That is the intended migration state, and the audit's first job was to prove the split is clean rather than assume it.
| Lane | Total | Three-region | Old-shape | Conformance |
|---|---|---|---|---|
| broker | 2,552 | 1,191 | 1,361 | 2552 / 0 failed |
| substack | 122 | 0 | 122 | conformant |
| internal | 30 | 0 | 30 | conformant |
The 1,191 converted parcels are exactly the 1,191 reviewed parcels; the 1,361 old-shape are exactly the unreviewed. The layout boundary and the review boundary are the same boundary — there is no parcel that is reviewed but unconverted, or converted but unreviewed.
Every converted parcel was read through the independent reader classes and compared on
findings, sources, review_run, contract_version
and review_state:
This is the property that failed before the read-half fix landed — a converted parcel reported
findings ABSENT, and absent is how OKF encodes "never reviewed". It now holds
corpus-wide.
Aggregate source-anchoring across the reviewed corpus is 27.3%. Read as a quality metric that looks alarming. It is not a quality metric — it is two contract regimes averaged together.
Every day before 2026-08-13 is 0%. Every day from 08-13 is 100%. There is no
partial day and no decay: the anchor key was introduced by contract v2.3 and adopted
completely on the first batch that ran under it. The two source shapes in the corpus are exactly
(id, resource, title) ×9,845 and (anchor, id, resource, title) ×3,702 —
no third shape, no half-populated records.
Findings-per-document drops from ~26 to ~4.2 at the v2.4 → v3.5/3.6 boundary. This is the signal-or-nothing contract change working as designed — a no-signal document now earns the index layer only and is a complete record — not reviewers doing less work.
| Regime | contract | docs | findings/doc | quotes/doc | reading |
|---|---|---|---|---|---|
| 08-01 → 08-07 | pre-2.2 | 442 | 25.94 | 0.60 | quotes key arrives mid-band (08-07) |
| 08-09 → 08-14 | 2.2 – 2.4 | 338 | 15.11 | 2.05 | quotes + anchors arrive |
| 08-15 → 08-23 | 3.5 – 3.8 | 366 | 4.24 | 2.23 | signal-or-nothing |
The load-bearing question: does the parcel conversion change what the engine produces? Answered by re-emitting real August days from the converted corpus and comparing section by section against what shipped.
| Batch | nodes | edges | counts | edges on disk / re-emit |
|---|---|---|---|---|
| 2026-08-17 | identical | identical | identical | 59 / 59 |
| 2026-08-19 | identical | identical | identical | 37 / 37 |
| 2026-08-20 | identical | identical | identical | 26 / 26 |
| 2026-08-21 | identical | identical | identical | 79 / 79 |
| 2026-08-22 | identical | identical | identical | 20 / 20 |
| 2026-08-23 | identical | identical | identical | 28 / 28 |
Compared as canonicalized JSON, section by section — nodes, edges,
counts, axes, layout, quadrants,
vendorable all hash equal. The conversion moves no payload.
The content_digest does differ between shipped and re-emitted payloads. Three
causes, all provenance, none content:
digest_recipe v1 → v2 — v1 hashed generated_from; v2 excludes it. A
recipe change moves the digest by design.generated_from.parcels — shipped payloads carry the n8n runtime path
/files/ViskaRes/…; current code emits repo-relative. Same corpus, two spellings.--since omission — re-emitting without it drops edges_from_history
(28 → 0 on 08-23), because edges are additive across days. The engine is right; a bare
--date re-emit is the wrong comparison.thesis_uncited is a member of GATE_KEYS and is set by
check_parcel, but the failure-reporting block had no print branch for it. A parcel
failing on that property alone was counted in "N parcels FAIL the gate" and then named
nothing — every property line above it reading ok.
Mutation-proven in both directions on the live batch: with the fix deleted the silent failure returns; restored, the parcel is named. Reporting only — no gate semantics changed, no parcel edited, self-check PASS.
The only coverage hole in August. Every other measurable day is complete (08-16 13/13, 08-17 68/68, 08-18 55/55, 08-19 80/80).
The graph for 08-23 was therefore built from 31 of 35 available documents. Additive by construction, so re-reading these two only adds — no rebuild of prior days is implied.
The dominant live-contract violation class by an order of magnitude, and the contract is explicit that a date must be neither sharpened nor blurred from what the document gave.
Both directions appear, so this is not a single formatting habit — the reviewer is filling
expected_at and date_precision independently rather than deriving one
from the other.
Entity lists containing empty or non-string members — up to 13 in a single parcel. Contained to one batch band, which suggests a single reader run rather than a standing contract gap.
regime) · sha1:f392e3d2… (eureka) · both batch 08-13, contract v2.3Both are legacy v2.3 records. The gate catches them correctly — this is not a
gate hole, it is unrepaired history. eureka is a legitimate top-level synthesis key,
which is likely how it migrated into a finding's class slot.
Two records out of 18,126 August findings. Repair is a two-record edit, not an arc.
The live contract hashes to the approved v3.8 sha, so leg 2b passes and the daily run is
unaffected. But verified_run.py — the operator's one-verified-run proof —
reads the stale string and reports link 2 as NO on a batch where the reviewer
correctly held v3.8.
Severity per existing ruling, not re-derived:
N8N-SIGNAL-GRAPH-PROTOCOL.md:547 already rules this low — CONTRACT-v2's header is an
artifact of the retired ledger lane, declared_version() lives only in the manual
proof tool and reaches no daily run. Flagged here because that manual tool is precisely what the
operator reads to approve a batch, so the false negative lands in front of a human.
daily.yml has never been rundaily.yml is still on origin/main, now workflow_dispatch:
only — no schedule: or cron: anywhere in the file. It is kept deliberately,
not forgotten: the handoff that hands the pipeline to n8n makes its removal conditional.
RES's stated condition for closing it was that the first unattended n8n run happen first.
That run fired and landed today — 3a316f51, batch 08-23, automated
bare emit, 11:45Z. The precondition is now met, and running the comparison is assigned to no one.
What actually exists on disk, per August day, against what the pipeline contract describes.
| Deliverable | days present | state | reader |
|---|---|---|---|
| graph-<batch>.json | 22 / 22 | complete | FE, DB, STRAT |
| conviction-payload.json | 17 / 22 | gaps | STRAT |
| plot-payload.json | 6 / 22 | stops 08-06 | FE |
| daily-<batch>.json | 2 / 22 | 08-07, 08-10 only | FE / Slack |
| DAILY-CLOSE-<batch>.md | 0 / 22 | none in repo | leg 1 arbiter |
The DAILY-CLOSE absence was checked with a positive control — find
resolves other names in the same tree, so the search could see. Zero files exist repo-wide under
that name, and check_folder_complete.py names it as a leg-1 requirement. These are
seat-only legs that read the local Dropbox corpus, so a gap here does not necessarily mean the
day failed — but it does mean the artifact the contract names as the close is not in the
repo for any August day.
The two excluded days are the insufficient_corpus holds, which the engine marks
vendorable: false with a stated reason rather than shipping an unexplained empty
graph. Correct behaviour. One nit: the manifest header still declares
payload_schema: viska.signal-graph/1.0 while its contents are 1.1 and 1.4.
| Gate | batch 08-23 | note |
|---|---|---|
| quotes in document | 71 / 71 | byte-exact against source, no model in the loop |
| sources anchored | 216 / 216 | every anchor a verifiable span |
| cites resolve | 471 / 471 | each names a declared source |
| values in body | 186 / 186 | flag tier, never a gate |
| review substance | 33 / 33 | every reviewed parcel carries substance |
| narratives supported | 73 / 95 | flag — no finding-to-narrative edge exists to satisfy |
| thesis uncited | 1 parcel | now named — see F1 |
The A1 anchor halt is substantially resolved: the class-B elision trims landed, and 08-23 now carries zero unanchored sources and zero missing quotes. The remaining gate failure is the single uncited thesis.
cites_unresolved.August reviews name 16 distinct model strings for roughly 8 actual models —
sonnet-5 beside claude-sonnet-5, mimo-v2.5 beside
xiaomi-mimo-v2.5, four spellings of Haiku 4.5. The 33 OpenRouter provider-prefix
records were repaired this cycle; the remaining variance is reviewer-side spelling, and it makes
any per-model quality comparison unreliable until normalized.
| Claim | tier | method |
|---|---|---|
| 2,704 parcels conformant, both layouts | live-verified | parcel_conformance.py over all three lanes |
| Conversion moves no payload | live-verified | 6 days re-emitted, section-level JSON hash comparison |
| 1,191 parcels reader-equivalent | live-verified | every converted parcel through each reader class |
| Anchor step function at 08-13 | live-verified | per-day anchored/bare census over reviewed corpus |
| F1 gate fix works | mutation-proven | real → names parcel; fix deleted → silent |
| No DAILY-CLOSE artifact exists | live-verified | find repo-wide + positive control |
| F6 severity is low | file-sourced | cites existing ruling rather than re-deriving |
expected_at from date_precision. 160
records is the largest live-contract class and it is one rule stated once.CONTRACT-v2.md or retire it. Low severity by
standing ruling, but it currently makes the operator's approval tool report a false NO.daily.yml's retirement says "Byte-parity with daily.yml is the
acceptance test", and both seats are on record that it has never been run. RES's own
condition for closing it — that the first unattended n8n run happen first — was met
today (3a316f51, batch 08-23, automated, 11:45Z). The precondition is
satisfied and the test is nobody's task.