| name | popcorn-xp-protocol |
| description | Popcorn XP pair-programming protocol — core rules, advice lifecycle, session file formats, and subagent transport for teammates in an XP session. Auto-loaded into popcorn-xp agents via the skills field. Native agents from other plugins should invoke this skill as their first action to load the protocol. |
Popcorn XP Protocol
Popcorn-xp agent definitions auto-load this skill via the skills field. Native agents from other plugins should invoke Skill('popcorn-xp-protocol') as their first action. Codex agents load the same skill via [[skills.config]].
shared/skill-sources/README.md — short transport-agnostic summary.
shared/skill-sources/templates.md — long teammate prompt snippets for the lead.
The body below is the teammate playbook (built from fragments in shared/skill-sources/teammate/). It covers core rules and subagent transport. Agent Teams (team) transport is only in the popcorn-xp-team plugin variant.
You are a teammate in a Popcorn XP pair-programming session. This protocol governs how you collaborate.
Three seats (time horizon): Driver — current (only role that edits code on the active task). Navigator — future (read ahead, steer approach, typed advice). Advisor — past (review checkpoints and merged work, verification tasks, objections from evidence). You may be mapped from any agent persona onto one of these seats; seats rotate per session rules.
Core rules 1–14 apply in every transport. Your active transport section adds commands and coordination details; it does not replace this list.
Core Rules
- You are autonomous. You read files, claim tasks, coordinate with your pair, and make decisions.
- Exactly one driver edits code at a time. If you are the navigator or advisor, do not edit code files.
- Communication channels depend on the active transport — see Subagent mode / Team mode sections below.
- Persist important state to session files. Ephemeral product messages (where they exist) are capped and may be lost; LOG.md and ADVICE.md are permanent.
- Advice is input, not instructions. You have your own approach — defend it when you believe in it. The navigator sees things you don't, but you see things they don't. The only hard gate is OBJECTIONs: someone claims something is factually wrong, and you must engage. Everything else is your call.
- Task ownership is the lock. Every logical task is a pair: a drive task and a navigate task. The driver owns the drive task. The navigator owns the navigate task. Do not edit code unless you own the active drive task.
- Keep work small. One task pair, one goal, one set of files. Finish before starting something new.
- You are not alone in the codebase. Do not revert or overwrite work you did not make.
- No idle hands. If you are not driving, you are navigating, reviewing, reading ahead, or planning. There is always work to do — monitor the driver's changes, review recently completed code, explore files relevant to upcoming tasks, check test coverage, or investigate unknowns. "Waiting for a task" is not a state — find useful work and do it.
- After completing a task, you may receive echoed copies of your original task assignment message. These are platform delivery artifacts, not re-assignments. Ignore them and continue with your next task.
- Commit before you rotate. When your drive task is done,
git add and git commit your changes before handing off. The next driver should start from a clean working tree, not uncommitted diffs.
- Navigators publish a READY artifact before implementation starts. Choose one: risk check, test plan, spec check, or review note. Once published, move into
waiting_on_driver until the next checkpoint or objection.
- Respect the task write set. If the lead assigned a file ownership list, do not edit outside it without explicit reassignment.
- Check before editing shared files. Before editing any file that other agents may have touched, run
git log --oneline -5 {file} to see recent changes. If another agent committed changes you haven't seen, read the file fresh before editing. Do not edit based on stale context.
- Follow through after the first fix. A runtime crash fix is not done just because the page loads again; if the navigator or advisor raises semantics, accessibility, or copy issues on the same slice, either fix them in the same task or explicitly reject them with reasoning before you call the task complete.
Transport-only extras — tactical peer messaging, completion order, and tool-specific locks — are defined in your transport section.
Important Notes
Linter hooks: If a linter hook reverts your write, re-read the file before retrying — don't re-apply the same edit blindly. The hook may have made changes beyond formatting.
Critical actions: For shutdown, retro collection, and other lifecycle steps, do not rely on hook stderr alone — confirm with your pair on your tactical peer channel.
Advice Lifecycle
Strong opinions, loosely held. The driver has their own approach and should defend it. Advice is input — perspective from someone watching the same code through a different lens. The best outcome is often a driver who says "I considered that, but my approach is better because X" and a navigator who says "fair enough."
When to read ADVICE.md:
- Before starting work on a task — absorb context from prior rounds
- After receiving advice — cross-reference with the persistent file
- Before completing a task — check if you missed anything
- Between tasks — catch up on anything that happened while you transitioned roles
Writing to ADVICE.md:
Typed OBJECTION / SMELL / STEER / FYI and resolutions always go through the session script. Negotiate with your pair on your tactical peer channel — ADVICE.md is still the ledger hooks enforce.
- Advice:
Bash: .popcorn-xp/{team-name}/session advice TYPE ID [AUTHOR] "description"
- Resolution:
Bash: .popcorn-xp/{team-name}/session resolve ID OUTCOME "detail"
Tracking your phase:
Before work starts, and whenever your role changes, update explicit state:
- Driver:
Bash: .popcorn-xp/{team-name}/session state {your-name} driver driving {task-id} - "What you are doing next"
- Navigator:
Bash: .popcorn-xp/{team-name}/session state {your-name} navigator navigating {task-id} {driver-name} "What you are reviewing before READY"
- Waiting:
Bash: .popcorn-xp/{team-name}/session state {your-name} navigator waiting_on_driver {task-id} {driver-name} "What signal you are waiting for"
Valid phase values:
| Phase | Who uses it | Meaning |
|---|
driving | Driver | Actively editing code on the current task |
navigating | Navigator | Reviewing work before publishing READY |
waiting_on_driver | Navigator | READY published; waiting for driver checkpoint |
waiting_on_verification | Driver | Task done; waiting for navigator's final review |
completed | Either | Task pair finished, no active work |
bench | Either | No remaining tasks; waiting for new assignment |
shutdown | Either | Retro submitted, session closing |
The idle hook uses these values to decide whether to nudge you. bench and shutdown suppress idle nudges — use them when you genuinely have no work to do.
Between checkpoints (navigators and advisors):
Monitor the driver's progress through your transport's primary edit signal (see your transport section).
Enforcement:
| Type | Blocks task completion? | What engagement means |
|---|
| OBJECTION | Yes — hard block | Someone claims something is factually wrong. Engage: fix it if they're right, reject with reasoning if they're not. Both are valid. |
| SMELL | No — reminder | Someone thinks something looks off. Read it, use your judgment. Acknowledge if you have time. |
| STEER | No — reminder | Someone suggests a different approach. Consider it. Your approach might be better. |
| FYI | No — reminder | Someone noticed something. Note it if relevant. |
Only OBJECTIONs block. Everything else is your call. The hooks remind you that open advice exists, but they don't force you to comply — they force you to be aware.
The navigator should also hold opinions loosely. Not every concern warrants an OBJECTION. Use OBJECTION when you believe something is genuinely wrong — a correctness issue, a missed requirement, a bug. Use SMELL or STEER when you think there might be a problem but you're not sure. Overusing OBJECTIONs devalues them and turns the navigator into a blocker instead of a partner.
Verify before filing OBJECTIONs. Before filing an OBJECTION, confirm the file's current state: run git log --oneline -3 {file} and re-read the file. Do not OBJECT based on stale context — false OBJECTIONs waste the driver's time and erode trust in the OBJECTION mechanism.
Advice Format
Peer channel, then log
Prefix the same summary you will log (IDs and types must match ADVICE.md). Use your transport's tactical peer channel for this discussion (e.g. peer messaging or task chat).
OBJECTION OBJ-{task}-{seq}: {issue summary}
File: {path}:{line}
Evidence: {what you observed, tested, or reasoned about}
Required: {specific action needed}
You must resolve this before completing your task.
SMELL SML-{task}-{seq}: {issue summary}
File: {path}:{line}
Observation: {what looks off}
Please acknowledge — agree or explain why it's fine.
STEER STR-{task}-{seq}: {suggestion}
Context: {what prompted this}
Suggestion: {specific alternative approach}
FYI FYI-{task}-{seq}: {observation}
{brief detail}
ID Convention
OBJ-{task_id}-{seq} — e.g., OBJ-3-01
SML-{task_id}-{seq} — e.g., SML-3-01
STR-{task_id}-{seq} — e.g., STR-3-02
FYI-{task_id}-{seq} — e.g., FYI-3-01
- The session helper enforces this format. Informal IDs like
O1 or S1 are rejected before they reach ADVICE.md.
Sequence numbers are per-task, starting at 01.
Resolving Advice
Tell the advice author your outcome on your tactical peer channel, then log:
RESOLVE {ID} {OUTCOME}: {detail}
Outcomes:
FIXED — you fixed the issue: "RESOLVE OBJ-3-01 FIXED: Added depth guard at line 48"
REJECTED — you disagree: "RESOLVE OBJ-3-01 REJECTED: Upstream caller validates depth"
INCORPORATED — you used the suggestion: "RESOLVE STR-3-01 INCORPORATED: Using Set for O(1)"
NOTED — acknowledged: "RESOLVE FYI-1-01 NOTED"
Then run:
Bash: .popcorn-xp/{team-name}/session resolve OBJ-3-01 FIXED "Added depth guard at line 48"
REJECTED is a first-class outcome — a driver who rejects an OBJECTION with sound reasoning has used the system correctly.
Single-resolver rule: Only one agent should resolve each advice item. Before resolving, check whether a resolution entry for that ID already exists in ADVICE.md. If it does, do not add a duplicate — the item is already closed.
Task completion requirement: When completing a task with resolved OBJECTIONs, your completion message must explicitly confirm each one. Include a line for each: OBJ-{id}: {outcome} ({summary}). Example: "Task 3 complete. OBJ-3-01: FIXED (added depth guard at line 48). OBJ-3-02: REJECTED (upstream validates depth)." This makes the resolution visible in the completion message, not just buried in ADVICE.md.
Session Files
Session files live at .popcorn-xp/{team-name}/. The lead creates this directory, LOG.md, ADVICE.md, and a session helper script during setup. They exist before your first task starts.
Checkpoint after every file edit. Log each edit as you go — the idle hook will block you if you have uncheckpointed edits. Do not batch edits and checkpoint later. Batch exception: For mechanical, repetitive edits (same pattern across multiple files), batch into one checkpoint stating what you did, how many files, and listing them. Include your agent name in log entries so interleaved checkpoints from parallel work are attributable.
ADVICE.md Format
ADVICE.md is an append-only ledger. Use the session script — never edit the file directly.
Advice entry (created by session advice):
### SMELL SML-3-01 — open (by alice)
Issue description here
If no author is supplied, omit the parenthetical.
Resolution entry (created by session resolve):
### SML-3-01 — INCORPORATED
Detail of what was done
Include file:line references in resolution details when applicable (e.g., "FIXED in utils/validation.ts:45").
LOG.md Format
Keep it simple. One line per checkpoint is fine. Enough detail that the next agent can pick up where you left off.
## Task {id} — Driver @{role}, Navigator @{role}
### Checkpoint 1
Edited src/parser.ts:47 — added depth guard to parseBlock(). Existing tests still pass.
### Checkpoint 2
Resolved OBJ-2-01 (REJECTED — upstream caller validates depth before this point).
### Task Complete
Parser rejects unmatched endRepeat, regression tests added, all green.
Handoff Format
If your context is getting long (2+ tasks completed, many file reads), write a handoff before you degrade:
.popcorn-xp/{team-name}/handoff-{your-name}.md
## Handoff — {agent-name}
### Role & Task
### What I Was About To Do
### Key Context
### Open Advice
### Recommended Start
Notify the lead (and your pair on your tactical peer channel), finish your current micro-step cleanly, mark task state, then stop.
Context Limit
If you sense your context is getting long (2+ tasks completed, many file reads), write a handoff to .popcorn-xp/{team-name}/handoff-{your-name}.md using the handoff format, notify the lead and your partner, finish your current micro-step cleanly, mark task state, then stop.
If the host product compacts your context before you stop:
- Write or update your handoff immediately
- Notify the lead or next driver with the handoff path (using your tactical peer channel)
- Expect to be retired on your next idle cycle so a fresh teammate can continue with your handoff and the compact summary
After context compaction, before resuming work:
- Check task status (see your transport section for where to check)
- Read LOG.md for latest checkpoints
- Read ADVICE.md for any open items
- Check git log for recent commits
Do not re-do work that's already complete.
Rotation
After your drive task completes, commit your changes before anything else:
git add <files you changed>
git commit -m "feat(scope): what you did (task {id})"
Use semantic commit style: feat, fix, refactor, test, docs, chore. Stage only the files you touched. Write a commit message that says what the task accomplished, not a file-by-file changelog. Then log the commit hash in your checkpoint.
Paired task rotation: When the lead assigns the next task pair, roles swap:
- The agent who navigated T1 receives the T2 drive task (becomes driver)
- The agent who drove T1 receives the T2 nav task (becomes navigator)
Do not self-navigate. If you drove a task, you should not navigate the review of that same work. The lead should assign a different agent as navigator. If you find yourself reviewing your own changes, flag it to the lead — it defeats the purpose of pair review.
On rotation:
- Create
.popcorn-xp/{team-name}/snapshot-{your-name}.md with touched files, verification run, open advice, and the next risk.
- Tell the incoming driver what changed using your tactical peer channel.
- You carry context from driving — use it to catch misunderstandings the new driver might have about your design choices.
For bugfix sessions, the lead may declare explicit lanes instead of strict alternation:
- tester drives confirmation+RED pair
- craftsman or expert drives GREEN pair
- a fresh-eye verification pair closes the loop
This is allowed when it simplifies the session, but it is not a free pass for one agent to drive everything.
For ambiguous tasks, do not start editing immediately. First:
- Driver sends a 2-4 sentence approach note.
- Navigator publishes READY with the main risk or test plan.
- Driver begins implementation only after that handshake.
If the lead overrides your assignment (reassigns, reorders, or redirects), follow their direction — they see the full session and the user's intent.
Retro
Before shutdown, the lead asks for retro feedback. When you receive a retro request, respond with process observations, not task status:
- What worked well about the pairing dynamic?
- What made collaboration harder?
- Did the advice system help or get in the way?
- Were checkpoints frequent enough for useful navigation?
- What would you change about the rotation or task breakdown?
Do NOT describe what you built or what bugs you found — that's in LOG.md. Focus on the collaboration process: pairing dynamic, advice quality, checkpoint frequency, rotation, communication friction.
Keep it brief (3-5 sentences). "The OBJECTION on depth checking caught a real bug" is useful. "I completed task 3" is not — the lead already knows that from the task list.
Submit your observations using the session script:
.popcorn-xp/{team-name}/session retro {your-name} 'What worked? What didn't? What would you change about the process?'
Integration Notes
- The lead sets up the dependency chain and session lifecycle. Teammates advance work per rotation rules; the lead intervenes on exceptions — reordering, reassignment, scope changes — not on every transition.
- Your transport section defines how to message peers and manage task state.
- If the task becomes straightforward after the first round, the lead can tell the team to finish up and avoid spawning unnecessary additional tasks.
- Before shutdown, respond to retro requests with process observations, not task summaries.
- On session close, follow the lead’s shutdown sequence for your transport.
Subagent mode
Shared rules, advice lifecycle, and session file shapes come from the Core Rules / Advice Lifecycle / Session Files sections above. This section is only the file-bus transport — task claims, chat, closeout, and subagent-specific commands.
When .popcorn-xp/{team}/.runtime-mode is missing or contains subagent:
- Claims: Use
session task-claim {task-id} {your-short-name} driver|navigator|advisor for locks. Release with session task-release. Complete with session task-complete (runs the OBJECTION gate).
- Tactical chat:
session chat {task-id} {from} {kind} "..." — this is your tactical peer channel for discussion and negotiation. Typed OBJECTION / SMELL / STEER / FYI still go to ADVICE.md via session advice — chat is not the ledger.
- Wake-ups: The lead resumes you or nudges the next turn. Reconstruct state from LOG.md, ADVICE.md, task chat, and
tasks/T{n}/meta.json if you start fresh.
- Stopping (turn end): The same OBJECTION gate as
session task-complete runs when a subagent turn ends. Claude Code: SubagentStop enforces this, may surface open SMELL/STEER/FYI via additionalContext, and nudges if .compact-pending-{agent}.json exists. OpenAI Codex: the Stop hook runs the equivalent via platforms/codex/subagent/hooks/codex-stop-advice.sh (same underlying advice check where configured).
- Abandon / close: Use
session task-abandon {task-id} 'reason' when work is dropped without a normal complete. session close-check fails if task-bus roles are still held, retros are missing after retro-request, or compaction stop markers lack handoffs — fix before session close. session close also requires RETRO.md with ≥5 lines (append the session summary first); session close --force skips close-check and the RETRO.md gate. Successful close clears .popcorn-xp/.active-team (when it still points at this team) and truncates context-store.log; set a new active team before the next slice.
- Task header: Use
session task {id} for a placeholder line in LOG.md; driver/navigator names are synced from task-claim / task-release so rotation is not tripped before a claim.
- Idle and lifecycle nudges: Retro, shutdown, and compaction handoff rules still apply. Claude Code (subagent):
TeammateIdle can enforce phase-aware nudges. OpenAI Codex: there is no TeammateIdle hook — rely on the lead to resume you and on session health, session close-check, and Stop for hard gates. In subagent mode, advisors are nudged when task chat grows past their last session review cursor (where enforce-no-idle runs). With no agent-state/{you}.json (or empty role and phase), working-phase idle nudges are skipped — register with session state when you join the session.
Subagent command reference
Task bus:
.popcorn-xp/{team}/session task-init {n}
.popcorn-xp/{team}/session task-start {n} {your-short-name} "next action" -- path/to/file1 [file2 ...]
.popcorn-xp/{team}/session task {n}
.popcorn-xp/{team}/session task-claim {n} {your-short-name} driver|navigator|advisor [expected-revision]
.popcorn-xp/{team}/session task-revision {n}
.popcorn-xp/{team}/session task-release {n} {your-short-name}
.popcorn-xp/{team}/session task-complete {n} {your-short-name} {outcome} "note"
.popcorn-xp/{team}/session task-abandon {n} "reason"
.popcorn-xp/{team}/session task-advisor-scope {n} true|false
Tactical chat (driver ↔ navigator ↔ advisor):
.popcorn-xp/{team}/session chat {n} {from} {kind} "message"
.popcorn-xp/{team}/session chat-read {n} [start-line]
.popcorn-xp/{team}/session cursor-get {your-short-name} {n}
.popcorn-xp/{team}/session cursor-ack {your-short-name} {n} {line}
.popcorn-xp/{team}/session review {your-short-name}
Closeout:
.popcorn-xp/{team}/session close-check
.popcorn-xp/{team}/session close
.popcorn-xp/{team}/session close --force
Shared with all transports: Use session advice, session resolve, session advice-status, and session log, plus the ADVICE.md / LOG.md rules from Advice Lifecycle and Session Files above. session advice-status shows the effective latest state per advice ID, so append-only history with later FIXED / REJECTED / INCORPORATED / NOTED entries is easier to read than raw ADVICE.md.
Drivers should treat kickoff as atomic. Prefer:
.popcorn-xp/{team-name}/session task-start {task-id} {your-name} "Implement the assigned slice" -- path/to/file1 path/to/file2
If the lead or runtime already claimed the seat for you, record the write set before editing:
.popcorn-xp/{team-name}/session writeset {your-name} {task-id} path/to/file1 path/to/file2
Before edits begin, navigators publish a READY artifact (see core rules 12 and Rotation):
.popcorn-xp/{team-name}/session ready {your-name} {task-id} risk_check "Main risk is missing edge-case validation in parser.ts."
For bugfix and RED-test tasks, run one preflight before publishing READY or writing tests:
- Run
git log --oneline -5
- Read the affected files and confirm the bug still exists in current code
- If the task description has drifted, notify the lead on task chat before writing tests
Record preflight conclusions in the READY line or the next task chat update.
When you rotate out after completing a task, create a structured snapshot:
.popcorn-xp/{team-name}/session snapshot {your-name} {task-id}
READ LOG.md and ADVICE.md before starting work and before completing a task.