Files
Sylpheed/tools/stale-instrument
MechaCat02 3e60560344 register: reclassify under R1 -- name every instrument, re-open the ten our own killed
Both agents asked for this and neither could do it: the register is the file
they both read to decide what NOT to try, so two agents agreeing is not the
authority for changing it (RETRO-2026-08-31-agreed §7.1).

R1: a refutation whose instrument is one of our renderers is not a refutation,
it is "our renderer disagrees" -- 🟡, not . The motivating case was not
careless work. "Blending those sprites additively worsens every measure against
the capture" killed a real disc field for weeks, and read exactly like a
publishable negative; the renderer behind it had a stale keyframe association,
no leaf geometry and no rotation. Nothing in the entry could have told you.

All 222 entries now end with ⟨instrument⟩, read off each entry's OWN stated
evidence -- never inferred. An entry that states none gets `unrecorded`, which
is 83 of them.

Ten moved  -> 🟡, each naming what would settle it: 8 render-vs-capture,
1 our-reader, 1 harness.

Three things the pass turned up:

* The rest() question is OPEN and had been reading as settled in both
  directions -- "rest = last keyframe" was refuted by a sibling argument, and
  that refutation refuted by correlating our render against captures. Both legs
  are our renderer. Which one you believed depended on which entry you found
  first, and it decides the pose every plateau-less element is drawn at.
* A withdrawal never reached its sibling: "2 391 frames, max glyph 0" was
  withdrawn because a long-lived x11grab stream freezes and repeats a stale
  frame; the 1 674-sample negative three lines above it, same probe, was left
  standing as a reinstated measurement.
* 83 of 222 -- 37 % -- record no instrument at all. Not disputed, not safe:
  unauditable, and larger than every other group combined.

tools/stale-instrument is the --stale query the rule needs, because a colour
alone re-opens nothing: the failure was that nothing re-opened a claim when the
instrument that killed it improved. Its own --check found a real bug on the
first run -- sys.exit("text") exits 1, so three faults documented as exit 2
were reporting the same code as an ordinary miss.

R1 is now standing text in PROTOCOL.md, with R5's exception: our tool is the
right instrument for a question about our tool.
2026-09-01 17:21:17 +02:00

256 lines
10 KiB
Python
Executable File

#!/usr/bin/env python3
"""What did this instrument kill? -- the re-open query for `docs/re/REFUTED.md`.
tools/stale-instrument everything, grouped
tools/stale-instrument render-vs-capture what one instrument killed
tools/stale-instrument --ours only instruments that are ours
tools/stale-instrument --check self-test; exits non-zero if broken
Why this exists
---------------
Rule R1. A refutation whose instrument is one of our renderers is not a
refutation -- it is *"our renderer disagrees"*. The register carries that as a
🟡, but a colour alone does not re-open anything: the failure it is there to
prevent was a real disc field sitting dead for weeks because **nothing re-opens a
claim when the instrument that killed it improves.**
So this is the query you run *after* you fix a renderer, a reader or the harness.
It answers "what did I just invalidate?" in one command, instead of relying on
someone remembering which of 222 entries rested on the thing they changed.
The register is the only source. There is no second list to drift out of sync
with it -- the tags live at the end of each entry, in the file people actually
read, which is this corpus's own repeatedly-learned lesson about where a fact has
to live to exist.
"""
from __future__ import annotations
import os
import re
import sys
from collections import OrderedDict
REGISTER = os.environ.get("SYLPH_REGISTER", "docs/re/REFUTED.md")
# Ours, in the sense R1 means: an instrument whose defects we cannot rule out,
# because we built it. `our-tool` is ours too, but it is not disqualifying --
# see the note below and in the register's reading guide.
OURS = {"render-vs-capture", "screen-render", "our-reader", "harness", "our-tool"}
# Not a verdict. It means nobody recorded how the claim died.
UNRECORDED = "unrecorded"
TAG = re.compile(r"⟨([a-z][a-z-]*)⟩\s*$")
def entries(text: str):
"""Every bullet, with its instrument tag and whether it is already 🟡.
An entry is a `* ` bullet plus its continuation lines, ending at a blank
line or a heading -- the same span rule the register's own enumeration uses.
"""
out, cur, start = [], None, 0
for i, line in enumerate(text.split("\n"), 1):
if line.startswith("* "):
if cur is not None:
out.append((start, cur))
cur, start = [line], i
elif line.startswith("#"):
if cur is not None:
out.append((start, cur))
cur = None
elif cur is not None:
if not line.strip():
out.append((start, cur))
cur = None
else:
cur.append(line)
if cur is not None:
out.append((start, cur))
for ln, body in out:
joined = " ".join(x.strip() for x in body)
m = TAG.search(body[-1].rstrip())
# 🔴 THE VERDICT IS THE LEADING GLYPH, NOT ANY 🟡 IN THE ENTRY. Matching
# anywhere counted four entries as re-opened that merely carry an inline
# 🟡 caveat mid-sentence ("🟡 a third recorded run implies NEW GAME").
# An entry whose verdict is ❌ and whose *reach* is qualified is not an
# open claim, and reporting it as one inflates exactly the number this
# tool exists to make trustworthy.
yield {
"line": ln,
"instrument": m.group(1) if m else None,
"open": body[0].startswith("* 🟡"),
"settled": body[0].startswith("* ✅"),
"text": re.sub(r"\s+", " ", joined),
}
def summary(text: str) -> str:
"""The claim, short enough to scan a list of them."""
t = re.sub(r"^\*\s*(🟡|❌|✅)?\s*", "", text)
t = re.sub(r"[*`~]", "", t)
return (t[:118] + "") if len(t) > 118 else t
def die(msg: str):
"""A HARNESS fault, exit 2 -- distinct from 'no such instrument', exit 1.
🔴 `sys.exit("text")` exits **1**, not 2. Every one of these sites used it,
so three faults that this file's own docstring calls exit-2 were reporting
the same code as an ordinary miss -- a real failure wearing a wrong
diagnosis, the exact shape the register catalogues elsewhere. Its own
`--check` caught it on the first run, which is the argument for having one.
"""
print(msg, file=sys.stderr)
raise SystemExit(2)
def load():
if not os.path.exists(REGISTER):
die(
f"stale-instrument: {REGISTER} is not here.\n"
" Run from the repository root, or set SYLPH_REGISTER.\n"
" Exit 2: the harness is broken, not the corpus."
)
rows = list(entries(open(REGISTER, encoding="utf-8").read()))
# 🔴 LIVENESS. A reader that parses nothing reports "no claims rest on that
# instrument" -- which reads exactly like the good news you were hoping for.
# A renamed file, a changed bullet shape or a lost tag all produce it. This
# corpus has already produced one false zero from a reader invented minutes
# earlier, so the empty case is a harness fault with its own exit code.
if not rows:
die("stale-instrument: parsed 0 entries from "
f"{REGISTER} -- exit 2, the reader is broken.")
if not any(r["instrument"] for r in rows):
die(f"stale-instrument: {len(rows)} entries, none tagged ⟨…⟩ -- "
"exit 2, the reader is broken or the register is untagged.")
return rows
def main(argv: list[str]) -> int:
if "--check" in argv:
return selftest()
rows = load()
only_ours = "--ours" in argv
wanted = [a for a in argv if not a.startswith("-")]
by = OrderedDict()
for r in rows:
by.setdefault(r["instrument"] or UNRECORDED, []).append(r)
if wanted:
name = wanted[0]
if name not in by:
print(f"no entry names ⟨{name}⟩. Known instruments:")
for k in sorted(by):
print(f" {k}")
return 1
group = by[name]
mine = " -- OURS, so these are re-openable" if name in OURS else ""
print(f"{name}⟩ killed {len(group)} claim(s){mine}\n")
for r in group:
mark = "🟡" if r["open"] else ("" if r["settled"] else "")
print(f" {mark} L{r['line']:<4} {summary(r['text'])}")
if name in OURS:
print(f"\n If you have improved {name}, every ❌ above is a claim that"
"\n died to an instrument that no longer exists in that form.")
return 0
print(f"{len(rows)} entries in {REGISTER}\n")
order = sorted(by, key=lambda k: (k not in OURS, k == UNRECORDED, -len(by[k])))
for k in order:
g = by[k]
tag = " ← OURS" if k in OURS else (" ← nobody wrote it down"
if k == UNRECORDED else "")
opened = sum(1 for r in g if r["open"])
note = f", {opened} already 🟡" if opened else ""
print(f" {k:20s} {len(g):3d} claim(s){note}{tag}")
ours = sum(len(by[k]) for k in by if k in OURS)
unrec = len(by.get(UNRECORDED, []))
print(f"\n {ours} claim(s) died to an instrument WE BUILT.")
print(f" {unrec} claim(s) record no instrument at all -- "
"neither safe nor suspect,\n just unauditable. That is the backfill queue.")
print("\n tools/stale-instrument <instrument> to list one")
return 0
def selftest() -> int:
"""Cases that must hold, executed -- not reasoned about.
A control that does not run is not a control; this file's neighbours in
`tools/` say so about other people's tools, so it is asserted here.
"""
import subprocess
import tempfile
me = os.path.abspath(__file__)
ok = 0
def run(reg, args=()):
env = dict(os.environ, SYLPH_REGISTER=reg)
p = subprocess.run([sys.executable, me, *args], capture_output=True,
text=True, env=env)
return p.returncode, p.stdout + p.stderr
with tempfile.TemporaryDirectory() as d:
good = os.path.join(d, "good.md")
open(good, "w", encoding="utf-8").write(
'* "a" → refuted. ⟨disc⟩\n\n* 🟡 "b" — our renderer disagrees. ⟨render-vs-capture⟩\n'
)
cases = [
("a tagged register parses", (good, ()), 0, "2 entries"),
("one instrument lists", (good, ("disc",)), 0, '"a"'),
("an OURS instrument says so", (good, ("render-vs-capture",)),
0, "re-openable"),
("an unknown instrument fails", (good, ("nope",)), 1, "no entry names"),
]
for name, (reg, args), want_rc, want_txt in cases:
rc, out = run(reg, args)
good_rc = rc == want_rc
good_tx = want_txt in out
if good_rc and good_tx:
print(f" {name:34s} exit {rc}")
else:
print(f" {name:34s} exit {rc} (wanted {want_rc}), "
f"text {'found' if good_tx else 'MISSING'} 🔴")
ok = 1
# The two harness faults, which must be distinguishable from a clean run.
empty = os.path.join(d, "empty.md")
open(empty, "w").write("# nothing here\n")
rc, out = run(empty)
if rc == 2 and "reader is broken" in out:
print(f" {'an empty register is a fault':34s} exit 2 ✅")
else:
print(f" {'an empty register is a fault':34s} exit {rc}, wanted 2 🔴")
ok = 1
untagged = os.path.join(d, "untagged.md")
open(untagged, "w", encoding="utf-8").write('* "a" → refuted.\n')
rc, out = run(untagged)
if rc == 2 and "none tagged" in out:
print(f" {'an untagged register is a fault':34s} exit 2 ✅")
else:
print(f" {'an untagged register is a fault':34s} exit {rc}, wanted 2 🔴")
ok = 1
rc, _ = run(os.path.join(d, "does-not-exist.md"))
if rc == 2:
print(f" {'a missing register is a fault':34s} exit 2 ✅")
else:
print(f" {'a missing register is a fault':34s} exit {rc}, wanted 2 🔴")
ok = 1
print()
print("the query fails when it must, and says so distinctly" if not ok
else "🔴 the query's own control is broken")
return ok
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))