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.")