Skip to content

feat(task-board): delivery lanes behind a default-off org flag - #6457

Open
vibe-dex wants to merge 1 commit into
mainfrom
iqaluit
Open

feat(task-board): delivery lanes behind a default-off org flag#6457
vibe-dex wants to merge 1 commit into
mainfrom
iqaluit

Conversation

@vibe-dex

@vibe-dex vibe-dex commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

What is this contribution about?

Adds three board lanes — Approved, Deployed, Post-deploy Validation — between In Review and Done, for teams whose release process continues after the merge, gated by a new default-off org flag delivery_lanes_enabled. Every automatic ship path (the review-decision auto-merge, the auto-merge retry, "Ship to production", prs-get's reconcile-on-view, and the merged sweep) now reads one function, shippedLane(flags), so "flag off = zero behaviour change" is a single tested fact rather than five call sites agreeing by luck. Along the way this fixes a latent bug: prs-get's status !== "done" && !== "archived" enumeration would have dragged a card resting in Post-deploy Validation back to Deployed on every PR-modal open, so it and run-reactions' delivered-failure relabel now compare by rank (LANE_RANK/movesForward, extracted into lanes.ts). Three related holes are closed in the same PR: REVIEW_CLOSING_STATUSES now covers the new lanes (a run setting deployed otherwise escaped closesOwnReview and dropped the card out of listItemsPendingReview, so its reviewers never ran), hasHumanRejectedDone treats leaving deployed as the same veto as leaving done, and the web ship-button gate accepts Approved so the lane isn't a UI dead end.

Note approved is deliberately human-only here — reachable by drag, "Move to" and Jira mapping, never written by automation. Making automation write it requires widening seven sites together (listItemsPendingReview, review-sweeper, advanceToDoneIfMerged, retryAutoMergeIfApproved, claimInReviewSuperAgentSlot, conflict-reaction, isTaskHandedToHuman); any subset strands cards, so that is a follow-up.

How did you verify your code works?

New pure unit suites lanes.test.ts (rank ordering, movesForward refusing the backward drag, shippedLane resolving every falsy flag shape to done), plus new cases in config.test.ts (moveTargets, laneVisibility incl. the "card stuck in a switched-off lane stays reachable" property) and review-status.test.ts (laneCanShip). Per the repo's inversion rule I inverted the tests that encoded the old behaviour rather than appending: reconcile-merged.test.ts now asserts both flag-off → done and flag-on → deployed, and update.test.ts's closesOwnReview "anywhere but Done/Archived" case now pins the delivery lanes as review-closing. Real-Postgres coverage added to archive-merged.integration.test.ts (a card parked in a delivery lane is never swept, via both the candidate query and the write path) and human-rejected-done.integration.test.ts (leaving deployed is a veto; leaving a later lane is not). Against real Postgres the touched scope went 880 → 908 passing with the same two pre-existing order-dependent failures (task-filters, which pass standalone) before and after; bun run check reports 0 type errors, bun run lint 18 warnings identical to baseline, and bun run knip is clean.

Not verified, flagging honestly: packages/e2e/tests/task-board-delivery-lanes.spec.ts is written and typechecks but is unrun — its harness spawns bun run dev, which needs an .env this environment lacks — and there was no live browser check for the same reason. Both are worth a run before merge.

Screenshots/Demonstration

Not captured — see above. The UI change is three additional board columns plus one settings toggle, both invisible until the flag is enabled.

How to Test

  1. On the task board with the flag unset, confirm the board is unchanged from main (5 visible columns, Archived hidden) and that "Move to" and the task dialog's status dropdown offer no new lanes.
  2. Enable it: ORGANIZATION_SETTINGS_UPDATE { flags: { delivery_lanes_enabled: true } }, or Settings → Review → "Show delivery lanes".
  3. Drag a card In Review → Approved → Deployed → Post-deploy Validation → Done; each move should persist and write a status_changed timeline entry.
  4. Confirm "Ship to production" is offered from Approved and not from Deployed.
  5. Turn the flag back off with a card still in Deployed — the lane must appear under "Hidden columns" with a count of 1, and "Show" must bring the column back so the card can be dragged out (it should also stay visible in list view throughout).
  6. Expected: with the flag off, a merged PR still lands the card on Done; with it on, the same merge lands it on Deployed.

Migration Notes

None. task_board_items.status is plain text with no CHECK constraint (migration 126) and the existing status_changed activity action is reused, so no schema change is needed. The generated packages/shared/src/tools/tool-io.ts diff is committed — regenerate with bun run --cwd=apps/api generate:tool-contracts if you touch the status or flags schemas.

Review Checklist

  • PR title is clear and descriptive
  • Changes are tested and working
  • Documentation is updated (if needed)
  • No breaking changes

🤖 Generated with Claude Code


Summary by cubic

Adds three delivery lanes — Approved, Deployed, Post‑deploy Validation — behind a default‑off org flag. With the flag off, merged PRs still move tasks to Done; with it on, merged PRs land on Deployed and the “Ship to production” button works from In Review and Approved.

  • Centralizes ship target in shippedLane(flags) and guards all auto-moves with rank (LANE_RANK/movesForward) to prevent backward drags.
  • Treats leaving Deployed as a human veto of a ship (hasHumanRejectedDone), and excludes delivery lanes from archive sweeps.
  • Keeps Approved human-only; automation never writes it in this PR.
  • Web shows delivery columns only when enabled; cards in hidden delivery lanes remain reachable via the “Hidden columns” drawer. “Move to”/status dropdown respects moveTargets(deliveryEnabled).
  • Jira status mapping options and the ship button mirror server rules; server accepts shipping from Approved.
  • Extends status unions and schemas; updates tool-io types; no DB migration.

Review/Focus

  • packages/shared/src/task-board.ts: shippedLane, deliveryLanesEnabled.
  • apps/api/src/tools/task-board/lanes.ts: LANE_RANK, movesForward, SHIP_ELIGIBLE_LANES; rank-based checks in run-reactions and prs-get.
  • Ship paths now read shippedLane: review-decision, merge-pr retry, merged-PR reconcile (reconcile-merged, prs-get), manual ship (promote-to-production).
  • Review loop gates: REVIEW_CLOSING_STATUSES widened; UI gating in laneVisibility, moveTargets, laneCanShip.
  • Tests pin zero-behavior-change when the flag is off and Deployed when on.

Rollout/Testing

  • Default off; safe to merge. Enable per org via delivery_lanes_enabled.
  • Run the new e2e spec packages/e2e/tests/task-board-delivery-lanes.spec.ts locally.
  • No migration steps required.

Written for commit 816b03e. Summary will update on new commits.

Review in cubic

Add Approved, Deployed and Post-deploy Validation between In Review and
Done, for teams whose release process continues after the merge. Gated by
`delivery_lanes_enabled` (default off): with it off, the board and the
state machine behave exactly as if the lanes did not exist.

Every automatic ship path now reads one function, `shippedLane(flags)`, so
the no-behaviour-change property is a single tested fact rather than five
call sites agreeing by luck. `LANE_RANK` moves to its own module alongside
`movesForward`, and two enumerated guards that would have dragged cards
backward once the lanes existed (`prs-get`'s merged-PR reconcile and
`run-reactions`' delivered-failure relabel) now compare by rank.

No migration: `task_board_items.status` is plain text with no CHECK, and
the existing `status_changed` activity action is reused.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added the claude PR authored by a coding agent label Aug 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

claude PR authored by a coding agent

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant