fix(2242): say why rfcs is exempt, accurately, and stop one anchor describing two repos - #306
fix(2242): say why rfcs is exempt, accurately, and stop one anchor describing two repos#306LukasWodka wants to merge 1 commit into
Conversation
…scribing two repos The `rfcs` block asserted "this repo has no `develop`" in two places. It has one, and it takes merges. Corrected both, without touching the `required` flip that is still blocked on the callers reaching rfcs' default branch. Refs backend#2242, tracebloc/rfcs#41 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 96ef1e0. Configure here.
saadqbal
left a comment
There was a problem hiding this comment.
The correction is right and I'd take it — but not approving while audit and gate are red, and there's an ordering point in your own note that I think has a hole.
On the red: it isn't this diff. The audit reports two findings, both of the form <repo>: stale-backlog.yml is marked \exempt` but a caller exists (stale-backlog-caller.yml). The exemption is stale—claude-skillsanddocs, the two wave callers that had merged when this ran. That's the transient window .github#307predicts, and it closes with.github#293's flip. audit` is fleet-wide, so any PR in this repo is red while the wave is mid-migration; this one is collateral. Sequence is #307 → #293, then re-run here.
On the substance: the anchor correction checks out, and the measurement is corroborated from the other side. rfcs does have a develop that takes merges — rfcs#41's own README change cites the same split from the same date (#32–#36, #38 to develop; #37, #39, #40 to main), so two independent PRs measured it identically. One anchor describing both rfcs and release-train was genuinely wrong, and develop_unprotected_non_train is the accurate one. Recording that no check could have surfaced this — because no_develop_branch_single_branch_repo's own text admits it can't tell an unprotected develop from an absent one — is the right way to mark human-only work.
Restating the board exemption from "structural" to "staged" is also the honest fix: "no deploy stages" was true but argued about which Status to write, not whether a card should move, and cards were dying in Code review precisely because the caller was absent.
The hole, and it's why I'm writing rather than just waiting. Your flip note says to flip once rfcs#41 "has reached rfcs' DEFAULT branch, which is main". Measured just now: rfcs's default branch is indeed main — and rfcs#41 targets develop. So merging #41 as it stands puts the callers and .kanban.yml on develop only, the audited branch still won't carry them, and the flip stays blocked with no obvious sign of why. Given #41's own .kanban.yml comment says the file is fetched per branch, it needs to exist on main as well for a merge into main to map at all.
Worth stating in one place, because rfcs#41 now has two upstream constraints and one downstream: it needs .github#304 on main first (ENV_FOR_STATUS doesn't declare Done yet — I raised that over there), and it needs to reach rfcs's main before this entry can flip. None of the three PRs says all three things.
saqlainsyed007
left a comment
There was a problem hiding this comment.
The diff itself is clean and I have nothing to change in it — this is a
comment, not a change request. But I can't approve while audit/gate are red,
so flagging why they're red and what clears it.
The red audit is not from anything in this PR. The 2 caller-drift findings are:
claude-skills: stale-backlog.yml is marked exempt but a caller exists…docs: stale-backlog.yml is marked exempt but a caller exists…
Both are about other repos (claude-skills, docs), not rfcs. This PR's hunks
are confined to the rfcs block and flip nothing to required, so it cannot
itself produce caller-drift. Those two are the mid-migration exempt-with-a-caller
drift that #293 closes (it flips all 17 migration entries to required). Once
#293 lands, those findings disappear and this PR's audit/gate go green.
On the diff's substance: swapping *no_develop_branch_single_branch_repo →
*develop_unprotected_non_train for rfcs is the accurate call — that anchor was
one reason describing two different repos, correct for release-train (no develop
at all) and false for rfcs (which has a develop that takes merges). Restating the
advance-deploy-env / kanban-closure-router reasons as STAGED-not-structural,
while keeping them exempt until rfcs#41's callers reach rfcs' default branch, is
the right sequencing and matches the "land the caller first, flip after" rule.
No change requested. I'll approve once CI is green (i.e. after #293 merges).
Follow-up to backend#2242. Corrects two exemption reasons in the
rfcsblock that were factually wrong, and records the bookkeeping the eventual flip will need. It deliberately does not do the flip.The flip is not here, and cannot be yet
rfcs' two board callers stayexempt. Flipping them torequiredneeds the callers on rfcs' default branch —audit_branch: develop-first-on-trainaudits a non-train repo on its default branch, andrfcs' default ismain. Measured today:tracebloc/rfcs#41is open, not merged, and neitheradvance-deploy-env.ymlnorkanban-closure-routing.ymlexists on rfcs'developormain(404 on all four reads). This file's own header says it: land the caller first, flip the entry after.So the flip is a later PR, gated on rfcs#41 — which is itself gated on
.github#304reaching.github'smain.1.
protection: develop:cited an anchor that describes a different repoIt read
exempt: *no_develop_branch_single_branch_repo— "single-branch repo:mainis the only integration branch, so there is nodevelopto protect."rfcshas adevelop, and it receives merges. Measured 2026-08-22: #32, #33, #34, #35, #36 and #38 merged intodevelop; #37, #39 and #40 went tomain.That anchor is cited twice. For
release-trainit is correct — nodevelopat all (404), defaultmain. Forrfcsit was false. One anchor was describing two different situations, and the wrong half read as decided.The accurate anchor already existed and needed no new prose:
develop_unprotected_non_train— "developexists but carries no branch protection, and the repo is not on the train so nothing promotes out of it. UNREMEDIATED." Verified that isrfcsexactly:developexists, classic protection returns 404, andrules/branches/developreturns zero matching rules.No check was ever going to find this.
no_develop_branch_single_branch_repo's own text says so: "the guard flags an exemption when the role's branch appears AND carries protection. Adevelopcreated and left UNPROTECTED is not flagged — the checker cannot distinguish that fromdevelop_unprotected_non_train." The blind spot was documented, and this is a case that fell into it.2. The
advance-deploy-env.ymlreason was half false, and the true half didn't support itIt read: "this repo has no
developand no deploy stages — it ismain-only by decision, so there is no dev stage for a card to advance INTO. Structural, not a gap."develop" — false, per the measurement above.stagingbranch; nothing deploys), but that is an argument about which Status to write, not about whether a card should move at all. Cards were dying inCode reviewprecisely because this caller was absent.Restated as what it actually is: STAGED, not structural. rfcs#41 adds both callers plus a
.kanban.ymlmappingdevelopandmaintoDone, so a merge there writes the terminal Status that "deploys nothing" actually implies, rather than a deploy state it never reaches.The new comment carries the flip condition, the ordering reason, and a self-destruct clause modelled on
stale_backlog_migration_in_flight: if the note outlives rfcs#41 reachingmain, it has stopped being a sequencing note and become a written excuse — treat it as a defect then.3. Anchor bookkeeping for whoever does the flip
Measured on non-comment lines:
kanban_closure_router_caller_missingrfcscustomer_priority_bump_caller_missingno_develop_branch_single_branch_reporelease-train)develop_unprotected_non_trainrfcs)Nothing will tell you if you forget. No check flags an orphaned YAML anchor — measured. And
stale_exemptions()inkanban-columns-check.py, which looks like the relevant guard, is a different mechanism: it governs workflow files that name board columns, not this file's anchors. So it does not cover the case at all. Recorded in-file next to the entry rather than only here.Verification
make check→ EXIT=0 (80 passed, 0 failed), includingselftest-caller-drift.set-pr-status.yml: requiredre-read as an untouched control.caller-drift.pyrun against the real fleet with this inventory:rfcsrow is| rfcs | - | OK | OK | OK | OK | OK |— clean, and unchanged from baseline.*anchorfrom one of my own comments after noticing it inflated every citation grep by one, including the grep I was using to produce the table above.One caveat about this PR's own
gatecheckConformance gateis a required context ondevelopand demands the audit for a PR that touches this contract — which this one does. The audit is currently red for reasons unrelated to this diff: the backend#1979 caller wave is landing right now, and each merged caller creates a transientexempt-but-caller-exists finding until.github#293flips those entries torequired.claude-skills#31anddocs#131merged at 18:30 today, producing exactly two such findings.I verified this is not caused by this diff by running the audit with and without these changes: both report the identical two findings, and both name only
claude-skillsanddocs. Expect this PR'sgateto stay red, with a growing count, until the wave completes and #293 lands — which is the drift window thestale_backlog_migration_in_flightanchor was written to bound.Note
Low Risk
Inventory comment and exemption-reason edits only; caller required/exempt status is unchanged, so fleet audit behavior should not shift. The file is the org contract, but this PR is documentation of measured state, not a policy flip.
Overview
Corrects factually wrong
rfcsexemptions inrepo-inventory.yml. Does not flip any caller torequired.protection.developnow cites*develop_unprotected_non_traininstead of*no_develop_branch_single_branch_repo.rfcshas an unprotecteddevelopthat receives merges; the old anchor is only true forrelease-train.advance-deploy-env.ymlis restated as STAGED (awaitingrfcs#41on defaultmain), not as a structural “no develop / no deploy” gap. Comments on that entry andkanban-closure-router.ymlrecord the later flip order and that the closure-router missing-caller anchor must be deleted when it becomes uncited.Reviewed by Cursor Bugbot for commit 96ef1e0. Bugbot is set up for automated code reviews on this repo. Configure here.