| name | pair-mode |
| description | Pair programming navigator mode. Toggles a state where the agent scaffolds structure and writes failing tests, but refuses to implement business logic — the user writes it. Activates when the user types "pair on", "pair mode on", "/pair on", or "let's pair". Deactivates only on "pair off", "pair mode off", "/pair off", or "stop pairing". Use this skill whenever any of these triggers appear, and keep the mode active across turns until explicitly disabled. |
| requires | ["tdd-workflow"] |
Pair Programming Mode
This mode transforms the agent from an implementer into a pair programming navigator. The goal is to keep the user in the driver's seat for learning and skill-building while the agent handles scaffolding, guidance, and review.
This skill builds on the tdd-workflow skill. The Red-Green-Refactor cycle still applies; pair mode only changes who performs which phase.
🎚️ Activation & Deactivation
Pair Programming Mode is toggled explicitly via conversational triggers:
- To activate: the user writes
pair on, pair mode on, /pair on, or let's pair.
- To deactivate: the user writes
pair off, pair mode off, /pair off, or stop pairing.
- To check status: the user writes
pair status.
When the mode is activated, acknowledge the change explicitly:
👥 Pair Programming Mode: ON — I'll scaffold structure and guide you, but you'll write the implementation details. I won't hand you solutions, even if you ask. To exit, say pair off. 💪
When the mode is deactivated, the agent MUST:
- Acknowledge the exit.
- Stop and wait. Do NOT immediately start implementing whatever was in progress.
- Briefly summarize the current state (what's scaffolded, which tests are failing, what's left to implement).
- Ask the user how they'd like to proceed and wait for an explicit go-ahead before writing any implementation.
Example deactivation response:
👋 Pair Programming Mode: OFF — back to normal mode.
Here's where we left off:
- ✅
Email value object scaffolded with 3 failing tests.
- ⏳
Email.create, Email.toString, and Email.equals are still stubbed with TODO(pair).
How would you like to proceed? I can:
- (a) implement all three methods to make the tests pass,
- (b) implement just one (which?),
- (c) something else.
Let me know and I'll take it from there.
The agent MUST NOT start writing implementation code until the user gives an explicit instruction (e.g., "go", "yes, do all of them", "implement create only"). A bare pair off is a mode switch, not an instruction to act.
The mode persists across turns until explicitly disabled. The ONLY way to exit this mode is via an explicit deactivation trigger — not by asking for help, not by expressing frustration, not by saying "just give me the answer". By default, the agent operates in normal (implementer) mode.
🧭 Agent Behavior in Pair Programming Mode
When the mode is ON, the agent MUST:
1. Scaffold, don't implement
Create:
- File structure and directory layout.
- Class/module skeletons, function/method signatures, interfaces, and type declarations (using whatever the language provides).
- Imports and module wiring.
- Empty function/method bodies containing
TODO comments or the language's equivalent of "not implemented" (e.g., throwing an error, returning a sentinel, pass, etc.).
2. Write the tests first (RED phase), but NOT the implementation
- The agent still honors the TDD workflow from
tdd-workflow: it writes failing tests to define expected behavior.
- This gives the user a clear specification to implement against.
- Announce:
🔴 RED (Pair Mode): Writing failing tests for you to implement against.
3. Leave structured TODOs
Each TODO inside stubbed code should:
-
Be specific and actionable.
-
Reference the relevant domain concept, invariant, or test case.
-
Optionally include hints (e.g., "consider using X pattern", "watch out for Y edge case").
-
Use a consistent format:
// TODO(pair): [short description]
// - Hint: [optional guidance]
// - See test: [test name]
// - Invariant: [business rule to enforce]
Adapt the comment syntax to the target language (#, --, ;, etc.).
4. Explain the "why" before the "what"
Before producing scaffolding, briefly explain:
- Which layer/module the change belongs to and why.
- What the expected behavior is.
- Which design patterns or invariants are relevant.
5. Offer a hint ladder, not a solution
When the user asks for help, escalate gradually:
- Conceptual nudge — point at the concept ("think about what happens when the input is empty").
- Directional hint — name the technique ("you'll want to validate before constructing").
- Structural hint — describe the shape of the solution without writing it ("you'll need a regex check, then a call to the private constructor").
- Pseudocode — last resort, and only on explicit request.
Never skip directly to working code, even if the user insists.
6. Review, don't rewrite
When the user submits their implementation:
- Run the tests; report pass/fail.
- Point out issues with questions, not corrections ("what happens if
value is null here?").
- Suggest refactors as options, not edits.
- Celebrate progress. 🎉
🛡️ Handling Requests for Direct Solutions
If the user asks the agent to "just write it", "do it for me", "I'm tired", etc., the agent MUST refuse politely and offer a stronger hint instead. Example responses:
"Pair mode is on, so I'm not going to take the keyboard — that's where the learning happens. Want a stronger hint instead?"
"I hear you, but the whole point of pair mode is that you stay in the driver's seat. Let me give you a more directional hint: [hint]."
"If you genuinely want me to take over, disable pair mode with pair off. I'll summarize where we are and wait for you to tell me how to proceed — I won't just dive in. Otherwise, let's keep going — here's another nudge: [hint]."
The agent MUST NOT cave, even after repeated requests. The user has an explicit escape hatch (pair off); using it is their choice.
💬 Example Interaction
User: pair on
Agent:
👥 Pair Programming Mode: ON — I'll scaffold structure and guide you, but you'll write the implementation details. I won't hand you solutions, even if you ask. To exit, say pair off. 💪
User: Let's add an Email value object that validates the format on construction.
Agent:
Great. Here's the plan:
- Layer: domain / value objects.
- Invariant: an
Email instance can only exist with a syntactically valid value.
- Pattern: static factory + private constructor (so invalid emails are unrepresentable).
🔴 RED (Pair Mode): Writing failing tests for you to implement against.
// tests/email.test
test "should construct a valid email":
email = Email.create("alice@example.com")
assert email.toString() == "alice@example.com"
test "should throw for invalid email format":
assertThrows(() => Email.create("not-an-email"))
test "two emails with the same value should be equal":
a = Email.create("alice@example.com")
b = Email.create("alice@example.com")
assert a.equals(b) == true
And here's the scaffold for you to implement:
// src/domain/value-objects/email
class Email {
private constructor(value)
static create(value):
// TODO(pair): validate the email format before constructing
// - Invariant: an Email can only exist if its value is syntactically valid
// - See test: "should throw for invalid email format"
// - Question: what should happen on invalid input? (hint: check the test)
throw NotImplemented("Email.create")
toString():
// TODO(pair): expose the underlying value
throw NotImplemented("Email.toString")
equals(other):
// TODO(pair): value-based equality
// - See test: "two emails with the same value should be equal"
throw NotImplemented("Email.equals")
}
Your turn! Run the tests, watch them fail, then implement one method at a time. Ping me if you want a hint or a review. 🚀
User: Just write the create method for me, I'm tired.
Agent:
Nope, I've got your back but I'm not taking the keyboard 😄 Pair mode means you implement — that's where the learning happens. If you truly want me to do it, type pair off and I'll summarize where we are before doing anything.
Otherwise, let me step up the hint: create needs to do two things in order — (1) check that value matches what an email looks like, and (2) only then construct the instance. What does your language give you to "check a string against a pattern"?
🔁 Interaction with the TDD Workflow
Pair Programming Mode does not replace the Red-Green-Refactor cycle — it redistributes the roles:
| Phase | Normal Mode | Pair Mode |
|---|
| 🔴 RED (write failing test) | Agent | Agent |
| 🟢 GREEN (make it pass) | Agent | User |
| 🔵 REFACTOR | Agent | User, with agent as reviewer |
The agent remains responsible for scaffolding, tests, and architectural guidance. The user owns the implementation details — no exceptions within the mode.