---
name: ic-workflow
description: Use when working an implementation ticket as any IC role — app, backend, web, CLI, library, or a specialist like monetization. Holds the ticket lifecycle every one of them runs: branch-before-you-write isolation, the choke-point rule, the read order, the commit and daily-fragment discipline, and the CODE output contract. Triggers the moment an IC agent is handed a ticket ID. Product-agnostic: the language, framework and hazards live in the agent file that invokes this.
---

# IC workflow

Every IC on this team runs the same loop, whatever the product is. Only the language, the
conventions pack and the hazards differ — those live in your own agent file. Everything below is
the same for all of you, and it is the part that has actually gone wrong in live runs.

## Isolation — read this before you touch a file

Use the `agent-isolation` skill — worktree discipline, the ban on blanket staging, confirming the
mutation landed, the stop-and-report rule when HEAD moves under you, and the measured cost of
skipping all of it. The one thing it does not spell out: **branch before you write, never after.**
`git checkout -b feat/APP-NNN-short-slug` is your *first* action, not your seventh. If you were
given no worktree, say so in your first line.
Write-up: `${CLAUDE_PLUGIN_ROOT}/docs/research/2026-07-29-dry-run-parallel-agent-collision.md`.

## Fix at the choke point, not on the path the ticket names

Run the `defect-hunting` skill §1 procedure before you edit a function that touches persisted or
user-visible state — it holds the writer/reader enumeration and the question that does the work.

## Input contract

You are given:
- A ticket ID (e.g. `APP-001`) and the corresponding entry in `docs/31-board.md`
- The PRD section and architecture/impl-spec references the ticket points to
- The repo or subtree you work in — your agent file names it

You do not start coding until you have read all three. If any is missing or ambiguous, you stop and
write your blocker to a **per-run fragment** at `docs/daily/<today>-<role>-<ticket>.md` — not
the canonical daily file, because `tech-manager` concatenates fragments to avoid write-races
between parallel agents — then exit.

## The ticket loop

0. **Create your branch first.** Inside your worktree (or the repo root if you were not given
   one): `git checkout -b feat/APP-NNN-short-slug`. Nothing is written before this exists.

1. **Read, in order.** Your own agent file names the impl spec you work from — read that first.
   Then whichever of these the ticket actually touches:
   - `docs/12-flows.md` — behaviour of the surface you are building, including its empty, loading
     and error states and the edge cases
   - `docs/13-design-tokens.md` and `docs/14-components.md` — if the ticket has a user-facing
     surface. Use the tokens and the existing components rather than rolling your own.
   - `docs/52-analytics.md` **if the ticket emits any event** — the event names, params and
     consent gate are defined there, not invented here. An `APP-NNN-analytics` ticket that invents
     its own event names produces a funnel nobody can query.
   - `docs/40-api.md` if a service contract is involved — the contract is binding; don't guess.

2. **Re-read the ticket's acceptance criteria.**

3. **Plan** the change in 5-10 lines of plain prose in your scratch — files you'll touch, new
   types, tests.

4. **Implement.** Follow the impl spec's patterns; do not invent a new one. Your agent file lists
   the language rules and banned constructs that apply to you. Universal, whatever you build: no
   debug print/log noise — use the spec's logger — and no unhandled failure path. If what you build
   has a user-facing surface, user-visible strings go into the localization file from the start and
   every interactive element carries an accessibility label; retrofitting either is far more
   expensive than doing it now. The two skills that hold those rules are `localisation` and
   `accessibility-gate` — run the second on your own diff before you claim done, because
   `code-reviewer` will, and its `FAIL` is a `REQUEST CHANGES`.

5. **Test.** Unit tests for the logic you added and for the layer that persists or fetches it, plus
   whatever integration, UI or snapshot test the spec requires for this ticket.

6. **Build and run the tests locally** with your project's command — fix until green.

7. **Commit on the branch you created in step 0**, staging explicit paths only. Commit message:
   `APP-NNN: <one-line summary>` with a body listing what changed and why. Then confirm the
   mutation landed: `git diff --cached --numstat` before commit, `git show --stat` after.

8. **Drop a one-paragraph status note** at `docs/daily/<today>-<role>-<ticket>.md` **inside your
   worktree, and commit it with your change** — never to the repo root. It reaches `main` when your
   branch merges; a fragment on `main` for unmerged work describes something that has not shipped.
   Summarise what shipped, what's still in flight, and blockers. **This is not optional and it is
   not for you** — `tech-manager` builds the standup by concatenating these fragments, and it is
   the only input it has. Across six dry-run agent-runs, five skipped this and the standup
   aggregated nothing. `/app-build` now refuses to move your ticket to review without it.

## Talking to the rest of the team

Use the `team-protocol` skill: the channel, the anti-ping-pong guard, and the ask-before-you-block
rule — send the question, keep working on another part of the ticket, and only write `BLOCKED` when
nothing else on the ticket can proceed, naming who must answer what.

## Output — the CODE profile

Return the **CODE profile** defined in `team-protocol` — that section defines every field and what
makes each one honest, and the sprint loop parses it. A field you omit is a gate that silently
passes.

```
DONE: APP-NNN
Worktree: <the path you were given, or "none — shared tree">
Branch: feat/APP-NNN-short-slug        (created BEFORE any file was written)
Staged (explicit paths): <list>
Mutation confirmed: git diff --numstat -> <N files, +A/-B>
Files: <list>
Tests: <count> added, <exact command run>, exit 0     ("all green" is not a result)
Second-path check: <the writers/readers you grepped, or "none applicable">
Daily fragment: docs/daily/<today>-<role>-<ticket>.md
Assumptions & open questions: <ledger row each, or "ASSUMED, NOT RAISED">
Shared surfaces touched: <shared types, DI graph, design-system components, and any cross-cutting
  abstraction you had to CREATE — or "none">
Next: code-reviewer
```

Roles that produce more than code append their own lines to this block — `backend-developer` its
endpoints, migrations and contract update; `monetization-engineer` its products, paywall and ad
formats. Those are additions, never replacements.

If blocked, return `team-protocol`'s `BLOCKED:` block instead — `Reason:` and `Need:`, naming who
must answer what.

## What you never do, whatever you are building

- You never edit the architecture or impl spec. If the spec is wrong, you write a blocker note and
  stop.
- You never merge your own work. `code-reviewer` reviews; `tech-manager` merges.
- You never write outside your ticket's surface. Another IC's code, another platform's tree, and a
  file you were not assigned are all somebody else's — if your change needs one, say so and stop.
