fabro/apps/fabro-web/app
Bryan Helmkamp b8af65a9c6
refactor(runs): blocked status canonicalization cleanup (#165)
## Summary

Stacked cleanup of the `canonicalize blocked run status` work (local
commit `d13cdf374`) plus reconciliation with origin's `canonicalize
paginated run list responses` (origin commit `8ab689da7`). Both efforts
ran in parallel and diverged on the column name (`blocked` vs `waiting`)
and on how the board response is shaped — this PR converges them,
keeping `blocked` as the canonical column id while adopting origin's
`column` field on `RunListItem` and `StoreRunSummary` shape.

Also fixes a production-worker regression introduced by the
canonicalization: the worker's start-precondition only accepted
`Submitted | Starting`, so once runs started transitioning through
`Queued` on the way to `Starting`, every subprocess-worker run failed
with `Precondition failed: cannot start run: status is Queued`. That
cascaded into ~90 failing CLI/server integration tests locally.

## Commits

1. `f65843168` refactor(runs): simplify blocked status follow-ups
2. `1492d956c` chore: resolve clippy warnings
3. `676fd9f44` first merge of origin/main
4. `23fc92a2f` **fix(runs): allow Queued status in start precondition**
← the cascade-fix
5. `36b507a83` refactor: simplify pause/unpause + dedupe web status
tables
6. `8d8d27748` refactor(workflow): encapsulate BlockedStateTracker
inside HumanHandler
7. `1c17fda35` second merge of origin/main — resolves waiting vs blocked
8. `4cd3ef7b1` refactor(workflow): Mutex<usize> → AtomicUsize
9. `2e5a58e8a` fix(demo): align run-4 lifecycle status with Blocked
board column

## Test plan

- [x] fmt, clippy, build, doctests all clean
- [x] `cargo nextest run --workspace` — **4092/4092 pass**
- [x] `bun test` — **26/26 pass**, typecheck + production build clean
- [x] Manual CLI repro of the Queued-precondition fix
- [x] Browser smoke test: all 5 columns render with correct
labels/colors, demo run-4 appears in Blocked lane with question text
intact

## Known follow-up (not blocking)

A "paused-while-blocked" run (status `Paused` + `blocked_reason: Some`)
lands in the `running` column because the visible status chooses
`Paused` over `Blocked`. The pending question is not prominent on the
board. Addressing it would require `board_column()` to branch on
`(status, blocked_reason)` rather than just `status` — worth a separate
ticket.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 14:53:46 -04:00
..
components feat(web): render command/script stage output on stage detail page 2026-04-15 10:23:55 -04:00
data refactor(runs): blocked status canonicalization cleanup (#165) 2026-04-19 14:53:46 -04:00
layouts feat(web): add empty state to runs page and fix logo link 2026-04-16 08:02:18 -04:00
lib feat(web): graph direction control, failed node colors, breadcrumb and stage fixes 2026-04-15 10:52:12 -04:00
routes refactor(runs): blocked status canonicalization cleanup (#165) 2026-04-19 14:53:46 -04:00
api.test.ts fix(runs): bound board enrichment and demo normalization 2026-04-19 11:35:30 -04:00
api.ts fix(runs): bound board enrichment and demo normalization 2026-04-19 11:35:30 -04:00
app.css feat(web): render markdown in stage system prompt and assistant blocks 2026-04-15 11:21:25 -04:00
entry.tsx Cut over Fabro web app to a server-backed SPA 2026-04-01 21:36:01 -07:00
root.tsx fix(fabro-web): default unsaved theme selection to dark 2026-04-08 12:10:34 -04:00
router.test.tsx refactor(setup): remove browser-based GitHub app bootstrap 2026-04-13 18:25:29 -04:00
router.tsx feat(web): enhance run detail UI with stages tab, graph controls, and live annotations 2026-04-15 10:12:10 -04:00