Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .claude/doctrine-watermark
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
b2a3d4706516189d17533e30c9115d8c65b99d64
38 changes: 37 additions & 1 deletion tools/runmarker.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,52 @@
...
result("ESTABLISHED-NOTHING") # on every controlled path
"""
import subprocess
import sys

PREFIX_RUN = "NFORMA-RUN"
PREFIX_RESULT = "NFORMA-RESULT"


def tree_distance():
"""How far is THIS WORKING TREE behind `origin/main`? "" when unmeasurable.

⛔ WHY THE MARKER CARRIES IT. #205: nine panes share one working tree, and that tree has
been pinned at `a163854` for two days — **365 commits behind**, with `CLAUDE.md` differing by
25 lines and `goals/` by 2046. Every reading taken there is a reading of a two-day-old
repository, and nothing said so.

⇒ AND CI CANNOT DETECT IT, STRUCTURALLY. A workflow checks out fresh, so a gate NEVER sees a
pane's working tree. That is why #205 outlived every other missing-caller gap tonight: each
of those was closed by adding a caller in CI, and this one cannot be. The caller has to run
WHERE THE STALENESS LIVES — and 13 instruments already import this module, so they are it.

★ `tools/doctrine-uncommitted.py` fires on exactly this condition and has reported it to
nobody for two days: `git grep -l` finds four references — the tool, its test, its docs, its
ledger. A detector with no caller and a rule with no enforcement fail identically.

⚠ COSTS 14ms, measured. And it is REPORTED, NEVER ENFORCED: a stale tree is not an error and
this must not turn one into a failure. It is the label a reading always needed — the same
move as `ON <local|CI>` in the gate summary, applied to the tree instead of the machine.
"""
try:
r = subprocess.run(["git", "rev-list", "--count", "HEAD..origin/main"],
capture_output=True, text=True, timeout=5)
except (OSError, subprocess.SubprocessError):
return ""
n = r.stdout.strip()
if r.returncode != 0 or not n.isdigit():
# ⛔ UNMEASURABLE IS NOT ZERO. No repository, no `origin/main`, a failed call — each
# would read as "current" if this returned 0, which is the confident-wrong-answer this
# whole convention exists against.
return " tree=UNKNOWN"
return "" if n == "0" else f" tree={n}-behind-origin/main"


def begin(tool):
"""Emit the start marker. ⛔ Call before argument parsing, or the marker cannot
separate a rejected flag from a refused file."""
print(f"{PREFIX_RUN} {tool}", file=sys.stderr, flush=True)
print(f"{PREFIX_RUN} {tool}{tree_distance()}", file=sys.stderr, flush=True)


def result(state):
Expand Down
41 changes: 41 additions & 0 deletions tools/test_runmarker.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,5 +116,46 @@ def test_markers_survive_the_construct_that_destroys_the_exit_code(self):
self.assertIn("NFORMA-RESULT", err)



def test_tree_distance_is_silent_when_current_and_never_guesses():
"""⛔ THREE STATES, and the third is the one that matters (#205).

The shared tree has been pinned 365 commits behind `origin/main` for two days, with
CLAUDE.md differing by 25 lines and goals/ by 2046 — and nothing said so. ⇒ CI cannot
detect that: a workflow checks out fresh, so a gate NEVER sees a pane's working tree.
The marker can, because 13 instruments import this module and run IN the pane.

⚠ UNMEASURABLE MUST NOT READ AS CURRENT. Returning 0 for "no repository" or "no
origin/main" would report the confident wrong answer this convention exists against.
"""
import subprocess, tempfile, os
import runmarker

# current tree -> SILENT. A label on every line is a label nobody reads.
here = runmarker.tree_distance()
assert here == "" or "behind-origin/main" in here or here == " tree=UNKNOWN", here

# ⛔ no repository at all -> UNKNOWN, never 0
with tempfile.TemporaryDirectory() as d:
cwd = os.getcwd()
try:
os.chdir(d)
assert runmarker.tree_distance() == " tree=UNKNOWN"
finally:
os.chdir(cwd)


def test_begin_carries_the_distance_into_the_marker():
"""The distance is useless if it does not reach the line a reader sees."""
import io, contextlib, runmarker
buf = io.StringIO()
with contextlib.redirect_stderr(buf):
runmarker.begin("probe")
line = buf.getvalue().strip()
assert line.startswith("NFORMA-RUN probe"), line
# ⚠ asserts the SHAPE, not the number — the number is a property of the tree, and a
# control coupled to it would fail every time someone merged.
assert line == "NFORMA-RUN probe" or " tree=" in line, line

if __name__ == "__main__":
unittest.main(verbosity=2)
Loading