Two things, and the first is a refutation of mine that lands.
1. THE 12-UNIT BRACKET IS WITHDRAWN. It excludes nothing.
I kept 60 units/s on the ground that "12 declared units measured at 0.14-0.30 s
gives 40-86 units/s, so 120 is excluded". The Decoder refuted it and I checked
the arithmetic myself:
120 units/s predicts 12 units in 0.100 s -- BELOW the sampler's own 0.125 s
resolution, which the source doc states in its own words ("at a sampling
resolution that cannot do better"). A 0.125 s sampler reports such an interval
as about one sample, ~0.125-0.14 s. So the 0.14 s low end is the INSTRUMENT'S
FLOOR, and 12/0.14 = 85.7 is an upper bound produced by dividing by a floored
duration. It is the value 120 predicts once the sampler is accounted for.
🔴 And the deeper error is mine rather than the arithmetic. I argued the leg
survived because it "never touched a frame count". True, and INSUFFICIENT: every
wall-clock duration off Canary is true/speed_factor, so apparent units/s = true x
speed, and the speed factor is precisely what makes the three routes disagree. I
checked the leg for the WRONG CONTAMINANT. Frame-free is not clock-free, and on
this emulator clock-free is the property that matters.
What survives is the half I did not lead with: the declared 12 units are
independently confirmed as SIX FRAMES by screen-transitions.md's 255/6-per-frame
ramp, with no wall clock in it. That is evidence about units per FRAME -- never in
dispute -- and silent about units per second.
So 60 has NO surviving bracket. It stays because nothing supports 120 either and
moving a shipped timeline on no evidence is worse. That is a default, not a
derivation, and the entry now says so. `kind` is already `authored`.
2. 41 % OF THE REPO PATHS CITED IN MY OWN docs/port/ PROSE DID NOT RESOLVE.
The Decoder observed that everything they hand me links into docs/re/ files that
live only on their branch, so every link they send dangles from here. I turned it
on myself and it was worse than I expected: 37 of 91, in two classes.
19 on their topic branch -- real files, not merged. Not errors, and no one in
this container can fix them; the fix is a merge.
7 resolve NOWHERE: docs/BLOCKED.md, docs/DECISIONS.md, docs/FORMAT.md,
port/manifest.json, port/screens/title/*.json. Left behind by the monorepo
move and the export/ rename. Simply wrong -- a reader following one gets
nothing, and nothing had ever told anyone.
All 7 fixed. audit-kinds checks citations in authored/; nothing checked the
PROSE, which is where this port explains itself.
New: tools/port/check-citations, wired into check-all with its control. It fails
ONLY on the resolve-nowhere class and reports the peer-branch class, because a
check that went red for a state nobody here can change is the shape the display
guard exists to prevent. The --selftest plants a dangling citation and requires it
caught, AND a real one and requires it passed -- both directions, since a scanner
that flagged everything would also "pass" the first.
Not settled: finding 3 has no surviving cause and 60 now has no surviving
derivation either; the ~1.0-1.2 menu residual; pgloading_loop5's residual; the
allowance still waits on its grep trigger.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018AHUQvXGyNcKonSEWsgWcX
107 lines
4.4 KiB
Python
Executable File
107 lines
4.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Do the repo paths cited in `docs/port/*.md` actually resolve?
|
|
|
|
tools/port/check-citations # assert
|
|
tools/port/check-citations --selftest # can it fail?
|
|
|
|
`audit-kinds` checks citations in `authored/`. Nothing checked the PROSE, and
|
|
prose is where this port explains itself. A first run found **37 of 91**
|
|
non-resolving, 41 %, in two very different classes:
|
|
|
|
* **19 on the Decoder's topic branch** — real files, not merged here. Not
|
|
errors. A reader in this checkout still cannot follow them, which is worth
|
|
reporting and not worth failing on; the fix is a merge, not an edit.
|
|
* **7 that resolve NOWHERE** — `docs/BLOCKED.md`, `docs/FORMAT.md`,
|
|
`port/manifest.json`, `port/screens/title/*.json`. Left behind by the
|
|
monorepo move and the `export/` rename. Those are simply wrong: a reader
|
|
following one gets nothing, and nothing had ever told anyone.
|
|
|
|
So the two classes are separated and only the second fails. A check that failed
|
|
on the first would be red for a state nobody in this container can fix, which is
|
|
the shape the display guard exists to prevent.
|
|
|
|
⚠️ THE PEER-BRANCH CLASS IS THE OTHER AGENT'S POINT, TURNED ON MYSELF. They
|
|
observed that everything they hand over links into `docs/re/` files that live
|
|
only on their branch, so every link they send is dangling from here. The same is
|
|
true in reverse and neither of us was counting.
|
|
"""
|
|
import os
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
import glob
|
|
|
|
# A repo path with a file extension, optionally in backticks or a markdown link.
|
|
CITE = re.compile(
|
|
r"`?((?:docs|crates|port|tools|authored|export)/[\w./-]+"
|
|
r"\.(?:md|rs|gd|json|txt|py|tsv|csv))`?"
|
|
)
|
|
PEER_REFS = ("origin/auto/frame-blend-draw-path", "origin/main")
|
|
|
|
|
|
def on_a_ref(path: str) -> str | None:
|
|
"""The first ref that carries `path`, or None."""
|
|
for ref in PEER_REFS:
|
|
if subprocess.run(["git", "cat-file", "-e", f"{ref}:{path}"],
|
|
capture_output=True).returncode == 0:
|
|
return ref
|
|
return None
|
|
|
|
|
|
def scan(files):
|
|
resolves, peer, nowhere = 0, {}, {}
|
|
for p in files:
|
|
try:
|
|
text = open(p, encoding="utf-8").read()
|
|
except OSError:
|
|
continue
|
|
for m in sorted(set(CITE.findall(text))):
|
|
if os.path.exists(m):
|
|
resolves += 1
|
|
elif (ref := on_a_ref(m)):
|
|
peer.setdefault(m, (p, ref))
|
|
else:
|
|
nowhere.setdefault(m, p)
|
|
return resolves, peer, nowhere
|
|
|
|
|
|
def main() -> int:
|
|
if "--selftest" in sys.argv:
|
|
# 🔴 A CHECK THAT CANNOT FAIL IS NOT A CHECK. This plants a citation of a
|
|
# path that exists on no ref and requires the scanner to catch it, and a
|
|
# citation of a real file and requires it NOT to. Both directions,
|
|
# because a scanner that flagged everything would also "pass" the first.
|
|
tmp = os.path.join(os.environ.get("TMPDIR", "/tmp"), "check-citations-selftest")
|
|
os.makedirs(tmp, exist_ok=True)
|
|
bad = os.path.join(tmp, "bad.md")
|
|
open(bad, "w").write("see `docs/port/this-file-does-not-exist-anywhere.md`\n")
|
|
good = os.path.join(tmp, "good.md")
|
|
open(good, "w").write("see `docs/port/PORT-MISSION.md`\n")
|
|
_, _, nb = scan([bad])
|
|
r, _, ng = scan([good])
|
|
ok = len(nb) == 1 and len(ng) == 0 and r == 1
|
|
print("selftest: planted dangling caught=%s, real citation passed=%s -> %s"
|
|
% (len(nb) == 1, len(ng) == 0 and r == 1, "ok" if ok else "🔴 BROKEN"))
|
|
return 0 if ok else 2
|
|
|
|
files = sorted(glob.glob("docs/port/*.md"))
|
|
resolves, peer, nowhere = scan(files)
|
|
total = resolves + len(peer) + len(nowhere)
|
|
print("citations of repo paths in docs/port/*.md: %d" % total)
|
|
print(" resolve here : %d" % resolves)
|
|
print(" on a peer branch, not merged: %d (reported, not failed)" % len(peer))
|
|
for m, (src, ref) in sorted(peer.items()):
|
|
print(" %-52s %s <- %s" % (m, ref.split("/")[-1], os.path.basename(src)))
|
|
if nowhere:
|
|
print(" 🔴 resolve NOWHERE : %d" % len(nowhere))
|
|
for m, src in sorted(nowhere.items()):
|
|
print(" %-52s <- %s" % (m, os.path.basename(src)))
|
|
print("\n🔴 a reader following those gets nothing. Fix the path or drop the citation.")
|
|
return 1
|
|
print(" 🔴 resolve nowhere : 0")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|