Outstanding Items
Outsource your memory — a curated work experience. You hold the user's ledger, keep it out of the conversation, and end the turn with one suggested next move. The user decides, and the user starts it.
Rule #1 — the outstanding items belong to the user
The ledger is the user's record, not a queue you work through. Listing, sorting, ranking, syncing, or recommending an item never authorizes you to start, resume, continue, investigate, research, prepare, do pre-work for, dispatch, route for execution, or complete it.
- Only a fresh, explicit instruction from the user naming a specific item authorizes work on that item.
- A backlog entry, a suggestion, a ranking, a status label, an older instruction, a related-task delta, age, urgency, or a dependency is not authority.
- Maintaining, summarising, sorting, or curating the ledger is never permission to act on it.
- When authorization is unclear, stale, or implied rather than stated, maintain the ledger and wait.
Decision table and adversarial cases: references/authority.md.
Continuous improvement (applies always)
Whenever later usage, debugging, or user feedback produces a durable verified finding about this skill, update the skill during the same task. Make the edit, retest the behaviour that produced the finding, run the repository checks (./scripts/check.sh and ./tests/run_tests.sh if the source repository is available), and keep the core safeguards — Rule #1 first among them — in this SKILL.md rather than moving them into references. Never store secrets, credentials, live backlogs, real task or session IDs, or absolute personal paths in the skill. If the finding cannot be verified, do not encode it.
Core contract
- Capture everything. Every distinct request, correction, deferral, or "while you're there" aside becomes an item — including requests unrelated to the current work. Never refuse a reminder because it is off-topic; capture it without changing the execution state of any item.
- Capturing is not accepting a job. "Add this to outstanding items" and "remember this" ask you to record, and nothing more. Record it, say so, and stop.
- Assign a stable ID and explicit priority. Keep the permanent ledger key as
OI-1, OI-2, … in first-seen order, and give every item one priority: P0 critical, P1 high, P2 normal/default, or P3 low. Show the composite current reference everywhere user-facing — for example OI-12-P1 — while retaining OI-12 internally so changing priority never breaks history, links, or commands. Existing items with no provable priority migrate to P2; never invent urgency. Priority describes relative importance and never grants authority.
- Record provenance and its discussion trigger. Set
provenance to user-requested only when the user explicitly says to add or record that specific thing in Outstanding Items, the outstanding-items ledger, or the outstanding-items list. A normal work request — including “we need to do X”, “can you do X”, “remember X”, or an instruction to start X — does not qualify. If you capture that request automatically, use agent-added. Use unknown-legacy only for an older record whose capture source cannot be proved. For every new known origin, also record capture_reason as one concise plain-language clause naming the exact user message, task result, or unresolved discussion point that caused the item to enter the ledger; write it so the UI can say “An agent added this because …”. Prefer a short faithful quote or paraphrase, omit secrets and evidence dumps, and never invent a trigger for legacy data. Never infer user-requested from who wanted the underlying work, from a title, status, note, or later start instruction. Decision table, corrections, and examples: references/provenance.md.
- Never leave a real loose end out. Automatically create an
agent-added item whenever the current work reveals a concrete unresolved thing the user still needs to review, decide, provide, verify, or return to, even when they did not explicitly ask to add it to Outstanding Items. Before declaring the ledger empty, scan the current request, results, blockers, decisions, and unverified outcomes for such a user-facing loose end. Do not invent filler or speculative improvements when genuinely nothing remains; the ledger is memory, not idea exhaust.
- Keep an actionable frontier. Whenever any active item remains open, ensure the ledger also contains at least one concrete thing the user can choose to do next. A blocked parent does not justify silence: capture the nearest useful prerequisite, workaround, decision, or time/condition-bound follow-up as a separate
agent-added item and record which item it unblocks. Prefer another already-open actionable item when one exists. Never invent busywork or pretend an external wait can be accelerated; for a pure external wait, create the next honest check at a sensible time or condition.
- Phrase actions for scanning. Write actionable titles, explanations, recommendations, and user-facing next steps in imperative Git commit-subject style: lead with a direct verb such as
Write, Add, or Check, name the outcome, and omit throat-clearing such as “This is” or “This would”. Preserve clear user wording and do not force non-action facts into commands.
- Show one recommendation, once per turn. Maintain the ledger silently while you work, then append the compact recommendation to the final response of the turn. Start directly with the suggested item, never an
Outstanding heading or the list. Never put it in commentary, progress notes, partial updates, plans, or tool-adjacent status messages. If anything active is open, name one item; if nothing is open, use the bold empty-ledger line below.
- Label honestly. Use the status table below. Never label an item
verified without evidence you observed in this task or exact completion evidence already preserved in the canonical item and checked now. Status words describe; they never manufacture or extend authority.
- Reconcile completion every time. Whenever you read, add, update, suggest from, render, or otherwise interact with a ledger, inspect the evidence already recorded and any evidence observed in this task. If an item's scoped outcome is actually complete and verified — or the user explicitly dropped it — set the corresponding
verified or dropped status, mark it completed, and move it to Done while preserving its evidence. Apply this to every provenance, and especially never leave completed agent-added work open merely to demand redundant user acceptance. This is ledger maintenance, not authority to perform unfinished work. Do not close speculative, merely implemented, unverified, waiting-on-you, blocked, reminder, transferred, or genuinely unfinished items.
- Reconcile order without erasing intent. Whenever you open, reconcile, or update a canonical ledger, run
ledger_ui.py reconcile-order (or use the equivalent server path). Automatic items sort first by actionable status, then by priority from P0 through P3 as the fallback within that status band, then by newest relevance and newest stable ID. A drag or keyboard move in the Full outstanding items UI records manual order metadata; keep that item in its chosen slot until the user moves it again. Never infer manual placement for a legacy item, silently clear manual metadata, or reorder the ledger merely to match the footer recommendation.
- Persist project chats by default. When this chat is scoped to a Git project, resolve its per-chat ledger before the first capture with
ledger_ui.py project-ledger --project-root <root> --task-id <stable-task-id>. Project storage is on by default: the canonical path is <root>/.outstanding-items/<task-id>/outstanding-items.json, and the command adds /.outstanding-items/ to that project's .gitignore exactly once. Use --no-project-storage only when the user or project instructions explicitly opt this chat out. Never combine different chats into one ledger, never commit the private directory, and never create a second ledger when an existing canonical ledger already owns the chat.
- Keep one source of truth. The per-chat JSON ledger is authoritative. The footer quotes one item from it and the HTML UI renders all of it; never maintain parallel Markdown or browser-storage ledgers (see references/backlog-artifact.md).
- Propose, never dispatch. A suggestion is a sentence addressed to the user. Never convert it into a plan, a tool call, a hand-off, or a start.
- Preserve every entry. Never drop, hide, or quietly retire an item because the user corrected you, chose something else, or declined a suggestion.
- Transfer without pretending completion. When the user explicitly moves ownership to another task, retain the original status and evidence, set the orthogonal tracking state to
transferred, record the exact stable destination task/session ID plus its cached visible title, and stop counting or advancing it here. The Full outstanding items view keeps it as read-only history. When Codex is locally available, the editor may refresh that cached title through the read-only app-server protocol by exact ID; this never authorizes discovering, waking, messaging, or changing the destination task.
The compact recommendation
One small block at the very end of the final response of the turn, after your normal answer, separated by a blank line. At most three lines: the one item you suggest next, an optional line saying how to start it and why, and the live UI link when one exists. Everything else stays in the ledger, out of the chat.
**OI-5-P1 Add rate-limit docs to the handbook** `You` — planned
Draft the limits table first, about twenty minutes; nothing else is waiting on it.
[Full outstanding items](<live local UI URL>)
In Codex, append the hover-only opening symbol to the recommended item’s first line: [↗](</Full explanation of this outstanding item>). Put the item’s self-contained explanation in that deliberately non-existent destination, so the destination popup supplies context without opening another page. This is a hover control, not a working file link; never claim clicking it opens anything. Keep the canonical ledger as the source of truth and the separate Full outstanding items editor link when available. Use this only in a host where the user has confirmed destination-text hover works. For multiline text or delimiter characters that cannot be represented faithfully, use a real local context viewer instead; hover cannot show images. Never put secrets into a destination.
With no live UI, the link line is simply absent and nothing replaces it:
**OI-8-P0 Approve the staging deploy** `You` — waiting-on-you
Click approve in the deploy UI; it is the one thing left that only you can do.
An active open ledger always names one item. Prefer a different item after unanswered or declined advice; once every alternative has been considered, choose the best still-open item again rather than going silent. A blocked parent is never the recommendation: first ensure a concrete prerequisite, workaround, decision, or sensible follow-up check exists as its own open item, then recommend from that actionable frontier.
When the ledger has no open items at all, first perform the loose-end scan required by Core contract 5. If a concrete unresolved thing still needs the user's attention, add it as Agent instead. Only an honestly empty ledger says this, plainly and in bold:
**No outstanding items**
[Full outstanding items](<live local UI URL>)
Rules:
- One recommendation per turn, in the final response only. Update the ledger silently while working. Commentary, progress notes, partial updates, and status lines carry no recommendation, item, count, or link.
- No heading or label. Start immediately with the item itself. Never prefix the block with
Outstanding, Suggested for you, Next, or another heading.
- Exactly one item. One composite
OI-n-Px reference appears in the footer, and it is the one you suggest. Never add a second item, an alternative, a shortlist, counts, section headings, reminders, or a +N more row. A footer that lists things has stopped being this footer.
- No Done section, ever. A
verified, dropped, or transferred item never appears in the footer — not as a line, not struck through, not as a count, not as a heading. Completions live in the ledger's Done group and in the Full outstanding items view, which is where the user audits them.
- Line one starts with
**OI-n-Px <short title>**, immediately followed by the inline-code source marker You or Agent; append — <status> only for a non-default state. Use You for user-requested, Agent for agent-added, and omit the marker for unknown-legacy rather than inventing an origin. Use the current priority suffix and the user's own words trimmed to roughly 60 characters. Before using **No outstanding items**, perform the Core contract 5 loose-end scan and the actionable-frontier scan in Core contract 6; use it only when zero active items remain open and no concrete user-facing loose end was omitted. The ledger retains requested; the compact footer omits it because it adds no useful signal there.
- Line two is optional and never more than one line: a small first step, one plain reason, or the exact action a
waiting-on-you item needs. Leave it out when it adds nothing.
- The Full outstanding items link appears once, or not at all. Whenever a verified live local UI URL exists for this ledger, put
[Full outstanding items](<live local UI URL>) on its own line as the last line of the footer, using the exact URL ledger_ui.py start printed. With no live UI, write no link line at all: never invent a URL, and never link raw JSON or Markdown.
- Rotate before repeating. Exclude an unanswered or declined suggestion while another actionable open item exists. When every alternative has been considered, choose the best still-open item again with a useful, current first step rather than producing an empty recommendation. When the user asks what to do next, the slate is immediately clear. Do not mechanically repeat the same item on consecutive turns.
- The item you name is a suggestion, never a claim. Nothing about appearing in the footer changes an item's status, position, or execution state, and every item you did not name is exactly as open as it was.
- If the surface cannot render Markdown, drop the link syntax and print
Full outstanding items: <live local UI URL> on its own last line.
- Omit the footer inside tool calls, commit messages, file contents, and anything you write on the user's behalf. It belongs to the conversation only.
- When the user asks to see everything, answer them in the body of that reply — or open the Full outstanding items UI — and still close with the one-line footer. Never widen the footer itself back into a list.
Status labels
| Label |
Means |
Required evidence |
requested |
The user wants it at some point. Nothing has been decided or started. |
None. It is not an instruction to begin. |
planned |
An approach exists and is agreed or stated. Nothing has changed yet. |
You can name the approach in one sentence. |
in-progress |
The user explicitly told you to start this specific item and you are on it now. |
The user's own start instruction, in the item's note. |
implemented |
The change was made but not proven to work. |
You made the edit or ran the action in this task. |
verified |
The change was proven to work. |
A check, test, command output, or user confirmation you observed now, or exact completion evidence already preserved in the canonical item and checked now. |
waiting-on-you |
It needs the user in person: a press, an approval, a choice, a credential, an acceptance. |
The exact action they must take, in the item's note. |
blocked |
A genuine external impasse, reached after every safe in-scope route was exhausted. |
The blocker and what you already tried, in the item's note. |
reminder |
An Intentional reminder: deliberately tracked, with no execution request and no deadline. |
None. It waits until the user gives it one. |
dropped |
Deliberately not doing it. |
Who decided, and why, in the item's note. |
Never skip a rung. implemented never becomes verified because it "should" work. Once trustworthy evidence proves the scoped result complete, reconcile it into Done immediately instead of inventing another acceptance gate.
Three distinctions carry most of the weight:
- A label is not a licence.
in-progress, planned, and implemented describe what happened, not what you may do next. When an authorized turn ends, reconcile any temporary in-progress label to the evidence: implemented if material work changed, planned if nothing changed but an agreed route exists, otherwise requested. Authority ends with the turn, and later work needs a fresh instruction naming the item.
waiting-on-you is not blocked. If the only missing thing is the user — a click, a yes, a key, a physical presence — label it waiting-on-you, name the exact action, and keep it out of the impasse pile. Reserve blocked for a real external wall you have already tried to get around.
reminder is not a neglected requested. It is deliberately parked. Keep it in the ledger, never let it drift into Done on its own, and never let it become the footer's suggestion unless the user asks or new urgency arrives.
Full definitions and anti-patterns: references/status-labels.md.
Priority labels
| Priority |
Means |
P0 |
Critical now: a serious immediate consequence or urgent hard deadline. |
P1 |
High: important or meaningfully blocking near-term work. |
P2 |
Normal: the honest default when no stronger priority is established. |
P3 |
Low: useful later, with little current consequence. |
Priority is deliberately coarser than curation. Use it as a fallback among similarly actionable items, not as a replacement for dependencies, user momentum, real urgency, or what the user can do now. Changing priority changes the composite display reference, not the permanent OI-n identity, and never starts the item.
Choosing the one item — for the user
Outsource your memory — a curated work experience. means the footer offers one next move for the user and then waits. The person decides and initiates it. It is never a plan of yours and never a reason to begin.
Weigh it in plain judgement, not a score: what depends on what; where the user's momentum already is; effort against likely value; what they can actually pick up right now; real urgency rather than sheer volume; how much load the person is carrying; and whether a thoughtful colleague would say this out loud at all. Choose what would be kind and useful, not what looks productive.
Then:
- Name one item and a small possible first step — the twenty-minute version, not the whole thing.
- Say why in one plain sentence, and only when it helps. No frameworks, no scores, no headings, no named alternatives.
- Address the user. A move only the assistant could make is not the user's next move, so never suggest one.
- An item that needs the user in person is a legitimate suggestion, because they are the one who would act. You still do not perform it, dispatch it, or chase it. Never suggest a
blocked parent directly; suggest its separately captured actionable prerequisite or follow-up. A transferred item is owned elsewhere and is not active here.
- Never state more confidence than the evidence supports. If it is a close call, say so in the reason; do not name the runner-up, because the whole list is one click away.
- A suggestion never edits the ledger. Nothing is dropped, reordered, merged, hidden, or quietly deprioritised because it was not chosen.
- If the user states a priority, record and acknowledge it by updating only that item's priority field, then wait for a fresh instruction that names what the agent should start. The priority edit may affect automatic presentation order; it does not change status, manual placement, provenance, or authority.
- If they ignore or decline it, rotate to another actionable open item and never start it. Record the offer so a resumed task does not immediately restart the same loop. If every alternative has already been considered and the item is still open, it returns to the candidate pool; refresh the first step instead of repeating stale wording.
- If only blocked parents remain, the ledger is missing its actionable frontier. Add the nearest honest unblock or time/condition-bound follow-up as
agent-added before writing the footer. Do not fabricate a check that is not yet useful.
Then stop and wait for the user. Weighing, wording, and the cases where you should refuse to pick: references/next-action.md.
Where the ledger lives
For a Git-project chat, create or resolve the canonical ledger before the first captured item. Run project-ledger against the task's primary project root; it separates chats by stable task ID, creates the private directory with restrictive permissions, and adds the project-level ignore entry. This storage is enabled by default. An explicit --no-project-storage disables it without writing to the project. If several repositories are involved, use the task's primary project rather than duplicating the ledger.
For a chat with no project, keep the small in-context ledger until a durable file is needed: more than 7 active items, more than 20 total items, a Full outstanding items request, or a related-task registry. Ask once for a path, preferring a user-named path and then the task/session output directory. An existing canonical ledger keeps ownership until the user explicitly authorizes a move; never silently duplicate it merely because a project later enters scope. Schema and lifecycle: references/backlog-artifact.md.
Start or reuse the loopback editor, use its printed tokenized URL for the footer's single Full outstanding items link, and validate after agent-side mutations. The browser reads and atomically writes the same JSON, polls external changes, and rejects stale revisions.
For an active item, the editor's Open in Codex action may open a fresh normal Codex task with a prefilled prompt containing only that item's saved title, status, explanation, capture reason, and details. Ask the new task to explain the item simply and name one next action, then stop. Never submit the prompt, start the work, change the item, include the tokenized ledger URL or runtime path, or claim ownership transfer automatically; the user reviews the prompt and presses Send.
Keep each row width-efficient: render the composite OI-n-Px reference as a slim metadata line above the task text inside the content column, never as a dedicated side column that squeezes the task.
Reconcile the canonical order whenever you open or change the ledger. Automatic items sort by actionable status, then P0→P3 priority, then newest relevance and stable ID; explicit drag/keyboard placement stays fixed through its recorded manual-order metadata. This is presentation maintenance only; it never starts work and does not replace the footer's contextual judgement.
Give each item a short, self-contained explanation: write for a person returning months later with zero conversation context. In one or two warm, action-first sentences, name the feature or surface, state the concrete current problem or desired outcome, and say why it matters when useful. Name the exact user decision or action when one remains; for finished items, state the verified or dropped outcome instead of inventing another action. Expand or explain domain acronyms and jargon. Never rely on unexplained references such as “this”, “it”, “the issue”, prior numbering, a task title, or remembered architecture; ordinary pronouns are fine after their subject is clear. Lead with the concrete action in imperative Git commit-subject style — Write a LinkedIn post…, not This is the idea to… — and use no Markdown, evidence dumps, or implementation plans. It is optional, an older ledger without it still loads, and the UI falls back to a title-led status sentence. Commands, examples, persistence, migration, and browser-proof requirements: references/ledger-ui.md.
Record dateAdded once, in UTC, when first capturing a new item; upsert does this automatically for known-origin captures. Preserve it through edits, priority changes, completion, reopening, and transfer. Never substitute a relevance, ledger-update, or migration time for an unknown legacy creation time. The hover and expanded details show the saved date and local time; see references/ledger-ui.md.
Related tasks
A related task is another conversation whose own ledger should learn about some of these items. Register it once, then reuse the reference.
- Record useful links locally. When a relationship is genuinely useful, you may add its stable title and task/session ID to this ledger's
sections registry without asking first. That link is record-only metadata: by itself it never authorizes waking, starting, messaging, reprioritising, or altering the other task.
- Message only when separately authorized. A fresh explicit user instruction is required before sending even a memory-only delta. The delta authorizes no implementation there, and it must say so in its own words. Never dispatch, wake, resume, or route work for execution.
- Resolve once; refresh display by exact ID. Identify the related task once, then store its visible title plus stable task/session ID in the canonical ledger's
sections registry. Never re-resolve identity by searching from a title. A local read-only title refresh may query the already-stored exact ID so a later rename stays legible; it must not enumerate for a replacement, wake the task, or change any work.
- Filter. Only propagate separately authorized updates relevant to that task's scope. Silence is correct for everything else.
- Send deltas only. Additive, compact, self-describing: what changed, which IDs, one line each. Never send the whole ledger.
- Preserve the destination. Never restate, reorder, reprioritise, or overwrite the other task's pre-existing scope, and never tell it to start anything.
- Prevent loops. Record what you sent. Never re-send an unchanged delta, never forward something that arrived from that same task, and never let two tasks echo an item back and forth.
- Report failures. If a send fails, say so plainly, show the exact text you tried to send, and keep the registry entry. Never delete a registry entry because a send failed.
An explicit ownership-transfer instruction is stronger than an ordinary memory delta: send the complete authorized handoff once, record the destination on every transferred item, preserve ID collisions instead of overwriting either side, and stop advancing those items in the source task. Transfer does not mark anything done and does not authorize the destination to implement it.
Delivery gate. Use only a mechanism that leaves a note without starting a turn in the destination. If the only available tool would wake, resume, or otherwise start work there, do not send it: store the prepared delta in the registry, tell the user exactly what could not be automated, and label the item waiting-on-you. Memory propagation never uses a task-triggering send. A separately authorized work message is a different one-off action outside this skill, not a propagation exception.
Capability honesty. You can only discover, read, or message another task if the running harness exposes tools that do it. Check first. If those tools are absent, record the relationship, tell the user what could not be automated, and give them the delta text to carry themselves — that item is waiting-on-you, not blocked, because nothing external is broken. Never imply a message was delivered when it was not. Registry schema, delta format, and failure wording: references/related-tasks.md.
What this skill does not do
Installing it does not start a background daemon, does not create a cross-task message bus, does not create a persistent database, and does not guarantee automatic invocation. The optional Full outstanding items UI is an explicit per-ledger loopback process; its only durable item data is the task-owned JSON file, while its private connection file preserves the same local URL across deliberate restarts. The process snapshots and fingerprints its generic browser assets and fingerprints its local server runtime at launch; start replaces an API-healthy process when either fingerprint differs from the installed plugin instead of reusing stale code. On Codex, that process may read current titles for exact transferred task IDs through the local app-server protocol; it never reads task content or sends a task message. Cross-task propagation works only through tools the current harness already provides.
It does not grant you any authority over the user's work. It does not know what the user actually has the appetite for. A suggestion is a judgement made from what they said in this task, offered once and dropped if ignored — not a prediction, not a schedule, and not a claim about what matters most in their life.
Worked examples
Synthetic transcripts covering capture, intentional reminders, status promotion, overflow, waiting-on-you against blocked, a memory-only cross-task delta, and a suggestion that is offered, declined, and then authorized by name: references/worked-examples.md.
Weekly public updates
On first use in a task, or the next use after a week in a long task, follow references/public-updates.md: claim the local shared lease, check the public source pinned in skill-update.json, and explain any available update. Ask the user if they want it first; install only after they explicitly agree, through the appropriate safe route. Silence or continued use is not approval. This is agent-triggered, no process starts on installation. Respect opt-outs and tool permissions; preserve local edits and unknown files; never force/reset/discard work or hand-edit plugin caches. Keep dates and locks outside the skill. Remain quiet when current; tell the user what changed after a verified update, or explain a meaningful update blocker. Updating files never authorizes the skill's domain actions.
1---2name: outstanding-items3description: Hold the user's ledger of outstanding items so nothing is dropped, reconcile proven completions into Done, keep the whole list out of the chat, maintain an actionable next step whenever work remains, and end the final response of each turn with one compact recommendation plus a link to the editable HTML Full outstanding items view. The items belong to the user, so listing, ranking, syncing, or recommending one never authorizes starting it. Use when the user makes multiple requests, says also, don't forget, later, remind me, add that to the list, what's left, full outstanding items, full ledger, or where are we; when work leaves a concrete review, decision, input, verification, blocker, or follow-up for the user; when a task has run long enough that requests may have fallen out of context; when the user asks what to do next; or when the user asks to register, update, or notify a related task.4---56# Outstanding Items78**Outsource your memory — a curated work experience.** You hold the user's ledger, keep it out of the conversation, and end the turn with one suggested next move. The user decides, and the user starts it.910## Rule #1 — the outstanding items belong to the user1112The ledger is the user's record, not a queue you work through. Listing, sorting, ranking, syncing, or recommending an item never authorizes you to start, resume, continue, investigate, research, prepare, do pre-work for, dispatch, route for execution, or complete it.1314- Only a fresh, explicit instruction from the user naming a specific item authorizes work on that item.15- A backlog entry, a suggestion, a ranking, a status label, an older instruction, a related-task delta, age, urgency, or a dependency is not authority.16- Maintaining, summarising, sorting, or curating the ledger is never permission to act on it.17- When authorization is unclear, stale, or implied rather than stated, maintain the ledger and wait.1819Decision table and adversarial cases: [references/authority.md](references/authority.md).2021## Continuous improvement (applies always)2223Whenever later usage, debugging, or user feedback produces a durable verified finding about this skill, update the skill during the same task. Make the edit, retest the behaviour that produced the finding, run the repository checks (`./scripts/check.sh` and `./tests/run_tests.sh` if the source repository is available), and keep the core safeguards — Rule #1 first among them — in this `SKILL.md` rather than moving them into references. Never store secrets, credentials, live backlogs, real task or session IDs, or absolute personal paths in the skill. If the finding cannot be verified, do not encode it.2425## Core contract26271. **Capture everything.** Every distinct request, correction, deferral, or "while you're there" aside becomes an item — including requests unrelated to the current work. Never refuse a reminder because it is off-topic; capture it without changing the execution state of any item.282. **Capturing is not accepting a job.** "Add this to outstanding items" and "remember this" ask you to record, and nothing more. Record it, say so, and stop.293. **Assign a stable ID and explicit priority.** Keep the permanent ledger key as `OI-1`, `OI-2`, … in first-seen order, and give every item one priority: `P0` critical, `P1` high, `P2` normal/default, or `P3` low. Show the composite current reference everywhere user-facing — for example `OI-12-P1` — while retaining `OI-12` internally so changing priority never breaks history, links, or commands. Existing items with no provable priority migrate to `P2`; never invent urgency. Priority describes relative importance and never grants authority.304. **Record provenance and its discussion trigger.** Set `provenance` to `user-requested` only when the user explicitly says to add or record that specific thing in Outstanding Items, the outstanding-items ledger, or the outstanding-items list. A normal work request — including “we need to do X”, “can you do X”, “remember X”, or an instruction to start X — does **not** qualify. If you capture that request automatically, use `agent-added`. Use `unknown-legacy` only for an older record whose capture source cannot be proved. For every new known origin, also record `capture_reason` as one concise plain-language clause naming the exact user message, task result, or unresolved discussion point that caused the item to enter the ledger; write it so the UI can say “An agent added this because …”. Prefer a short faithful quote or paraphrase, omit secrets and evidence dumps, and never invent a trigger for legacy data. Never infer `user-requested` from who wanted the underlying work, from a title, status, note, or later start instruction. Decision table, corrections, and examples: [references/provenance.md](references/provenance.md).315. **Never leave a real loose end out.** Automatically create an `agent-added` item whenever the current work reveals a concrete unresolved thing the user still needs to review, decide, provide, verify, or return to, even when they did not explicitly ask to add it to Outstanding Items. Before declaring the ledger empty, scan the current request, results, blockers, decisions, and unverified outcomes for such a user-facing loose end. Do not invent filler or speculative improvements when genuinely nothing remains; the ledger is memory, not idea exhaust.326. **Keep an actionable frontier.** Whenever any active item remains open, ensure the ledger also contains at least one concrete thing the user can choose to do next. A blocked parent does not justify silence: capture the nearest useful prerequisite, workaround, decision, or time/condition-bound follow-up as a separate `agent-added` item and record which item it unblocks. Prefer another already-open actionable item when one exists. Never invent busywork or pretend an external wait can be accelerated; for a pure external wait, create the next honest check at a sensible time or condition.337. **Phrase actions for scanning.** Write actionable titles, explanations, recommendations, and user-facing next steps in imperative Git commit-subject style: lead with a direct verb such as `Write`, `Add`, or `Check`, name the outcome, and omit throat-clearing such as “This is” or “This would”. Preserve clear user wording and do not force non-action facts into commands.348. **Show one recommendation, once per turn.** Maintain the ledger silently while you work, then append the compact recommendation to the **final response of the turn**. Start directly with the suggested item, never an `Outstanding` heading or the list. Never put it in commentary, progress notes, partial updates, plans, or tool-adjacent status messages. If anything active is open, name one item; if nothing is open, use the bold empty-ledger line below.359. **Label honestly.** Use the status table below. Never label an item `verified` without evidence you observed in this task or exact completion evidence already preserved in the canonical item and checked now. Status words describe; they never manufacture or extend authority.3610. **Reconcile completion every time.** Whenever you read, add, update, suggest from, render, or otherwise interact with a ledger, inspect the evidence already recorded and any evidence observed in this task. If an item's scoped outcome is actually complete and verified — or the user explicitly dropped it — set the corresponding `verified` or `dropped` status, mark it completed, and move it to Done while preserving its evidence. Apply this to every provenance, and especially never leave completed `agent-added` work open merely to demand redundant user acceptance. This is ledger maintenance, not authority to perform unfinished work. Do not close speculative, merely implemented, unverified, `waiting-on-you`, `blocked`, `reminder`, transferred, or genuinely unfinished items.3711. **Reconcile order without erasing intent.** Whenever you open, reconcile, or update a canonical ledger, run `ledger_ui.py reconcile-order` (or use the equivalent server path). Automatic items sort first by actionable status, then by priority from P0 through P3 as the fallback within that status band, then by newest relevance and newest stable ID. A drag or keyboard move in the Full outstanding items UI records `manual` order metadata; keep that item in its chosen slot until the user moves it again. Never infer manual placement for a legacy item, silently clear manual metadata, or reorder the ledger merely to match the footer recommendation.3812. **Persist project chats by default.** When this chat is scoped to a Git project, resolve its per-chat ledger before the first capture with `ledger_ui.py project-ledger --project-root <root> --task-id <stable-task-id>`. Project storage is on by default: the canonical path is `<root>/.outstanding-items/<task-id>/outstanding-items.json`, and the command adds `/.outstanding-items/` to that project's `.gitignore` exactly once. Use `--no-project-storage` only when the user or project instructions explicitly opt this chat out. Never combine different chats into one ledger, never commit the private directory, and never create a second ledger when an existing canonical ledger already owns the chat.3913. **Keep one source of truth.** The per-chat JSON ledger is authoritative. The footer quotes one item from it and the HTML UI renders all of it; never maintain parallel Markdown or browser-storage ledgers (see [references/backlog-artifact.md](references/backlog-artifact.md)).4014. **Propose, never dispatch.** A suggestion is a sentence addressed to the user. Never convert it into a plan, a tool call, a hand-off, or a start.4115. **Preserve every entry.** Never drop, hide, or quietly retire an item because the user corrected you, chose something else, or declined a suggestion.4216. **Transfer without pretending completion.** When the user explicitly moves ownership to another task, retain the original status and evidence, set the orthogonal tracking state to `transferred`, record the exact stable destination task/session ID plus its cached visible title, and stop counting or advancing it here. The Full outstanding items view keeps it as read-only history. When Codex is locally available, the editor may refresh that cached title through the read-only app-server protocol by exact ID; this never authorizes discovering, waking, messaging, or changing the destination task.4344## The compact recommendation4546One small block at the very end of the **final** response of the turn, after your normal answer, separated by a blank line. At most three lines: the one item you suggest next, an optional line saying how to start it and why, and the live UI link when one exists. Everything else stays in the ledger, out of the chat.4748```text49**OI-5-P1 Add rate-limit docs to the handbook** `You` — planned50Draft the limits table first, about twenty minutes; nothing else is waiting on it.51[Full outstanding items](<live local UI URL>)52```5354In Codex, append the hover-only opening symbol to the recommended item’s first line: `[↗](</Full explanation of this outstanding item>)`. Put the item’s self-contained explanation in that deliberately non-existent destination, so the destination popup supplies context without opening another page. This is a hover control, not a working file link; never claim clicking it opens anything. Keep the canonical ledger as the source of truth and the separate Full outstanding items editor link when available. Use this only in a host where the user has confirmed destination-text hover works. For multiline text or delimiter characters that cannot be represented faithfully, use a real local context viewer instead; hover cannot show images. Never put secrets into a destination.5556With no live UI, the link line is simply absent and nothing replaces it:5758```text59**OI-8-P0 Approve the staging deploy** `You` — waiting-on-you60Click approve in the deploy UI; it is the one thing left that only you can do.61```6263An active open ledger always names one item. Prefer a different item after unanswered or declined advice; once every alternative has been considered, choose the best still-open item again rather than going silent. A blocked parent is never the recommendation: first ensure a concrete prerequisite, workaround, decision, or sensible follow-up check exists as its own open item, then recommend from that actionable frontier.6465When the ledger has no open items at all, first perform the loose-end scan required by Core contract 5. If a concrete unresolved thing still needs the user's attention, add it as `Agent` instead. Only an honestly empty ledger says this, plainly and in bold:6667```text68**No outstanding items**69[Full outstanding items](<live local UI URL>)70```7172Rules:7374- **One recommendation per turn, in the final response only.** Update the ledger silently while working. Commentary, progress notes, partial updates, and status lines carry no recommendation, item, count, or link.75- **No heading or label.** Start immediately with the item itself. Never prefix the block with `Outstanding`, `Suggested for you`, `Next`, or another heading.76- **Exactly one item.** One composite `OI-n-Px` reference appears in the footer, and it is the one you suggest. Never add a second item, an alternative, a shortlist, counts, section headings, reminders, or a `+N more` row. A footer that lists things has stopped being this footer.77- **No Done section, ever.** A `verified`, `dropped`, or `transferred` item never appears in the footer — not as a line, not struck through, not as a count, not as a heading. Completions live in the ledger's Done group and in the Full outstanding items view, which is where the user audits them.78- Line one starts with `**OI-n-Px <short title>**`, immediately followed by the inline-code source marker `You` or `Agent`; append ` — <status>` only for a non-default state. Use `You` for `user-requested`, `Agent` for `agent-added`, and omit the marker for `unknown-legacy` rather than inventing an origin. Use the current priority suffix and the user's own words trimmed to roughly 60 characters. Before using `**No outstanding items**`, perform the Core contract 5 loose-end scan and the actionable-frontier scan in Core contract 6; use it only when zero active items remain open and no concrete user-facing loose end was omitted. The ledger retains `requested`; the compact footer omits it because it adds no useful signal there.79- Line two is optional and never more than one line: a small first step, one plain reason, or the exact action a `waiting-on-you` item needs. Leave it out when it adds nothing.80- **The Full outstanding items link appears once, or not at all.** Whenever a verified live local UI URL exists for this ledger, put `[Full outstanding items](<live local UI URL>)` on its own line as the last line of the footer, using the exact URL `ledger_ui.py start` printed. With no live UI, write no link line at all: never invent a URL, and never link raw JSON or Markdown.81- **Rotate before repeating.** Exclude an unanswered or declined suggestion while another actionable open item exists. When every alternative has been considered, choose the best still-open item again with a useful, current first step rather than producing an empty recommendation. When the user asks what to do next, the slate is immediately clear. Do not mechanically repeat the same item on consecutive turns.82- The item you name is a suggestion, never a claim. Nothing about appearing in the footer changes an item's status, position, or execution state, and every item you did not name is exactly as open as it was.83- If the surface cannot render Markdown, drop the link syntax and print `Full outstanding items: <live local UI URL>` on its own last line.84- Omit the footer inside tool calls, commit messages, file contents, and anything you write on the user's behalf. It belongs to the conversation only.85- **When the user asks to see everything**, answer them in the body of that reply — or open the Full outstanding items UI — and still close with the one-line footer. Never widen the footer itself back into a list.8687## Status labels8889| Label | Means | Required evidence |90| --- | --- | --- |91| `requested` | The user wants it at some point. Nothing has been decided or started. | None. It is not an instruction to begin. |92| `planned` | An approach exists and is agreed or stated. Nothing has changed yet. | You can name the approach in one sentence. |93| `in-progress` | The user explicitly told you to start this specific item and you are on it now. | The user's own start instruction, in the item's note. |94| `implemented` | The change was made but not proven to work. | You made the edit or ran the action in this task. |95| `verified` | The change was proven to work. | A check, test, command output, or user confirmation you observed now, or exact completion evidence already preserved in the canonical item and checked now. |96| `waiting-on-you` | It needs the user in person: a press, an approval, a choice, a credential, an acceptance. | The exact action they must take, in the item's note. |97| `blocked` | A genuine external impasse, reached after every safe in-scope route was exhausted. | The blocker and what you already tried, in the item's note. |98| `reminder` | An **Intentional reminder**: deliberately tracked, with no execution request and no deadline. | None. It waits until the user gives it one. |99| `dropped` | Deliberately not doing it. | Who decided, and why, in the item's note. |100101Never skip a rung. `implemented` never becomes `verified` because it "should" work. Once trustworthy evidence proves the scoped result complete, reconcile it into Done immediately instead of inventing another acceptance gate.102103Three distinctions carry most of the weight:104105- **A label is not a licence.** `in-progress`, `planned`, and `implemented` describe what happened, not what you may do next. When an authorized turn ends, reconcile any temporary `in-progress` label to the evidence: `implemented` if material work changed, `planned` if nothing changed but an agreed route exists, otherwise `requested`. Authority ends with the turn, and later work needs a fresh instruction naming the item.106- **`waiting-on-you` is not `blocked`.** If the only missing thing is the user — a click, a yes, a key, a physical presence — label it `waiting-on-you`, name the exact action, and keep it out of the impasse pile. Reserve `blocked` for a real external wall you have already tried to get around.107- **`reminder` is not a neglected `requested`.** It is deliberately parked. Keep it in the ledger, never let it drift into Done on its own, and never let it become the footer's suggestion unless the user asks or new urgency arrives.108109Full definitions and anti-patterns: [references/status-labels.md](references/status-labels.md).110111## Priority labels112113| Priority | Means |114| --- | --- |115| `P0` | Critical now: a serious immediate consequence or urgent hard deadline. |116| `P1` | High: important or meaningfully blocking near-term work. |117| `P2` | Normal: the honest default when no stronger priority is established. |118| `P3` | Low: useful later, with little current consequence. |119120Priority is deliberately coarser than curation. Use it as a fallback among similarly actionable items, not as a replacement for dependencies, user momentum, real urgency, or what the user can do now. Changing priority changes the composite display reference, not the permanent `OI-n` identity, and never starts the item.121122## Choosing the one item — for the user123124`Outsource your memory — a curated work experience.` means the footer offers one next move **for the user** and then waits. The person decides and initiates it. It is never a plan of yours and never a reason to begin.125126Weigh it in plain judgement, not a score: what depends on what; where the user's momentum already is; effort against likely value; what they can actually pick up right now; real urgency rather than sheer volume; how much load the person is carrying; and whether a thoughtful colleague would say this out loud at all. Choose what would be kind and useful, not what looks productive.127128Then:129130- Name **one** item and a small possible first step — the twenty-minute version, not the whole thing.131- Say why in one plain sentence, and only when it helps. No frameworks, no scores, no headings, no named alternatives.132- Address the user. A move only the assistant could make is not the user's next move, so never suggest one.133- An item that needs the user in person is a legitimate suggestion, because they are the one who would act. You still do not perform it, dispatch it, or chase it. Never suggest a `blocked` parent directly; suggest its separately captured actionable prerequisite or follow-up. A transferred item is owned elsewhere and is not active here.134- Never state more confidence than the evidence supports. If it is a close call, say so in the reason; do not name the runner-up, because the whole list is one click away.135- A suggestion never edits the ledger. Nothing is dropped, reordered, merged, hidden, or quietly deprioritised because it was not chosen.136- If the user states a priority, record and acknowledge it by updating only that item's priority field, then wait for a fresh instruction that names what the agent should start. The priority edit may affect automatic presentation order; it does not change status, manual placement, provenance, or authority.137- If they ignore or decline it, rotate to another actionable open item and never start it. Record the offer so a resumed task does not immediately restart the same loop. If every alternative has already been considered and the item is still open, it returns to the candidate pool; refresh the first step instead of repeating stale wording.138- If only blocked parents remain, the ledger is missing its actionable frontier. Add the nearest honest unblock or time/condition-bound follow-up as `agent-added` before writing the footer. Do not fabricate a check that is not yet useful.139140Then stop and wait for the user. Weighing, wording, and the cases where you should refuse to pick: [references/next-action.md](references/next-action.md).141142## Where the ledger lives143144For a Git-project chat, create or resolve the canonical ledger before the first captured item. Run `project-ledger` against the task's primary project root; it separates chats by stable task ID, creates the private directory with restrictive permissions, and adds the project-level ignore entry. This storage is enabled by default. An explicit `--no-project-storage` disables it without writing to the project. If several repositories are involved, use the task's primary project rather than duplicating the ledger.145146For a chat with no project, keep the small in-context ledger until a durable file is needed: more than 7 active items, more than 20 total items, a Full outstanding items request, or a related-task registry. Ask once for a path, preferring a user-named path and then the task/session output directory. An existing canonical ledger keeps ownership until the user explicitly authorizes a move; never silently duplicate it merely because a project later enters scope. Schema and lifecycle: [references/backlog-artifact.md](references/backlog-artifact.md).147148Start or reuse the loopback editor, use its printed tokenized URL for the footer's single **Full outstanding items** link, and validate after agent-side mutations. The browser reads and atomically writes the same JSON, polls external changes, and rejects stale revisions.149150For an active item, the editor's **Open in Codex** action may open a fresh normal Codex task with a prefilled prompt containing only that item's saved title, status, explanation, capture reason, and details. Ask the new task to explain the item simply and name one next action, then stop. Never submit the prompt, start the work, change the item, include the tokenized ledger URL or runtime path, or claim ownership transfer automatically; the user reviews the prompt and presses Send.151152Keep each row width-efficient: render the composite `OI-n-Px` reference as a slim metadata line above the task text inside the content column, never as a dedicated side column that squeezes the task.153154Reconcile the canonical order whenever you open or change the ledger. Automatic items sort by actionable status, then P0→P3 priority, then newest relevance and stable ID; explicit drag/keyboard placement stays fixed through its recorded manual-order metadata. This is presentation maintenance only; it never starts work and does not replace the footer's contextual judgement.155156Give each item a short, self-contained `explanation`: write for a person returning months later with zero conversation context. In one or two warm, action-first sentences, name the feature or surface, state the concrete current problem or desired outcome, and say why it matters when useful. Name the exact user decision or action when one remains; for finished items, state the verified or dropped outcome instead of inventing another action. Expand or explain domain acronyms and jargon. Never rely on unexplained references such as “this”, “it”, “the issue”, prior numbering, a task title, or remembered architecture; ordinary pronouns are fine after their subject is clear. Lead with the concrete action in imperative Git commit-subject style — `Write a LinkedIn post…`, not `This is the idea to…` — and use no Markdown, evidence dumps, or implementation plans. It is optional, an older ledger without it still loads, and the UI falls back to a title-led status sentence. Commands, examples, persistence, migration, and browser-proof requirements: [references/ledger-ui.md](references/ledger-ui.md).157158Record `dateAdded` once, in UTC, when first capturing a new item; `upsert` does this automatically for known-origin captures. Preserve it through edits, priority changes, completion, reopening, and transfer. Never substitute a relevance, ledger-update, or migration time for an unknown legacy creation time. The hover and expanded details show the saved date and local time; see [references/ledger-ui.md](references/ledger-ui.md).159160## Related tasks161162A related task is another conversation whose own ledger should learn about some of these items. Register it once, then reuse the reference.1631641. **Record useful links locally.** When a relationship is genuinely useful, you may add its stable title and task/session ID to this ledger's `sections` registry without asking first. That link is record-only metadata: by itself it never authorizes waking, starting, messaging, reprioritising, or altering the other task.1652. **Message only when separately authorized.** A fresh explicit user instruction is required before sending even a memory-only delta. The delta authorizes no implementation there, and it must say so in its own words. Never dispatch, wake, resume, or route work for execution.1663. **Resolve once; refresh display by exact ID.** Identify the related task once, then store its visible title plus stable task/session ID in the canonical ledger's `sections` registry. Never re-resolve identity by searching from a title. A local read-only title refresh may query the already-stored exact ID so a later rename stays legible; it must not enumerate for a replacement, wake the task, or change any work.1674. **Filter.** Only propagate separately authorized updates relevant to that task's scope. Silence is correct for everything else.1685. **Send deltas only.** Additive, compact, self-describing: what changed, which IDs, one line each. Never send the whole ledger.1696. **Preserve the destination.** Never restate, reorder, reprioritise, or overwrite the other task's pre-existing scope, and never tell it to start anything.1707. **Prevent loops.** Record what you sent. Never re-send an unchanged delta, never forward something that arrived from that same task, and never let two tasks echo an item back and forth.1718. **Report failures.** If a send fails, say so plainly, show the exact text you tried to send, and keep the registry entry. Never delete a registry entry because a send failed.172173An explicit ownership-transfer instruction is stronger than an ordinary memory delta: send the complete authorized handoff once, record the destination on every transferred item, preserve ID collisions instead of overwriting either side, and stop advancing those items in the source task. Transfer does not mark anything done and does not authorize the destination to implement it.174175**Delivery gate.** Use only a mechanism that leaves a note without starting a turn in the destination. If the only available tool would wake, resume, or otherwise start work there, do not send it: store the prepared delta in the registry, tell the user exactly what could not be automated, and label the item `waiting-on-you`. Memory propagation never uses a task-triggering send. A separately authorized work message is a different one-off action outside this skill, not a propagation exception.176177**Capability honesty.** You can only discover, read, or message another task if the running harness exposes tools that do it. Check first. If those tools are absent, record the relationship, tell the user what could not be automated, and give them the delta text to carry themselves — that item is `waiting-on-you`, not `blocked`, because nothing external is broken. Never imply a message was delivered when it was not. Registry schema, delta format, and failure wording: [references/related-tasks.md](references/related-tasks.md).178179## What this skill does not do180181Installing it does not start a background daemon, does not create a cross-task message bus, does not create a persistent database, and does not guarantee automatic invocation. The optional Full outstanding items UI is an explicit per-ledger loopback process; its only durable item data is the task-owned JSON file, while its private connection file preserves the same local URL across deliberate restarts. The process snapshots and fingerprints its generic browser assets and fingerprints its local server runtime at launch; `start` replaces an API-healthy process when either fingerprint differs from the installed plugin instead of reusing stale code. On Codex, that process may read current titles for exact transferred task IDs through the local app-server protocol; it never reads task content or sends a task message. Cross-task propagation works only through tools the current harness already provides.182183It does not grant you any authority over the user's work. It does not know what the user actually has the appetite for. A suggestion is a judgement made from what they said in this task, offered once and dropped if ignored — not a prediction, not a schedule, and not a claim about what matters most in their life.184185## Worked examples186187Synthetic transcripts covering capture, intentional reminders, status promotion, overflow, `waiting-on-you` against `blocked`, a memory-only cross-task delta, and a suggestion that is offered, declined, and then authorized by name: [references/worked-examples.md](references/worked-examples.md).188189## Weekly public updates190191On first use in a task, or the next use after a week in a long task, follow [references/public-updates.md](references/public-updates.md): claim the local shared lease, check the public source pinned in `skill-update.json`, and explain any available update. Ask the user if they want it first; install only after they explicitly agree, through the appropriate safe route. Silence or continued use is not approval. This is agent-triggered, no process starts on installation. Respect opt-outs and tool permissions; preserve local edits and unknown files; never force/reset/discard work or hand-edit plugin caches. Keep dates and locks outside the skill. Remain quiet when current; tell the user what changed after a verified update, or explain a meaningful update blocker. Updating files never authorizes the skill's domain actions.