Uh oh!
There was an error while loading. Please reload this page.
ci: teach every rank table to READ the agent column (backend#1577) - #200
Merged
Conversation
Hop 1 of RFC-BACKEND-1552 D5: reads before writes, in separate hops, because org-github's callers are pinned @main and both old and new callee code are live during a promotion of the reusables. THIS WAS ALREADY A LIVE LANDMINE. `Staging (agent review)` EXISTS on project 2 today (added by the #1592 rename) and NO rank table knew it. rank() returned "", the `[ -n "$SR" ]` guard failed, evaluation fell through to strict equality, and the card would have BLOCKED every prod promotion carrying it -- the backend#1411 shape. Measured: 633 board items scanned, zero currently in that column, so it was armed and waiting rather than firing. fr-gate.yml rank 7, FR->8, Ready for prod->9, Prod->10, terminals->11 advance-deploy-env.yml same, plus the agent column maps to the `staging` deploy environment if a card is dragged there by hand kanban-reconcile.yml the agent column joins its sibling post-merge columns, so an OPEN issue drifting there goes back to Backlog like it would from `On dev` Renumbering is safe: every comparison is relative (`rank(a) >= rank(b)`, and TARGET_RANK is itself `$(rank ...)`), with no hardcoded rank literals anywhere. Checked before touching the numbers. Caught while renumbering: Prod moved to 10 and collided with the terminals, also 10. Terminals must rank STRICTLY above Prod or the no-demotion guard weakens. Bumped to 11. READ ONLY -- nothing writes this Status yet. That is #1578, deliberately a later hop, and it must not land before the agent can produce a verdict or cards park in a column nothing advances. Verified: agent column vs required "On dev" -> PASS agent column vs required "Ready for prod" -> BLOCKED an unknown column -> BLOCKED (still fails closed) actionlint clean on all three; standards selftest 20/20. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit d7f44ba. Configure here.
Uh oh!
There was an error while loading. Please reload this page.
Bugbot (#200): the classify case I added for `Staging (agent review)` was DEAD CODE. The non-terminal pull filter that populates items.ndjson never listed the column, so cards there were filtered out before classification ran. That is the exact shape this whole session has been auditing -- a guard exists, nothing reaches it -- and I shipped one while writing the audit. Found by reading rather than reported: a SECOND omission at the closed-completed case. A closed issue in the agent column fell through to `*)` and was marked Done, overwriting a deploy state -- precisely what its sibling list exists to prevent (D8: a deploy state is not Done, follow the PR's stage). Swept every column list in the file. The one remaining absence is DELIBERATE: the `CLOSER_BASE` mapping at ~L426 is a WRITER (branch -> destination column), and hop 1 is read-only. That belongs to #1578. actionlint clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
shujaatTracebloc
approved these changes
Aug 10, 2026
Uh oh!
There was an error while loading. Please reload this page.
3 tasks
LukasWodka added a commit
that referenced
this pull request
Aug 10, 2026
Same artifact as .github#204, removed on this branch as well. This branch was cut after #200, so it carries the file; without this, merging #197 after #204 would put it straight back and the fix would look like it had held. The .gitignore is identical to #204's, so whichever merges first the other resolves cleanly. Selftest: 27 checks, 0 failed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
LukasWodka added a commit
that referenced
this pull request
Aug 10, 2026
`scripts/__pycache__/standards-sync.cpython-314.pyc` was committed by a `git add -A` in #200 and reached `develop`. It is now riding the develop -> staging promotion in .github#203, which is how I noticed it. It is a build artifact and does not belong in the tree: version- and platform-specific (cpython-314, while CI runs 3.12), regenerated on every local run of the selftest, and a stale one silently shadows the source it was built from. Added a .gitignore covering the whole class rather than the one file that got caught -- `__pycache__/`, `*.py[cod]`, plus .DS_Store and .pytest_cache, which the same careless `add -A` would sweep in next. The file is also present on the #197 branch, which branched after #200; removed there too, so whichever lands first the artifact is gone and the other cannot reintroduce it. Selftest still passes (20 checks on this branch; #197 takes it to 27). Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
saadqbal pushed a commit
that referenced
this pull request
Aug 11, 2026
…tes (backend#1602) (#197) * fix(standards): retry fresh-branch reads; refresh sha on rejected writes (backend#1602) Design rule 5: fresh refs are eventually consistent. On run 31373298821 (frontend-app leg) the contents read on a just-created branch transiently 404'd, the 404 was believed, and the sha-less PUT was rejected as 'Invalid request' — one flaky read failed a fleet run. remediate() now knows whether the base has the file: reads the base proves must succeed retry with backoff and fail closed if they never do; genuine absence is confirmed by a re-read; a 409/422-rejected write refreshes the sha and retries exactly once. Five new offline selftest checks pin the contract with a scripted gh stub (25 checks total). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(standards): a reused sync branch may honestly 404, and say so on a real conflict Two Bugbot findings on #197. 1. `expect_file` MEANS "a 404 here cannot be true" -- which holds only when the ref was cut moments ago from a base that has the file. That is the eventual consistency window the retry exists for. A REUSED branch (the 422 path) is a different situation: it may have been cut BEFORE CLAUDE.md existed on the base, so a 404 is honest and permanent. Passing file_on_base alone made the read retry five times and fail closed, so the sha-less create could never run and that repo was stuck forever. The old code read the 404 as absence and created the file, which was right here. expect_file is now `file_on_base and branch_is_fresh`. 2. The second-rejection message was UNREACHABLE. On attempt 2 the flow fell through to the generic return inside the loop, so the one failure worth distinguishing -- refreshed the sha and was rejected anyway, i.e. another writer is racing the branch -- was the one nobody could see. It now returns its own message, and the post-loop return is documented as a fail-closed backstop rather than dead code that would return None (i.e. SUCCESS). Selftest 25 -> 27. Mutation-verified both: reverting expect_file, and making the second-rejection branch unreachable again -- both CAUGHT. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * test(standards): the reused-branch check asserted an end state and proved nothing Mutation-checking the previous commit caught its own test. Reverting the expect_file fix left the selftest GREEN, because the check asserted only "the file got created". With the bug present the read retries, swallows the scripted PUT response, reads its `{}` body as the file, and the run reaches the same end state by a different path. Same outcome, wrong reason -- so the check could not distinguish fixed from broken, in either direction. Assert the READ COUNT instead: 2 when a 404 on a reused branch is believed as absence, 5 when it is wrongly treated as the eventual consistency window. That is the thing the fix actually changes. Also catches the stub's exhaustion assertion and records it as a failure rather than letting it abort the whole selftest. Re-verified: reverting expect_file is now CAUGHT (reads=3, expected 2). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * chore: drop the committed .pyc here too (backend#1602) Same artifact as .github#204, removed on this branch as well. This branch was cut after #200, so it carries the file; without this, merging #197 after #204 would put it straight back and the fix would look like it had held. The .gitignore is identical to #204's, so whichever merges first the other resolves cleanly. Selftest: 27 checks, 0 failed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
Hop 1 of RFC-BACKEND-1552 D5 — reads before writes, in separate hops, because
org-github's callers are pinned@mainand both old and new callee code are live during a promotion of the reusables.This was already a live landmine
Staging (agent review)exists on project 2 today (added by the #1592 rename) and no rank table knew it.rank()returned"", the[ -n "$SR" ]guard failed, evaluation fell through to strict equality, and the card would have blocked every prod promotion carrying it — the backend#1411 shape.Measured: 633 board items scanned, zero currently in that column. Armed and waiting, not yet firing.
Changes
fr-gate.ymlFR on staging→8,Ready for prod→9,Prod→10, terminals→11advance-deploy-env.ymlstagingdeploy environment if a card is dragged there by handkanban-reconcile.ymlOn devWhy renumbering is safe
Every comparison is relative —
rank(a) >= rank(b), andTARGET_RANKis itself$(rank …). No hardcoded rank literals anywhere. I checked that before touching the numbers.Caught while renumbering:
Prodmoved to 10 and collided with the terminals, also 10. Terminals must rank strictly aboveProdor the no-demotion guard weakens. Bumped to 11.Read-only, deliberately
Nothing writes this Status yet. That is #1578, and it must not land before the agent can produce a verdict — otherwise cards park in a column nothing advances.
Test plan
actionlintclean on all three; standards selftest 20/20.🤖 Generated with Claude Code
Note
Medium Risk
Changes shared promotion-gate and monotonic deploy-advancement ordering used on every staging/main promotion; mistakes could block or mis-rank cards, though comparisons are relative-only and the change is intentionally read-only.
Overview
Hop 1 (read-only) for RFC-BACKEND-1552 D5: the board already has
Staging (agent review), but workflows treated it as unknown—rank()returned empty and cards there would fail closed on prod promotions. This PR fixes that before anything writes that Status (#1578).fr-gate.ymlandadvance-deploy-env.ymladd the agent column at rank 7 (betweenOn devand human FR) and renumber later stages (Staging (human review)/FR on staging→ 8,Ready for prod→ 9,Prod→ 10,Done/Cancelled→ 11 so terminals stay strictly above Prod).advance-deploy-env.ymlalso maps a.kanban.ymloverride of that Status to thestagingdeploy environment.kanban-reconcile.ymlincludes the agent column in the reconcile sweep and treats it like other post-merge deploy columns: closed-completed issues there are not forced to Done, and open issues drifted there move back to Backlog.Reviewed by Cursor Bugbot for commit 2657523. Bugbot is set up for automated code reviews on this repo. Configure here.