Skip to content

fix(kanban): the column check missed three writers, and could not tell - #248

Merged
LukasWodka merged 3 commits into
developfrom
fix/1948-column-check-misses-writers
Aug 13, 2026
Merged

fix(kanban): the column check missed three writers, and could not tell#248
LukasWodka merged 3 commits into
developfrom
fix/1948-column-check-misses-writers

Conversation

@LukasWodka

@LukasWodka LukasWodka commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Two Bugbot findings on the staging promotion PR #243both on code I added today.

Medium — the conformance check was itself incomplete

Which is the exact defect it exists to prevent. WRITERS named two files and LITERAL matched one idiom, so it never saw:

workflow idiom names missed
set-pr-status.yml echo "status_name=In progress" (unquoted) In progress, Code review
fr-pass-comment.yml NEXT="Ready for prod" Ready for prod

Three column names invisible to a guard built to make a rename impossible to miss. It reported a clean sweep of a subset — which reads exactly like a clean sweep of everything.

Widening the list alone would rot the same way

So the names are now derived a second, independent way and compared: any board column name assigned in a writer file that no idiom matched means the idiom list is stale — an error, not a smaller answer. Assignment sites only, whole values, so comments, the rank case arms and prose are ignored and Ready does not match inside Ready for prod.

It earned that immediately. The cross-check caught my own first attempt at the widened regex, which required a trailing quote and silently stopped matching STATUS_NAME="FR on staging" ;;. Without it I would have shipped a check that found fewer names than before while printing "all names exist".

Coverage: 5 names / 2 files → 8 names / 4 files.

Low — the abort message claimed a write that cannot have happened

#246 said "The Deploy environment write may already have happened." It cannot: that check runs at :190, the first update_field is at :314. On that path nothing was written. Corrected — the point of the message is to tell an operator where they stand.

Verification

  • selftest 8/8, adding: an assigned-but-unmatched name is reported; a comment mentioning a column is not mistaken for a write
  • caller-drift selftest 162/0; ruff + actionlint clean
  • the real check passes end to end against the live board

Note

Low Risk
Changes are limited to CI validation scripts, workflow path filters, and an operator-facing error message; no runtime deploy or auth behavior changes.

Overview
Fixes the kanban column conformance guard so it actually watches every workflow that writes Status, and fails when its own extraction logic is incomplete instead of reporting a false green.

Checker (kanban-columns-check.py): WRITERS now includes set-pr-status.yml and fr-pass-comment.yml. The literal extractor matches quoted and bare assignments (status_name=In progress, NEXT="Ready for prod", etc.). A new cross_check pass independently finds board column names assigned in writer files that the regex missed and errors with a stale-idiom message. Selftests cover cross-check behavior and assert every WRITERS entry appears in the PR paths: filter in kanban-columns.yml (which now lists the two missing workflows).

advance-deploy-env.yml: When Status resolution fails, the error text now states that no field updates run on that path (replacing the incorrect hint that Deploy might already have been written).

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

Two Bugbot findings on the staging promotion PR #243, both on code I added today.

MEDIUM — the conformance check from #247 was itself incomplete, which is the
exact defect it exists to prevent. `WRITERS` named two files and `LITERAL`
matched one idiom, so it never saw:

  set-pr-status.yml    `echo "status_name=In progress"`   (UNQUOTED value)
  fr-pass-comment.yml  `NEXT="Ready for prod"`

Three column names -- In progress, Code review, Ready for prod -- were invisible
to a guard built to make a rename impossible to miss. It reported a clean sweep
of a subset, which reads exactly like a clean sweep of everything.

Widening the hand-list alone would rot the same way, so the names are now derived
a SECOND, independent way and the two are compared: any board column name
ASSIGNED in a writer file that no idiom matched means the idiom list is stale,
and that is an error rather than a smaller answer. Assignment sites only, whole
values -- so comments, the rank `case` arms and prose are ignored, and `Ready`
does not match inside `Ready for prod`.

It earned that immediately: the cross-check caught my own first attempt at the
widened regex, which required a trailing quote and silently stopped matching
`STATUS_NAME="FR on staging" ;;`. Without it I would have shipped a check that
found fewer names than before while printing "all names exist".

Coverage went 5 names / 2 files -> 8 names / 4 files.

LOW — the abort message added in #246 said "The Deploy environment write may
already have happened". It cannot have: that check runs at :190 and the first
`update_field` is at :314, so on that path nothing was written at all. Corrected
to say so, since the point of the message is to tell an operator where they
stand.

Selftest 8/8 (adds: an assigned-but-unmatched name is reported; a comment
mentioning a column is not). caller-drift selftest 162/0. ruff + actionlint clean.
@LukasWodka LukasWodka self-assigned this Aug 13, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit a3efd86. Configure here.

Comment thread scripts/kanban-columns-check.py
…rift

Bugbot Medium on this PR. I broadened `WRITERS` to four workflows and left
`kanban-columns.yml`'s `paths:` filter listing the original two — so a PR
touching only `set-pr-status.yml` or `fr-pass-comment.yml` never ran this check
and a bad column write could merge until the next cron.

Same shape as the defect this PR is already fixing: the guard is present, reports
green, and is not watching the thing it names. Two files apart this time instead
of two variables.

The filter now lists all four. But listing them is what went wrong once already,
so the selftest DERIVES the requirement: every entry in WRITERS must appear in
the workflow's `paths:` block, read out of the YAML rather than restated. Adding
a fifth writer without wiring its trigger is now a red test, not a silent gap.

Verified by removing `set-pr-status.yml` from the filter: the assertion fails.
Selftest 10/10 with it restored. ruff + actionlint clean.

This is the third instance today of "fixed the code, left the trigger config" --
e2e#81 was the same bug in a tsc dry-run paths filter. Recorded in the message
because the pattern is worth more than the fix.
It was in the block I added two commits ago and I claimed ruff clean without
reading the exit code -- the `&&` swallowed it. Checked properly this time.
@LukasWodka

Copy link
Copy Markdown
Contributor Author

Bugbot Medium addressed in aceffe0.

"PR trigger omits new writers" — correct, and it is the same defect this PR is already fixing, two files apart instead of two variables. I broadened WRITERS to four workflows and left the paths: filter listing the original two, so a PR touching only set-pr-status.yml or fr-pass-comment.yml would never have run this check — the guard present, green, and not watching what it names.

The filter now lists all four. But listing them is exactly what went wrong once already, so the selftest derives the requirement instead: every entry in WRITERS must appear in the workflow’s paths: block, parsed out of the YAML rather than restated in the test. Adding a fifth writer without wiring its trigger is now a red test rather than a silent gap.

Verified by removing set-pr-status.yml from the filter — the assertion fails. Selftest 10/10 restored.

Also pushed a follow-up: I claimed "ruff clean" in the previous commit message without reading the exit code (the && swallowed a real E401 in the block I had just added). Fixed and checked properly.

Third instance today of fixed the code, left the trigger config — e2e#81 was the identical bug in a tsc dry-run paths filter. Noting it because the pattern is worth more than the individual fix.

@LukasWodka
LukasWodka merged commit ed77044 into develop Aug 13, 2026
11 checks passed
Sign up for free to 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.

1 participant