protocol: findings before citing code, and checks that were kind once
Two rules that look unrelated and are one failure, plus the change that makes
the second enforceable.
1. A FINDING REACHES `main` BEFORE THE CODE THAT CITES IT. A citation resolving
only on a peer branch is dead the moment it merges. Not hypothetical: 495
decoder and 366 port commits sit off `main`, and `port/scripts/boot.gd`
already cites two docs/re pages present on neither its own branch nor main.
2. A CHECK MAY ONLY SOFTEN AGAINST A CONDITION IT CAN TEST -- the Pi agent's
wording, and better than mine, because it is applicable while writing rather
than a call to be vigilant. The mechanical form:
Can this branch tell the difference between "not yet" and "no longer"?
`gitea-protect --verify` printed ⚪ "not a collaborator (yet)" and continued,
so the only instrument checking Write-not-Admin could not report that gate
being REMOVED. `check-citations` reported peer citations instead of failing
them, because under the old topology that was unfixable from the container.
Both were correct AND kind when written; neither recorded that the kindness
had a scope. Nobody edits these into being wrong -- the world moves and the
allowance stays, which is why they survive review. The smell is leniency with
an expiry date nobody set; the fix is the testable-condition rule.
check-citations gains `--for-merge`, which turns the peer class into a failure.
A flag rather than a new default because BOTH readings are still live: mid-work
on a topic branch the peer class really is unfixable noise. What the old code
could not express is where the code is GOING, and that is a condition the caller
can state. Measured on this tree: 19 citations resolve only on a peer branch --
which is the size of the #7-depends-on-#8 edge, not the 2 I had counted in
boot.gd.
The selftest gains that third class, because a flag whose classification is
unexercised is the shape this rule exists to catch. Controlled: emptying
PEER_REFS makes the peer case collapse into "nowhere" and the selftest reports
🔴 BROKEN, rc=2.
⚠️ Pre-existing and NOT from this change: the default run already exits 1 on 4
citations of `export/...` paths. Those are the generated tree, gitignored by
design, and main's copy of the tool fails identically. The CITE regex treats
`export/` as a repo prefix. Reported, not fixed -- it is the port's file and its
call whether the regex or the citations are wrong.
This commit is contained in:
@@ -77,11 +77,28 @@ def main() -> int:
|
||||
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")
|
||||
# The THIRD class, which `--for-merge` turns into a failure. It has to be
|
||||
# told apart from both others: a peer citation is not dangling (the file
|
||||
# exists) and does not resolve here (the reader still gets nothing), and
|
||||
# a scanner that collapsed it into either would make the flag meaningless
|
||||
# while still passing the two checks above.
|
||||
peerfile = os.path.join(tmp, "peer.md")
|
||||
open(peerfile, "w").write("see `docs/re/f5-a-press-snaps-the-plate.md`\n")
|
||||
rp, pp, np_ = scan([peerfile])
|
||||
|
||||
_, _, 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"))
|
||||
caught = len(nb) == 1
|
||||
passed = len(ng) == 0 and r == 1
|
||||
peer_ok = len(pp) == 1 and rp == 0 and len(np_) == 0
|
||||
ok = caught and passed and peer_ok
|
||||
print("selftest: planted dangling caught=%s, real citation passed=%s, "
|
||||
"peer-branch classed separately=%s -> %s"
|
||||
% (caught, passed, peer_ok, "ok" if ok else "🔴 BROKEN"))
|
||||
if not peer_ok:
|
||||
print(" 🔴 --for-merge cannot mean anything if the peer class is "
|
||||
"not distinguished; got resolves=%d peer=%d nowhere=%d"
|
||||
% (rp, len(pp), len(np_)))
|
||||
return 0 if ok else 2
|
||||
|
||||
files = sorted(glob.glob("docs/port/*.md"))
|
||||
@@ -89,9 +106,30 @@ def main() -> int:
|
||||
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-merge TURNS THE PEER CLASS INTO A FAILURE.
|
||||
#
|
||||
# Reporting-not-failing was right when it was written: a peer-branch
|
||||
# citation was "a state nobody in this container can fix", so failing on it
|
||||
# would have been red for something unactionable. Under the pull-request
|
||||
# workflow that stopped being true -- a PR into `main` is EXACTLY where it
|
||||
# becomes fixable, by opening the finding's PR first and depending on it.
|
||||
# The citation is dead the moment this merges, so the merge is the last
|
||||
# place the leniency can still be withdrawn.
|
||||
#
|
||||
# Left as a flag rather than made unconditional, because both readings are
|
||||
# still live: mid-work on a topic branch the peer class really is unfixable
|
||||
# noise. The difference the old code could not express is WHERE the code is
|
||||
# going, and that is a condition the caller can state.
|
||||
merging = "--for-merge" in sys.argv
|
||||
label = "🔴 FAILS (--for-merge)" if merging else "reported, not failed"
|
||||
print(" on a peer branch, not merged: %d (%s)" % (len(peer), label))
|
||||
for m, (src, ref) in sorted(peer.items()):
|
||||
print(" %-52s %s <- %s" % (m, ref.split("/")[-1], os.path.basename(src)))
|
||||
if peer and merging:
|
||||
print("\n🔴 %d citation(s) resolve only on a peer branch." % len(peer))
|
||||
print(" After this merges they resolve NOWHERE -- the reader gets a dead")
|
||||
print(" path. Land the finding first and make it a dependency of this PR.")
|
||||
return 1
|
||||
if nowhere:
|
||||
print(" 🔴 resolve NOWHERE : %d" % len(nowhere))
|
||||
for m, src in sorted(nowhere.items()):
|
||||
|
||||
Reference in New Issue
Block a user