| name | UsePairflow |
| description | Manage pairflow bubble lifecycle with strict state-aware routing and optional evidence bootstrap planning. USE WHEN create/start bubble OR intervene/troubleshoot active bubbles OR review for approval OR close/approve/rework/commit/merge OR cleanup/recovery OR bootstrap evidence. |
UsePairflow
State-aware Pairflow orchestration skill.
This skill exists to avoid lifecycle mistakes (wrong command in wrong state, lost worktree changes, stuck watchdog loops, accidental rebase/merge chaos).
Maintainer Warning
- Workflow files under
Workflows/ are reusable templates: keep default wording project-agnostic.
- Do not hardwire project-specific routes, selectors, or product copy as defaults in a workflow.
- Keep project-specific pieces in workflows only as clearly labeled examples/placeholders.
Workflow Routing
| Workflow | Trigger | File |
|---|
| CreateBubble | "create bubble", "start bubble", "kick off bubble", "ideation kickoff" | Workflows/CreateBubble.md |
| InterveneBubble | "bubble stuck", "watchdog", "waiting human", "continue loop", "pass to implementer/reviewer" | Workflows/InterveneBubble.md |
| TroubleshootBubble | "pairflow issue", "something is odd", "status mismatch", "why command failed" | Workflows/TroubleshootBubble.md |
| ReviewBubble | "explain bubble changes", "detailed review", "approval review", "deep mode" | Workflows/ReviewBubble.md |
| CloseBubble | "close bubble", "bubble done", "approve and merge", "finalize bubble", "clean bubble" | Workflows/CloseBubble.md |
| RecoverBubble | "cancelled bubble but keep changes", "recover worktree", "commit cancelled bubble" | Workflows/RecoverBubble.md |
| BootstrapEvidence | "bootstrap evidence", "evidence plan", "trusted test evidence", "how to generate evidence logs" | Workflows/BootstrapEvidence.md |
| TestBubble | "manual test report", "test bubble", "smoke test plan", "fixture and browser matrix", "what to click and run" | Workflows/TestBubble.md |
ReviewBubble Mental Model
Bubble source means findings from the bubble loop context (reviewer/implementer transcript and related runtime artifacts).
MetaReview source means findings from the meta-reviewer layer.
ReviewBubble always runs the surviving direct review path from bubble worktree/task/transcript context.
- Existing meta-reviewer artifacts can still be cited as
[MetaReview], but there is no operator-facing source-mode selector.
Core Principles
- Always run
pairflow bubble status --id <id> --json before any state-changing command.
- Use the command that matches current state. Never guess.
- Prefer Pairflow lifecycle commands over raw git/tmux when state progression is normal.
- If bubble has valuable unmerged work but lifecycle state blocks normal flow (for example
CANCELLED), switch to explicit recovery workflow.
- Treat workflow boundaries as strict contracts: do only what the selected workflow is for.
- For any bubble message payload (
reply, request-rework, ask-human), use shell-safe message passing. Never inline raw text containing backticks or $ directly in --message "...".
- For bubble creation, always include
--review-artifact-type <document|code> in pairflow bubble create.
- For implementation bubbles (
review_artifact_type=code), CloseBubble includes mandatory close completion: task/progress/archive admin is a pre-commit hook in the bubble worktree, then finalized bubble artifact deletion and any non-task follow-up after merge. Do not repair missing closed-task archive/status/progress with a direct post-merge main commit.
- For document bubbles whose caller requires a close metadata postcondition,
CloseBubble applies that admin metadata in the bubble worktree before pairflow bubble commit --stage-all; do not repair missing document-close status with a direct post-merge main commit.
- In
ReviewBubble outputs, every finding must include source label: [Bubble] (from bubble transcript/tool output, e.g. reviewer findings) or [MetaReview] (from meta-reviewer artifacts already present in bubble context).
ReviewBubble uses the surviving direct review contract only; do not expose or suggest any removed source-selection flag.
- Hard rule: do not route
ReviewBubble through pairflow bubble meta-review * read-model commands as an operator source-selection path.
- Decision separation:
--decide approve|rework controls lifecycle action only (bubble approve / bubble request-rework) and is independent from review content gathering.
- Ideation lifecycle is explicit: if a bubble was created with
--ideation, run pairflow bubble kickoff before any pass/converged loop command.
- If runtime is unhealthy (agent pane unresponsive, tmux/session mismatch, token/login refresh needed), prefer
pairflow bubble restart --id <id> [--repo <path>] over manual tmux kill/start steps.
- Remote exception: if a started remote bubble reports runtime loss (
remoteExecution.pointerKind="started" with runtime unavailable/missing), treat that fail-closed. Do not assume bubble start or bubble restart is the supported recovery contract on top of preserved remote state in this phase.
- For remote bubble creation, use
pairflow bubble create --remote <host> ...; execution still begins only at bubble start.
- Remote attach is a separate operator step.
bubble attach for remote bubbles uses the persisted started pointer plus optional --port-forward, not local tmux attach.
- Do not add
--attach to pairflow bubble start unless the user explicitly asks for an interactive attach/switch step right now.
RUNNING round=0 ideation state is a valid hold state. Do not auto-kickoff. Exception: if the user asks for a loop action (pass/converged) while still in round-0 ideation, run kickoff first because loop actions require an active round.
- Pre-kickoff manual preparation in the bubble worktree is allowed when explicitly requested by the user. In this pattern, kickoff text should summarize already-applied work and define expected first handoff behavior.
ReviewBubble should explain findings in business-technical language by default, not just reviewer shorthand:
- explain the technical issue,
- explain why it matters in practical terms,
- state whether it is blocking now or only future hardening debt.
- For started remote bubbles, the laptop/local repo remains the operator control plane. Run lifecycle commands from the local repo so Pairflow can use the retained pointer/cache state and SSH routing; do not SSH into the remote clone and run
approve, reply, commit, merge, or delete there manually.
- The only bounded remote-clone local-parity exception in this design slice is
request-rework, and only when Pairflow can prove the verified remote clone workspace context and no retained clone-local remote.json pointer artifacts are present. Default to the laptop-routed path unless that exception is explicitly known to apply.
Execution Modes (Mandatory)
- Default execution mode for bubble-scoped requests is
bubble_autonomous.
bubble_autonomous mode:
- Allowed: Pairflow lifecycle/protocol actions (
bubble ..., pass, ask-human, converged) and state diagnostics.
- Forbidden: direct feature implementation via manual file edits/tests as the primary execution path.
- Exception: ideation pre-kickoff prep edits are allowed only when explicitly requested by the user; after kickoff, return to lifecycle/protocol-driven flow.
manual_assist mode is allowed only with explicit user opt-in.
- Never silently switch from
bubble_autonomous to manual_assist.
- If intent is ambiguous between modes, ask exactly one explicit clarification question before editing files.
Workflow Scope Contract
CreateBubble is lifecycle-only:
- Allowed: pre-flight checks,
pairflow bubble create, pairflow bubble start, pairflow bubble kickoff, pairflow bubble status.
- Not allowed: reading/implementing/reviewing the feature/task content after bubble start.
- If the user asks only to start/create a bubble, stop immediately after reporting the started state.
- Any task execution inside the bubble must be a separate, explicit follow-up request.
- In
bubble_autonomous mode, follow-up handling remains lifecycle/protocol-driven; do not replace it with direct edits.
State-to-Action Map
CREATED -> pairflow bubble start
RUNNING with ideation pending (round=0 and [ideation].task_pending=true) -> pairflow bubble kickoff --id <id> (--task <text> | --task-file <path>)
RUNNING with ideation pending and no kickoff request yet -> hold in round-0; report status and wait for explicit kickoff decision
RUNNING document bubble kickoff (review_artifact_type=document) -> use a docs/spec refinement task payload. The payload must forbid product/runtime/source-code implementation and must instruct the agent to ask for replanning or a human decision if the requested outcome cannot be completed without code edits.
RUNNING (active round, typically round>=1) -> no approve/rework yet; use normal loop commands (pass, converged) in agent panes
- Runtime-health issue in non-final active states (for example stalled pane, refreshed agent login/session) ->
pairflow bubble restart --id <id> [--repo <path>]
- Remote started-pointer runtime loss (
remoteExecution.pointerKind="started" with runtime unavailable/missing) -> inspect pairflow bubble status --id <id> --repo <path> --json or pairflow bubble list --refresh; report preserved-state fail-closed and do not imply that start/restart is already the supported recovery path
WAITING_HUMAN -> use pairflow bubble reply (NOT bubble request-rework)
META_REVIEW_RUNNING -> inspect pairflow bubble status --id <id> --json; if gate appears stuck or runtime is unhealthy, use pairflow bubble restart --id <id> [--repo <path>]
READY_FOR_HUMAN_APPROVAL (legacy compatible: READY_FOR_APPROVAL) -> choose pairflow bubble approve OR pairflow bubble request-rework
- For remote bubbles, this still means the laptop-side routed command from the local repo by default, not manual lifecycle mutation inside the remote clone.
pairflow bubble approve enforces override requirements from transcript context.
- If approve fails with
APPROVAL_OVERRIDE_REQUIRED or APPROVAL_PARITY_OVERRIDE_REQUIRED, rerun only with explicit human justification via --override-non-approve --override-reason "<reason>".
APPROVED_FOR_COMMIT -> run CloseBubble; do not shortcut directly to pairflow bubble commit --stage-all.
- For
review_artifact_type=code, CloseBubble must first prove the implementation pre-commit admin/archive hook in the bubble worktree when the task source is under plans/tasks/.
- If that proof is missing, STOP before commit. Do not commit first and inspect later.
- For remote bubbles, run the routed command from the laptop/local repo; do not
ssh into the remote clone and commit manually.
DONE -> run CloseBubble; do not shortcut directly to pairflow bubble merge.
- For
review_artifact_type=code, CloseBubble must first prove the already-committed bubble content contains the implementation task archive/status/parent-plan admin postcondition.
- If that proof is missing, STOP before merge. Do not repair the missing closed-task admin directly on
main.
- For remote bubbles, run the routed command from the laptop/local repo; Pairflow imports the started-remote merge handoff, completes the durable merge in the local repo, then performs remote cleanup.
- After successful merge, run finalized bubble cleanup through
pairflow bubble delete --force unless the close workflow reports a concrete retained-bubble reason.
CANCELLED with needed changes -> recovery workflow (manual git path from bubble worktree)
Practical Guardrails
- Pre-flight before starting a bubble:
- Start from clean
main worktree.
- Ensure no ongoing merge/rebase/cherry-pick.
- If task file exists on
main, commit it before bubble start.
- Exception: if the only pre-flight blocker is that the selected task file is uncommitted (new or modified), auto-commit that task file without asking for approval, then continue bubble create/start.
- This exception applies to both docs-only refinement bubbles and implementation bubbles when the task source is that file.
- Remote create/start guardrails:
pairflow bubble create --remote <host> configures a remote executor but does not touch the remote host yet.
- Keep
bubble attach as a separate explicit step after remote start; do not assume create/start should auto-attach.
- Do not add
--attach to bubble start by default for either local or remote bubbles; only do it on explicit user request for interactive switching.
- Respect repository-specific bubble-create guardrails such as required
--bootstrap-command when they are declared in the repo docs or AGENTS instructions.
- Remote routed-command guardrails after start:
- For started remote bubbles,
status, approve, reply, commit, merge, and delete stay on the retained laptop-side thin-client routed path by default.
- Do not treat the remote clone as the operator control plane for those commands; the local repo's
.pairflow/bubbles/<id>/remote.json and state-cache.json remain part of the routing contract.
- The bounded exception is verified remote-clone local
request-rework parity; if that proof is absent, stay on the laptop-routed path.
- While a bubble is running, parallel direct commits on
main are allowed only for file-disjoint scope (no overlap with the bubble's touched files).
- After
bubble start, status may be briefly stale. Poll status once more before deciding it failed.
- If
--repo lookup behaves unexpectedly, retry from repo root cwd and verify with status --json.
- Never start a second bubble for the same change while the first bubble still has unmerged code, unless intentionally abandoning and archiving that work.
- For message-bearing commands, always build the message via quoted heredoc, then pass as a variable. This prevents backtick/
$ shell expansion and quote breakage.
- Artifact type gate for create:
pairflow bubble create requires --review-artifact-type.
- Use
document for docs-only refinement/review/update bubbles.
- Use
code for implementation/testing/runtime behavior bubbles.
- If intent is ambiguous, ask one explicit clarification question before create.
- Task input gate for create:
- Provide exactly one of
--task, --task-file, or --ideation.
--ideation cannot be combined with --task or --task-file.
- If created with
--ideation, run bubble kickoff before any pass/converged.
- Do not auto-kickoff immediately after create/start unless the user explicitly asks for kickoff now.
- Bubble ID gate for create:
pairflow bubble create --id <id> accepts only 3-40 chars.
- Pattern: start with lowercase letter or digit, then lowercase letters, digits,
_ or -.
- This validation is create-time only; do not block lifecycle operations for already existing bubbles that may have longer IDs.
- CloseBubble completion for
code bubbles:
- Before lifecycle commit, archive the completed task from
plans/tasks/... into the canonical plans/archive/tasks/<archive_group>/<task_id>.md, set archived status, and update the parent plan tracker/table rows inside the bubble worktree.
- Lifecycle commit is forbidden until that pre-commit admin proof is collected when the task source is known under
plans/tasks/.
- Before merge from
DONE, verify the already-committed bubble content contains that same admin/archive proof.
- Delete the finalized bubble artifact after successful merge unless there is a concrete retained-bubble reason.
- Determine whether
README.md, relevant docs/, or other non-task follow-up files must be updated based on merged behavior changes, then apply required updates separately when allowed. Closed-task archive/status/progress completion is not a post-merge follow-up.
Shell-safe message pattern (mandatory)
Use this pattern whenever text can contain backticks, $, quotes, or markdown:
msg=$(cat <<'MSG'
Issue details:
- Keep literal text like `previous reviewer clean PASS`
- Keep literal text like `round>=2`
- Keep literal text like $HOME unchanged
MSG
)
pairflow bubble reply --id <id> --message "$msg"
Also valid for rework:
msg=$(cat <<'MSG'
Please rework:
- Enforce most-recent-only overlap handling
- Add explicit round>=2 gate in Given
MSG
)
pairflow bubble request-rework --id <id> --message "$msg"
Do not use this with untrusted inline command substitution. The quoted heredoc (<<'MSG') is the default safe route.
Examples
Example 1: Watchdog timeout in WAITING_HUMAN
User: "bubble stuck, timeout happened"
-> status shows WAITING_HUMAN
-> build message via quoted heredoc, then `pairflow bubble reply --id <id> --message "$msg"`
Example 2: Human wants rework but bubble is not in approval state
If state is WAITING_HUMAN or RUNNING:
- do not use `bubble request-rework`
- route through `bubble reply` or continue normal reviewer->implementer pass flow
Example 3: Deep approval review requested
Use ReviewBubble (deep mode default)
-> direct Codex review from bubble worktree/task/transcript context
-> file-by-file changes
-> findings labeled by origin (`[Bubble]`, `[MetaReview]`)
-> findings explained in business-technical language by default
-> validation evidence summary
-> explicit approve/rework recommendation
Example 6: Direct review invocation
ReviewBubble --id <id> --mode deep --decide none
Example 4: Cancelled bubble but work is valuable
Use RecoverBubble workflow:
- commit on bubble branch from bubble worktree
- merge to main manually
- delete bubble artifacts
Example 5: Bootstrap evidence planning
Use BootstrapEvidence workflow:
- inspect project validation surface
- propose minimal evidence-generation plan
- provide handoff --ref pattern
Example 7: Operator-ready manual test runbook
Use TestBubble workflow:
- quick mode: critical smoke checks only (`--mode quick`)
- default mode: full recommended manual suite (`--mode default`)
- output must include fixtures, browser/session isolation, exact clicks, console commands, and GO/NO-GO rules
Example 8: Preworked ideation kickoff
User: "Create ideation bubble first; I'll decide kickoff later."
-> create + start only, keep RUNNING round=0 hold
Later user: "Apply these manual edits in bubble worktree, then kickoff."
-> perform requested pre-kickoff edits
-> kickoff with inline task summarizing completed edits
-> first loop step can be explicit validation/pass-to-reviewer