Skip to content

fix(kanban): reconcile must check for a closer, not infer it from the column (backend#1411) - #128

Merged
LukasWodka merged 1 commit into
developfrom
fix/1411-reconcile-closer-check
Aug 3, 2026
Merged

fix(kanban): reconcile must check for a closer, not infer it from the column (backend#1411)#128
LukasWodka merged 1 commit into
developfrom
fix/1411-reconcile-closer-check

Conversation

@LukasWodka

@LukasWodkaLukasWodka commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Bugbot on #127. Third variant of the same hole — this time in the guard I added for the second one.

The circularity

My reconcile check used the card's column as evidence for "did anything deploy?". That is circular: the column is exactly what is wrong when the router misses a close.

  1. An issue is closed by a PR that merged to develop — so the work shipped.
  2. The router's closer lookup fails, so it deliberately leaves Status alone.
  3. The card therefore stays in Backlog / Code review — no deploy column.
  4. Reconcile reads that column, sees no deploy state, and asserts Done.
  5. kanban-archive hides it the next day.

That is the same fail-wrong outcome the router's guard was written to prevent, reached through the backstop instead. And it is now reachable because the router correctly refuses to guess — my fix for finding 2 created the path for this one.

The fix

Done needs two things true: no deploy state on the card, and nothing closed the issue. Reconcile now asks the second question directly.

cardcloseroutcome
non-deploy columnnoneDone
non-deploy columnPR or Commitskip — it shipped, the router owns the stage
non-deploy columnlookup failedskip — unreadable is not evidence of absence
deploy columnanyskip, as before

Verified by extracting the decision and running the table rather than reading the case arms.

Also: REPO in this workflow is the bare repository name, not owner/name, so ${REPO#*/} was correct only by accident. Uses $REPO directly.

Note

This targets develop, and #127 promotes develop → main, so #127 picks it up automatically — no separate promotion needed.

🤖 Generated with Claude Code


Note

Medium Risk
Changes kanban terminalization logic for closed issues; mistakes could mis-route cards or leave drift, but the change is conservative (skip on ambiguity) and mirrors existing closure-router behavior.

Overview
Fixes a circular guard in weekly kanban-reconcile: closed completed issues in non-deploy columns were moved to Done whenever the card wasn’t already in a deploy column, which wrongly treated “stuck in Backlog after a failed router close” as “nothing deployed.”

For those issues, reconcile now queries the issue’s close event (same GraphQL CLOSED_EVENT / closer pattern as kanban-closure-router). Done is planned only when the closer is genuinely absent (NONE). If a PullRequest or Commit closed the issue, or the lookup fails, the run skips and logs instead of asserting Done—so shipped work isn’t archived as “completed, nothing deployed.”

Comments are updated to state that Done needs both no deploy column and no closer. The GraphQL call uses $REPO as the bare repository name (not owner/name stripping).

Reviewed by Cursor Bugbot for commit e27c29d. Bugbot is set up for automated code reviews on this repo. Configure here.

… from the column
Bugbot on .github#127, and it is the third variant of the same hole -- this time in the
guard I added for the second one.
My reconcile check used the CARD'S COLUMN as evidence for "did anything deploy". That is
circular: the column is exactly what is wrong when kanban-closure-router misses a close.
The router's closer lookup can fail, and it then deliberately leaves Status alone -- so
the card stays in Backlog or Code review while the work has actually shipped to dev.
Reconcile then read that column, saw no deploy state, and asserted Done. kanban-archive
hides it the next day. Precisely the fail-WRONG outcome the router's guard was written
to prevent, reached through the backstop instead.
Done needs TWO things true: no deploy state on the card, AND nothing closed the issue.
Reconcile now asks the second question directly instead of inferring it:
no closer -> Done
closed by PR or Commit -> SKIP; it shipped, the router owns the stage
lookup failed -> SKIP; unreadable is not evidence of absence
already in a deploy col -> SKIP, as before
Verified by extracting the decision and running the table.
Also: REPO here is the bare repository name, not owner/name, so ${REPO#*/} was correct
only by accident (no slash to strip). Uses $REPO directly.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@LukasWodka
LukasWodka merged commit 1207902 into developAug 3, 2026
4 checks passed
@LukasWodka
LukasWodka deleted the fix/1411-reconcile-closer-check branch August 14, 2026 13:53
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@LukasWodka@saadqbal