Concepts
The repo is the source of truth
A task is a markdown file in your configured task directory (repoos/work/ on a fresh install). Its status is a field in that file's YAML frontmatter. Tasks are markdown files — there is no separate board database behind the UI. RepoOS may create gitignored runtime files under .repoos/ (for example repoos.db when login is enabled); those are not the task board. The UI is a view over the task files, and anything derived (the index, caches) can be deleted and rebuilt.
This has practical consequences you'll feel immediately:
- Tasks are versioned, diffable and reviewable like code.
- Task history travels with a clone. Nothing lives in a service you can lose access to.
- An agent can read the board with
cat, and your project's context is sitting right next to the code it describes.
Git history in the UI
The Context page (/repo) includes a History tab: the repository's git log, grouped by day, with branch and path filters. Commits that follow the type(NNNN): message convention (for example docs(0514): …) link to that task. Opening a commit shows the files it changed and a full diff — the same diff view used for task worktrees.
The log is read-only. Checkout, revert, and cherry-pick stay on the command line.
The left sidebar also shows a small canary digit (0–9) above the git summary. Clicking it starts a deliberately trivial task that walks the full lifecycle (draft through done) by incrementing the digit in .repoos/canary.txt in your repo — a smoke test that any failure is in the pipeline, not your product code. The digit reflects that file on disk and advances after a canary run merges.
The git row below it is a one-line summary of the checkout you are actually running from: the branch, and clean, dirty (n) or unknown. It describes the repo root checkout only — task worktrees are separate, and a task branch moving never flips it. A warning colour means either the checkout is not on the base branch (or HEAD is detached) or there are uncommitted changes; unknown is what you see when git could not be read or the last check is older than a minute and a half, and it never means clean.
The ℹ button next to it opens the detail: the changed files with their status letters when dirty, the three most recent commits exactly as the History tab lists them (docs(NNNN): bookkeeping excluded), how long ago the state was checked, and a link into History. It reads the same data as the History tab and is read-only — committing and switching branches stay on the command line.
The state is pushed to every open tab over the event stream when it changes (working-tree writes, branch switches, commits, staging, and RepoOS's own task-file commits), with focus, tab-visibility, reconnect and a slow interval as backstops.
One cadence note: git's own state changes are pushed immediately, but an ordinary edit outside the task tree (say, under src/) is not watched — watching the whole checkout would be a lot of filesystem noise for one indicator. Those edits show up on the next backstop (window focus, tab visibility, event-stream reconnect, or the 45-second interval), so the row can be up to ~45 seconds behind an edit made with a plain text editor. Staging or committing that edit pushes it at once.
Status is a field, not a folder
---
id: "0001"
title: Fix the login redirect loop
status: ready
priority: p1
---Tasks move through inbox → ready → active → review → done by editing that one field in place. Files never move between directories, so a status change is a one-line diff instead of a rename, and two people moving different tasks never conflict.
Don't hand-edit task files
Status, activity log and metadata are written by RepoOS so the board stays consistent. Use repoos mv, repoos update, repoos note, or the UI.
What each status means
| Status | Meaning |
|---|---|
inbox | Captured, not yet specified well enough to act on. |
ready | Specified. An agent (or person) can pick this up as-is. |
active | Being worked, in its own git worktree. |
review | Implementation finished and checks pass. Waiting on a human. |
done | Approved and merged. |
Pipeline view
The Work Queue page has two views, switched with the Pipeline | Board toggle in the header. Board is the default and shows every status. Pipeline is a horizontal race track for the work in flight: one lane per task in active or review, plus recently merged tasks. Your last choice is remembered.
Lanes run through six stage columns, left to right: Coding, Checks, Handoff, Review, Close-out, Merged. Each card sits in the column of its current stage and moves backwards too — when review sends a task back, it returns to Coding with a small amber "sent back" note on its lane. ready tasks are not lanes; a Ready · n count sits at the left edge. The Merged column is the tinted goal: recently merged tasks sit in it for ten minutes, then drop off the track.
Stuck, needs-input, paused and held are states, not stages: the card stays where it stalled, with a red (stuck), amber (needs input) or green (merged) chip, and held/paused cards render dimmed.
Each card shows four lines: id, type and priority; the title; the live step ("Coding", "Running checks 3/5", "Confirming handoff", "In review", "Merging") with time in this state; and the engineer round (E2), reviewer round (R1 ✓), model(s) and run host (this Mac or the remote host name). Click a card to open the task panel, exactly like a board card. The small icon button (pause, resume, or a check mark once merged) acts without opening the panel and is reachable by keyboard.
Archiving a task
Archive parks a task you don't intend to finish right now without changing its status. A task archived from review is still review underneath — it just stops appearing in the board columns, and unarchiving drops it back into that same column. Nothing else changes: the branch and worktree are kept, so an archived task resumes exactly where it left off.
Use Archive task at the bottom of the task panel and optionally give a reason. Archiving is refused while a run, review, or close-out is still live, because hiding a half-stopped run from the automatic scanners would orphan it — stop the work first. A running preview is not a refusal: archiving stops it (the recorded preview process and its build shell) as part of parking the task.
Archived tasks live in a minimised Archived (n) list below the board on the Work Queue page. Archiving is orthogonal to status: there is no archived status, and it never merges, stops, or deletes anything.
From the CLI, repoos list hides archived tasks by default and prints a count; repoos list archived shows them, and repoos show <id> marks an archived task. repoos mv refuses to move an archived task's status — unarchive it first (from the Archived list, or POST /api/tasks/:id/unarchive).
An archived task that another task depends_on does not count as done: the dependent stays blocked and reads “Blocked by archived task #id; unarchive it to unblock” until the upstream is unarchived.
Stories
A story is an optional grouping over tasks: a delivery slice that spans several areas and owners, tagged with a matching story: value and optionally described by a markdown file under stories/. Forms the shared background for a related set of tasks — why the work exists, decisions already made, the tasks it contains — without repeating it in every task body. A story has no worktree, branch or status of its own; it is complete when all its tasks are done. See Configuration → Stories.
Agents get this background too: when a tagged task with a registered story is picked up, the engineer and the reviewer both receive the story's title, the path to its definition file, the sibling tasks (ids, titles, statuses) and a bounded excerpt of the definition in their prompt. So the context you write once into a story steers the work, not just the humans reading the board.
One task, one worktree
When a task goes active, RepoOS creates a dedicated git worktree and branch for it. The agent works there — never in your primary checkout — so you can keep working while an agent does, and several tasks can be in flight without stepping on each other.
Checks before merge
repoos checkThis is the single bar for "did this break anything?". It runs the check plan your repo declares in repoos.toml — the same command for Go, Gradle/Android, Rust, JavaScript or a mix — and each step ends in a pass, a failure, a timeout, a missing-prerequisite error, or an explicitly-stated skip (see Checks before merge). An agent must get it green before handing work back, and it runs again before anything merges.
Because it's one command with a non-zero exit code on failure, the same checks works locally, in CI, and inside RepoOS's own close-out pipeline.
Humans hold the merge
Human-assigned tasks follow a separate, inert board pathway. They can move between Inbox, Ready, Active, Review and Done without starting AI work or running checks, review or close-out. The drawer identifies them as human work and offers Mark done with an optional completion note. hold is not required for a human-assigned task. AI agents may change its board status only when the human explicitly asks them to.
An agent that finishes a task asks for it to move to review and stops. It does not merge its own branch, and it can't — the merge happens only when a human moves the task to done.
Reaching review is a request, not a status edit: RepoOS commits the branch, runs repoos check and passes a commit guard first, from whichever route you use (the Review button, a board drag, repoos mv, or the agent). Until that finishes the task is still active. See Review and close-out.
If a reviewer agent is enabled, it reads the branch diff and writes an advisory report for that review — findings, edge cases, suggestions. It changes nothing and it doesn't replace your approval; it's there to make your review faster.
Your docs directory is the project's memory
repoos init creates repoos/docs/ alongside repoos/work/ by default. It holds the context an agent needs to work on your project: architecture notes, decisions and their rationale, incident write-ups, conventions that aren't obvious from the code.
This matters more than it sounds. An agent starting a task reads AGENTS.md and your configured docs directory to get oriented — so knowledge you write down once stops being re-derived, re-litigated, or re-broken on every future task.
TIP
Your docs directory is for building your project. The documentation you're reading now — how to use RepoOS itself — is a separate thing, kept in its own directory in the RepoOS repo.
AGENTS.md
AGENTS.md is the cross-tool standard for agent instructions, read directly by Claude Code, Codex, Cursor, Aider, Zed and others. repoos init scaffolds one describing the task lifecycle and the rules of your repo. Add a one-line shim only if a tool you use ignores it.