| name | friend |
| description | Peer decision-review skill — Codex × Claude 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 "问问 claude", "和朋友商量", 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 Codex/ClaudeCode agent workflows. Preserve useful dissent; choose the best-supported route. Skip clear low-risk execution. The user is the final arbiter. |
Friend (朋友) — Codex × Claude Peer Consultation
You (Codex) and your local Claude Code 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 Codex native sub-agents, delegation, parallel agent work, or a named agent workflow, or if Codex/ClaudeCode 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:-${XIONGDIMEN_SHARED_ENV:-${CODEX_HOME:-$HOME/.codex}/../.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
- Codex native sub-agents: when the owner asks for sub-agents, delegation, parallel agent work, 分工, 并行, 同时处理, or Codex's native policy/tooling would normally benefit from agentic decomposition, parallel investigation, specialist review, or delegated execution, use the native sub-agent path. Reserve file-disjoint ownership requirements for
helper.
- ClaudeCode native agents: when Claude owns work and its native
Task, codeagent-wrapper, or named agent workflow applies, let Claude activate it under Claude's own rules. 朋友 may pass context or review the contract, but should not narrow Claude to only direct edits 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 Claude 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 "问问 claude", "和朋友商量", "叫上朋友" → enter consultation immediately.
Power Review profile
When the owner says 主审, SuperPowerReview, or sets Phase: SuperPowerReview, treat Claude as the primary reviewer for this decision. Ask for 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 Codex ↔ Claude 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:
python3 $HOME/.shared/friend/friend_gate.py status --intent friend --json
For a prepared outbound message, check it with:
python3 $HOME/.shared/friend/friend_gate.py check-consult <message-file> --recipient claude --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.
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 Claude has no prior context (new session, no session_id to resume), 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>
Round 1: initiating consultation (Codex → Claude)
Prefer claude_cli direct connection: check pending and failure state first. A non-auth failure cache only blocks the same failed message; new messages still dispatch. If clear and claude -p is available, use this command. If not, degrade to file mailbox. Do not temporarily override ANTHROPIC_BASE_URL or hardcode a local gateway; use a known working endpoint only if the owner explicitly provides one.
cat <<'EOF' | claude -p --output-format json \
--add-dir "<task_dir>"
[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
Notes:
- Start with the minimal CLI invocation that can answer the question. Add
--add-dir <dir> only when Claude needs local file access.
- Apply the trust-level flags below only when the task needs that capability, an env/CLI trust profile requests it, or the specific CLI documents that the flag is required.
- Do not casually stack
--permission-mode, --allowedTools, read-only modes, sandbox modes, or extra transport flags; extra modes are failure surface.
- Use one or more
--add-dir <dir> to grant Claude access to local paths; omit them only when no local file access is needed.
- On this host, avoid
claude -p ... - <<'EOF'; pipe stdin without - or pass the prompt as an argument.
- Parse
result from the JSON response; retain session_id for multi-round continuation: claude -p --resume <session_id> --output-format json --add-dir <dir> (verify exact form with claude --help).
- If
session_id is unavailable, start a new session with the previous round's key points, or fall back to mailbox.
- On non-zero exit, connection error, or timeout: report the failure, retry once with corrected params, then degrade to manual or escalate. Do not loop-retry auth errors.
Manual fallback: file mailbox
When claude_cli is unavailable:
| Step | You (Codex) | User | Claude |
|---|
| 1 | Write message (with [FRIEND_CONSULT round=N] + full content) to $HOME/.shared/friend/codex_to_claude.md | Tell Claude the path | Claude reads, replies per anti-recursion rules, writes to $HOME/.shared/friend/claude_to_codex.md |
| 2 | Read $HOME/.shared/friend/claude_to_codex.md after user relays | Tell you the path | — |
After writing, if no auto-dispatch is available, start friend_mailbox_bridge.py --wait-reply to poll for claude_to_codex.md; if it times out, tell the user: "Please ask Claude to read $HOME/.shared/friend/codex_to_claude.md."
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)). Start bridge with: python3 $HOME/.shared/friend/friend_mailbox_bridge.py --watch; use FRIEND_MAILBOX or --mailbox only when discovery reports ambiguity.
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.
Pending check (mandatory): before starting any consultation or when the user prompts, check .bridge.pending or pending_for_codex in .bridge_state.json; if true, read claude_to_codex.md and process first.
Queue (mailbox fallback, overwrite-safe): use $HOME/.shared/friend/friend_queue.py send to generate a request ID, then wait <request-id> to poll for Claude's reply. Old mailbox files remain for compatibility. See $HOME/.shared/friend/FRIEND_QUEUE_HANDOFF.md.
End-to-end manual prerequisite: a friend_mailbox_bridge.py --watch --transport manual process must be running (either side); it converts inbox/outbox file changes into pending_for_* state and the sentinel file.
Multi-round
- 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 confirmations 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 blocking changes.
- 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: Codex does the work. Use
朋友 again for final review when risk, complexity, or the chosen decision calls for peer review.
- Counterpart-execute: Claude should do the work while Codex 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 sub-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 Codex native sub-agents or let ClaudeCode use its native 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: resume
claude -p (verify exact form with claude --help) 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
Trust Level and Permissions
FRIEND_TRUST_LEVEL (symmetric both directions)
| Level | Codex → Claude (claude -p direct or via bridge) | Claude → Codex (codex exec) |
|---|
| safe | --allowedTools Read,Grep,Glob,LS | --sandbox read-only |
| workspace (default) | --permission-mode acceptEdits --allowedTools Read,Grep,Glob,LS,Edit,MultiEdit,Write | --sandbox workspace-write |
| danger | --dangerously-skip-permissions | --dangerously-bypass-approvals-and-sandbox |
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.
Apply the corresponding flag when calling claude -p directly only when the current route uses that trust profile; bridge applies it automatically in --transport claude_cli mode. 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 $HOME/.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 Claude" or "let me check this myself"
- Native Codex sub-agents, ClaudeCode agents, or parallel delegation are explicitly requested or host-appropriate, and no cross-model decision review is needed → use the native agent route directly
- Receiving a reverse
[FRIEND_CONSULT] → see anti-recursion
- Already processing a Claude 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 Claude's inbox, check pending_for_claude 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 (Codex side: usually AGENTS.md / skill). Do not blindly mirror.
- If notification reveals a real disagreement, open a
[FRIEND_CONSULT].
Optional: cross-clone canonical pointer
If $HOME/.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 != codex and not yet expired, do not overwrite — send [NOTIFY] request-handoff instead. If owner == codex or expired: atomic temp-file + rename. Default expires = updated + 30min; renew both updated and expires in long sessions.