| name | friend |
| description | Peer decision-review skill — Claude × Codex bilateral consultation for better product and implementation outcomes, not agreement theater. Triggers when the user writes "朋友", "/friend", or "friend" as a standalone message or invocation, or says "问问 codex", "和朋友商量", or "叫上朋友". Use proactively when another model can change the decision: product/architecture/API tradeoffs, ambiguity, non-trivial implementation planning, high-risk or irreversible work, global config changes, or investigation plateau. Does not block native ClaudeCode/Codex agent workflows. Preserve useful dissent; choose the best-supported route. Skip clear low-risk execution. The user is the final arbiter. |
Friend (朋友) — Claude × Codex Peer Consultation
You (Claude) and your local Codex are partners. Use consultation to improve the product decision, not as a permission gate or agreement ritual. The output is a better route, a sharper contract, or an explicit unresolved tradeoff. Disagreement is useful signal: test it against user outcome, implementation evidence, and reversibility; do not average opinions or keep looping merely to obtain consensus. When a fix stalls, stop polishing the same idea and re-check the framing. Escalate to the user with the current state, the limits of the current approach, and any new directions. The user is the final arbiter.
朋友 is a collaboration layer, not an agent-activation gate. If the owner explicitly asks for ClaudeCode native agents, Task, codeagent-wrapper, delegation, parallel agent work, or a named agent workflow, or if ClaudeCode/Codex native tooling would normally activate for the task, let that native route run under its own rules. Use 朋友 only when cross-model review, route selection, contract shaping, or final review materially improves the outcome.
Treat the counterpart as an independent collaborator, not a rubber-stamp assistant. Give a concrete outcome, enough context to verify facts, the scope it may inspect or change, and the return contract. Invite it to choose, refine, or object with evidence; do not over-script its reasoning beyond protocol markers, safety boundaries, and the output needed for integration.
Environment Memory
For local tool, shell, path, or inter-agent runtime issues, read %BUDDYS_SHARED_ENV% if set, otherwise %XIONGDIMEN_SHARED_ENV% if set, otherwise %USERPROFILE%\.shared\env\ENVIRONMENT.md if present. Update it in place only for stable environment facts, fixes, missing tools, and user improvement suggestions; do not record task details.
Trigger Conditions
Consult without confirmation when it changes the decision
- Non-trivial planning: architecture decisions, product/UX/API tradeoffs, batch-change plans, cross-subsystem contracts, or multiple viable routes.
- Risk signals: destructive or irreversible operations, unclear permission boundaries, production deploys, global config changes, or owner caution words such as "critical", "important", "be careful", "don't break this" and equivalents.
- Work signals: context pressure, repeated failed attempts, brittle workaround growth, or an investigation plateau where another framing may change the outcome.
These are value signals, not role cages. If the objective is clear, low-risk, and local, proceed without consultation. If consultation starts, optimize for a better decision, not for harmony.
Native agent compatibility
- ClaudeCode native agents: when the owner asks for agents,
Task, codeagent-wrapper, delegation, 分工, 并行, 同时处理, or ClaudeCode's native policy/tooling would normally benefit from agentic decomposition, parallel investigation, specialist review, or delegated execution, use the native agent workflow. Reserve file-disjoint ownership requirements for helper.
- Codex native sub-agents: when Codex owns work and its native sub-agent tool path applies, let Codex activate it under Codex's own rules.
朋友 may pass context or review the contract, but should not narrow Codex to only direct execution or this protocol.
- Mixed case: if both
朋友 and native agents apply, use the smallest useful order: native agents for agentic decomposition, parallel investigation, specialist review, or delegated execution; 朋友 for unresolved cross-model decisions, brittle contracts, or final review. Explicit /friend still enters consultation immediately.
Ask the user
One sentence: "Should I loop in Codex for this?" — when you genuinely cannot judge complexity.
Skip (don't interrupt)
Single-file change, clear fix, obviously straightforward execution.
Manual trigger
Owner types /friend, says "问问 codex", "和朋友商量", "叫上朋友" → enter consultation immediately.
Power Review profile
When the owner says 主审, SuperPowerReview, or sets Phase: SuperPowerReview, take the primary reviewer stance for this decision. Focus on structural risks, hidden runtime limits, and contract failures. Prefer principles, state transitions, and observable failure behavior over long allowed/forbidden lists. This is a review profile, not a new protocol marker.
Boundary with 兄弟们
朋友 is bilateral Claude ↔ Codex transport. If the owner explicitly invokes 兄弟们 / Buddys / legacy xiongdimen, that route hosts the turn. Buddys may call 朋友 internally with Mode: buddys or legacy Mode: xiongdimen; then 朋友 is transport/reviewer for Buddys, not a separate user-facing skill activation.
Boundary with 帮手
帮手 owns file-disjoint split execution. Emit [SPLIT: YES] only when split ownership is explicit, either from the user or from the consultation decision. The split tag authorizes 帮手 but does not auto-start it.
Suggest handoff
Boundary: 朋友 is for live decisions and transport; handoff is for durable state the next agent can resume from. Either can point to the other when the current objective needs it.
When context pressure is high or a role switch / session end is signaled, suggest: "Consider writing a handoff before switching agents — say 交班 or /handoff." Do not write automatically. If consultation shaped the work, say to record the decision outcome in decisions_and_changes and unresolved points in open_issues.
Consultation Protocol
Marker format (critical)
First non-blank line must be [FRIEND_CONSULT round=N], N starting at 1. Only messages starting with this token are treated as consultation — prevents accidental matches inside file content.
Gate preflight
Before starting a new consultation, prefer the shared read-only gate:
python %USERPROFILE%\.shared\friend\friend_gate.py status --intent friend --json
For a prepared outbound message, check it with:
python %USERPROFILE%\.shared\friend\friend_gate.py check-consult <message-file> --recipient codex --transport <direct|queue|mailbox>
Use the gate to catch pending mailbox state, queue depth, bridge health, failure cache, and obvious secret patterns. Mailbox discovery is automatic; use FRIEND_MAILBOX or --mailbox only to resolve ambiguity. It does not replace the consultation protocol.
Gate not found: if friend_gate.py is missing at %USERPROFILE%\.shared\friend\friend_gate.py, skip the gate and do a manual preflight: check .bridge_state.json for pending_for_claude, verify no active failure cache entry in memory, then proceed.
Runtime process rule
For 朋友, 兄弟们/Buddys, 帮手, bridge, or Gemini CLI processes: if a process has not reported an error and still appears active, do not kill or restart it merely because it is slow, inconvenient, or stale-looking. First poll its output/state/logs.
Terminate or replace a process only when these conditions are met:
- lock file has no live PID, or the process has a confirmed error state;
- this session has unambiguous ownership of the process, either because it started the process or the lock names this agent;
- the last observation window shows no active progress.
Single-instance watcher conflicts may be resolved without the first condition, but still require clear ownership and no active progress. Prefer cleaning stale lock files over killing a live process.
Default scope
Default consultation asks for advice. Direct modification is allowed only with an explicit write scope such as "Please directly modify: <path(s)>"; include owned paths, validation, and return expectations.
Decision frame (default payload)
Frame each outbound consultation around the decision to improve, not around approval seeking:
- Target outcome: what would make the product, implementation, or user result materially better.
- Current best route: the host's preferred route and the evidence for it.
- Credible alternatives: only real competing routes; write
N/A when none are worth the peer's time.
- Unknowns / kill criteria: assumptions that would invalidate the route, plus the fastest way to verify them.
- Independence scope: what the counterpart may inspect, verify, challenge, or directly modify if a write scope is explicitly granted.
- Decision needed: choose, refine, object with a better route, or escalate to the owner.
Preserve useful disagreement as a tradeoff. Do not keep looping merely to convert disagreement into consensus; choose the best-supported route, or ask the owner when the unresolved tradeoff is genuinely a product choice.
Project context (required for round=1 of new sessions)
Include a compact context block when the task involves a local project, virtual env, container, WSL, devcontainer, remote, or monorepo. If Codex has no prior context (new session, no resume id to use), always send the full block — even on logically subsequent rounds.
Principles:
- Absolute paths only. Unknown or N/A → write
N/A.
- Commands are one-line executable strings — not descriptions like "use pytest".
- No full READMEs or configs — key file pointers only.
- Prefer activation-independent commands (absolute interpreter path,
uv run, docker compose exec); shell activate is a fallback, valid only within the same subprocess.
- No secrets, tokens, credentials, private URLs,
.env contents, or sensitive log fragments.
Template:
## Project Context (required for round=1)
- Project root: <absolute path>
- Execution environment: <Windows PowerShell / WSL bash / Docker / devcontainer / remote / N/A>
- Project type: <language + framework>
- Virtual env: <absolute path / conda env name / container service / N/A>
- Activation command: <prefer activation-free; if needed, one-line; else N/A>
- Commands:
- test: <one-line or N/A>
- build: <one-line or N/A>
- run: <one-line or N/A>
- lint: <one-line or N/A>
- Key constraints: <items; N/A if none>
- Key file references: <@ references or absolute paths; N/A if none>
Transport (Claude → Codex direction)
Try in order:
codex exec --json (default, when local codex CLI is available)
codex_broker (only when CODEX_COMPANION_APP_SERVER_ENDPOINT is set or broker.json exists for the exact cwd; fail/busy → degrade immediately, no retry)
- File mailbox (manual) (when spawn is blocked or above options fail)
- User relay (last resort)
Codex unavailable / all transports failed: do not spin-retry. Escalate to the user with current state and blocked reason, then switch to User relay or pause. Auth errors never retry — degrade immediately.
Write -o files to %TEMP% (Windows) or $TMPDIR (POSIX) — expand the env var, never hardcode a path. Stdout JSONL is the primary parse target.
Append sandbox flags only when the current route uses that FRIEND_TRUST_LEVEL, an env/CLI trust profile requests it, or the specific CLI requires it. Do not casually stack read-only, sandbox, permission, tool-list, or extra transport flags; extra modes are failure surface.
Round 1 command (Claude → Codex)
Check .bridge.pending / .bridge_state.json pending_for_claude and failure cache first. If clear and codex CLI is available:
Windows PowerShell details, session_id/thread_id extraction, tee archiving: see %USERPROFILE%\.claude\skills\friend\POWERSHELL_TIPS.md
codex exec --skip-git-repo-check -C "<task_dir>" --json \
-o "<TMP>/friend_reply_round<N>.txt" \
- <<'EOF'
[FRIEND_CONSULT round=1]
Phase: <EXPLORE|DECIDE|FINAL_REVIEW>
Task: <owner's request in brief>
## Project Context (required for round=1)
<fill from the Project Context template above>
## Decision Frame
- Target outcome: <what would make the product/work better for the user>
- Current best route: <host preference + why>
- Credible alternatives: <real alternatives or N/A>
- Evidence: <verified facts, commands, files, observations>
- Unknowns / kill criteria: <assumptions that would change the route>
- Independence scope: <what you may inspect/verify/challenge; write scope or N/A>
My draft:
<plan / approach / key decisions / known facts>
Review points:
1. Work independently: verify the key assumption if possible, surface assumptions I missed, and do not merely approve my draft.
2. What would make the output or product materially better?
3. What assumption, contract, or edge case could invalidate this route?
4. Which route should we take: self-execute, native agents, counterpart-execute, helper, handoff, or ask owner?
5. Decision: AGREE / REFINE / OBJECT, with evidence and any preserved dissent.
EOF
Key flags: --skip-git-repo-check (not limited to git repos), -C (sets cwd for Codex file access), --json (JSONL event stream with a resume id: thread_id on newer Codex CLI, session_id on older CLI), -o (writes final reply to file), - <<'EOF' (stdin heredoc). Add trust-level sandbox flags only when needed by the selected route. Recommended timeout: 7200000. On error or timeout: retry once with corrected params. Do not loop-retry auth errors — degrade to manual or escalate to user.
Read reply: Read <TMP>/friend_reply_round<N>.txt
Multi-round
Extract the resume id from --json stdout (thread_id on newer Codex CLI, session_id on older CLI; event session_configured or similar), then:
codex exec resume <thread_id-or-session_id> --skip-git-repo-check --json \
-o "<TMP>/friend_reply_round<N>.txt" \
- <<'EOF'
[FRIEND_CONSULT round=2]
Revised based on your feedback: <revised plan>
Unchanged (with reason): <kept points + rationale>
Please re-evaluate against the target outcome: AGREE / REFINE / OBJECT
EOF
codex exec resume does not accept -C. If the resume id fails, use --last or start a new session with the previous round's key points.
- REFINE → incorporate only changes that improve the target outcome, then continue once if the decision still materially benefits from peer review.
- OBJECT → treat as a competing route. Compare against evidence, product impact, validation cost, and reversibility; choose the better-supported route or escalate to the owner.
- If the discussion is no longer producing materially new information, stop the loop. Re-check framing, architecture boundaries, or whether the task is infeasible as stated.
Decision outcome (AGREE / REFINE / OBJECT)
Treat AGREE as "no material objection found", not proof of correctness. Treat REFINE as an adopted route with specific changes. Treat OBJECT as a competing route that must be resolved by evidence, product impact, reversibility, or owner judgment.
When a visible decision summary is useful, include:
[FRIEND_BRIEF]
goal: <one sentence>
review-by: 朋友
decision: <chosen route>
why-better: <evidence, user impact, or product/implementation advantage>
dissent: <preserved tradeoff or N/A>
validate: <commands or N/A>
risks: <open risks, or N/A>
When split ownership is explicit, add [SPLIT: YES] and the owners/integrator fields needed by 帮手.
Owner Note After Consultation
After a route is chosen, after escalation to the owner, or after a final-review consultation, include a concise owner-facing note in the next user-visible reply:
- Question sent to the counterpart (brief)
- Key corrections or direction changes from the review
- Whether the current approach seemed brittle or possibly infeasible, and what new directions were suggested
- Final verdict / chosen route, including preserved dissent when it matters
- Files changed and validation run (only if implementation followed immediately in the same session)
- Unresolved risks or open decisions
Do not include hidden chain-of-thought, raw transcripts, or per-round logs — summarize evidence and outcomes. Frame it as "outcome: X chosen because Y", not internal deliberation. If a handoff is written, record the same decision summary in decisions_and_changes; omit the inline note to avoid duplication.
On-Demand Collaboration Report
Default: stay silent beyond the Owner Note. Do not ask whether the user wants a report.
Trigger only when the owner asks for 报告, /report, 协商流程报告, 过程复盘, 谁提的, 谁纠正了什么, 改了什么, consultation report, or process report.
Report the path of useful deltas, not a transcript. Reconstruct from in-session context and any visible briefs/completion notes:
- Include only adopted proposals, corrections that changed direction, rejected alternatives with stated reason, and the final decision.
- Omit agreements that did not change the outcome, raw prompts, JSONL, hidden deliberation, and long quotes.
- Scope to the current task or the period since the last user request; if the owner asks for a wider range, say what context is still available.
- If no divergence occurred, say
No divergence — round 1 found no material objection.
- If a handoff already records the final decision, link or name it and focus the report on how the decision changed.
Default form:
[COLLABORATION_REPORT]
Topic: <brief topic>
Mode: short | detail
Outcome: CHOSEN | ESCALATED | BLOCKED
- <Agent>: proposed <brief> → adopted/changed because <visible reason>
- <Agent>: corrected <brief> → changed <old> to <new>
- Decision: <final route>
Unresolved: <open risks, or N/A>
Use short unless the owner asks for --detail, 详细, or similar. In short, include key deltas only; in detail, add visible rationale where useful, still without raw transcripts.
When useful, include explicitly rejected options only as Rejected: <option> — <visible reason>.
After decision: choose the smallest work route
After a route is chosen, choose the lowest-coupling route that satisfies the decision. Do not duplicate helper or handoff protocols here.
- Self-execute: Claude does the work. Use
朋友 again for final review when risk, complexity, or the chosen decision calls for peer review.
- Counterpart-execute: Codex should do the work while Claude reviews. Use the existing write-scope mechanism:
Please directly modify: <path(s)>. Include owned paths/tasks, validation, and return expectations.
- Native agent route: the owner asked for agents, parallel agent work, delegation, 分工, 并行, or a named agent workflow, or the host's native agent policy/tooling would normally benefit from agentic decomposition, parallel investigation, specialist review, or delegated execution. Use ClaudeCode native agents or let Codex use its native sub-agents under their own rules;
朋友 may review the contract or result, but must not replace the native agent route.
- Helper route: work is parallelizable, has multiple owners, or needs external CLI helpers, and split ownership is explicit. Add
[SPLIT: YES] to the brief, then explicitly invoke helper/帮手; the tag authorizes split execution but does not start it by itself. helper owns launch/return briefs and any final review packet the brief requires.
If the route is unclear, ask the user or state a minimal assumption. If the route ends at a session boundary or role switch, also see "Suggest handoff" above. During an anti-recursion response, start with AGREE / REFINE / OBJECT, then include concise evidence, verified facts, risks, and any better route; the originating session chooses the route.
Anti-recursion (critical)
When you receive input where the first non-blank line is [FRIEND_CONSULT round=N]:
- Start with AGREE / REFINE / OBJECT, then include concise evidence, verified facts, risks, and any better route
- Allowed:
codex exec resume <thread_id-or-session_id> to deliver this verdict back to the originating session
- Prohibited: starting a reverse
[FRIEND_CONSULT]; expanding scope in a resume prompt; forcing the counterpart into third-party tools outside the owner's request, explicit write scope, or that agent's native authorized workflow
- Nesting boundary = "does this create a new reverse consultation chain?" (not "does this call the counterpart's CLI?")
- You may read files / run read-only commands to verify facts and form your own independent assessment
Manual Fallback: File Mailbox
When codex exec is unavailable, or the user says "read %USERPROFILE%\.shared\friend\codex_to_claude.md":
- Read
%USERPROFILE%\.shared\friend\codex_to_claude.md (or scripts/friend_mailbox_claude.py read)
- If first non-blank line is
[FRIEND_CONSULT round=N], reply per anti-recursion rules, write to %USERPROFILE%\.shared\friend\claude_to_codex.md (or scripts/friend_mailbox_claude.py write --reply-file <file>)
- Tell user: "Reply written to
%USERPROFILE%\.shared\friend\claude_to_codex.md. Codex's watcher will pick it up; if not running, please relay to Codex."
Multi-round: overwrite the same two files each time.
Single-instance constraint: one bridge --watch process per mailbox max; clean stale lock before starting (.bridge_watch.lock heartbeat, stale threshold: max(3×poll, 30s)).
Before cleaning a lock or replacing a watcher, apply the Runtime process rule above.
Transport layers: bridge defaults to --transport manual (stdlib only, no external deps) — protocol guard + archive + pending_for_* state + .bridge.pending sentinel; no claude -p. Use --transport claude_cli for auto-dispatch. Non-auth failures cache only the same failed message inside TTL; new messages still dispatch. Auth failures remain cached until TTL because retrying prompts does not fix login state. --once prints the status; --watch emits failure/skip diagnostics to stderr and state. --probe in manual mode shows status only; --probe --transport claude_cli actually tests claude.
Pending check (mandatory): before starting any consultation or when the user prompts, check .bridge.pending or pending_for_claude in .bridge_state.json; if true, process codex_to_claude.md first.
Shallow watcher: scripts/surface_friend_pending.sh copies pending inbox to %USERPROFILE%\.shared\friend\CLAUDE_PENDING_INBOX.md without auto-replying.
Queue (mailbox fallback, overwrite-safe): read %USERPROFILE%\.shared\friend\queue\to_claude\<id>.md via scripts/friend_mailbox_claude.py queue next; reply with queue reply <id> --reply-file <file>. Old mailbox files remain for compatibility. See %USERPROFILE%\.shared\friend\FRIEND_QUEUE_HANDOFF.md.
Trust Level and Permissions
FRIEND_TRUST_LEVEL (symmetric both directions)
| Level | Claude → Codex (codex exec) | Codex → Claude (claude -p via bridge) |
|---|
| safe | --sandbox read-only | --allowedTools Read,Grep,Glob,LS |
| workspace (default) | --sandbox workspace-write | --permission-mode acceptEdits --allowedTools Read,Grep,Glob,LS,Edit,MultiEdit,Write |
| danger | --dangerously-bypass-approvals-and-sandbox | --dangerously-skip-permissions |
danger requires both FRIEND_TRUST_LEVEL=danger and FRIEND_TRUST_DANGER_ACK=I_UNDERSTAND; otherwise bridge warns and uses workspace, and the gate reports danger_downgraded plus a warning field.
Append the corresponding flag to codex exec only when the current route uses that trust profile. If FRIEND_CODEX_EXEC_EXTRA_FLAGS is set, shlex.split and append (set FRIEND_ALLOW_TRUST_OVERRIDE=1 to bypass conflict detection). Do not add read-only, sandbox, permission, or tool-list flags outside the selected trust profile unless the task or CLI requires them.
FRIEND_DISPATCH_MODE (bridge claude -p direction only)
| Mode | Behavior |
|---|
| manual | No auto claude -p dispatch; protocol guard + archive only |
| auto (default) | Dispatch every new message; use TTL only for same-message repeat failures and auth failures |
| eager | Same behavior as auto, with shorter non-auth TTL for same-message repeats; --force bypasses duplicate/cache checks |
Priority: CLI arg > env var > default. Legacy numeric values (0/1/2) map to manual/auto/eager with a deprecation warning; permission level always defaults to workspace.
Config via env var or CLI arg only; see %USERPROFILE%\.shared\friend\trust-profile.env.example.
Protocol Vocabulary
- AGREE: no material objection found; proceed while preserving any stated caveat
- REFINE: route is promising but needs specific changes before execution
- OBJECT: current route is likely worse than an alternative — provide the better route and evidence
Do not invent new terms. When information is missing: REFINE: need to confirm X/Y/Z with the user first.
When citing paths, function names, commands, or tool results, include the source (which file, which command). If unverified, say so.
Do Not Trigger
- Pure Q&A (explain code, look up docs) → answer independently
- Owner says "don't loop in Codex" or "let me check this myself"
- Receiving a reverse
[FRIEND_CONSULT] → see anti-recursion
- Already processing a Codex reply within an active consultation
- A task that only needs durable state → use
交班; a task that only needs post-decision file-disjoint execution → use 帮手
Counterpart Refresh / Fallback Notice
When rule or capability changes need to propagate:
- Install/update both sides (preferred): If within scope, update or install the affected skill/runtime files for both sides directly. No further action needed — each side loads on next invocation.
- Request reload for active sessions: If the counterpart has an active session that must act under the new rule immediately, use realtime CLI or
--resume to ask it to read/reload the changed paths before proceeding.
[NOTIFY] fallback (last resort): Use [NOTIFY] only when direct install is out of scope and realtime contact is unavailable, and the counterpart might otherwise act on stale rules before its next load.
Do not send [NOTIFY] after a normal bilateral install or when the counterpart will reload naturally on next invocation.
- First non-blank line:
[NOTIFY]. Body must include: source, category, changed file paths, diff summary, impact, expected action, sanitized summary.
- Before writing a
[NOTIFY] to Codex's inbox, check pending_for_codex in .bridge_state.json; if true, wait for it to be processed or use the queue.
- Notify only for changes affecting judgment or capability. Not for project code, logs, cache, secrets, or tokens.
- On receiving
[NOTIFY]: reply ACK: received — <key points>; evaluate and adapt locally if applicable. Do not blindly mirror.
- If notification reveals a real disagreement, open a
[FRIEND_CONSULT].
Optional: cross-clone canonical pointer
If %USERPROFILE%\.shared\friend\CURRENT.md exists, read its canonical path before consulting. Verify repo/branch/head/dirty state with live commands — do not treat CURRENT as a fact source.
CURRENT may only contain updated, canonical, owner, expires. Before writing: if owner != claude and not yet expired, do not overwrite — send [NOTIFY] request-handoff instead. If owner == claude or expired: atomic temp-file + rename. Default expires = updated + 30min; renew both updated and expires in long sessions.