Work on the Otaq ticket named by $OTAQ_TICKET from start to review - get its context with `otaq prime`, follow the user's Agent instructions, check the ticket for gaps and ask what changes what gets built (options with pros and cons) before coding, decide by the size measure whether to build alone or write a Plan of pieces, implement (or, when the Plan has pieces, start a helper per piece, review, test and merge each, and re-split when the work grows or a helper hands back a piece too big), c...
Installs into .claude/skills of the current project.
Sponsors
SSkills DirectorySkills Directory
Know which skills are safe — weekly.
SSkills DirectorySkills Directory
Is that skill safe to install?
Are you the author of Work Ticket?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/otaq-io-work-ticket)
---
name: work-ticket
description: Work on the Otaq ticket named by $OTAQ_TICKET from start to review - get its context with `otaq prime`, follow the user's Agent instructions, check the ticket for gaps and ask what changes what gets built (options with pros and cons) before coding, decide by the size measure whether to build alone or write a Plan of pieces, implement (or, when the Plan has pieces, start a helper per piece, review, test and merge each, and re-split when the work grows or a helper hands back a piece too big), commit everything, then end your stage with a short comment through `otaq stage next` that says what you ran, at which commit, and where the log is. With $OTAQ_PIECE set, build one piece as a helper and hand it back with `otaq helper done`, early with a suggested split when it is too big.
disable-model-invocation: true
---
# Work on your Otaq ticket
You are the agent for one Otaq ticket. Its key is in `$OTAQ_TICKET` (for example `SHOP-19`). You work in
the ticket's own git worktree, on its own branch. The user watches the board and can type into this session at any
time.
**Is `$OTAQ_PIECE` set** (for example `3`)? Then you are not the ticket's agent but a **helper** building one piece of
it: skip the steps below and follow "As a helper" at the end.
**Your stage ends only when you run `otaq stage next`** (or `otaq stage done` when there is nothing to deliver), or
pauses while you wait for the user's answer to `otaq ask human --stdin`. A summary in this chat reaches no one: the
board, the user and the next stage see only what those commands carry. So when your work is done and nothing is open,
don't stop to report or to ask whether to go on: commit and end your stage. If you end your turn without either, Otaq
types a reminder into this session.
## Steps
1. **Get the context first.** Run `otaq prime` and read all of it: the ticket and its description, the
user's **Agent instructions** and the project's notes, your stage and its skill, the earlier stages, the
**comments** (what the user and the earlier stages' agents handed over), the tickets it depends on (with their
agents' last comments) and Otaq's rules. Otaq refuses to end your stage until you have run it: "Run `otaq prime`
first: SHOP-19 has 2 comments you haven't read." The description is the plan; when a comment changes it, follow the
comment. **Open the reports from you before you start.** `prime` lists the files the user attached under "Reports from
you · read these before you start"; read each one (`otaq report SHOP-19 1`, or search a long one with
`grep -n "Safari" "$(otaq report SHOP-19 1 --path)"`). The agents' reports you open only when you need them.
**Your stage may have nothing to add.** `prime` lists every stage of the flow under "## The flow", each with what
it is for. When this ticket needs nothing your stage does (the earlier stages' commits are already the whole
change), end your stage at once with a short note saying so: `otaq stage next` with, on stdin, "Nothing to build: the
docs Product spec committed are the whole change". That is an ordinary finish, never a skip: only the user skips a
stage. With no commits on the branch at all, it is nothing to deliver instead (`otaq stage done`, in Otaq's rules).
2. **Follow the Agent instructions** that `prime` prints. They are the user's own rules (tests to run, skills to use,
how to plan) and they apply to every step below. They add to these steps; they never remove getting the context
(step 1) or ending your stage (step 6).
3. **Check the ticket before you build** (see "Check the ticket first" below). If something that changes what gets
built is open, ask before you write any code.
4. **Plan, then implement** until the ticket is done, as its description describes, and **prove each criterion**
your gap check listed (see "Prove it works"); for a bug, reproduce it before you change any code. Keep to the
ticket; file anything else as a new ticket (see below) instead of doing it here. **When `prime` shows a Plan with pieces** ("Pieces: 4
(1 → 2, 3 → 4)" under "## Plan"), don't build them yourself: you are the **agent in charge** (see "With a Plan:
work as the agent in charge"). **With no pieces, decide the split up front**: once your gap check has listed its
criteria, and before you write any code, judge the work by the size measure and either build it alone, as
described here, or write a Plan of pieces on this ticket and work as the agent in charge (see "Decide the split").
If the work turns out bigger partway through, see "When the work grows".
5. **Commit everything** with Otaq's `commit` skill. Nothing may stay uncommitted:
`stage next` is refused while files are uncommitted. Delete scratch files instead of committing them.
6. **End your stage** with a short comment on stdin: what you changed and what the next stage needs to know, in a
few lines (at most 2,000 characters); the next stage's agent reads it in `prime`. Run your last checks **after
your last commit** and give one line each: the command, the commit (`git rev-parse --short HEAD`), the result and
the log (see "Long output"). Then give **one line per criterion** with its evidence (a run proving several gets
one line), and for a bug the repro before and after the fix (see "Prove it works"):
```sh
otaq stage next --stdin \
--manual-check "On a phone-width window, open /prices and scroll the table sideways: the header stays put" <<'COMMENT'
Added the price table with sorting by price and name. Prices align right; the table scrolls on mobile widths.
`npm test` at a1b2c3d: 48 passed; log: `$OTAQ_RESOURCE_DIR/test-run.txt`
Sort by price, sort by name: `npm test prices.sort` in that run, passed.
Header stays put on mobile (inferred): manual check; no browser tooling in this project.
COMMENT
```
Report a failing or partial run as it is ("2 failed, in `cart.test.ts`, which the ticket doesn't touch"), and any
change after it.
**List what you couldn't check yourself** with `--manual-check "<what to check>"`, one line per check, repeated
for each: something that needs a real browser, a device, or a service you can't reach. The user sees them as
"Manual checks for you" at review and ticks them. Never leave a check to "the PR" or "a manual test later": the
flow may merge without a PR, and then nobody would try it. Each `stage next` replaces your stage's unticked
checks, so after a failed check or a Send back list again the ones that still apply.
If you learned something a later ticket should know (an API shape, a trap, a file others will touch), end the
comment with a line that starts `Notes for later tickets:`.
Then **end your turn** and wait. Otaq may validate your work first: the result arrives in this session as a
message. If validation failed, the message says only that ("Validate failed round 2. Run `otaq prime`."): run
`otaq prime`, read the checker's comment under "Comments" and search the log it names when you need the details (see
"Long output"), then fix them, commit everything and run `otaq stage next` again. **If a finding repeats one from
an earlier round** (the same behaviour or the same file and line), your last fix rested on a wrong idea: see
"When a finding comes back" before you change any code. When it passes, the ticket
moves on (to Review on the default flow) and the user reviews the diff.
**Nothing to deliver?** Only when the ticket needs no change at all (for example it was already fixed in SHOP-31)
and you committed nothing, end the ticket instead, with the reason on stdin. It goes to Done as "Done · nothing to
merge" and counts as merged, so tickets waiting on it start. It is refused once the branch has commits: then use
`otaq stage next`, so they're checked and delivered.
```sh
otaq stage done --stdin <<'REASON'
Already fixed in SHOP-31: the price table sorts by name since its merge.
REASON
```
## Decide the split
When `prime` shows no Pieces (a quick-flow ticket, a Plan with one piece, or a ticket whose planning the user
skipped), decide after your gap check, before any code, whether one agent should build it. The size measure:
> **A piece fits one agent when** it changes one behaviour, in one area or layer (for example the API, or the page,
> not both), and the agent needs to read only a handful of files to do it. **Split it** when it crosses layers,
> bundles several behaviours, or needs a lot of unfamiliar code read first. **When unsure, split.**
Don't ask the user about size: decide it yourself. Ask only about design choices the ticket didn't settle, as in
"Check the ticket first".
- **It fits:** build it alone (step 4).
- **It doesn't:** write a Plan of pieces on this ticket and work as the agent in charge (see "With a Plan: work as the
agent in charge"). Give it a "Pieces" heading and number the pieces 1, 2, 3; after each title write " — waits for "
and the pieces it needs ("nothing" when none). Indent a piece's details under it. Each piece stands on its own: its
helper sees the Plan and the ticket, not your reading of the code, so name the files and the behaviour. Each piece
also names which of your gap check's criteria it proves:
```sh
otaq update --plan-stdin <<'PLAN'
Why: the API lands first so the page has something to call.
## Pieces
1. Wishlist API — waits for nothing
Add, remove and list saved items in app/api/wishlist/. Proves: a saved item is still there after a reload.
2. Wishlist button — waits for 1
A heart on each product card (app/products/card.tsx). Proves: tapping it saves the item.
3. Wishlist page — waits for 1
/wishlist lists the saved items, with an empty state. Proves: the page shows what was saved.
PLAN
```
It prints "Updated SHOP-40 · Wishlist", and `otaq prime` then shows the Plan with its order line ("Pieces: 3 (1 → 2,
3)"). Nothing else comes back: the card shows "Updated by agent" and the History "Written by Dev", as for any
agent edit. Then start the helpers. The pieces don't take the criteria off you: after merging them you still prove
every one yourself (see "Prove it works").
## When the work grows
Partway through, the work turns out bigger than you judged by the size measure (more layers, more behaviours, more
unfamiliar code than it looked). Don't push on alone, and don't ask the user about size:
1. **Stop coding**, and stop any Run you started (`otaq run stop`): helpers get no Run. Keep the evidence you already
gathered in `$OTAQ_RESOURCE_DIR`; you use it when you prove the criteria at the end.
2. **Commit what you have**, as in step 5. Helpers start from this ticket's branch, so they build on it.
3. **Write a Plan for the remaining work** with `otaq update --plan-stdin`, as in "Decide the split": only what is
left, each piece naming the criteria it proves, and say in the Plan's first lines what is already built.
4. **Go on as the agent in charge** (see "With a Plan: work as the agent in charge").
This is about size only. A failed check that repeats a finding is about a wrong idea, not size: see "When a finding
comes back".
## With a Plan: work as the agent in charge
When the Plan under "## Plan" in `prime` has a Pieces list (from a planning stage, or one you wrote), the work is
already split. You start a **helper** for each
piece, each in its own worktree on its own branch, check what it hands back and merge it into this ticket's branch. You
stay the ticket's agent: the gap check (step 3), the questions to the user and ending your stage (step 6) are yours.
**While helpers build the pieces, commit nothing yourself but the merges.**
1. **Start the pieces that can start.** A piece can start once every piece it waits for is merged. In "Pieces: 4
(1 → 2, 3 → 4)" piece 1 starts first, then 2 and 3 side by side, then 4. Name each piece as the Plan does; a note
on stdin gives its helper anything the Plan doesn't say:
```sh
otaq helper start 1 --title "Wishlist API"
otaq helper start 3 --title "Wishlist page" --stdin <<'NOTE'
Reuse the product grid from app/products/page.tsx.
NOTE
```
Each helper runs your agent and model. When your tool's usage limit holds one ("waiting for limit reset"), carry on
with the rest: Otaq starts it when the limit resets and tells you. Then **end your turn**: each helper's hand-back,
question or stop is typed into this session as a message. `otaq helper list` shows every helper's status, branch
and worktree.
2. **Check each piece it hands back** ("40.3 handed its piece back: …"):
- Read what merging it would bring: `otaq helper diff 3` (a long one goes to a file in `$OTAQ_RESOURCE_DIR`; search
it).
- Run the project's tests in the helper's worktree (`otaq helper list` names it), the ones the project's notes and
the Agent instructions name. Their output goes to a file in `$OTAQ_RESOURCE_DIR`, as in "Long output".
- **Good:** merge it into this ticket's branch. Merge one piece at a time; then start the pieces that waited for
it.
```sh
otaq helper merge 3
```
- **Not yet:** send it back with one clear note: what is wrong, where, and what done looks like. Its helper fixes it
and hands back again.
```sh
otaq helper back 3 --stdin <<'NOTE'
The wishlist page doesn't show the empty state the description asks for (app/wishlist/page.tsx). Add it, with
a test.
NOTE
```
A merge refused for a conflict merges nothing and tells you the note to send the helper back with: send it.
3. **Answer your helpers' questions** ("Piece 3's helper asks: …"). Answer from the Plan, the description, the comments
and the decisions recorded on the ticket:
```sh
otaq helper answer 3 --stdin <<'ANSWER'
Guests can't save items: show the sign-in prompt, as the Plan's piece 1 says.
ANSWER
```
When your answer settles a product choice (what gets built, not how), also record it with `otaq decision record`
(see "Product questions while you work"), so the user sees it in the review. When only the user can answer, pass the
question on with its id from the message, and why:
```sh
otaq helper pass-on 0199d2a4-6f1e-7c3b-9a52-1f0e8d7c6b5a --note "a product question the Plan doesn't answer"
```
"Piece 3's helper stopped without handing back" means it ended its turn without `helper done`: read its last line,
then answer it with a note (`otaq helper back 3 --stdin`) or check its work as a hand-back.
4. **The Plan changed** ("The plan changed: 40.4 removed. Run `otaq prime`…"): run `otaq prime` and read the Plan
again. Tell running helpers what changed for them with `otaq helper back <n> --stdin`, start the new pieces, and
never merge a removed piece whose helper started: drop it with `otaq helper drop <n> --stdin` and the reason (see
below).
5. **A helper hands back a piece too big** ("40.1 handed its piece back: Add and list are done; export is left."). The
message carries only the hand-back's first line; its suggested split is in the helper's comment under
"## Comments" in `otaq prime`. **You alone change the Plan**; helpers only suggest.
1. **Check and merge the finished part**, as in step 2 (`otaq helper diff 1`, then `otaq helper merge 1`).
2. **Add the new pieces to the Plan**: rewrite it with `otaq update --plan-stdin`, as in "Decide the split". Judge
the helper's suggestion by the size measure; shrink the handed-back piece's text to what was built, and give
each new piece the criteria it proves:
```sh
otaq update --plan-stdin <<'PLAN'
## Pieces
1. Wishlist API — waits for nothing
Built: add and list.
2. Wishlist button — waits for 1
3. Wishlist page — waits for 1
Show the list only; export comes with 5.
4. Export API — waits for 1
5. Export button — waits for 3, 4
PLAN
```
- **New pieces get the next free whole numbers** (4, 5), never "3a" or "3b": "3a." isn't read as a piece, only
as text under the piece above it.
- **Never renumber a piece or reuse a number.** Helpers are kept per number: a merged or dropped piece can't start
again, and a working one can't start twice. Work left over from a merged piece goes into new pieces.
- **Don't remove a piece whose helper still works**: it keeps running. Drop it first, with the reason on stdin,
then take it out of the Plan with `otaq update --plan-stdin`. Its helper stops, its worktree and branch are
removed, and it shows as "dropped":
```sh
otaq helper drop 3 --stdin <<'WHY'
The page moved into pieces 4 and 5.
WHY
```
- **Changing the Plan tells no one.** When you change a running piece's text, tell its helper with
`otaq helper back <n> --stdin`; its next `otaq prime` shows the new text.
3. **Start the new pieces that can start**, named as the Plan names them: `otaq helper start 4 --title "Export API"`.
6. **Finish the stage** once every piece is merged (`otaq helper list` shows them all "merged", apart from those you
dropped): the whole ticket's tests pass on this branch, nothing is uncommitted, and `otaq stage next` names the
pieces in its comment, for example "40.1 Wishlist API, 40.2 Wishlist button, 40.3 Wishlist page, 40.4 Share link:
merged." Add the checks your helpers couldn't do themselves (their hand-backs list them) as `--manual-check` lines.
When the ticket comes back (a failed check, a Send back), the fix is yours as the agent in charge: make a small one
yourself, or start a helper for it with the next free piece number, for example piece 5 when the Plan has 4:
```sh
otaq helper start 5 --title "Fixing the Validate failure" --stdin <<'NOTE'
Validate failed: src/cart.ts:42 ignores the discount. Run `otaq prime` for the checker's comment.
NOTE
```
## Long output
Long command output (a test run, a build log, a long diff) goes to a file in `$OTAQ_RESOURCE_DIR`, Otaq's folder for
this ticket outside the repository, never into this session or a comment in full:
```sh
npm test > "$OTAQ_RESOURCE_DIR/test-run.txt" 2>&1
grep -n "FAIL" "$OTAQ_RESOURCE_DIR/test-run.txt"
```
- **Never in the worktree:** an untracked file there makes `otaq stage next` refuse.
- **Search it** with `grep` or `tail`; **never print it in full or retype it.**
- **Name it** in your comment; never attach command output, such as a run, a diff or a log. **Attach only a
document you wrote**, such as an investigation write-up, with `--report-file` (at most 20 MB).
### Reading a report
Under a comment with a report, `prime` shows a line such as "Report: test-run.txt · 48 KB, 2,310 lines · `otaq report SHOP-19 4`".
Open it only when you need it, and search it: `grep -n "expected" "$(otaq report SHOP-19 4 --path)"`.
A comment can carry several files (`--attachment 2` picks one); an image or any other file shows as "Image: shot.png ·
120 KB · open this path to view it: `…`": open that path (quote it in a shell; it may hold spaces), `otaq report` never
prints it.
## Prove it works
A passing test suite shows that nothing the tests cover broke, not that the ticket is done. Prove each criterion
your gap check listed, and for a bug, prove the bug was there and is gone.
**The ladder.** Prove each one with the first of these you can, and never install a tool to climb higher (adding
Playwright or a browser tool to the project is a ticket of its own):
1. **The project's own tests**, reaching the logic: a unit test, or a component test with jsdom. Many frontend bugs
live in a function, a hook or a store, not on the screen.
2. **Browser tooling the project already has**, run from the shell: `npx playwright test`, `npx cypress run`.
3. **The running app**, when the criterion shows in what the app does (a page, a response, a screen) and no test
above reaches it. See "Run the app" below.
4. **A manual check**: when nothing above reaches it (a layout bug, a Safari-only glitch, a real device), say in one
line why, and give the user `--manual-check` with the exact steps and what they should see: "On a phone-width
window, open /prices and scroll the table sideways: the header stays put", never "check the table".
### Run the app
1. **Start it** with `otaq run start --wait`. It returns once the app is running and prints its URL (or its port), or
fails with the app's last lines. When the project has no run command yet, the refusal says so: if you know how the
project starts, add it with `otaq run set --command "<cmd>"` (use `$PORT` where it listens); it is saved once it
runs. If the user already started the app for this ticket, you use theirs. **It runs code from before your
change?** Restart it with `otaq run restart --wait`: same command and port, and it stays theirs. Never start a copy
of the app yourself on a port you pick: it can take another ticket's port, and the board never sees it.
**Several apps** (a monorepo: `otaq run status` lists them): name the one each command is for, and start the apps
the criterion needs, for example both for a page that calls the API: `otaq run start api --wait`, then
`otaq run start web --wait`. `otaq run log` and `otaq run stop` take the name too. Each app listens on its own
`$PORT` and finds the others at `$OTAQ_PORT_<NAME>` (`$OTAQ_PORT_API`). An app the project lacks:
`otaq run set worker --command "<cmd>"`.
2. **Use this ticket's data.** Where the project has ticket resources, the app gets this ticket's database in
`$OTAQ_DB_NAME`, as your shell does: seed and change that one, never a shared one.
3. **Drive it as the verification guide says**: `docs/verify/` in the repository, or where the project's notes say
the guide lives. Its `README.md` says how to drive the app and what counts as evidence; each feature's file says
how to reach the feature and what proves it. No guide yet: drive it the simplest way that shows the criterion
(`curl`, the project's own scripts), then write it down (see "Write down what you drove").
4. **Keep the evidence** in `$OTAQ_RESOURCE_DIR`, like any long output: the requests you made and what came back, and
the app's own output with `otaq run log > "$OTAQ_RESOURCE_DIR/run.txt"`. `otaq run status` says whether it is
still up and who started it.
5. **Stop what you started** with `otaq run stop` before `otaq stage next`. Never stop a Run the user started: it
stays up (Otaq refuses anyway). If you forget, Otaq stops your Run when your stage ends, so never write in your
comment that the app was "left running".
For a bug, the running app can be the repro: the same request before and after the fix, both runs in your comment.
### Write down what you drove
When you drove the running app, leave the guide better than you found it, in this ticket's commits (a few lines, not
a manual):
- **No `docs/verify/README.md` yet** (and the project's notes name no other place): write it: how to start and drive
the app, what counts as evidence, and the seed data an empty database needs.
- **A feature the guide lacks**: add its file, for example `docs/verify/prices.md`: how to reach it, how to drive it,
what proves it works.
- **You changed how a feature is reached** (a new route, a renamed button, a new step): update its file.
When that is too big to do in passing (for example the app needs seed data that doesn't exist at all), file a
follow-up with `otaq create "Title" --stdin` and prove the criterion with a manual check this time.
**A bug** (the description reports wrong behaviour, not something new):
1. **Reproduce it before you change any code**, with the ladder: a command, an existing test with a filter, or a
small new test. Its output goes to a file in `$OTAQ_RESOURCE_DIR`. If it doesn't fail, you haven't found the bug
yet: keep looking instead of fixing.
2. **Fix it where it starts**: the first place the code does something wrong, not the place the symptom shows. A
guard is a fix only when the state it handles is one the code may really be in; otherwise find what produced it.
3. **Run the same repro again** and give both runs in your comment:
```text
Repro `cargo test cart_total_empty` before the fix: failed (NaN); log: `$OTAQ_RESOURCE_DIR/repro-before.txt`
After, at a1b2c3d: passed; log: `$OTAQ_RESOURCE_DIR/repro-after.txt`
```
Commit the new test with the fix, in the same commit: a commit that fails on purpose breaks bisecting, and the
project's hooks may refuse it. When no cheap repro exists (a race, production data, a device), say why in one
line and use the closest check. No new test is better than a bad one: one that mostly tests mocks, depends on
timing, or copies the code it checks.
## When a finding comes back
When a failed check repeats a finding from an earlier round (the same behaviour or the same file and line), your
fixes so far rested on the same wrong idea, and the check has few rounds left before the ticket stops for the user.
Before you change any code:
1. **Write the idea down** in one sentence: what both fixes assumed. "Both fixes assumed the discount is applied
before tax."
2. **Test it directly**, with a run whose result would differ if the idea were wrong (the ladder above; its output
in `$OTAQ_RESOURCE_DIR`).
3. **Follow the result.** Wrong: the cause is elsewhere, so look again. Right: the earlier fixes treated a symptom,
so ask the next "why" and fix where it starts.
4. **Say both in your comment**:
```text
Round 2 repeated "the total ignores the discount". Assumed: the discount applies before tax.
Tested: `shop total --debug` shows tax computed first (log: `$OTAQ_RESOURCE_DIR/premise.txt`). Wrong: fixed the
order in pricing.rs.
```
A finding that is new in this round is a new bug: fix it as usual.
## Check the ticket first
Before you write any code, make a quick gap check: read the description, the comments, the dependencies' last
comments and the code the ticket touches, then answer for yourself:
- **What is asked?** One or two sentences in your own words.
- **What is there already?** The files, screens and behaviour the ticket builds on.
- **What is missing or doesn't fit?** A vague word ("faster", "better", "export"), a screen or user group the ticket
doesn't name, a description that contradicts the code or a dependency, two ways to read the same sentence.
- **What will prove it's done?** List the criteria you will prove (see "Prove it works"): the ones the description
writes, and the ones you infer from it, marked `(inferred)`. Don't ask the user about them; the inferred ones
show in your comment at review. A bug's criterion is its repro: it fails before your fix and passes after.
Keep it quick: read, don't build or run long test suites for it. Then sort each open point:
- **It changes what gets built** (what the user sees or can do, which screens, which users, which data, how much work
it is): ask before you code. Building the wrong thing wastes the whole ticket.
- **It only changes how you build it** (file layout, naming, a helper, a library that follows the project's habits):
decide yourself. If it is still a product choice, record it (below).
**Most tickets are clear: then ask nothing and go straight on.** Don't ask what the description, the dependencies,
the code or the Agent instructions already answer, and don't ask about things the ticket plainly leaves to you.
When you do ask:
- **One question at a time, most important first.** A ticket holds one open question; a second one would replace the
first. Say where you are: "Question 1 of 3". After each answer, check again: an answer can settle or drop the next
question ("CSV only" makes a PDF layout question go away).
- **Offer options, each with its pros and cons**, and recommend one (see "Offer options" below). The user should see
what each choice costs and what it changes before they pick.
- **Write no code while a gap-check question is open.** Ask, end your turn, and go on when the answer arrives.
```sh
otaq ask human \
--option "CSV only" --note "One small library, about half a day. No printable copy for customers." \
--option "CSV and PDF" --note "Printable invoices too, but needs a page layout and a PDF library: about two days." \
--recommended 1 --stdin <<'QUESTION'
Question 1 of 2: SHOP-31 says "Add export" to the orders page but not which format. The accounting team's
spreadsheet import (docs/accounting.md) reads CSV.
QUESTION
```
## Product questions while you work: record, or ask only if you can't go on
When you meet a product question while you build that the code and the documents don't settle (what to build, not how):
- **If you can't go on without the answer**, ask the user (below).
- **Otherwise decide and record it.** Build one option, record the choice on your ticket, and carry on; nothing
waits. The user sees every recorded decision in the review and can change it there.
Give each field on its own line, `Other option:` once per option:
```sh
otaq decision record --stdin <<'DECISION'
Question: Split `fullName` everywhere, or only in the profile form?
Built: only in the profile form
Other option: everywhere
Why: the description only mentions the profile form
DECISION
```
The user's Agent instructions may add to this rule (for example "always ask about copy text"); follow them.
## A problem that belongs to an earlier stage: ask to send it back
`prime` lists every stage of the flow under "## The flow", each with what it is for, and marks the ones this ticket
skipped. When you find a problem that one of the **earlier** stages is for, skipped or already run (a product gap with
no Product spec behind it, an approach Tech spec should have settled), don't settle it yourself in your stage and never
move the ticket back: ask the user, naming that stage, with your reason on stdin, then end your turn:
```sh
otaq ask human --send-back "Product spec" --stdin <<'QUESTION'
Product gap: refunds over 30 days aren't specified, and the order rules decide what Dev builds.
QUESTION
```
The question offers the user two ways out: **Send back to Product spec** (the ticket goes there, that stage runs again,
a skip on it is cleared, and your session stops; the ticket comes back to your stage later with the stage's result) or
**Answer here** (the answer arrives in this session like any other). Name only an earlier stage the ticket has been
through: a later stage, your own, or one it never reached is refused. A small gap you can decide and record is not a
reason to send it back (see "Product questions while you work").
## When you need the user
If you are stuck, or you can't go on without the user's decision, ask, then end your turn:
```sh
otaq ask human --stdin <<'QUESTION'
Should `fullName` be split into first and last name everywhere, or only in the profile form?
QUESTION
```
The user answers on the ticket's Overview in Otaq (or in this terminal). The answer arrives in this session as the user's next message.
### Offer options when there are clear alternatives
When the question has a few clear alternatives, offer them as **2–4 options** so the user can answer with one key, give
each option a **note with its pros and cons**, and recommend one when there is a sensible default:
```sh
otaq ask human \
--option "Postmark" --note "Already sends password resets: no new account or keys. Costs more per email." \
--option "SES" --note "Cheapest at volume, but needs AWS setup and domain checks first." \
--option "Resend" --note "Simple API, but a new account and a new vendor to manage." \
--recommended 1 --stdin <<'QUESTION'
Which email provider should send the order confirmation?
QUESTION
```
The answer then arrives as, for example, "Answer to your question: Postmark (option 1)." The user can always type
something else instead.
An **open question** stays free text, with no options:
```sh
otaq ask human --stdin <<'QUESTION'
What should the empty wishlist page say?
QUESTION
```
- 2–4 options, each a short label (at most 40 characters). The context goes in the question, each option's pros and
cons in its `--note`, right after its `--option`.
- A note is one or two short sentences, at most about 200 characters: what the option costs (time, a new dependency, setup) and what it changes for
the user or for later work. Give every option one, so the user can weigh the side effects of each choice.
- Recommend one with `--recommended N` (1-based) when there is a sensible default; leave it out when there isn't.
- Never invent options for an open question.
- The question text always goes through stdin; only the short labels and notes are arguments.
- The user's Agent instructions take precedence over this guidance.
## Rules
- **Always finish with `otaq stage next --stdin`** (or `otaq stage done --stdin` when there is nothing to deliver), as
step 6 says. A summary in this chat isn't a hand-over.
- **Never push, never open a PR, never merge.** The user does that from the board. The one merge that is yours:
your helpers' pieces into this ticket's branch, with `otaq helper merge`.
- **Long text always goes through stdin** (`--stdin`), never quoted arguments: comments, questions, ticket bodies.
Long command output never does: it goes to a file (see "Long output").
- Useful commands: `otaq show <KEY>` (any ticket), `otaq dep tree` (your ticket's chain),
`otaq create "Title" --stdin` (a follow-up in Backlog).
- **Stop the Run you started** (`otaq run stop`) before `otaq stage next`; never stop one the user started. Helpers
get no Run: the agent in charge runs the app after merging the pieces.
- If `otaq stage next` is refused, read why (uncommitted files, a comment over 2,000 characters, or `prime` not run
since Otaq last resumed you), fix it and run it again.
- **You never set a stage choice: only the user picks a stage's agent or skips a stage.** If what you learned
changes how hard a later stage's work is (for example the change turned out risky), say so in your comment for the
user. If you try, the CLI refuses:
"Only the user picks a stage's agent: leave the stage's own agent, or ask the user to change it".
## As a helper
`$OTAQ_PIECE` is set: you build **one piece** of the ticket for its agent in charge, in your own worktree, on your own
branch. The agent in charge reviews your work, merges it and moves the ticket; you never do.
1. **Run `otaq prime`.** As a helper it prints your piece first, the notes between you and the agent in charge, then
the ticket, the whole Plan, its comments and your rules. Follow the user's Agent instructions and the project's
notes it names, as far as they apply to your piece.
2. **Build only your piece**, as the Plan describes it. Anything else you notice goes in your hand-back, not in your
code. If the piece turns out too big for one agent, see step 7.
3. **Commit everything** with Otaq's `commit` skill. Never push and never merge: the agent in charge merges your branch.
4. **Questions** go through `otaq ask human --stdin`, as in "When you need the user": they reach the agent in charge
first, which answers or passes them on to the user. End your turn and wait; the answer is typed into this session.
5. **Hand your piece back** with what you built and what you couldn't check yourself (a real browser, a device), then
end your turn:
```sh
otaq helper done --stdin <<'SUMMARY'
Wishlist page with its empty state; `npm test` passes.
Couldn't check: on a phone, the grid shows two columns.
SUMMARY
```
It is refused while files are uncommitted. The agent in charge lists your "Couldn't check" lines for the user.
6. **Sent back?** The agent in charge's note is typed into this session ("To 40.3: …" in `prime`). Read it, fix what it
asks, commit, and hand back again with `otaq helper done --stdin`.
7. **Piece too big?** When your piece turns out bigger than one agent should build, judged by the size measure in
"Decide the split" (it crosses layers, bundles several behaviours, or needs a lot of unfamiliar code read first),
hand it back early instead of pushing on:
1. **Commit what you built.** The hand-back is refused while files are uncommitted, and only what is committed
gets merged.
2. **Hand back early** with `otaq helper done --stdin`: the **first line** says what is done and what is left
(it is the only line the agent in charge is sent; the rest it reads in `prime`). Then suggest a split, with the
next free whole numbers after the Plan's last piece, never "3a" or "3b":
```sh
otaq helper done --stdin <<'SUMMARY'
Add and list are done; export is left.
Piece 1 also needs the export API and an export button. Suggest: 4 export API, 5 export button.
SUMMARY
```
3. **Never start helpers yourself, and never change the Plan**: the agent in charge does both (your `otaq update`
is refused). Then end your turn.