diff --git a/authored/flow.json b/authored/flow.json index 5ae4cdc7..ef7d675f 100644 --- a/authored/flow.json +++ b/authored/flow.json @@ -114,6 +114,22 @@ "goto": "main_menu", "goto_name": "TITLE_MENU", "goto_name_kind": "name match, not measured", + "goto_name_why": [ + "NOT MEASURED, and the label says so. HANDOFF Q4 states it exactly: \"the", + "screens are measured; the ids are a name match onto the executable's class", + "names.\" So `TITLE_MENU` is a string that exists in the executable and plausibly", + "denotes this screen -- nothing observed binds it to this transition.", + "", + "It is carried so a reader can search for it and so the port never has to", + "invent one. THE PORT NEVER BRANCHES ON IT: navigation uses `goto`, which is", + "a screen file, and this field is documentation.", + "", + "๐Ÿ”ด THIS `why` DID NOT EXIST UNTIL 2026-08-30. All seven `goto_name_kind`", + "labels rested on a sibling `why` that argues the DESTINATION -- a different", + "claim from where the NAME came from. `tools/port/audit-kinds` reports that", + "as BORROWED rather than ok, because a label resting on a neighbour's", + "argument reads as evidenced and is not." + ], "why": "MEASURED, HANDOFF: (A) on the title opens the main menu, with (A) on the boot title as the control in the same run." }, "on_cancel": null, @@ -182,7 +198,23 @@ "goto": "title", "goto_name": "TITLE_SCREEN", "goto_name_kind": "name match, not measured", - "kind": "MEASURED", + "goto_name_why": [ + "NOT MEASURED, and the label says so. HANDOFF Q4 states it exactly: \"the", + "screens are measured; the ids are a name match onto the executable's class", + "names.\" So `TITLE_SCREEN` is a string that exists in the executable and plausibly", + "denotes this screen -- nothing observed binds it to this transition.", + "", + "It is carried so a reader can search for it and so the port never has to", + "invent one. THE PORT NEVER BRANCHES ON IT: navigation uses `goto`, which is", + "a screen file, and this field is documentation.", + "", + "๐Ÿ”ด THIS `why` DID NOT EXIST UNTIL 2026-08-30. All seven `goto_name_kind`", + "labels rested on a sibling `why` that argues the DESTINATION -- a different", + "claim from where the NAME came from. `tools/port/audit-kinds` reports that", + "as BORROWED rather than ok, because a label resting on a neighbour's", + "argument reads as evidenced and is not." + ], + "kind": "measured", "why": "MEASURED 2026-08-30, delivery-confirmed (B = 0x5801), 73.5 % of pixels changed, and both captures name themselves. Latency <= 0.4 s and NO loading screen in between, which matters because the disc carries four pgloading_* screens. This entry previously read 'likely but UNPROVEN': it had been seen once without a capture, and the title ALSO returns on its own after ~8-10 s idle, so an observer could not tell a response from a timeout. The <= 0.4 s latency is what kills that confound -- it is twenty times faster than the idle return. Decoder 86a8ce7, menu-navigation-semantics.md row 'B on the main menu', docs/re/data/b-on-main-menu.txt." }, "buttons": { @@ -191,6 +223,22 @@ "goto": null, "goto_name": "DIFFICULTY", "goto_name_kind": "name match, not measured", + "goto_name_why": [ + "NOT MEASURED, and the label says so. HANDOFF Q4 states it exactly: \"the", + "screens are measured; the ids are a name match onto the executable's class", + "names.\" So `DIFFICULTY` is a string that exists in the executable and plausibly", + "denotes this screen -- nothing observed binds it to this transition.", + "", + "It is carried so a reader can search for it and so the port never has to", + "invent one. THE PORT NEVER BRANCHES ON IT: navigation uses `goto`, which is", + "a screen file, and this field is documentation.", + "", + "๐Ÿ”ด THIS `why` DID NOT EXIST UNTIL 2026-08-30. All seven `goto_name_kind`", + "labels rested on a sibling `why` that argues the DESTINATION -- a different", + "claim from where the NAME came from. `tools/port/audit-kinds` reports that", + "as BORROWED rather than ok, because a label resting on a neighbour's", + "argument reads as evidenced and is not." + ], "blocked": "DIFFICULTY is not in this export. MEASURED destination (EASY/NORMAL/HARD/BACK, opening on NORMAL, then SELECT DATA) but it is not a GP_TITLE build, so there is no screen file to go to yet.", "skipped_chain": [ "DIFFICULTY", @@ -219,6 +267,22 @@ "goto": null, "goto_name": "TUTORIAL_MENU", "goto_name_kind": "name match, not measured", + "goto_name_why": [ + "NOT MEASURED, and the label says so. HANDOFF Q4 states it exactly: \"the", + "screens are measured; the ids are a name match onto the executable's class", + "names.\" So `TUTORIAL_MENU` is a string that exists in the executable and plausibly", + "denotes this screen -- nothing observed binds it to this transition.", + "", + "It is carried so a reader can search for it and so the port never has to", + "invent one. THE PORT NEVER BRANCHES ON IT: navigation uses `goto`, which is", + "a screen file, and this field is documentation.", + "", + "๐Ÿ”ด THIS `why` DID NOT EXIST UNTIL 2026-08-30. All seven `goto_name_kind`", + "labels rested on a sibling `why` that argues the DESTINATION -- a different", + "claim from where the NAME came from. `tools/port/audit-kinds` reports that", + "as BORROWED rather than ok, because a label resting on a neighbour's", + "argument reads as evidenced and is not." + ], "blocked": "The lesson list is not a GP_TITLE build. Destination MEASURED." }, "ptbtn04": { @@ -232,6 +296,22 @@ "goto": "extras", "goto_name": "EXTRA_MENU", "goto_name_kind": "name match, not measured", + "goto_name_why": [ + "NOT MEASURED, and the label says so. HANDOFF Q4 states it exactly: \"the", + "screens are measured; the ids are a name match onto the executable's class", + "names.\" So `EXTRA_MENU` is a string that exists in the executable and plausibly", + "denotes this screen -- nothing observed binds it to this transition.", + "", + "It is carried so a reader can search for it and so the port never has to", + "invent one. THE PORT NEVER BRANCHES ON IT: navigation uses `goto`, which is", + "a screen file, and this field is documentation.", + "", + "๐Ÿ”ด THIS `why` DID NOT EXIST UNTIL 2026-08-30. All seven `goto_name_kind`", + "labels rested on a sibling `why` that argues the DESTINATION -- a different", + "claim from where the NAME came from. `tools/port/audit-kinds` reports that", + "as BORROWED rather than ok, because a label resting on a neighbour's", + "argument reads as evidenced and is not." + ], "why": "MEASURED, HANDOFF Q4: EXTRAS opens GP_TITLE build 6. It is the ONLY main-menu destination inside this archive, and therefore the only (A)-into-a-submenu the P5 gate can actually walk." } }, @@ -258,6 +338,22 @@ "goto": "main_menu", "goto_name": "TITLE_MENU", "goto_name_kind": "name match, not measured", + "goto_name_why": [ + "NOT MEASURED, and the label says so. HANDOFF Q4 states it exactly: \"the", + "screens are measured; the ids are a name match onto the executable's class", + "names.\" So `TITLE_MENU` is a string that exists in the executable and plausibly", + "denotes this screen -- nothing observed binds it to this transition.", + "", + "It is carried so a reader can search for it and so the port never has to", + "invent one. THE PORT NEVER BRANCHES ON IT: navigation uses `goto`, which is", + "a screen file, and this field is documentation.", + "", + "๐Ÿ”ด THIS `why` DID NOT EXIST UNTIL 2026-08-30. All seven `goto_name_kind`", + "labels rested on a sibling `why` that argues the DESTINATION -- a different", + "claim from where the NAME came from. `tools/port/audit-kinds` reports that", + "as BORROWED rather than ok, because a label resting on a neighbour's", + "argument reads as evidenced and is not." + ], "why": "MEASURED, HANDOFF Q5: (B) goes up one level and RESTORES FOCUS to the item you came from. EXTRAS advertises (B) in its own footer -- the red glyph is in ptmsg2.png and absent from the main menu's ptmsg.png." }, "buttons": { @@ -278,6 +374,22 @@ "goto": "main_menu", "goto_name": "TITLE_MENU", "goto_name_kind": "name match, not measured", + "goto_name_why": [ + "NOT MEASURED, and the label says so. HANDOFF Q4 states it exactly: \"the", + "screens are measured; the ids are a name match onto the executable's class", + "names.\" So `TITLE_MENU` is a string that exists in the executable and plausibly", + "denotes this screen -- nothing observed binds it to this transition.", + "", + "It is carried so a reader can search for it and so the port never has to", + "invent one. THE PORT NEVER BRANCHES ON IT: navigation uses `goto`, which is", + "a screen file, and this field is documentation.", + "", + "๐Ÿ”ด THIS `why` DID NOT EXIST UNTIL 2026-08-30. All seven `goto_name_kind`", + "labels rested on a sibling `why` that argues the DESTINATION -- a different", + "claim from where the NAME came from. `tools/port/audit-kinds` reports that", + "as BORROWED rather than ok, because a label resting on a neighbour's", + "argument reads as evidenced and is not." + ], "same_as_cancel": true, "why": "MEASURED: EXTRAS' third item is BACK (live-extras.png). Treated as (B): it pops the stack, so focus is restored on the main menu exactly as (B) does. Whether the game distinguishes them is untested and there is no reason here to invent a difference." } diff --git a/docs/port/BLOCKED.md b/docs/port/BLOCKED.md index 9012d04a..e1f3428f 100644 --- a/docs/port/BLOCKED.md +++ b/docs/port/BLOCKED.md @@ -147,6 +147,12 @@ HANDOFF. | ~~P1โ€“P7 โ€” the keyframe record layout~~ | ~~adopt the corrected pose/time pairing~~ | โ€” | โœ… **ADOPTED 2026-08-29 by pinning `formats-pin-2026-08-29c`.** This row was wrong twice: it said the change *"cannot be taken yet"* and that it *"reaches the port only when that branch lands on `main`"*. **It arrives when the tag is pinned**, which is what MISSION ยง2's tagging rule exists for. โš ๏ธ And the knob I tested first, `SYLPHEED_KF_TIME_SHIFT`, is a **retired partial fix** that left pose 0 untimed โ€” the real correction is the tagged crate's default, with the old reading behind `SYLPHEED_KF_TIME_LEGACY=1`. **The blast radius was far smaller than this row predicted**: under the correction *every pose is timed* (866 keyframes, 0 untimed), so `pose_at`'s synthetic-exit branch became dead code rather than wrong code and nothing needed re-deriving. Oracle: `publisher_logo` 1.00 %โ†’**0.75 %**, `developer_logos` 0.39 %โ†’**0.33 %**, `extras`' differing region collapsing from 736ร—525 to **398ร—295 at the sweep position**. ๐Ÿ”ด Open cost: `sylpheed-cli` builds from the workspace crate, so `verify-screen` compares two decoder eras until the tag reaches `main`. Revert to the path dependency then. | | ~~P7 / naming โ€” the four unnamed builds~~ | ~~which locale and variant is each of entries 0, 1, 12, 15?~~ | โ€” | โœ… **answered 2026-08-29** (`docs/re/ui-title-build-map.md`): all four are the loading screen, two variants โ€” plain (7 elements) and dressed (10) โ€” decoded from their own `pgloading_*` element names. โš ๏ธ **Not adopted as names yet, for two reasons the RE agent gave and one the port found.** Theirs: the executable names exactly two, and *which* bundle takes which name is ๐ŸŸก undecided, so `LOADING`/`LOADING2` must not go in an asset path; and locale is ๐ŸŸก โ€” the English member of a pair is the one in the first half of `GP_TITLE.p00`, 8/8 structurally but only 3/3 where a capture can check, and the three pairs that matter are the three no capture can check. Mine: **the message gives the bundles as "0/1 and 10/11", which is the `is_build` ordinal, and `authored/screen_names.json` is keyed by PAK ENTRY** โ€” in entry space 10 and 11 are `palogo_sqex` and `palogo_gamearts`, the splashes. See the refutation section in `DECISIONS.md`. | +## Reported to the DECODER, 2026-08-30 โ€” derived from HANDOFF `12c9f04` + +| Milestone | Needs | HANDOFF | State | +|---|---|---|---| +| P0โ€“P7 โ€” Q2's map of `GP_TITLE` | **list entries 10, 11, 13 and 14 in the Q2 row** | `12c9f04` | ๐ŸŸก **the count is right and the enumeration is short; not blocking.** Q2 says *"`GP_TITLE` is 8 screens shipped twice, EN/JP"* and lists `2/3`, `4/7`, `5/8`, `6/9`, `0/1`, `12/15` โ€” **six states of the eight**. The two boot splashes, `publisher_logo` (10/13) and `developer_logos` (11/14), appear nowhere in it. โœ… The headline is confirmed by my export's entry map: 4 UI states + 2 loading variants + **2 splashes** = 8, shipped twice = the 16 entries the archive holds. ๐Ÿ”ด A reader counting Q2 gets twelve and has no slot for the splashes โ€” **and this is the row already corrected once for an ordinal-versus-entry error**, which is the mistake four unlisted entries feed. The port is unaffected: both splashes are exported, named, and verified against captures at RMSE 2.17 and 3.05. | + ## Ask for the HUMAN, 2026-08-30 โ€” derived from HANDOFF `27938aa` | Milestone | Needs | HANDOFF | State | diff --git a/docs/port/DECISIONS.md b/docs/port/DECISIONS.md index edf4c6eb..68686288 100644 --- a/docs/port/DECISIONS.md +++ b/docs/port/DECISIONS.md @@ -9,7 +9,7 @@ dies, which is what this file is for. -242 sections. Search this before re-deriving anything. +244 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) @@ -253,6 +253,8 @@ dies, which is what this file is for. * [The pin moves to `formats-pin-2026-08-30b`, and the port stops owning `+0x08`](#the-pin-moves-to-formats-pin-2026-08-30b-and-the-port-stops-owning-0x08) * [The menu remembers its cursor โ€” a measured P5 defect, fixed and scoped](#the-menu-remembers-its-cursor--a-measured-p5-defect-fixed-and-scoped) * [๐Ÿ”ด Correction, same day: I encoded an absence of measurement as a finding](#correction-same-day-i-encoded-an-absence-of-measurement-as-a-finding) +* [The `kind` sweep I said I owed: 15 labels, and 7 rested on a neighbour's argument](#the-kind-sweep-i-said-i-owed-15-labels-and-7-rested-on-a-neighbours-argument) +* [A refutation attempt on Q2's map of `GP_TITLE` โ€” the count is right, the list is short](#a-refutation-attempt-on-q2s-map-of-gp_title--the-count-is-right-the-list-is-short) ## P0 โ€” the exporter, 2026-08-28 @@ -12633,3 +12635,74 @@ Delivery-confirmation went to โ’ถ and โ’ท because those broke once; the d-pad ha always quietly worked, so nothing directed attention at it. `kind: "measured"` is the same shape โ€” it has never visibly failed, so nothing has been checking what each instance of it actually rests on. + +## The `kind` sweep I said I owed: 15 labels, and 7 rested on a neighbour's argument + +Every authored entry carries a `kind` โ€” `measured`, `authored`, `name match, not +measured` โ€” and the label is the load-bearing part: `measured` tells a reader +downstream that the port is repeating something observed off the running game. +**Nothing had ever checked them**, which is the point โ€” the Decoder's sharpening +is that *the disciplines that fail this way are the ones that never visibly +failed*. `tools/port/audit-kinds` now reports what each label rests on. + +### ๐Ÿ”ด It found the same error I was corrected for, one level down + +Seven of fifteen labels โ€” **every `goto_name_kind`** โ€” had no `why` of their own. +Four of them scored `ok` on the first run because the audit fell back to the +parent's `why`, which argues **the destination**. `goto_name_kind` is about +**where the NAME came from**. Different claims, and the audit was crediting one +with the other's evidence. + +That is precisely what I had been corrected for the previous iteration: treating +evidence as bearing on a claim it does not bear on. Borrowed evidence is now its +own outcome, `BORROW`, because *a label resting on a neighbour's argument reads +as evidenced and is not*. All seven now carry a `why` citing HANDOFF Q4's own +words โ€” *"the screens are measured; the ids are a name match onto the +executable's class names"* โ€” and state that the port never branches on the field. + +### And the audit refuted itself twice before it was worth trusting + +* **Four false positives.** The first version counted only paths, shas and + filenames as citations, so `HANDOFF Q1` and `PORT-MISSION section 7` read as + *cites nothing*. **An audit that invents defects is worse than no audit**: its + false positives are indistinguishable from its true ones until each is opened + by hand. +* **Seven false dangling.** It resolved paths against committed refs only, so a + `why` citing the tool being written this iteration failed. Working-tree paths + count now. + +โš ๏ธ **What it cannot do** is read the cited page and confirm it says what the `why` +claims, and it prints that on every run. Fifteen labels with resolving citations +is not fifteen verified labels. + +๐Ÿ“Œ One cosmetic find with teeth: `MEASURED` and `measured` both existed. **A +consumer comparing `== "measured"` misses the other, and a label that fails to +match reads as ABSENT rather than as wrong.** Normalised. + +## A refutation attempt on Q2's map of `GP_TITLE` โ€” the count is right, the list is short + +Q2 is titled *"which build is which screen state"* and reads: **`GP_TITLE` is 8 +screens shipped twice, EN/JP** โ€” `2/3` plate, `4/7` title, `5/8` main menu, `6/9` +EXTRAS, and `0/1` and `12/15` the loading screen. The port ships **16** screen +files, so I checked the enumeration against my own export's entry map: + +| entries | state | +|---|---| +| 0/1, 12/15 | loading, two variants โ€” โœ… in Q2 | +| 2/3, 4/7, 5/8, 6/9 | plate, title, main menu, EXTRAS โ€” โœ… in Q2 | +| **10/13, 11/14** | **`publisher_logo`, `developer_logos` โ€” absent from Q2** | + +โœ… **The headline survives and is exactly right.** Four UI states + two loading +variants + **two boot splashes** = 8 states, each shipped twice = **16 entries**, +which is what the archive holds. The count is confirmed by a second reading. + +๐Ÿ”ด **The row's own enumeration lists 6 of those 8.** A reader who counts Q2's +entries gets twelve and has no slot for the splashes โ€” and **this is the row +already corrected once for an ordinal-versus-entry error**, which is exactly the +mistake an incomplete map feeds: four unlisted entries are four places for an +off-by-three to hide. The splashes are not obscure to the contract either; the +190/145 dwell retraction is about these very entries. + +Not a defect in the port โ€” `publisher_logo` and `developer_logos` are exported, +named and verified against captures at RMSE 2.17 and 3.05. Reported because the +map is what the next reader will trust. diff --git a/tools/port/audit-kinds b/tools/port/audit-kinds new file mode 100755 index 00000000..89f3e5c1 --- /dev/null +++ b/tools/port/audit-kinds @@ -0,0 +1,173 @@ +#!/usr/bin/env python3 +"""What does each `kind` label in `authored/` actually REST on? + +Every authored entry carries a `kind` -- `measured`, `authored`, `name match, +not measured` -- and a `why`. The label is the load-bearing part: `measured` +means the port is repeating something observed off the running game, and a +reader downstream will treat it as fact. + +Nothing has ever checked them. That is the point: **a discipline that has never +visibly failed is the one nothing directs attention at.** The Decoder reached +this from the input side -- โ’ถ and โ’ท were delivery-confirmed because they had +once broken, so the d-pad never was -- and on the same day a `measured` label of +mine turned out to rest on a single entry that may have been measuring history. + +So this checks what is checkable about a label, and is explicit that the rest is +not: + + citations resolvable references in the `why` -- a `docs/` path that exists on + some ref, a commit sha that resolves, a capture filename + BARE a label whose `why` cites nothing a reader could go and open + DANGLING a citation that does not resolve anywhere in the repository + +๐Ÿ”ด What it CANNOT do is read the cited page and confirm it says what the `why` +claims. A label with three resolvable citations can still be wrong. This narrows +"which labels rest on nothing" from unknown to a list; it does not audit meaning. +""" +import json, glob, os, re, subprocess, sys + +REFS = None + + +def known_paths(): + """Every path in the repo, across ALL refs -- docs/re/ lives on a branch. + + Checked against the working tree as well: a file added this iteration is not + in any ref yet, and reporting a citation to it as unresolvable would make the + audit fail every time it is itself referenced. + """ + global REFS + if REFS is None: + out = subprocess.run(["git", "rev-list", "--all", "--objects"], + capture_output=True, text=True).stdout + REFS = {l.split(" ", 1)[1] for l in out.splitlines() if " " in l} + return REFS + + +HANDOFF_TEXT = None + + +def handoff(): + """The live HANDOFF, so a cited Q number is checked against the real table.""" + global HANDOFF_TEXT + if HANDOFF_TEXT is None: + sha = subprocess.run(["git", "log", "--all", "--format=%h", "--", + "docs/port/HANDOFF.md"], capture_output=True, + text=True).stdout.split()[0] + HANDOFF_TEXT = subprocess.run(["git", "show", f"{sha}:docs/port/HANDOFF.md"], + capture_output=True, text=True).stdout + return HANDOFF_TEXT + + +def sha_ok(s): + r = subprocess.run(["git", "cat-file", "-e", s + "^{commit}"], capture_output=True) + return r.returncode == 0 + + +def text_of(why): + if isinstance(why, str): + return why + if isinstance(why, list): + return " ".join(str(x) for x in why) + return "" + + +def citations(t): + """References a reader could actually follow.""" + out = [] + for p in re.findall(r"\b(?:docs|crates|port|tools|authored)/[\w./-]+\w", t): + out.append(("path", p.rstrip(".,"))) + for s in re.findall(r"\b([0-9a-f]{7,40})\b", t): + out.append(("sha", s)) + for p in re.findall(r"\b([\w-]+\.(?:png|txt|tsv|wav))\b", t): + out.append(("file", p)) + # The corpus cites two things that are not paths and are still followable: + # a HANDOFF question number, and a MISSION section. Leaving these out made + # the first run report four labels as resting on nothing when they rest on + # the two documents the mission names -- an audit inventing defects is worse + # than no audit, because its false positives are indistinguishable from its + # true ones until each is opened. + for q in re.findall(r"HANDOFF Q(\d+)", t): + out.append(("handoff", "Q" + q)) + for m in re.findall(r"(PORT-MISSION|MISSION)[ ]section[ ](\d+)", t): + out.append(("mission", m[1])) + for r in re.findall(r"MODDING rule (\d+)", t): + out.append(("modding", r)) + return out + + +def walk(o, f, path, out): + if isinstance(o, dict): + for k, v in o.items(): + if (k == "kind" or k.endswith("_kind")) and isinstance(v, str): + stem = "" if k == "kind" else k[: -len("_kind")] + own = o.get((stem + "_why") if stem else "why") + # ๐Ÿ”ด An earlier version fell back to the parent's `why` when a + # label had none of its own, and reported the result as `ok`. + # That credits a label with evidence for a DIFFERENT claim: + # every `goto_name_kind` scored on a sibling `why` about the + # DESTINATION, while the label is about where the NAME came + # from. Borrowed evidence is now its own outcome, because a + # label resting on a neighbour's argument is exactly the case + # this audit exists to surface. + out.append((f, path + "/" + k, v, text_of(own), + own is None and bool(text_of(o.get("why"))))) + walk(v, f, path + "/" + k, out) + elif isinstance(o, list): + for x in o: + walk(x, f, path, out) + + +def main(): + rows = [] + for f in sorted(glob.glob("authored/*.json")): + walk(json.load(open(f)), f, "", rows) + paths = known_paths() + bare = dangling = 0 + kinds = {} + print(f" {len(rows)} kind label(s) in authored/\n") + for f, where, kind, why, borrowed in rows: + kinds.setdefault(kind, 0) + kinds[kind] += 1 + cites = citations(why) + bad = [] + for typ, c in cites: + if typ == "handoff": + if not re.search(rf"\|\s*{c}\s*\|", handoff()): + bad.append(f"HANDOFF {c} (no such row)") + elif typ == "path" and c not in paths and not os.path.exists(c): + bad.append(c) + elif typ == "sha" and not sha_ok(c): + bad.append(c) + mark = "ok " + if not cites and borrowed: + mark, bare = "๐Ÿ”ด BORROW", bare + 1 + elif not cites: + mark, bare = "๐Ÿ”ด BARE", bare + 1 + elif bad: + mark, dangling = "๐Ÿ”ด DANGL", dangling + 1 + print(f" {mark} {kind:<24} {f.split('/')[-1]}{where}") + if not cites and borrowed: + print(" no `why` of its own; a sibling `why` argues a" + " DIFFERENT claim") + elif not cites: + print(f" cites nothing openable -- {len(why)} chars of prose") + elif bad: + print(f" unresolvable: {', '.join(sorted(set(bad))[:4])}") + else: + print(f" {len(cites)} citation(s), all resolve") + print() + # Casing is checked because a consumer comparing == "measured" silently + # misses "MEASURED", and a label that fails to match reads as absent. + variants = [k for k in kinds if k.lower() == "measured"] + if len(variants) > 1: + 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") + 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.") + return 1 if (bare or dangling) else 0 + + +sys.exit(main()) diff --git a/tools/port/check-all b/tools/port/check-all index 1b0c2830..9905a553 100755 --- a/tools/port/check-all +++ b/tools/port/check-all @@ -45,6 +45,10 @@ step format-validator must-pass "$BIN" check step contract-values must-pass tools/port/contract-check step contract-control must-pass tools/port/contract-check --control step modding-rules must-pass tools/port/check-modding +# Every `kind` in authored/ is a claim about where a value came from, and until +# 2026-08-30 nothing checked what any of them rested on -- seven were resting on +# a sibling `why` that argued a different claim. +step authored-kinds must-pass tools/port/audit-kinds step capture-controls must-pass tools/port/check-capture-controls step menu-audio must-pass env OUT="$OUT/audio" tools/port/verify-menu-audio # A stale index is worse than none: it answers "is this already decided?" with a