From 21645dfe6fb4f956fd40cd6060505f694d7dfb2f Mon Sep 17 00:00:00 2001 From: Sylpheed port agent Date: Mon, 31 Aug 2026 03:31:34 +0000 Subject: [PATCH] port: audit-kinds was auditing 16 of 71 authored justifications and never said so Back to the port, and the finding came from reading data rather than a tool. P6's three SE cues -- move, confirm, back -- carry measured provenance from HANDOFF Q8, byte offsets in Static.slb and careful why text. None of them had a kind field, so audit-kinds, the audit that exists to check provenance, had never looked at them. Counting the corpus: 55 why fields with no kind against 16 with one. The tool audits what declares itself, and I have quoted its clean runs in DECISIONS as evidence that the authored data is grounded. That was a statement about 16 of 71. It now prints its own coverage before the verdict, so a clean run cannot be read as full coverage. The three SE cues are labelled measured -- accurate -- and now pass the citation check they had been exempt from. 19 of 71. Not every why should have a kind, and the tool says so: section prose and _ blocks explain a group rather than assert one value's provenance, and forcing a label there would invite mislabelling to satisfy a counter, which is worse than the gap. So it reports the ratio rather than demanding it be 1. This is the liveness family again but about SCOPE rather than aliveness. Every earlier instance was a checker that could not fail; this one fails correctly and describes a sixth of the corpus. 'I checked and it was fine' and 'I checked the part that declared itself' read identically in a log, and only one of them is what I have been quoting. Also recorded so I do not rebuild it: the Decoder tried twice to build the stale-justification detector and both failed. Flagging tools whose cited page is newer gave 126 candidates and no signal; narrowing to pages that later received a correction commit gave 43, better signal and still unauditable by hand. They sampled 3 before publishing and all three were false positives. The structural reason is that co-citation is not co-reference -- a tool cites a page for one fact and the page is corrected about another. They did not publish the 43, and their reach is stated: 3 of 43, so the rate is not established, only shown low enough that the report is not worth reading. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01N7FiFFFwbvG2uxdcEh8HyF --- authored/audio.json | 9 ++++--- docs/port/DECISIONS.md | 54 +++++++++++++++++++++++++++++++++++++++++- tools/port/audit-kinds | 43 +++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 4 deletions(-) diff --git a/authored/audio.json b/authored/audio.json index 82b17f59..f030d304 100644 --- a/authored/audio.json +++ b/authored/audio.json @@ -55,7 +55,8 @@ "channels": 1, "rate": 48000, "name_match": "SE_UI_CURSOR", - "why": "HANDOFF Q8, measured: the d-pad move cue, 8 192 B / 0.533 s, reproduced across two boots. Left/right play nothing at all, which is a measurement too and is why there is no `left`/`right` row here rather than a silent file." + "why": "HANDOFF Q8, measured: the d-pad move cue, 8 192 B / 0.533 s, reproduced across two boots. Left/right play nothing at all, which is a measurement too and is why there is no `left`/`right` row here rather than a silent file.", + "kind": "measured" }, "confirm": { "bank": "Static.slb", @@ -63,7 +64,8 @@ "packets": 6, "channels": 1, "rate": 48000, - "why": "HANDOFF Q8, measured: the (A) confirm cue, 12 288 B / 1.016 s. NO `name_match`: Q8 is explicit that (A)'s wave was not separated between `SE_UI_DECIDE` and `SE_UI_SUB_WIN_OPN`, so naming it would invent the one thing the measurement did not settle." + "why": "HANDOFF Q8, measured: the (A) confirm cue, 12 288 B / 1.016 s. NO `name_match`: Q8 is explicit that (A)'s wave was not separated between `SE_UI_DECIDE` and `SE_UI_SUB_WIN_OPN`, so naming it would invent the one thing the measurement did not settle.", + "kind": "measured" }, "back": { "bank": "Static.slb", @@ -71,7 +73,8 @@ "packets": 2, "channels": 1, "rate": 48000, - "why": "HANDOFF Q8, measured: the (B) back cue, 4 096 B / 0.344 s, reproduced across two boots. No `name_match` for the same reason as `confirm` -- Q8 names no identifier for it." + "why": "HANDOFF Q8, measured: the (B) back cue, 4 096 B / 0.344 s, reproduced across two boots. No `name_match` for the same reason as `confirm` -- Q8 names no identifier for it.", + "kind": "measured" } }, "bgm": { diff --git a/docs/port/DECISIONS.md b/docs/port/DECISIONS.md index ecff9704..d104885f 100644 --- a/docs/port/DECISIONS.md +++ b/docs/port/DECISIONS.md @@ -9,7 +9,7 @@ dies, which is what this file is for. -300 sections. Search this before re-deriving anything. +302 sections. Search this before re-deriving anything. * [P0 — the exporter, 2026-08-28](#p0--the-exporter-2026-08-28) * [P1 — Godot draws the screen, 2026-08-28](#p1--godot-draws-the-screen-2026-08-28) @@ -311,6 +311,8 @@ dies, which is what this file is for. * ["Independently" dies on a fact, and I decline to re-add the pairing they restored](#independently-dies-on-a-fact-and-i-decline-to-re-add-the-pairing-they-restored) * [Their docstring point found three stale claims in my code](#their-docstring-point-found-three-stale-claims-in-my-code) * [Their variant found a fourth in my tree: a stale JUSTIFICATION, not a stale number](#their-variant-found-a-fourth-in-my-tree-a-stale-justification-not-a-stale-number) +* [`audit-kinds` was auditing 16 of 71 authored justifications, and never said so](#audit-kinds-was-auditing-16-of-71-authored-justifications-and-never-said-so) +* [Their failed detector, recorded so I do not rebuild it](#their-failed-detector-recorded-so-i-do-not-rebuild-it) ## P0 — the exporter, 2026-08-28 @@ -14903,3 +14905,53 @@ thing. has already been retracted.** It catches propagation, not error. Their `ring_row.py` calibration and any equivalent of mine would still be invisible, because nothing had retracted them — **nobody knew they were wrong.** + +## `audit-kinds` was auditing 16 of 71 authored justifications, and never said so + +Back to the port, and the finding came from reading **data** rather than a tool. +P6's three SE cues — `move`, `confirm`, `back` — carry measured provenance from +HANDOFF Q8, byte offsets in `Static.slb`, and careful `why` text. **None of them +had a `kind` field**, so `audit-kinds` — the audit that exists to check +provenance — **had never looked at them.** + +Counting the corpus: **55 `why` fields with no `kind` against 16 with one.** The +tool audits what **declares itself**, and I have quoted its clean runs in this +file as evidence that the authored data is grounded. That was a statement about +**16 of 71**. + +✅ **It now prints its own coverage** before the verdict, so a clean run cannot be +read as full coverage. The three SE cues are labelled `measured` — accurate, and +they now pass the citation check they had been exempt from. **19 of 71.** + +⚠️ **Not every `why` should have a `kind`, and the tool says so.** Section prose +and `_` blocks explain a group rather than assert one value's provenance; forcing +a label there would invite **mislabelling to satisfy a counter**, which is a worse +failure than the gap. So it reports the ratio rather than demanding it be 1. + +📌 **This is the liveness family again, but about SCOPE rather than aliveness.** +Every earlier instance was a checker that could not fail; this one fails +correctly and **describes a sixth of the corpus**. *"I checked and it was fine"* +and *"I checked the part that declared itself"* read identically in a log, and +only one of them is what I have been quoting. + +## Their failed detector, recorded so I do not rebuild it + +They tried to build the stale-justification instrument I said did not exist — +**twice, both failed**, and did not publish the result. + +* **Attempt 1:** flag tools whose cited page is newer. **126 candidates, no + signal** — pages get appended to constantly for unrelated reasons. +* **Attempt 2:** narrow to pages later receiving a *correction* commit. **43 + candidates**, better signal, still unauditable by hand. They sampled **3 before + publishing**; all three were false positives. + +📌 **The structural reason is the keeper: co-citation is not co-reference.** A +tool cites a page for one fact; the page is corrected about another. `ob_flag.py` +cites its page for a counter's address while the correction refuted a prediction +about an offset the tool never mentions. + +✅ **And they did not publish the 43.** An unmeasured, evidently low rate is the +invents-defects failure, and their reach is stated: **3 of 43, so the rate is not +established** — only shown low enough that the report is not worth reading. +**That is a negative worth more than agreement**, because the class resisted two +different attempts for a reason rather than for want of attention. diff --git a/tools/port/audit-kinds b/tools/port/audit-kinds index 2c1a1507..4ded432a 100755 --- a/tools/port/audit-kinds +++ b/tools/port/audit-kinds @@ -178,6 +178,44 @@ def selftest(): return 0 +def coverage(files): + """How much of the authored corpus this audit can even see. + + 🔴 IT SEES 15 OF 70. Every `kind` label is checked for a citation, and a + clean run has been quoted in `DECISIONS.md` as evidence that the authored + data is grounded -- but a `why` with NO `kind` beside it is invisible to this + walk entirely, and there are 55 of those against 15 labels. + + Found by reading the data rather than the tool: `audio.json`'s three SE cues + carry measured provenance from HANDOFF Q8 and no `kind` field, so the audit + that exists to check provenance never looked at them. + + ⚠️ NOT every `why` should have a `kind`. Section prose and `_` blocks explain + a group rather than assert one value's provenance, and forcing a label there + would invite mislabelling to satisfy a counter. So this REPORTS the ratio + rather than demanding it be 1 -- a clean run must not read as full coverage. + """ + labelled = orphan = 0 + for f in files: + def walk(o): + nonlocal labelled, orphan + if isinstance(o, dict): + for k, v in o.items(): + if k.endswith("_why") or k == "why": + stem = k[:-4] if k.endswith("_why") else "" + kk = (stem + "_kind") if stem else "kind" + if kk in o: + labelled += 1 + else: + orphan += 1 + walk(v) + elif isinstance(o, list): + for x in o: + walk(x) + walk(json.load(open(f, encoding="utf-8"))) + return labelled, orphan + + def main(): if "--selftest" in sys.argv: return selftest() @@ -238,6 +276,11 @@ def main(): print(f" ⚠️ {len(variants)} spellings of the same label: {variants}") print(" A consumer comparing == 'measured' misses the others, and a") print(" label that fails to match reads as ABSENT, not as wrong.\n") + lab, orph = coverage(sorted(glob.glob("authored/*.json"))) + print(f" COVERAGE: {lab} `why` field(s) carry a `kind` and were audited above;") + print(f" {orph} carry NO `kind` and are INVISIBLE to this audit. A clean run") + print(f" below is a statement about {lab} of {lab + orph} authored justifications.") + print() print(f" {bare} bare or borrowed, {dangling} dangling, {len(rows) - bare - dangling} with resolving citations") print(" 🔴 A resolving citation is not a verified label. Nothing here reads") print(" the cited page to confirm it says what the `why` claims.")