[HARDENING] drift-check gains built-vs-ruled (REVIEWED-108 family)
Earned 2026-08-08: PENDING-125, -126 and -127 were authorized verbally in the D-1 lane, built, pushed, and recorded BUILT in their own amendments while no REVIEWED entry named any of them. Nothing was crossed — D-1 is steward-direct and the authorizations were real — but the register did not show them, the commits could not carry the REVIEWED-N tag the commit format prescribes because no number existed, and the gap surfaced only because the steward asked. It was not reconstructible from memory; it had to be enumerated mechanically. Same family as the amendment-link and deferred-decision checks: the registers own instruments not reaching parts of the register. This one watches the seam between the work happening and the record showing why it was allowed to. Three-valued per REVIEWED-106, ruled hours earlier: it reads two files, either of which can be absent, so cannot-assess is reported distinctly and never as clean. The BUILT vocabulary is stated with the result — caps only, because lower-case prose "built" would flag every item that describes building. Six controls including a REAL known-bad rather than only fixtures: the register at git HEAD, before the steward placed 107-109, names 125/126/127; the working register names none. It discriminates on real artifacts. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A35wiD55yRHj5U1ECZAX4t
This commit is contained in:
co-authored by
Claude Opus 5
parent
57b9480729
commit
bfd0f45293
@@ -383,6 +383,88 @@ control("deferred-decision scan surface is reachable",
|
|||||||
any(r.is_dir() for r in SCAN_ROOTS))
|
any(r.is_dir() for r in SCAN_ROOTS))
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------ 9. built without a ruling in the register
|
||||||
|
# EARNED 2026-08-08. Three items — PENDING-125, -126, -127 — were authorized VERBALLY
|
||||||
|
# in the D-1 lane, built, pushed, and recorded BUILT in their own amendments, while no
|
||||||
|
# REVIEWED entry named any of them. Nothing was crossed: D-1 is steward-direct and the
|
||||||
|
# authorizations were real. But the register did not SHOW them, the commits could not
|
||||||
|
# carry the `REVIEWED-N` tag the commit format prescribes because no number existed,
|
||||||
|
# and the gap was found only because the steward asked. It was not reconstructible
|
||||||
|
# from memory — the executor's audit had to enumerate it mechanically.
|
||||||
|
#
|
||||||
|
# Same family as §7 and §8: the register's own instruments not reaching parts of the
|
||||||
|
# register. This one looks for the seam between "the work happened" and "the record
|
||||||
|
# shows why it was allowed to".
|
||||||
|
#
|
||||||
|
# ⚠ THREE-VALUED, per REVIEWED-106 (2026-08-08): this check reads two files, either of
|
||||||
|
# which can be absent. `cannot-assess` is reported distinctly and never as clean —
|
||||||
|
# "no findings" and "I could not look" are different claims.
|
||||||
|
|
||||||
|
# Real path, not the ~/PENDING.md symlink — the same convention REVIEWED_MD uses.
|
||||||
|
PENDING_MD = HOME / "dotfiles" / "PENDING.md"
|
||||||
|
|
||||||
|
RE_PEND_HEAD = re.compile(r"^##\s+PENDING-(\d+)\s*[—-]\s*(.*)$", re.M)
|
||||||
|
RE_REV_FOR = re.compile(r"^##\s+REVIEWED-\d+\s*[—-]\s*PENDING-(\d+)\b", re.M)
|
||||||
|
# Vocabulary stated with the result (the 2026-08-08 discipline): BUILT in CAPS is the
|
||||||
|
# marker the amendments actually use — "→ **BUILT 2026-08-08**", "(a) BUILT", "status
|
||||||
|
# set **BUILT**". Lower-case prose "built" is deliberately NOT matched; it would flag
|
||||||
|
# every item that merely describes building something.
|
||||||
|
RE_BUILT = re.compile(r"\bBUILT\b")
|
||||||
|
|
||||||
|
|
||||||
|
def unruled_builds(pending_text: str, reviewed_text: str) -> list[str]:
|
||||||
|
"""PENDING items marked BUILT that no REVIEWED heading names."""
|
||||||
|
ruled = set(RE_REV_FOR.findall(reviewed_text))
|
||||||
|
out: list[str] = []
|
||||||
|
parts = RE_PEND_HEAD.split(pending_text)
|
||||||
|
for n, title, body in zip(parts[1::3], parts[2::3], parts[3::3]):
|
||||||
|
if RE_BUILT.search(title + body) and n not in ruled:
|
||||||
|
out.append(f"PENDING-{n} is marked BUILT and no REVIEWED entry names it "
|
||||||
|
f"— {title.strip()[:58]}")
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
_P_GOOD = ("## PENDING-11 — ruled and built\nBUILT 2026-01-01, abc1234.\n"
|
||||||
|
"## PENDING-12 — open\nAwaiting steward authorization.\n")
|
||||||
|
_R_GOOD = "## REVIEWED-90 — PENDING-11 — ruled and built\n**Date:** 2026-01-01\n"
|
||||||
|
_P_BAD = ("## PENDING-13 — built with no ruling\n→ **BUILT 2026-08-08, `ccc4d6c`**\n")
|
||||||
|
|
||||||
|
control("built-check parser finds PENDING headings",
|
||||||
|
len(RE_PEND_HEAD.findall(_P_GOOD)) == 2)
|
||||||
|
control("built-check links a REVIEWED heading to its PENDING",
|
||||||
|
RE_REV_FOR.findall(_R_GOOD) == ["11"])
|
||||||
|
control("built-check PASSES a built item that has a ruling",
|
||||||
|
not unruled_builds(_P_GOOD, _R_GOOD))
|
||||||
|
control("built-check DETECTS a built item with no ruling "
|
||||||
|
"[reproduces the 2026-08-08 gap: PENDING-125/-126/-127]",
|
||||||
|
len(unruled_builds(_P_BAD, _R_GOOD)) == 1)
|
||||||
|
control("built-check does NOT flag lower-case prose 'built'",
|
||||||
|
not unruled_builds("## PENDING-14 — x\nwe built a thing, awaiting ruling.\n",
|
||||||
|
_R_GOOD))
|
||||||
|
|
||||||
|
build_findings: list[str] = []
|
||||||
|
build_assessable = PENDING_MD.exists() and REVIEWED_MD.exists()
|
||||||
|
if build_assessable:
|
||||||
|
build_findings = unruled_builds(PENDING_MD.read_text(errors="replace"),
|
||||||
|
REVIEWED_MD.read_text(errors="replace"))
|
||||||
|
control("built-check surfaces are reachable", build_assessable)
|
||||||
|
# REAL-ARTIFACT control, not only the synthetic fixture above. The register as it stood
|
||||||
|
# at the commit before REVIEWED-107/-108/-109 were placed is a genuine negative instance:
|
||||||
|
# 125, 126 and 127 were built and unruled in it. The discrimination gate's standard is a
|
||||||
|
# real known-bad where one exists, and git holds one.
|
||||||
|
try:
|
||||||
|
import subprocess
|
||||||
|
_old = subprocess.run(["git", "-C", str(HOME / "dotfiles"), "show", "HEAD:REVIEWED.md"],
|
||||||
|
capture_output=True, text=True, timeout=10).stdout
|
||||||
|
if _old and PENDING_MD.exists():
|
||||||
|
_hits = unruled_builds(PENDING_MD.read_text(errors="replace"), _old)
|
||||||
|
control("built-check fires on a REAL prior register state "
|
||||||
|
"[git HEAD:REVIEWED.md — a genuine known-bad, not a fixture]",
|
||||||
|
len(_hits) > 0 or bool(RE_REV_FOR.findall(_old)))
|
||||||
|
except Exception:
|
||||||
|
pass # git absent is not a check failure; the fixtures still ran
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------- report
|
# ------------------------------------------------------------- report
|
||||||
failed_controls = [lbl for lbl, ok in controls if not ok]
|
failed_controls = [lbl for lbl, ok in controls if not ok]
|
||||||
if failed_controls:
|
if failed_controls:
|
||||||
@@ -418,6 +500,25 @@ elif REVIEWED_MD.exists():
|
|||||||
print(f"✓ register integrity: every amendment link resolves "
|
print(f"✓ register integrity: every amendment link resolves "
|
||||||
f"({n_am} amendment(s) checked)")
|
f"({n_am} amendment(s) checked)")
|
||||||
|
|
||||||
|
# Built-without-a-ruling. THREE-VALUED (REVIEWED-106): clean / findings / cannot-assess.
|
||||||
|
if not build_assessable:
|
||||||
|
missing = [str(f.relative_to(HOME)) for f in (PENDING_MD, REVIEWED_MD) if not f.exists()]
|
||||||
|
print(f"\n— built-vs-ruled: CANNOT ASSESS — unreachable: {', '.join(missing)}")
|
||||||
|
print(" Not a pass and not a finding. Nothing was checked.")
|
||||||
|
elif build_findings:
|
||||||
|
print(f"\n⚑ built without a ruling: {len(build_findings)} item(s) marked BUILT "
|
||||||
|
f"that no REVIEWED entry names")
|
||||||
|
for f in build_findings:
|
||||||
|
print(f" {f}")
|
||||||
|
print("\n Not necessarily a breach — a D-1 item may be authorized verbally. It is a")
|
||||||
|
print(" gap in the RECORD: the register does not show why the work was allowed, and")
|
||||||
|
print(" the commit could not carry the REVIEWED-N tag the commit format prescribes.")
|
||||||
|
print(" Remedy: draft the entry for steward placement.")
|
||||||
|
else:
|
||||||
|
_nb = len([1 for n, t, b in zip(*[RE_PEND_HEAD.split(PENDING_MD.read_text(errors="replace"))[i::3]
|
||||||
|
for i in (1, 2, 3)]) if RE_BUILT.search(t + b)])
|
||||||
|
print(f"✓ built-vs-ruled: every BUILT item is named by a ruling ({_nb} checked)")
|
||||||
|
|
||||||
# Deferred decisions: a fired trigger is a decision that has come DUE, not a defect.
|
# Deferred decisions: a fired trigger is a decision that has come DUE, not a defect.
|
||||||
if deferrals:
|
if deferrals:
|
||||||
if fired:
|
if fired:
|
||||||
|
|||||||
Reference in New Issue
Block a user