Skip to content
Backlog

A backlog your agents file into and your team can actually read.

Work an AI coding agent discovers and does not finish evaporates with the chat. Here it becomes a row: filed from the open session, attributed to the credential and the client, triaged into one of four states, prioritised, owned, and aged by a staleness clock only a person or an agent resets. Resolved stays resolved — a database trigger, not a convention — and every write lands on the workspace’s audit chain. Agents work it over MCP or REST; people read it as a board.

file_backlog_item

title · priority · category · parent · source
Backlog columns Three narrow columns of tiles; one tile carries a hollow amber tick for an item nobody has acknowledged. A hollow tick A hollow tick — an open item whose staleness clock is running. A filled amber tick A filled amber tick — an item resolved with closing notes; it does not reopen.

open → in_progress → resolved · dismissed — terminal, absorbing · illustrative

How it works

File. Triage. Prioritise, assign, close — and amend the notes.

Six verbs. Each is an MCP tool and a REST route; each tool links to its row in the catalogue.

  1. File

    A title of 1–300 characters, a body in markdown, a priority — critical, high, medium or low — and a free-text category up to 64 characters; optionally an hours estimate, the PR or commit that surfaced it, the decisions it relates to, a parent item and an initial owner. The project comes from project_id or from the build session the caller has open. The item lands open, attributed to the credential that filed it and the client it came in on.

    file_backlog_item
  2. Triage

    Move it between open and in_progress freely — the first move into in_progress stamps started_at — or close it: resolved needs a closing PR, a closing commit or closing notes; dismissed needs a reason in triage notes. Both closes are final. A same-status move is a no-op and writes no audit row.

    triage_backlog_item
  3. Prioritise

    Set the priority. It is stored as a persisted rank — critical first, low last — so the board and the list sort by it without a string compare, and it never changes on a closed item.

    reprioritize_backlog_item
  4. Assign

    Set or clear the owner: an agent by its account key or a person by theirs. Assignment is board hygiene — a no-op on a closed item, and a no-op when the owner is unchanged.

    assign_backlog_item
  5. Amend the closing notes

    A resolved or dismissed item never reopens. What you can do is append a dated amendment — up to 4,000 characters — under the original closing notes, which are preserved as written. Anything genuinely new is a new item, linked to the old one as its parent.

    amend_backlog_closing_notes
  6. Acknowledge staleness

    An open item’s staleness clock is its filing time until someone says “still relevant”; the acknowledgement stamps the clock and the item drops off the stale list. Nothing sweeps or closes a stale item — a person or an agent asks for the list and decides.

    acknowledge_backlog_item_staleness
Backlog columns Three narrow columns of tiles; one tile carries a hollow amber tick for an item nobody has acknowledged.
Open A hollow tick — open, clock running since filing. In progress A hollow tick with a bar beneath — in progress, started_at stamped. Resolved A filled amber tick — resolved with a closing reference; terminal.
Three columns of an agent’s backlog: open, in progress, resolved. The hollow amber tick is an open item nobody has acknowledged since it was filed; the filled tick is a close with notes, which does not reopen.

The problem is where deferred work goes. An agent finds a second bug while fixing the first, notices a test that should exist, decides a refactor is out of scope — and says so in the chat, which ends. A markdown TODO file records the item but not who filed it, from which session, or whether anyone has looked at it since; a tracker built for a product team wants a human to open it. The other shape is a row an agent can write and a person can read: file_backlog_item from the open session, a triage that moves it through four states, a priority and an owner, a staleness clock that runs until someone acknowledges the item, and a close that cannot be quietly undone.

In the session protocol this is step five: after the agent has recorded its decisions and before it ends the session, one file_backlog_item per deferral — the project comes from the session it has open, so the item lands where the work was. The next session’s start step reads count_backlog_items_by_status for the shape of the queue; the rules an agent asks for say what to do, the backlog says what is left.

What makes it trustworthy

A trigger, three persisted columns, one clock

Each card names the object it is made of. The invariants are written into the database and into single UPDATE statements, not into application code that reads and then writes; the numbers are constants the required check pins this page to.

Terminal states absorb

An AFTER UPDATE trigger rolls back any change of status out of resolved or dismissed. The service refuses first, with a conflict; the trigger is what makes the rule hold for every writer, including one with SQL access. There is no reopen tool, route or button.

trigger:tg_backlog_items_terminal_absorbing

Identity fixed at insert

The same trigger rolls back any UPDATE that touches the two identity columns — which is what keeps the terminal guard unbypassable, since a row cannot rewrite its id and slip the check. The project is the one thing that may move: reassign_backlog_item re-homes a misfiled item, in any state.

columns:workspace_id · backlog_item_id

Ranks, persisted

priority_rank orders critical, high, medium, low and status_rank orders open, in_progress, resolved, dismissed — both computed and persisted, so the board and list_backlog_items sort active work first, highest priority first, newest first, over an index built for exactly that.

columns:priority_rank · status_rank

Staleness, a clock

COALESCE(staleness_acknowledged_at, created_at), persisted. The stale list is every open or in-progress item older than the threshold you pass — default 90 days, 1–3650 — oldest first; acknowledge_backlog_item_staleness stamps the clock with one conditional UPDATE. Not audited, like a ping; nothing sweeps a stale item.

column:staleness_at

Attributed

The filer’s actor key is derived from the bearer that made the call — never from the arguments — with the client type (api or mcp), name and version it came in on; the triaging actor is recorded the same way, and the owner is the actor key named on assign. Only the filer may amend an open item, and only within 24 h of filing.

key:agent:<ai_account_id>

Audited, in the transaction

Every write reads its row under an update lock and appends its audit row before commit — a rollback drops both. A no-op — same status, same priority, same owner, same project — writes none. The exception is the staleness acknowledgement, deliberately: it is the high-frequency touch, like a session ping.

family:backlog.* · 7 event types

Closing is deliberately expensive to undo. Resolving needs closing_pr_url, closing_commit_sha or closing_notes_markdown; dismissing needs triage_notes_markdown. Afterwards the one write a closed item accepts, besides a project move, is amend_backlog_closing_notes: it appends Amendment yyyy-MM-dd: and your text — up to 4,000 characters — below the original notes, which stay as written. Anything genuinely new is a new item with the old one as its parent.

How we use it

A launch plan generated from the live backlog

Our practice on our own ledger — described because it is the worked example, and labelled as practice: it is not a feature the server enforces.

Every session that builds PostMQ files its deferrals into this backlog, on our own SpecStep ledger, and our launch plan is generated from it. A script joins the live backlog — status read from the server, never typed — to a hand-written cut that assigns each open item to one of five tiers, P0 to P4, each with a gate sentence: P0 is “cannot test the product”, P1 “before any outside user”, P2 “production hardening”, P3 “spec and doc accuracy”, P4 “post-launch”. Three rules keep the cut from turning back into a queue. P0 is a closed set — nothing enters it that is not a hard stop on one sentence (the founder can sign up, issue a credential, connect an agent, send, receive and see it in the dashboard). And the generator fails on an item left untiered for more than a day: an untriaged heading at the top of the plan lists it straight away, and once it is a day old the generator exits non-zero naming the item and its age — so filing an item forces the tier decision within a day, without one lane’s omission blocking every other session from regenerating the plan. It exits with a distinct code when it cannot reach the ledger rather than passing silently. And the two gate tiers are confirmed, not self-assigned: a session may propose P0 or P1 and the evidence for it, but the item is marked proposed and stays out of that tier’s gate count until a person confirms it — tier is a judgement about the whole set, and the session that just measured one defect holds one data point. The plan file is never hand-edited.

The reason is a measurement, not a preference. For four weeks the backlog was not growing — it was stalled: filing and closing at about the same rate, pinned near the same count, because the queue was an open-ended set drained by priority, with no finish line and priorities that were wrong. Scoping the set fixed what working faster could not. The mechanics — the start-session read, the end-session file — are on the session-state page; the decisions the sessions record along the way are the decision log.

What people see

A board with four columns, and an item page with two forms

app.postmq.com/backlog is the board: four columns in status order — Open, In progress, Resolved, Dismissed — each headed by its count from the same roll-up the API serves, each showing up to 50 cards a column in board order and a “+N more” line past that. A card is a link: title, priority, category, and the owner’s key when there is one. Above the board sit a project filter and a title/body search — the same substring match as query_backlog, whose results replace the board until you clear it. An empty workspace is told that agents file with file_backlog_item and offered the markdown import.

app.postmq.com/backlog/{id} shows the item: status, priority, category, project, estimate, filed by, assigned to, client, parent, source PR and commit, created, updated, started, resolved and closed; then the body, the closing notes and the triage notes. On an open or in-progress item there are two forms — Move, which offers the reachable statuses and asks for closing notes when you pick resolved and a reason when you pick dismissed, and Reprioritise. On a closed item both are gone and the page says its status and priority are fixed and that agents can still append to its closing notes over the API. The overview’s Backlog tile counts open items, with in-progress alongside.

Three honest limits. The dashboard does not file, assign, amend or acknowledge staleness — those are API and MCP writes; there is no drag-and-drop — a card is a link to its item, and a move is the form; and the board shows no stale marker — the stale list is a read you make over the API or MCP. The people who use the board are the ones supervising the agents; the agents use the tools.

Every one of these writes — filed, triaged, amended, closing_notes_amended, assigned, reprioritized, reassigned — is a row on the workspace’s tamper-evident SHA-256 audit chain, appended in the same transaction as the row it records by a serialised stored procedure: a plain hash over canonical bytes chained to a per-workspace genesis anchor, not an HMAC. It is the same chain every session-state lifecycle event lands on; the staleness acknowledgement is the one backlog write that is not audited. Every workspace can browse its own chain in the dashboard and read it over REST and MCP; the mechanism is on the security page.

API surface

13 tools, 13 routes, two dashboard pages

The MCP tool, the versioned REST route under /v1 and the dashboard page all run the same service layer; the tools are thin adapters over the services the routes call, and the reads are tested byte-identical between REST and MCP.

file_backlog_item
MCP tool
{
  "method": "tools/call",
  "params": {
    "name": "file_backlog_item",
    "arguments": {
      "title": "Rate-limit bucket sync: publish deltas, not levels",
      "body_markdown": "Two replicas can split a balance. Found while pinning the sync test.",
      "priority": "high",
      "category": "correctness",
      "source_pr_url": "https://github.com/…/pull/310",
      "related_decision_log_entry_ids": ["01K…"]
    }
  }
}
REST
POST /v1/backlog
Authorization: Bearer pmq_…redacted…
Content-Type: application/json

{
  "title": "Rate-limit bucket sync: publish deltas, not levels",
  "body_markdown": "Two replicas can split a balance. Found while pinning the sync test.",
  "priority": "high",
  "category": "correctness",
  "source_pr_url": "https://github.com/…/pull/310",
  "related_decision_log_entry_ids": ["01K…"]
}
Dashboard
app.postmq.com/backlog                 the new card in the Open column — title, priority, category, owner
app.postmq.com/backlog/{id}            Filed by: agent:<ai_account_id> · Client: mcp · the source PR and related decisions
triage_backlog_item
MCP tool
{
  "method": "tools/call",
  "params": {
    "name": "triage_backlog_item",
    "arguments": {
      "backlog_item_id": "01K…",
      "new_status": "resolved",
      "closing_pr_url": "https://github.com/…/pull/318",
      "closing_notes_markdown": "Deltas published; corrections only lower. Mutation-verified."
    }
  }
}
REST
POST /v1/backlog/01K…/triage
Authorization: Bearer pmq_…redacted…
Content-Type: application/json

{
  "new_status": "resolved",
  "closing_pr_url": "https://github.com/…/pull/318",
  "closing_notes_markdown": "Deltas published; corrections only lower. Mutation-verified."
}
Dashboard
app.postmq.com/backlog/{id}            Move: pick the new status; Closing notes for resolved, Reason for dismissed
app.postmq.com/backlog                 the card moves to the Resolved column
amend_backlog_closing_notes
MCP tool
{
  "method": "tools/call",
  "params": {
    "name": "amend_backlog_closing_notes",
    "arguments": {
      "backlog_item_id": "01K…",
      "amendment_markdown": "The follow-up (per-replica clamp) is filed as 01K…, parent = this item."
    }
  }
}
REST
POST /v1/backlog/01K…/closing-notes
Authorization: Bearer pmq_…redacted…
Content-Type: application/json

{
  "amendment_markdown": "The follow-up (per-replica clamp) is filed as 01K…, parent = this item."
}
Dashboard
app.postmq.com/backlog/{id}            Closing notes: the original, then **Amendment 2026-08-18:** and the new text
                                       “This item is resolved — a terminal state. Its status and priority are fixed”
list_stale_backlog_items
MCP tool
{
  "method": "tools/call",
  "params": {
    "name": "list_stale_backlog_items",
    "arguments": {
      "threshold_days": 90,
      "limit": 50
    }
  }
}
REST
GET /v1/backlog/stale?threshold_days=90&limit=50
Authorization: Bearer pmq_…redacted…
Dashboard
app.postmq.com/backlog                 no stale marker on the board — the stale list is an API and MCP read today

The 13 MCP tools · from the server's own manifest

File, triage, prioritise, assign and close work items; terminal states are absorbing. PostMQ speaks standard MCP, so any MCP-capable client can call them; each name links to its row in the catalogue.

The backlog MCP tools, from docs/mcp/tool-surface.json
toolwhat it doesneeds
file_backlog_item File a new backlog item (kanban work item) in the open state. If you have an open build session it supplies the project; otherwise pass project_id. priority is one of critical/high/medium/low. Requires the write_session_state scope. required: title, body_markdown, priority, category write_session_state
amend_backlog_item Correct your own open backlog item within 24 hours of filing. Each supplied field replaces the current value; omitted fields are unchanged. Only the filer may amend, only while open. Requires the write_session_state scope. required: backlog_item_id write_session_state
amend_backlog_closing_notes Append a dated amendment to a resolved/dismissed backlog item's closing notes (the original notes are preserved). Only valid on a terminal item. Requires the write_session_state scope. required: backlog_item_id, amendment_markdown write_session_state
triage_backlog_item Move a backlog item between kanban states: open <-> in_progress freely; either -> resolved (needs a closing PR/commit or closing notes) or dismissed (needs triage notes). Terminal states are absorbing. Requires the write_session_state scope. required: backlog_item_id, new_status write_session_state
reprioritize_backlog_item Change a backlog item's priority (critical/high/medium/low). A no-op on a terminal item. Requires the write_session_state scope. required: backlog_item_id, priority write_session_state
assign_backlog_item Set, change, or clear a backlog item's owner. Pass assigned_to_actor_key as agent:<ai_account_id> or human:<human_id>; omit it to unassign. A no-op on a terminal item. Requires the write_session_state scope. required: backlog_item_id write_session_state
reassign_backlog_item Move a misfiled backlog item to a different project in your workspace (scope-only — never touches content). Valid in any state; idempotent when already there. Requires the write_session_state scope. required: backlog_item_id, target_project_id write_session_state
acknowledge_backlog_item_staleness Mark a backlog item as still relevant ("I looked at it") — resets its staleness clock so it drops off the stale list. A no-op on a terminal item. Requires the write_session_state scope. required: backlog_item_id write_session_state
list_stale_backlog_items List non-terminal backlog items whose staleness clock predates now minus threshold_days, oldest at-risk first. Defaults to a 90-day threshold. Open to any authenticated caller. authenticated
list_backlog_items List backlog items in board order (active work first, highest priority first, newest first), offset-paged with a total. Optionally filter by project, one or more statuses/priorities, owner, filer, or parent. Open to any authenticated caller. authenticated
get_backlog_item Fetch a single backlog item in your workspace by its backlog_item_id. Open to any authenticated caller. required: backlog_item_id authenticated
query_backlog Search your workspace's backlog by a substring across title and body. Ranked by recency, capped at 50. Returns a lightweight summary shape. Open to any authenticated caller. required: q authenticated
count_backlog_items_by_status Count backlog items per kanban status (open, in_progress, resolved, dismissed) for a board summary, zero-filled in board order. Optionally scope to one project. Open to any authenticated caller. authenticated

The 13 REST routes

Under the versioned /v1 API. The eight writes carry the write_session_state scope; the five reads accept a bearer of either tier or a human session.

The backlog REST routes
routewhat it doesneeds
POST /v1/backlog file — title, body, priority, category, optional estimate, source PR or commit, related decision ids, parent, initial owner; the project from project_id or the caller’s open build session write_session_state
POST /v1/backlog/{id}/triage move between open, in_progress, resolved and dismissed — resolving needs a closing PR, commit or closing notes; dismissing needs triage notes; a terminal item refuses write_session_state
POST /v1/backlog/{id}/amend edit title, body, category, priority or estimate — the filer only, while open, within 24 h of filing write_session_state
POST /v1/backlog/{id}/closing-notes append a dated amendment to a resolved or dismissed item’s closing notes; the original stays write_session_state
POST /v1/backlog/{id}/acknowledge-staleness stamp “still relevant” — resets the staleness clock; a no-op on a terminal item; not audited write_session_state
POST /v1/backlog/{id}/assign set or clear the owner (agent:<ai_account_id> or human:<human_id>); a no-op on a terminal item write_session_state
POST /v1/backlog/{id}/reprioritize set the priority — critical, high, medium or low; a no-op on a terminal item write_session_state
POST /v1/backlog/{id}/reassign move the item to another project in the workspace — valid in any state, idempotent write_session_state
GET /v1/backlog the board as a list — status_rank, priority_rank, newest first; offset-paged with a total; filters project, status, priority, owner, filer, parent authenticated
GET /v1/backlog/stale open and in-progress items whose staleness clock predates now minus threshold_days (default 90), oldest first authenticated
GET /v1/backlog/search a substring match over title and body, newest first, capped at 50 — search, not full-text search authenticated
GET /v1/backlog/count-by-status the per-status roll-up the board headers show authenticated
GET /v1/backlog/{id} one item — every field, the body, the closing and triage notes authenticated
Guarantees and limits

What holds, how, and where the caveat is

A mechanism per row; the badge says whether the row is shipped as stated or shipped with a caveat the note carries. Nothing on this page is default-off or roadmap.

Backlog guarantees and limits: what holds, the mechanism, and its scope
what holdshowscope
Resolved stays resolved; dismissed stays dismissedC14 tg_backlog_items_terminal_absorbing rolls back any UPDATE that changes status out of resolved or dismissed; the service refuses first with a conflict; there is no reopen tool, route or button shipped
A close explains itselfC14 resolved needs closing_pr_url, closing_commit_sha or closing_notes_markdown; dismissed needs triage_notes_markdown; the dashboard’s Move form enforces the same two rules shipped
Identity is fixed at insertC98 the same trigger rolls back any UPDATE that touches workspace_id or backlog_item_id, which is what makes the terminal guard unbypassable — a row cannot rewrite its id and slip the check; project_id may move (reassign) shipped
A closed item can still be annotatedC98 amend_backlog_closing_notes appends “**Amendment yyyy-MM-dd:**” and your text (1–4,000 characters) below the original notes, on a resolved or dismissed item only; the trigger admits it because the status does not change shipped
Edits to an open item are the filer’s, and briefC98 amend_backlog_item changes title, body, category, priority or estimate — only the credential that filed it, only while open, only within 24 h of filing; after that, reprioritise or triage shipped
Order is stored, not computed at read timeC100 priority_rank (critical, high, medium, low) and status_rank (open, in_progress, resolved, dismissed) are persisted computed columns; the board and the list sort by status_rank, priority_rank, then newest first, over an index built for it shipped
Staleness is a persisted clockC99not audited: an acknowledgement writes no audit row, deliberately, like a ping; nothing sweeps a stale item, and the dashboard shows no stale marker staleness_at = COALESCE(staleness_acknowledged_at, created_at), persisted; the stale list returns open and in-progress items older than now minus threshold_days (default 90 days, 1–3650), oldest first; acknowledging stamps the clock with one conditional UPDATE and is a no-op on a closed item shipped with caveat
List and search boundsC100no full-text index and no relevance ranking — substring plus recency list_backlog_items is offset-paged with a total, 1–100 a page (default 50), filters by project, status, priority, owner, filer and parent; query_backlog is a SQL LIKE substring match over title and body, term up to 500 characters, newest first, capped at 50 — search, not full-text search shipped with caveat
Attributed to the credential and the clientC97 filed_by_actor_key is agent:<ai_account_id>, derived from the bearer that made the call — never taken from the arguments — with the client type (api or mcp), name and version; the triaging actor is recorded the same way; the owner is the actor key you name on assign shipped
Every write requires write_session_state; every read only a loginC97 the eight write tools pass write_session_state to TryAuthorize and the eight write routes carry RequireScope("write_session_state"); the five reads accept a bearer of either tier or a human session — the same rule over REST and MCP shipped
Every write is on the audit chain — 7 backlog.* event typesC102acknowledge staleness is the deliberate exception and says so above filed, triaged, amended, closing-notes-amended, assigned, reprioritised, reassigned — each appended in the same transaction as the row change, after the item is read under an update lock; a no-op writes none; the row lands on the workspace’s tamper-evident SHA-256 chain shipped with caveat
REST and MCP return the same bytesC05 the backlog reads serialize through one shared serializer for the session-state aggregates and are tested byte-identical between the two transports shipped
People see the board and the itemC101no filing, assigning, amending or staleness acknowledgement from the dashboard, and no drag-and-drop — cards are links app.postmq.com/backlog — four columns in status order, a project filter and a title/body search, up to 50 cards a column with a “+N more” count; app.postmq.com/backlog/{id} — every field, the body, the closing and triage notes, and two forms: Move and Reprioritise shipped with caveat
Honest limits

What this is not

It is a work queue for agents’ deferrals, not a tracker for a product team. Items link to a parent and to decision-log entries, and that is the whole graph: no epics, sprints, milestones, dependencies, labels, comments or notifications. Search is a substring match over title and body — search, not full-text search — and the list is offset-paged. Staleness is a persisted timestamp and a threshold you pass; nothing sweeps, escalates or closes a stale item for you, the acknowledgement is not audited, and the dashboard shows no stale marker. There is no reopen: a closed item takes closing-notes amendments and a project move, nothing else. The dashboard board has no drag-and-drop and no filing, assigning or amending forms — those are API and MCP writes. There is no status-transition history, so flow metrics read the board as it stands. There are no CLI session-state commands. The launch-plan tiers are our practice on our own ledger, not a feature of the product.

Questions

Seven things people ask

The board is for people; the tools are for agents. An agent files, triages, prioritises, assigns and closes over MCP or REST with a write_session_state credential, and asks for the stale list; a person opens app.postmq.com/backlog, sees the four columns and every card, opens an item and, if they choose, moves it or changes its priority. The two meet on the same rows: the same trigger, the same ranks, the same audit chain.

No. A database trigger rolls back any update that changes an item’s status out of resolved or dismissed, and the service refuses first with a conflict; there is no reopen tool, route or button. What you can do is append a dated amendment to the closing notes, or file a new item and name the old one as its parent. Closing is deliberately expensive to undo, so a close means what it says.

From one persisted timestamp. Each item carries staleness_at = COALESCE(staleness_acknowledged_at, created_at) — its filing time until someone acknowledges it. The stale list is every open or in-progress item whose staleness_at is older than now minus the threshold you pass (default 90 days, 1–3650), oldest first. acknowledge_backlog_item_staleness stamps the clock with one conditional UPDATE and is a no-op on a closed item; it is not audited, like a ping. Nothing sweeps a stale item or closes it for you, and the dashboard shows no stale marker today — the list is an API and MCP read.

For an AI coding agent’s deferrals, that is what it is for: a row per thing not done, filed in the session that discovered it, attributed to the credential and the client, triaged into four states, aged by a clock that only a person or an agent resets. It is not a tracker for a product team: items link to a parent and to decisions, and that is the whole graph — no epics, sprints, dependencies, labels, comments or notifications, no drag-and-drop, and no per-column history, so flow metrics are read from the board as it stands. If you run an issue tracker, keep it; this is the queue an agent reads before it starts and files into before it stops.

A credential with the write_session_state scope — an AI account in your workspace, over MCP or the versioned REST API; the same scope covers triage, amend, assign, reprioritise, reassign and the staleness acknowledgement. Reads — the list, the stale list, the search, the counts and a single item — need only an authenticated caller: a bearer of either tier or a signed-in person. The dashboard does not file; a person can move an item between states and change its priority from app.postmq.com/backlog/{id}.

Whatever it asks for. Our own start-session step calls count_backlog_items_by_status for the shape of the queue; an agent picking up work lists open items by project or by owner in board order, and asks list_stale_backlog_items for the at-risk ones. Nothing is pushed: the backlog is a read the agent makes, and a file it makes before it ends. The rest of the protocol is on the session-state page.

Every session that builds PostMQ files its deferrals here, on our own SpecStep ledger, and our launch plan is generated from it: a script joins the live backlog to a hand-written cut that assigns each open item to one of five tiers, P0 to P4, each with a gate sentence. P0 is a closed set — nothing enters it that is not a hard stop on the sentence “the founder can sign up, issue a credential, connect an agent, send, receive and see it”. An item filed with no tier is listed under an untriaged heading at the top of the plan straight away, and the generator exits non-zero once it has been untiered for more than a day, so filing an item forces the tier decision within a day without one session’s omission blocking everyone else’s plan, and the plan file is never hand-edited. That is our practice, not a feature the server enforces.

Last verified 2026-08-18 against main at ca62072: the backlog service and query service, the migration and its trigger, the 13 tools, the 13 routes, the two dashboard pages this page names and the launch-plan generator were read on that day.

Related: session state — the protocol this is step five of · the backlog tools in the catalogue · the decision log an item can point at · the audit chain every write lands on · connect an agent.

File it once. Let the next session find it.

Create a workspace, connect your agent, and file the first deferral from the session that found it.