ic-workflow · git:20260729.071181e · 2026-07-29 · sha256 b87e5c9c18d7a984
ic-workflow git:20260729.071181eA
Immutable. This exact content is served forever at /api/v1/blob/b87e5c9c18d7a984.
---
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.