Chips are a project's suggested tasks, the side work outside a run's target that the owner can start in a new session. They live as rows in one ledger per project, and a card in a suggest tool is only a view of one. The law is .agents/pstack/rules/chips.md, which sync-pstack renders into every project. Read it in full before this session's first ledger write. This skill runs its modes; it adds no rule of its own.
Every command below is node .agents/pstack/decisions-check.mjs <command>, run from the project's checkout, which a card session that opened in its own worktree names by the path its brief prints. Get this session's id from the runtime's session tool, such as Claude Code desktop's get_session with self, and pass --session <id> to every board read. A runtime with no session tool reads the board without it.
| Mode | Use it to |
|---|---|
Sweep, /chips with no argument |
bring every open task up to date, card what can start and report the board |
| Offer | add a finding, the one way new work enters the ledger |
| Start | begin a task a card opened, in the card's session |
| Drop | record the owner's word to drop a task |
pstack calls these modes too. Where a pstack step files a tracked issue, a follow-up or a reflect Backlog item, or puts an out-of-band fix in its own PR, the lead runs Offer instead. At each hand-back, after each compaction and at the close, it runs a quick sweep, which skips step 3. A question about open chips, such as "what's next" over side work, runs steps 1 and 6 and writes nothing.
Sweep
-
When the owner typed
/chips, runchips lead --session <id>first, which makes this session the chips lead, as chips.md's Lead says; a quick sweep skips it. Then runchips --session <id>andchips stale. The stale report lists each open task with its age, the paths it writes that were deleted since its offer or are missing, the commits on its paths since its offer, its closed PR waits and its card, the likeliest stale first. -
Apply the pass the Do list shows, together with the run's own rows that chips.md's Sweep lists, in one
append --from <file>batch:- Withdrawal pass: call the dismiss tool on each card it names, then log the row the tool's report decides, as each item says. That includes each card this session withdraws because another session leads the chips.
- Ledger pass: log each row it names.
- Card pass: leave it to step 5.
- Check items: look each session up with the session tool. Log
uncardedwith a card item'scard:when the tool reports its session archived or gone. For a started task whose rows name no session, find it as the item says and logstartedwith itssession:. When the tool reports a started task's session archived, read its last report with the tool, then loglandedwhen a commit holds the change or that report says the session delivered it, withpatch:when it names one. When that report hands back a patch it never applied, land the patch as chips.md's Landing says and loglandedwithpatch:. Logdismissed stoppedonly when that report hands back no patch and neither this checkout nor the session's own worktree holds an uncommitted edit on the task's paths. Otherwise, or when the tool cannot find the session, the task stays started, and step 6 says why.
Run
chips --session <id>again and repeat until the Do list shows only the card pass or nothing you can apply. Whenappendrefuses a batch, fix or drop the refused row as its message says and append the rest. -
Judge each task the stale report gives a fact, from its brief, those facts and the code, and append the rows in one batch:
- When the tree already holds its fix, log
dismissed done, citing the commit. - When its target was deleted since its offer, log
dismissed superseded. When a path only moved, logupdatedwith the newwrites:. - A missing path is one the offer named wrongly or one the task will create. Find the real path with
git ls-filesand logupdatedwith it, or leave a path the task creates. A carded task'supdatedonly drops paths, so its session names the real one in itsstartedrow. - When a PR it waits on closed without merging, log
updatedwith the waits it has now. - When two open tasks answer one question, log the topic move and
dismissed dupthat chips.md's Sweep gives. When the keeper holds a card or is started, logwaits: task:<keeper>on the other instead. - For a started task, log
landedwhen a commit holds its change. Step 2's check item settles the rest from its session, so never ask the owner whether that session still runs. - When the report marks a task possibly thin, find its finding in the plan, log or run its offer names, and log it as a
foldedrow. When this session holds the task's card, withdraw it first. When another session holds it, fold the finding once that card leaves the queue. When no source holds the finding, leave the task as it is. Step 6 says which tasks stay thin. - For each task that holds a card and whose Ready line says it shares paths with another open task, judge its dependencies as step 5 does, because it may have been carded before anyone judged them. When it needs another task's result, log
updatedwith its waits plustask:<that id>, which a carded task takes. - For each task that holds a card, check its effort against chips.md's Title rule as step 5 does, and log
updatedwith the righteffort:when they differ, which a carded task takes.
- When the tree already holds its fix, log
-
Repeat step 2 for what step 3 changed.
-
Card pass: before each card, judge whether the task needs the result of another open task, starting with each one its Ready line says shares its paths, or of an open design question its work builds on. When it does, log
updatedwith its waits plustask:<that id>instead of the card. Also check the effort its brief shows against chips.md's Title rule, and logupdatedwitheffort: highfor an(xhigh)fix whose finding names its cause and where it lives, oreffort: xhighfor a bug or slowness whose cause nobody has located. Then offer each card the Do list names with whatchips brief <id>prints as its prompt, verbatim, and the effort its brief shows, while the suggest tool's last result lists fewer than 20 pending cards, all in the same turn, then logcardedwithcard:andsession:. A runtime with no suggest tool lists each Ready task in the plan's## Open workinstead, as chips.md's Limits says. Before each card, check whether the task'swrites:touch an active plan, one whoseStatus:starts with a wordstatus.mjscounts as active, such as building. That plan's files are the plan itself, its decision log and its subject file<plans>/topics/<topic>.md. The topic is itsTopic:line, or the first entry of the frontmatter list thatpageTopic.fieldin.agents/pstack.jsonnames. Its session is rewriting those files, andchipssees only ledger tasks, so logupdatedwith the task's waits plusrun:<that plan>instead of the card. -
Report in plain words each row this sweep logged, one line each, then what can start and whether it has a card, with
start <id>beside each Ready task the 20-card limit left uncarded, what is started, why it stays open and that "drop " closes it, what waits and on what, grouped by the thing waited on, and the fast work owed a review. When a task waits on landed work the owner has not committed, the report suggests that commit before it lists what can start, naming each landed task and how many waiting tasks its commit frees, because the next wave starts only after it. Name each task by id and title. The report asks the owner nothing. The owner reverses a dismissal by asking, and the lead offers the task again. -
While any task is started or carded, and where the runtime re-invokes the lead when a background command exits, run
chips wait --session <id>in the background, as chips.md's Waves says. When it exits naming a started session, look that session up with the session tool. Lower it to its brief's effort when it still runs at its card's effort, whichchips waitprints, or at yours when the suggest tool took none, as chips.md says. Then run this sweep again.
Offer
- Run
chips --session <id>first, and read the brief of each open task whose topic or title touches the finding withchips brief <id>. - Pick the row as chips.md's Offer says:
- When the finding belongs to an offered task's question and that task holds no card, log a
foldedrow on it with what the finding adds. - When it belongs to the question of a started task or of one that holds a card, offer a new task in that topic with
waits: task:<id>.chipsmerges it into a carded task once the card is withdrawn. - Otherwise offer a new task with an id from
chips id, a plain imperative title,(xhigh)only where chips.md's Title rule gives it, and itswrites:,topic:,kind:,waits:,owns:andsession:, this session's id, so this session can card it at its close wherever the chips lead is. Itswaits:includerun:<plan>for each active plan whose files it writes, as Sweep step 5 finds them. Reuse a topic the board lists when the finding answers its question. A new topic names one owner question, never an area.
- When the finding belongs to an offered task's question and that task holds no card, log a
- Append it with
append <plans>/suggested-tasks.decisions.tsv chip "<id> <title>" "<finding>" "<tokens>" <result>. Whenappendrefuses the row, its message names the route; follow it. - Leave the card to the next sweep.
Start
A session a card opened, or one the lead started on the owner's "start ", runs this before it writes anything, as chips.md's Sweep says.
- Run
chips brief <id>and work from what it prints, not from the card's prompt. - Run
chips. When the task is neither Ready nor Started, tell the owner what it waits on and stop. - Log
startedwithwrites:naming any path the brief lacks andsession:naming this session's id where the runtime's session tool gives one, then runchips brief <id>again, because the task could change until that row. When the session tool shows this session above the brief'sEffort:, say so to the owner in your first reply, because a session cannot lower its own effort. - Before writing a path the task does not list, log another
startedrow with it. Whenappendrefuses that row because another started task writes that path outside the checkout, leave the path alone and tell the owner. - When the work is done, land it as the brief's paragraph on landing and chips.md's Landing say, and log
landedwithpatch:. A review task's session first logsreviewedon each task it reviewed.
Drop
- When the task is started, log
dismissed stopped. - When the task holds a card this session offered, call the dismiss tool on it. When the tool reports the owner started it, log
startedand tell the owner. Otherwise logdismissed declinedwith itscard:, in place ofuncarded, so no merge lands between the two. - When another session holds its card, log
dismissed declinedwith thatcard:. - When it holds no card, log
dismissed declined.