FleetDeck
When several AI coding sessions work the same repositories at once, the hard part is not running them. It is knowing what is true.
- Design · Engineering · Developer Tooling
- 2026 · In daily use
- Local web app · Node.js · Developer tooling
- Independent · Design & Engineering
- Me, and the coding sessions that need to pick up where another left off
- Developer Tools · Dashboard · AI Workflow
I designed and built all of it: the operating rules, the data model for tasks and reviews, the dashboard, and the daemon behind it.

Overview
FleetDeck reads what coding sessions, Git and GitHub already produce, projects it onto one board, and refuses to act on any of it.
Internal tool for my own products (GSDAQ, Sweetspot, Strollable, Daydream, this portfolio). Running since September 2026; it is the first thing I open in the morning.
- 7
- 42
- 0
- 2
Problem
The Status Docs Had Twelve Versions
By late summer I had five products in flight and several coding sessions working on each, often in parallel worktrees. Every session kept its own handoff notes inside the repository, and the notes forked with the worktrees: one project's handoff file existed in twelve versions, another's launch tracker in thirty-one. Nobody, human or model, could say which one was current.
The failure was not effort. It was that the record of truth lived inside the thing being changed.
- State written inside the repo diverges as soon as a second worktree exists
- A session that inherits work re-reads tens of kilobytes to find the current SHA and the next step
- "Ready to merge" meant different things in different documents
Core decision
Observe Everything. Execute Nothing.
The daemon is observe-only. It reads sessions, Git, task records and cached pull-request state, writes only a derived cache, and never starts an agent, runs a gate, or merges. Work happens in sessions a person opened, following one written procedure. The board shows where each task is in that procedure and what evidence exists for it.
Merging is always a person, with a head-commit match against the SHA that was reviewed and verified.
- Truth moves outside the repo: one ops directory per project with tracker, task records, reviews and evidence
- A task record names its owner session, branch, PR, recorded HEAD and next action
- Reviews are per SHA; a finding keeps its ID across rounds and is closed by the reviewer who opened it
- Gate definitions stay in each repo; FleetDeck only calls them and stores the logs with hashes

- Findings loop back into the same PR — The dashed connector above stages three and four is the only loop on the board. Review findings are fixed in the same pull request and re-reviewed at the new SHA. Nothing is re-opened somewhere else.
- Progress comes from the tracker — 111 of 208 done is read from the project's ops tracker, not from Git. The board never counts commits as progress.
- Work without a stage stays visible — Tracker items with no stage record are listed under the lane as "No stage" instead of being hidden. The board does not guess which stage they are in.
- "Ready to merge" is derived — A node lights up here only when gate evidence, the required independent reviews and a clean HEAD all exist for the latest SHA. It is a label, not a button; a person still merges.
- A stage is what the record says — This node reflects the phase written in the task record. Connectors show the procedure, not proof that an earlier stage was verified.
System
One Board, Six Stages, Two Machines
Each project is a lane with six stages: waiting, implementation, PR and review, revision, ready to merge, merged. A node is what the task record says, not a guess from Git. The sessions view lists open coding sessions with the project and model they are working on, and the resource column shows remaining quota per account so I can choose which model to spend on which task.
A second Mac reports into the same board: heartbeat, verification requests, results. The dashboard is server-rendered HTML with a small client script and server-sent events. No framework and no build step; it is fast on the machine it runs on and simple enough to change in an afternoon. On a phone the same HTML collapses to Flow and Sessions tabs and the resource column folds away.
A note on the screenshots: I keep my task records in Korean, so the titles in them are translated to English here. The board, the data and the numbers are what it was showing.

Workflow is the home.
Projects and progress in the sidebar, remaining quota per account up top, then the lanes. Everything on screen is a stored measurement; loading the page makes no model call.
Keyboard: ← → to switch surfaces
Evidence
The Reviewer Was Chosen by a Study, Not a Preference
The first mockup had one vendor's model write code and the other's review it, on instinct. A cross-vendor study of 116 review pairs showed the opposite pairing: one direction improved outcomes by about eighteen points while the reverse made them worse by about nine. The roles flipped before the first real run.
The same habit applies to the process itself. Pull-request size is a planning input, not a gate met after the fact: the plan lists PRs with expected line counts, and anything over the limit is split at a risk boundary before code is written. That rule exists because one late split introduced a real defect and another had to be re-cut into four pull requests.
- Planner: Claude in plan mode · Worker: Codex · Reviewer: Claude (arXiv:2607.21656, n=116)
- One to three independent reviews on the latest SHA, set per project, before a person merges
- Every gate log stored under the task and SHA with a checksum
Current state
Daily Use, Deliberately Manual
The autonomous loop the tool was designed for stays off. What runs today is the observe-only board plus the written manual procedure, and in FleetDeck's own repository alone that combination has carried forty-two pull requests to merge; the product repos run the same loop with their own counts. Automation returns one guarded step at a time, each behind a checkpoint I approve.
- 7
- 42
- 1–3
- Off
Reflection
Key Learnings
Put the Record Where the Work Isn't
Status that lives inside a repository forks with the repository. One ops directory per project ended the twelve-version problem in a day.
A Board Should Refuse to Act
Making the daemon unable to execute anything removed a whole class of accidents and made every green label mean exactly one thing: evidence exists.
Size Is a Design Input
Deciding PR boundaries before writing code produced smaller, reviewable changes and fewer defects than splitting afterwards.
