Skip to content

Latest commit

 

History

History
390 lines (293 loc) · 54.2 KB

File metadata and controls

390 lines (293 loc) · 54.2 KB

Claude Code / Codex / other agents -- determine your context before proceeding:

Source repo test: If bootstrap/bootstrap.sh, bootstrap/bootstrap.ps1, and skills/ all exist at the repo root, you are in the anywhere-agents source repo (or a fork with the same layout). Skip the bootstrap block below and proceed directly to ## Session Start Check. Do not execute the bootstrap script in the source repo; it would try to bootstrap itself.

Consumer repo path: Otherwise, you are in a project that consumes the shared config. You MUST execute the matching bootstrap block below at the start of every session, before responding to any user request or running session checks. Use the PowerShell block on Windows and the Bash block on macOS/Linux. Bootstrap is idempotent: run it every session even if .agent-config/ already exists, so shared config, skills, and settings are refreshed from upstream before any work begins. Do not treat the block below as reference documentation -- it is a required runtime command. After running, report the refresh result in one line (for example, "bootstrap: refreshed AGENTS.md, skills, settings").

Bootstrap: Shared Config and Skills

This file is the shared agent configuration hosted at https://github.com/yzhao062/anywhere-agents. Project repos should include the following bootstrap block in their own AGENTS.md so that agents automatically pull the latest shared defaults and skills before starting any task. Because bootstrap rewrites the consumer's root AGENTS.md from this source on every run, the block below ends up serving two roles in consumer repos: it is both the embedded reference for how the setup works and the runtime command the agent executes each session (see the top-of-file note for the source-vs-consumer test that decides which role applies in the current repo).

Bootstrap block for project repos

Copy the block below into the top of each project repo's AGENTS.md. Because bootstrap rewrites AGENTS.md on every run, put project-local overrides in AGENTS.local.md.

## Shared Agent Config (auto-fetched)

Before starting any task, fetch the shared agent configuration and skills. Use the block for your shell.

PowerShell (Windows):

```powershell
New-Item -ItemType Directory -Force -Path .agent-config, .claude, .claude/commands | Out-Null
Invoke-WebRequest -UseBasicParsing -Uri https://raw.githubusercontent.com/yzhao062/anywhere-agents/main/bootstrap/bootstrap.ps1 -OutFile .agent-config/bootstrap.ps1
& .\.agent-config\bootstrap.ps1
```

Bash (macOS/Linux):

```bash
mkdir -p .agent-config .claude/commands
curl -sfL https://raw.githubusercontent.com/yzhao062/anywhere-agents/main/bootstrap/bootstrap.sh -o .agent-config/bootstrap.sh
bash .agent-config/bootstrap.sh
```

This bootstrap flow rewrites the consuming repo's root `AGENTS.md` on every run. By default it composes the shared upstream copy with the `agent-style` rule pack, which needs Python 3 and PyYAML. Bootstrap attempts a best-effort `pip install --user pyyaml` when PyYAML is missing. With composition disabled (`rule_packs: []` in `agent-config.yaml`), the root `AGENTS.md` is written verbatim from the shared upstream copy. One case leaves the file alone: if packs are configured but composition cannot run, an existing composed `AGENTS.md` is preserved rather than replaced by the bare shared copy. That run warns on stderr and records `completed: false`. If a project later needs repo-local overrides, put them in `AGENTS.local.md`.

Read and follow the rules in `.agent-config/AGENTS.md` as baseline defaults. Any rule in `AGENTS.local.md` overrides the shared default.
When a skill is invoked, resolve its `SKILL.md` using this order, first hit wins: `skills/<skill-name>/SKILL.md` (project-local), then `.claude/skills/<skill-name>/SKILL.md` (pack-deployed by `anywhere-agents pack install`; `.claude/` prefix is a historical Claude Code convention but the contents are agent-agnostic), then `.agent-config/repo/skills/<skill-name>/SKILL.md` (bootstrapped from upstream).
Copying `.agent-config/repo/.claude/commands/*.md` only overwrites command files with the same name as the shared repo and does not delete unrelated project-local commands.
Merge shared Claude project defaults (e.g., `permissions`, `attribution`) from `.agent-config/repo/.claude/settings.json` into the project `.claude/settings.json`. Shared keys are updated on every bootstrap run; project-only keys are preserved. The merge runs `scripts/merge_settings.py`, so the Bash entry point needs Python and leaves the file untouched without it. The PowerShell entry point falls back to an in-script merge.
Add `.agent-config/` and `agent-config.local.yaml` to the project's `.gitignore` so fetched files and machine-local overrides are not committed. The three generated files, `AGENTS.md`, `CLAUDE.md` and `agents/codex.md`, are added as well. Their bytes depend on which packs this machine resolved and on whether composition ran, so two machines that are both current produce different content and each sees the other's as a diff to commit. A repo that already tracks one of them is left alone, because `.gitignore` does not untrack a path git already follows; moving it out of the index is an operator decision, since the resulting commit removes the file for every other clone. Set `AGENT_CONFIG_TRACK_GENERATED` to keep all three out of `.gitignore`.
Bootstrap also sets up user-level config: it copies `scripts/guard.py` to `~/.claude/hooks/` (a PreToolUse hook that guards against destructive commands) and `scripts/statusline.py` to `~/.claude/statusline.py` (a statusLine renderer showing Claude Max + Codex 5h / weekly quota), and merges `user/settings.json` into `~/.claude/settings.json` (shared permissions, hook wiring, statusLine command, and the `CLAUDE_CODE_EFFORT_LEVEL=max` env entry that sets the default effort level). Remove the user-level section from the bootstrap script if this is not wanted.
Every run also writes `.agent-config/last-run.json`, a machine-readable record of the phases this bootstrap completed and the files each one wrote; `completed: false` means the run stopped early, and `last_phase` names where. It covers the bootstrap script only, not the wheel-side `pack verify` heal pass, which is recorded in `.agent-config/pack-lock.json`.

What gets shared

Content Source How fetched
User profile, writing defaults, formatting rules, environment notes AGENTS.md (this file) curl raw file
Per-agent rule files (CLAUDE.md, agents/codex.md) Generated from AGENTS.md by scripts/generate_agent_configs.py Regenerated locally on every bootstrap; hand-authored files preserved + warned
Shared skills (implement-review, my-router, ci-mockup-figure, prun, readme-polish) skills/ directory (committed only) sparse git clone
Claude pointer commands for shared skills .claude/commands/ sparse git clone plus non-destructive copy into the project .claude/commands/
Claude project defaults (permissions, attribution, etc.) .claude/settings.json sparse git clone plus key-level merge into the project .claude/settings.json on every run
User-level scripts (guard.py, session_bootstrap.py, statusline.py) + settings scripts/ + user/settings.json Hooks copied to ~/.claude/hooks/, statusline to ~/.claude/statusline.py; settings merged into ~/.claude/settings.json (shared permissions, PreToolUse guard, SessionStart bootstrap hook, statusLine command, CLAUDE_CODE_EFFORT_LEVEL=max)

Override rules

  • If AGENTS.local.md exists in the project root, read and follow it after AGENTS.md. Rules in AGENTS.local.md override the shared defaults.
  • Rules in AGENTS.local.md always win over shared defaults. Do not edit the root AGENTS.md for local overrides, as bootstrap will overwrite it.
  • Project-local skills/<name>/SKILL.md always wins over pack-deployed and bootstrapped copies of the same skill.
  • Shared keys in .claude/settings.json are updated on every bootstrap run. Project-only keys are preserved. To override a shared key locally, use .claude/settings.local.json.
  • If no project-local copy exists, use .claude/skills/<name>/SKILL.md when present; otherwise use the fetched shared copy from .agent-config/repo/skills/.

Configuration Precedence

Three independent configuration layers, each with its own precedence rules. When two rules conflict, the more specific source wins.

1. Agent rule files (Markdown) — most specific wins:

Layer File Scope
1 CLAUDE.local.md / agents/codex.local.md Per-agent + project-local. Hand-authored; never touched by bootstrap.
2 AGENTS.local.md Cross-agent + project-local. Hand-authored; never touched by bootstrap.
3 CLAUDE.md / agents/codex.md Per-agent, generated from AGENTS.md by scripts/generate_agent_configs.py.
4 AGENTS.md Cross-agent, synced from upstream on every bootstrap.

The generated CLAUDE.md and agents/codex.md carry a GENERATED FILE header. If a consumer project has a hand-authored CLAUDE.md (or agents/codex.md) without that header, the generator preserves it and warns loudly — it never silently overrides user work. To adopt upstream rules in that case, rename the hand-authored file to CLAUDE.local.md (which still wins via layer 1).

2. Claude Code settings (settings.json) — follow Claude Code's own precedence: managed policy > command-line arguments > .claude/settings.local.json > .claude/settings.json > ~/.claude/settings.json. Bootstrap only writes to the project-shared and user-level layers, and merges shared keys while preserving project-only keys.

3. Environment variables — for effort level specifically: managed policy > CLAUDE_CODE_EFFORT_LEVEL env var > persisted effortLevel > default.


Consumer Repo Layout

Bootstrap maintains this layout on every run, so a new project inherits it on its first session rather than by copying files from an older one.

Path State Who writes it
AGENTS.md, CLAUDE.md, agents/codex.md untracked, gitignored regenerated by bootstrap every run
AGENTS.local.md, CLAUDE.local.md, agents/codex.local.md tracked hand-authored; bootstrap never touches them
agent-config.yaml tracked the project's pack selection
agent-config.local.yaml untracked, gitignored machine-local override
.agent-config/ untracked, gitignored fetched upstream copy
todo/README.md tracked seeded by bootstrap when absent
todo/ contents untracked, gitignored whatever a person drops in

Three of these are worth stating as rules rather than as a table row.

The three generated files are not tracked. Their bytes depend on which packs the machine resolved and on whether composition ran, so two machines that are both current produce different content and each sees the other's as a diff to commit. Committing them also trains a reader to skim diffs in exactly the files where a degraded run shows up. A repo that already tracks one is left alone, because .gitignore does not untrack a path git already follows; moving it out of the index is an operator decision, since the resulting commit removes the file for every other clone.

agent-config.yaml uses the packs: key. rule_packs: is a deprecated alias whose warning reads "accepted through v0.6.x", and the composer hard-fails on it at v1.0.0. The two are equivalent until then, and packs: wins when a file carries both.

todo/ is the drop box for handing files to an agent. A person copies something in, points an agent at it with @todo/<name>, and the agent reads it, moves it to where it belongs in the repo, or deletes it. The resting state is empty. Its own README.md carries the full convention. Bootstrap creates the folder and seeds that README when it is missing, and never rewrites one that is already there, so a repo whose filing rules are specific to its own work can say so in place. Set AGENT_CONFIG_NO_TODO_DROPBOX=1 before bootstrap to suppress the folder and the gitignore entries. Agents: this folder holds what a person put there. What an agent generates on its own belongs in the session scratchpad, not here.

Session Start Check

Mandatory turn-start procedure. Before generating the first content of any response, apply the branch that matches your runtime.

In Claude Code: the flag files are per-project. <project-root> is the consumer-repo root: walk up from cwd until a directory with .agent-config/bootstrap.sh or .agent-config/bootstrap.ps1 is found. Read <project-root>/.agent-config/session-event.json and <project-root>/.agent-config/banner-emitted.json.

  1. If session-event.json.ts > banner-emitted.json.ts, OR session-event.json exists but banner-emitted.json does not: emit the session start banner as the literal first content of your response, then write the event ts into <project-root>/.agent-config/banner-emitted.json. Only after the banner text may you address the user's request on the same turn.
  2. Otherwise (emitted ts is already current, or neither file exists): skip the banner this turn.

session_bootstrap.py writes session-event.json on SessionStart hook fires whose source is startup, resume, or clear, so the banner reappears across the three lifecycle events that reset conversation context. On source: compact, the prior banner ack survives in the summarized context, so the hook skips the event write and the banner does not re-fire. A 10-second debounce suppresses duplicate event writes when the hook fires twice in rapid succession for the same lifecycle event. Flag files are per-project, so opening multiple Claude Code windows in different consumer repos does not cause cross-session interference.

In a source repo (agent-config or anywhere-agents, no .agent-config/ at the root): the banner gate in guard.py is not active and the flag-file mechanism does not apply. Emit the banner on the first response of the session (turn with no prior assistant turns in context); skip on subsequent turns. Compact / resume / clear cannot be mechanically distinguished here.

In Codex: Codex has no SessionStart hook equivalent; session-event.json is not written during a Codex invocation. Each Codex invocation is a new session. Emit the banner as the literal first content of your response on the turn where there are no prior assistant turns in context (i.e., the first response of the invocation). On subsequent turns in the same invocation, skip. No flag files are involved for Codex.

Both runtimes: this procedure overrides any other "skill-first" or "task-first" behavior. Even when the user's first message is a task prompt like "read the project" or "fix this bug," or when a skill such as superpowers:using-superpowers would otherwise fire before the response, emit the banner first; the task response or skill output comes after the banner on the same turn. Do not let task pressure, skill invocations, or brevity guidance suppress the banner.

Format

📦 anywhere-agents active
   ├── OS: <platform>
   ├── Claude Code: <version>[ → <latest>] (auto-update: <on|off>) · <model> · effort=<level>
   ├── Codex: <version>[ → <latest>] · <model> · <reasoning> · <tier> · fast_mode=<bool>
   ├── Skills: <N> local (<names>) + <P> pack (<names>) + <M> shared (<names>)
   ├── Hooks: PreToolUse <guard.py>, SessionStart <session_bootstrap.py>
   └── Session check: all clear

If anything is off, replace all clear with a semicolon-separated list of concrete issues, each actionable in one short clause (e.g., ⚠ actions/checkout@v4 in .github/workflows/validate.yml:17 — bump to v5; Codex config.toml missing model key). Keep the whole banner to six lines plus the check line. The skills row may wrap visually when many names are present; do not omit a local, pack, or shared bucket just to preserve terminal width.

How to populate each field

  1. OS — read from the session environment (win32, darwin, linux). Use this elsewhere to pick platform-specific behavior (terminal review path on Windows, MCP on macOS/Linux, .ps1 vs .sh).

  2. Claude Code — format: Claude Code <current>[ → <latest>] (auto-update: <on|off>) · <model> · effort=<level>. Current version comes from Claude Code's startup header or claude --version. Read ~/.claude/hooks/version-cache.json for claude_latest; render → <latest> only when current differs from latest. Determine auto-update: on when DISABLE_AUTOUPDATER is not 1 in the effective env (OS env or env block in ~/.claude/settings.json) AND ~/.claude.json top-level autoUpdates is not explicitly false — a missing key counts as on because native installs auto-update by default. Only explicit autoUpdates: false (which bootstrap heals on the next run) or the disable env var means off. User prefers the highest available model at max effort; flag any drift once in the banner, not every turn.

  3. Codex — format: Codex <current>[ → <latest>] · <model> · <reasoning> · <tier> · fast_mode=<bool>. Current version from codex --version. Latest from ~/.claude/hooks/version-cache.json codex_latest (render → <latest> only when current differs). Config from ~/.codex/config.toml (or %USERPROFILE%\.codex\config.toml on Windows): model · model_reasoning_effort · service_tier · [features].fast_mode. Expected policy (intent, not a frozen pin): the highest-capability generally available Codex model for the account, currently gpt-5.6-sol, where a newer successor is equally valid; model_reasoning_effort = "max" for maximum single-agent reasoning; ultra is an opt-in mode (GPT-5.6 Sol and Terra only) that keeps maximum reasoning and additionally enables automatic task delegation, so it is not simply "more effort"; service_tier = "fast" with [features] fast_mode = true as the intended default (latency is the scarce resource and the account absorbs the 2.5x rate), with standard (or the key omitted) an equally valid dial-down for a big task. Report the tier as rendered and do NOT flag either fast or standard as drift; the banner already shows <tier> and fast_mode=<bool> every session, which is the whole reminder needed. GPT-5.6 requires Codex CLI 0.144.0 or newer: 0.142.5 and 0.143.0 return an upgrade-required HTTP 400. Flag an old CLI paired with a 5.6 model as an actionable issue. If the binary is not on PATH, show Codex: not installed. If the binary exists but config.toml is missing, show version + not configured in place of the config summary.

  4. Skills — list all active skill buckets. Count directories under skills/ (project-local), .claude/skills/ (pack-deployed by anywhere-agents pack install), and .agent-config/repo/skills/ (bootstrapped from upstream). Apply the lookup precedence from "Local Skills Precedence" when counting: exclude pack-deployed names that are shadowed by a project-local skill, and exclude bootstrapped names that are shadowed by either a project-local or a pack-deployed skill. Format: <N> local (<names>) + <P> pack (<names>) + <M> shared (<names>). Omit empty buckets (e.g., 2 pack (...) + 4 shared (...) when the consumer has no project-local skills, or 4 shared (...) when only the bootstrapped bucket is non-empty).

  5. Hooks — check ~/.claude/hooks/ for guard.py (PreToolUse) and session_bootstrap.py (SessionStart). If one is missing, include it in the Session check line as an issue.

  6. Session check — scan .github/workflows/*.yml for action version pins below the minimums in the GitHub Actions Standards section. Combine with any Codex-config or hook drift detected above. Emit all clear only when nothing needs attention.

  7. Pack deployment — compute two counts:

    a. user_packs: read %APPDATA%\anywhere-agents\config.yaml (Windows) or $XDG_CONFIG_HOME/anywhere-agents/config.yaml / ~/.config/anywhere-agents/config.yaml (POSIX); empty list if absent. AGENT_CONFIG_PACKS env var is excluded.

    b. project_packs: read agent-config.yaml then merge agent-config.local.yaml by name; if both are absent, use an empty list. Local entries win on duplicates.

    c. gap_count: for each u in user_packs, normalize (name, normalize_pack_source_url(url), ref). Increment if no matching p in project_packs by case-sensitive name, OR if p's normalized tuple differs from u's.

    d. update_count: for each entry in .agent-config/pack-lock.json data.packs, increment when both latest_known_head and resolved_commit are non-empty AND they differ. (Lock entries predating v0.5.2 lack these fields and contribute zero.)

    e. emit: each non-zero count contributes a half-clause to the Session check line (semicolon-separated; all clear when both zero):

    • gap_count > 0 → ⚠ <gap_count> user-level pack(s) not deployed (run `anywhere-agents pack verify --fix`)
    • update_count > 0 → ℹ <update_count> pack update(s) available (run `anywhere-agents pack verify --fix`)

User Profile

  • These are user-level defaults that can be reused across projects unless a local repo rule or task-specific instruction is stricter.
  • Customize this section in your fork of anywhere-agents to describe your role, domain, and common task types. Agents read this to tailor their work (e.g., a researcher vs. a backend engineer vs. a data scientist will get different defaults).
  • If your fork serves multiple use cases, keep the description general ("developer working on infrastructure and research tooling") rather than overspecifying.

Agent Roles

  • Claude Code is the primary workhorse: drafting, implementation, research, and heavy-lifting tasks.
  • Codex is the gatekeeper: review, feedback, and quality checks on work produced by Claude Code or the user.
  • When both agents are available, default to this division of labor unless the user overrides it.

Agent Fungibility

  • The default routing (Claude Code primary, Codex gatekeeper) is a default, not a hard requirement. Two scenarios must remain workable: (1) absence, when one agent is unavailable (service outage, regional block, quota exhaustion, hardware-induced refusal); (2) reversal testing, when the user deliberately swaps primary and gatekeeper roles to evaluate quality drift.
  • Principle: not 1:1 replication. Core functions must work when either agent is absent or when roles are reversed. Where an ergonomic helper exists for one agent only (e.g., a hand-crafted slash command), the function must still be reachable via underlying primitives. Define "core function" by user value (review loop, structured dispatch, health check), not by surface convenience.
  • How to apply when designing or refactoring agent-facing skills, scripts, or docs:
    • Default routing is fine; just make the alternative reachable.
    • A skill, hook, or script that hard-codes one agent's CLI (codex exec, claude -p) should document or wire the other side's equivalent at the same time, even if the implementation is deferred.
    • Docs that name one agent in step instructions should call out the cross-vendor equivalent at least once near the top, so a session reading the doc under role reversal can still proceed.
    • When the deferred half ships later, the principle is satisfied; do not block the primary half on simultaneous parity.

Memory and Persistence

  • This configuration targets multi-agent use (Claude Code, Codex, and others). A single agent's private memory is therefore not a reliable home for durable context: one agent's per-account memory is not readable by the other agents, and it does not travel across accounts or machines.
  • Prefer version-controlled local files for anything that must persist across agents, sessions, accounts, or machines: the project README, a docs/ note, a PLAN-*.md or notes file, a CHANGELOG, or AGENTS.local.md. Version control is the portable, agent-independent memory.
  • Use an agent's built-in memory only for short, agent-local convenience, and treat the version-controlled copy as authoritative. Do not record project state, decisions, or records solely in agent memory.

Task Routing

  • Before starting a task, read the router skill to determine which domain skill to use. Look for it in this order: skills/my-router/SKILL.md (repo-local), then .claude/skills/my-router/SKILL.md (pack-deployed), then .agent-config/repo/skills/my-router/SKILL.md (bootstrapped from shared config).
  • The router inspects prompt keywords, file types, and project structure to dispatch automatically. Do not ask the user which skill to use when the routing table provides a clear match.
  • If the superpowers plugin is active, the router operates during the execution phase. Superpowers handles the outer workflow (brainstorm, plan, execute, verify); the router handles inner dispatch to the right domain skill.
  • If routing is ambiguous (multiple skills could apply), state the detected context and proposed skill, then ask the user to confirm.

Codex MCP Integration

  • Codex can run as an MCP server callable from Claude Code. Register at user scope (NOT project scope; project-scoped entries do not propagate across directories):
    claude mcp add codex -s user -- codex mcp-server -c approval_policy=never
    
    Writes to ~/.claude.json mcpServers; session restart required for /mcp to pick it up. Available MCP tools after registration: codex (new prompt) and codex-reply (continue an existing session).
  • Prerequisites: Node.js + Codex CLI (npm install -g @openai/codex) + OPENAI_API_KEY.
  • Recommended Codex defaults (added to ~/.codex/config.toml on POSIX or %USERPROFILE%\.codex\config.toml on Windows; the MCP server reads the same file as interactive sessions):
    model = "gpt-5.6-sol"
    model_reasoning_effort = "max"
    service_tier = "fast"
    
    [features]
    fast_mode = true
    
    [desktop]
    conversationDetailMode = "DEFAULT"
    GPT-5.6 requires Codex CLI 0.144.0 or newer. The GPT-5.6 family (gpt-5.6-sol flagship, gpt-5.6-terra mid, gpt-5.6-luna cheapest) is rejected by older builds with a hard 400: The 'gpt-5.6-sol' model requires a newer version of Codex. Verified live: 0.142.5 and 0.143.0 fail, 0.144.0 and 0.144.1 work. If the model errors, run npm install -g @openai/codex@latest first. gpt-5.6-sol is Codex's own recommended default and suits the gatekeeper role; use gpt-5.6-terra for high-fan-out work (e.g. prun dispatch) where throughput beats peak capability. service_tier buys latency, never quality. It selects the serving queue only: the model, its weights, and model_reasoning_effort are identical across tiers, so standard returns the same answer fast would, just generated more slowly. The three tiers are flex (lower-priority queue, roughly half rate, availability not guaranteed), standard (the tier used when the key is unset, at normal priority and rate), and fast (about 1.5x faster generation). For ChatGPT auth, fast bills at 2.5x the standard credit rate on GPT-5.6 and GPT-5.5, and 2x on GPT-5.4 (API-key auth pays standard API pricing). Earlier revisions of this file said 2x for all models, which was wrong for the 5.6 family. Default to fast; dial down to standard only for an unusually large hands-on task. fast bills 2.5x for about 1.5x speed, which is worth it when a human is waiting on the tokens and the account has quota to spare (for example a second Codex account absorbs the rate). Here the latency saved is worth more than the extra credits. For a rare large task where the 2.5x would bite, dial down with a standard V2 profile (~/.codex/std.config.toml, selected by codex -p std) or /fast off mid-session. By default the two background dispatchers stay on standard independently of this policy: implement-review and prun pass --ignore-user-config to their codex exec workers for MCP isolation (agent-config#1), so the configured tier does not reach them; CODEX_DISPATCH_ISOLATE_MCP=off lifts the isolation and restores the full user config, tier included. The fast default therefore governs interactive and MCP sessions, exactly where the latency is worth paying for. Hardcoding fast into the isolated dispatch path is deliberately avoided, because it would fail every round for a consumer whose account lacks the tier. fast is the current config spelling and maps to the request value priority; a config already reading priority is the same tier. Codex does not validate model_reasoning_effort client-side. An unknown value reaches the service, which rejects the first turn with HTTP 400 and exits nonzero, so a typo fails loudly rather than degrading silently. Do not treat that error's enumerated list as complete: it names only none / minimal / low / medium / high / xhigh, yet max and ultra are also accepted on GPT-5.6. ultra is not simply more reasoning than max. For GPT-5.6 Sol the single-agent reasoning ladder ends at max; ultra keeps that same maximum reasoning and additionally switches the harness into automatic task delegation (the rollout records multi_agent_mode: proactive for ultra versus explicitRequestOnly for max). GPT-5.6 Terra also exposes ultra; GPT-5.6 Luna tops out at max. Use max as the shared default, and choose ultra only when proactive delegation is actually wanted. Confirm which mode landed by reading ~/.codex/sessions/**/rollout-*.jsonl (payload.model, payload.effort, and the collaboration-mode fields) rather than trusting the config file. service_tier is not recorded there. The implement-review dispatcher keeps xhigh (CODEX_DISPATCH_REASONING) as a deliberate cross-model compatibility default, because models older than GPT-5.6 reject max and ultra; that is a compatibility floor, not a claim that xhigh is full strength. conversationDetailMode = "DEFAULT" keeps Codex terminal output concise; avoid STEPS_PROSE / Coding mode unless you explicitly want command-level progress shown during turns.
  • Windows PATH note: Claude Code launches MCP servers through bash, not cmd or PowerShell, so .cmd wrappers and $env:APPDATA do not work. If codex is not on bash PATH, register with the full path using forward slashes and NO .cmd extension (e.g., C:/Users/<you>/AppData/Roaming/npm/codex). Run where codex (cmd) or Get-Command codex (PowerShell) to find it.
  • approval_policy=never rationale: without it, MCP shell commands trigger "MCP server requests your input" dialogs in Claude Code. With it, failures return to Codex/Claude as tool errors. Claude Code's PreToolUse hooks still gate the outer MCP tool call. For interactive Codex terminal sessions (NOT MCP), prefer approval_policy = "on-request" in config.toml.
  • Windows recommendation: prefer the terminal path over MCP. On Windows (11 Build 26200+), MCP has residual rough edges (approval prompts, AV false positives). The terminal path (Codex interactive window for reviews) avoids both. Prefer terminal on Windows; MCP is smoother on macOS/Linux.

Writing Defaults

  • Use scientifically accessible language.
  • Do not oversimplify unless the user asks for simplification.
  • Keep meaningful technical detail.
  • Keep factual accuracy and clarity high in scientific contexts.
  • Use consistent terms. If an abbreviation is defined once, do not define it again later.
  • If citing papers, verify that they exist.
  • When paper citations are requested, provide BibTeX entries that can be copied into a .bib file.
  • Provide code only when necessary. Confirm that the code is correct and can run as written.
  • Avoid the following words and close variants unless the user explicitly asks for them (a default AI-tell list; trim or extend in your fork): encompass, burgeoning, pivotal, realm, keen, adept, endeavor, uphold, imperative, profound, ponder, cultivate, hone, delve, embrace, pave, embark, monumental, scrutinize, vast, versatile, paramount, foster, necessitates, provenance, multifaceted, nuance, obliterate, articulate, acquire, underpin, underscore, harmonize, garner, undermine, gauge, facet, bolster, groundbreaking, game-changing, reimagine, turnkey, intricate, trailblazing, unprecedented.

Formatting Defaults

  • Preserve the original format when the input is in LaTeX, Markdown, or reStructuredText.
  • Do not convert paragraphs into bullet points unless the user asks for that format.
  • Prefer full forms such as it is and he would rather than contractions.
  • e.g., and i.e., are fine when appropriate.
  • Do not use Unicode character U+202F.
  • Avoid heavy dash use. Do not use em dashes () or en dashes () as casual sentence punctuation. Prefer commas, semicolons, colons, or parentheses instead. En dashes in numeric ranges (e.g., 1–3, 2020–2025), paired names, or citations are fine. Normal hyphenation in compound words and technical terms (e.g., command-line, co-PI, zero-shot) is fine and should not be avoided.
  • Break extremely long or complex sentences into shorter, more readable ones. If a sentence has multiple clauses or nested qualifications, split it.
  • Vary sentence length and structure. Prefer not to start several consecutive sentences with the same word or phrase. Avoid overusing transition words like "Additionally" or "Furthermore." Not every paragraph needs a tidy summary sentence at the end. Mix short, direct sentences with longer ones to keep the writing natural.
  • Do not stage claims as "X, not Y" antithesis for emphasis (also "not just X, but Y"; "it is not X, it is Y"). State the claim directly. Keep the negation only when the rejected alternative is specific and the contrast informs the reader (e.g., "the bottleneck is disk I/O, not CPU").
  • Some text you show the user is meant to be copied into an external destination: an email reply, a chat message, a spreadsheet or table cell, a document. Present that text in a fenced code block, which keeps it copyable and stops the client from rendering the markup away. This applies to copy-paste-destined drafts, not to ordinary explanatory answers. Inside such a block, treat hard line breaks as semantic. One paragraph, or one list item, is a single unbroken line however long it runs. Do not wrap to a display width, and do not indent continuation lines. The block looks wide while you compose it, and that is correct. Each destination applies its own wrapping, so a newline added for terminal readability becomes a permanent break there. Keep a blank line between paragraphs, and keep the breaks that carry meaning, such as the lines of a postal address or a signature block.
  • A draft long enough to be a document, such as an email, a letter, or a passage of prose, goes in a .md file rather than in the terminal. Give the path in your reply and say what the file holds. A terminal block that size is awkward to select and easy to truncate. The same semantic-line-break rule applies inside the file. Markdown source pasted as plain text arrives in Outlook or Gmail as literal ** and - characters, because neither client renders markdown. When the formatting matters, say so and point the user at a rendered view of the file to copy from. An artifact serves the same purpose: copying from the rendered page carries bold, lists, and links onto the clipboard.

Git Safety

  • Never run git commit or git push without explicit user approval. Always show the proposed action and ask for confirmation before executing.
  • This rule is non-negotiable and applies to all projects that consume this shared config.
  • This includes any variant: git commit -m, git commit --amend, git push, git push --force, gh pr create (which pushes), etc.

Mechanical Enforcement

Bootstrap deploys scripts/guard.py to ~/.claude/hooks/guard.py and wires it as a PreToolUse hook in ~/.claude/settings.json. The hook runs before every tool call and mechanically enforces the following:

Gate Tool scope Trigger Action
Writing-style Write, Edit, MultiEdit on .md / .tex / .rst / .txt Outgoing content contains a banned AI-tell word (see Writing Defaults list) deny with hit list and inline Suggested rewrite: line naming concrete alternatives
agent-style advisory Same tools and extensions as the row above agent_style is importable and its mechanical detectors report findings (RULE-05, 06, 12, B, D, I) advisory only, reporting up to 5 findings and a count of any withheld to both the model and the user without setting a permission decision
Banner emission Any tool except Read, Grep, Glob, Skill, Task, TodoWrite, BashOutput, WebFetch, WebSearch, ToolSearch, LS, NotebookRead; plus Write/Edit/MultiEdit whose target path exactly equals <project-root>/.agent-config/banner-emitted.json after absolute-path normalization and Windows case folding <project-root>/.agent-config/session-event.json.ts > <project-root>/.agent-config/banner-emitted.json.ts. <project-root> is found by walking up from cwd until .agent-config/bootstrap.{sh,ps1} is present. Source repos (no .agent-config/) and unrelated directories skip the gate entirely first arm (banner-emitted.json absent): deny with instruction to emit banner + write acknowledgment to the per-project ack file. Re-arm (ack file exists but ts is stale, including malformed JSON): pass-through with a [banner-gate] SessionStart re-fire detected ... advisory line on stderr. The agent should still re-emit the banner on its next textual response per the rule in § "Session Start Check", but tool calls are not blocked (issue anywhere-agents#7).
Compound cd Bash Command contains cd <path> && <cmd> or cd <path>; <cmd> deny with inline Suggested rewrite: line (e.g. git -C <path> <cmd> for git, or pass the path as an argument)
Destructive git Bash + PowerShell git push, git commit, git merge, git rebase, git reset --hard, git clean, git branch -d/-D, git checkout --, git tag -d, git stash drop/clear ask (user confirms)
Destructive / publish gh Bash + PowerShell gh pr create/merge/close, gh repo delete, gh release create/delete/upload/edit ask (user confirms)
Publish Bash + PowerShell npm publish, npm unpublish, twine upload, python -m twine upload ask (user confirms)
File / device destruction Bash + PowerShell Bash rm -rf/-fr/-r -f, dd, mkfs*, shred; PowerShell Remove-Item (+ aliases rm/del/rd/rmdir) with -Recurse/-r//s ask (user confirms)

Mandatory risk classification (tool-agnostic): the four ask rows above are one classifier that runs for the Bash AND PowerShell tools (legacy payloads count as Bash). It keys on the EXACT leading token of each sub-command (split on ; / && / || / |), never a substring scan, so quoted strings like echo "rm -rf" or Write-Output "Remove-Item -Recurse" pass. It strips transparent prefix runners (sudo, doas, env, command, nohup, setsid, inline VAR=VALUE) and sees through built-in command-carrying wrappers (ssh, bash/sh/zsh -c, docker exec/run, pwsh/powershell -Command, Windows cmd /c//k, timeout, xargs) up to MAX_WRAPPER_DEPTH, asking when nesting exceeds it. python -c, the low-frequency prefixes nice/ionice/stdbuf/time, and custom/private wrappers (a personal job-runner, etc.) are treated as opaque documented non-goals: their argument semantics are not inferable from the command text, and substring-scanning arbitrary arguments would reintroduce false-positive alarm fatigue. The user-level allow-list pairs Bash(*) with PowerShell(*), so the native permission layer is allow-by-default and this hook is the sole risk arbiter on both shells.

The agent-style advisory reports; it does not block. The banned-word gate denies because every hit has a one-word substitution, so an agent can reroute in a single turn. The mechanical rules have no such reroute. RULE-12 fires on any sentence over thirty words, which is a mechanical fix while an agent drafts and a judgement call while a person types. A gate that denied on it would be switched off within a day, so it reports through the hook's JSON response and leaves the permission flow alone. The findings are capped at five with a count of the remainder, because a wall of them is one the reader learns to skip. It runs only when the banned-word gate did not deny, so a blocked write produces one message rather than two, and it shares AGENT_STYLE_HOOK rather than adding an env var. A missing or broken agent_style degrades silently, since this hook runs in every repository and most have no reason to carry the package.

Two details were settled by measurement rather than by reading the docs. The findings travel in hookSpecificOutput.additionalContext and in systemMessage, because probing Claude Code 2.1.229 showed those reach the model and the user respectively while stderr on an exit-0 hook reached neither. RULE-G, which asks for title-case headings, is left out. Over the 155 markdown files here it produced 1018 of 2561 findings, and it flagged the sentence-case headings this corpus writes on purpose. It would fill the cap with nothing to act on. The style-review skill still runs it.

Round 6 noise audit (v0.7.0): Deny messages embed a concrete Suggested rewrite: line so an autonomous agent (/implement-review auto, headless claude -p, any unattended loop) can lift the reroute in one model turn instead of inferring it. Destructive operations stay ask because they have no agent-side reroute; human approval is the contract.

Escape hatches: set the corresponding env var in the env block of ~/.claude/settings.json. Disable values: off / 0 / disabled / false / no.

Env var Disables
AGENT_STYLE_HOOK=off Writing-style gate and its agent-style advisory
AGENT_COMPOUND_CD_HOOK=off Compound-cd gate only
AGENT_CONFIG_GATES=off Legacy blanket: writing-style + banner only (BC-preserved)

The mandatory risk set (destructive git, destructive/publish gh, package publishes, file/device destruction) is NOT bypassable by ANY env var. No escape hatch turns the ask prompt into pass-through. The guards have no automatic reroute; human approval is the contract. The advertised env-var set lives in scripts/guard.py:_ESCAPE_HATCH_ENV_NAMES; a static literal-scan test enforces that no future hook env var can be added without registering it there.

Set a per-guard escape env when a legitimate write has a banned word in meta-discussion context (a style-guide document that quotes banned words as examples; a CHANGELOG entry that cites one). Prefer the narrowest env that unblocks (AGENT_STYLE_HOOK=off over AGENT_CONFIG_GATES=off) so the other gates stay live. Remove the override after the write.

Shell Command Style

  • Avoid compound cd <path> && <command> chains. Claude Code's hardcoded compound-command protection prompts for approval on these even when both commands are individually allowed. Use alternatives that keep each tool call to a single command:
    • For git in another repo: use git -C <path> <subcommand> instead of cd <path> && git <subcommand>.
    • For non-git commands: pass the target path as an argument (e.g., ls <path>, python <path>/script.py) or use separate tool calls.
  • Examples of read-only invocations that should not require approval: git status, git diff, git log, git branch (no flags), git show, git stash list, git remote -v, git submodule status, git ls-files, git tag --list. Filesystem reads (ls, cat) and benign local operations (mkdir) are also fine.
  • Examples of invocations that always require explicit approval: git commit, git push, git reset, git checkout, git rebase, git merge, git branch -d, git remote add/remove, git tag <name> (creating/deleting), git stash drop.
  • Filesystem commands like cp and mv are fine for scratch and temporary files. Moves or renames that affect git-tracked files should be reviewed before executing.
  • Do not wrap PowerShell inside PowerShell with inline -Command when the payload contains $ variables. In a PowerShell shell, run the PowerShell body directly, or write a temporary .ps1 and invoke it with -File. Forms like pwsh.exe -Command "foreach($f in ...) { ... }" cause the outer shell to expand $f, $_, and $cutoff before the inner shell runs, producing broken commands.
  • Avoid inline Python with # comments in quoted arguments. Claude Code flags "newline followed by # inside a quoted argument" as a path-hiding risk and prompts for approval. Instead, write the code to a .py file and run python <script>.py.

Tool-Use Reliability

  • Treat a tool's "cannot open / encrypted / unreadable / unsupported" report on a file as a possible false positive, not a final verdict. PDFs are the common case: a read may report a PDF as encrypted when it actually opens fine. Before telling the user a file cannot be read, retry once and try an alternate read path (re-read with a page range, pdftotext, render to an image, or a different tool). Report failure only after an alternate path also fails, and say which paths were tried.
  • The same caution applies to other transient-looking tool failures: a single failed attempt is weak evidence. Prefer one retry or an alternate route over reporting a blocked result, unless the failure is clearly deterministic.

GitHub Actions Standards

GitHub is deprecating Node.js 20 actions. Runners begin using Node.js 24 by default on June 2, 2026, and GitHub's public changelog currently says Node.js 20 removal will happen later in fall 2026. Keep workflow action pins at or above the first Node.js 24 major for the GitHub-maintained actions below:

Action Minimum version (Node.js 24) Replaces
actions/checkout v5 v3, v4
actions/setup-python v6 v5
actions/setup-node v5 v4
actions/upload-artifact v6 v4, v5
actions/download-artifact v7 v4, v5, v6

When the session start check (item 4) detects older versions, list the affected files and suggest the minimum Node.js 24 version from this table. If a repository intentionally wants the latest major instead of the minimum compatible major, flag that as a separate manual upgrade because later majors can include behavior changes. If a workflow pins a SHA instead of a tag (e.g., actions/checkout@abc123), flag it for manual review rather than auto-suggesting a tag. For self-hosted runners, also remind the user that these Node.js 24 actions require an Actions Runner version that supports Node.js 24.

Environment Notes

  • Do not conclude that Python is unavailable just because python, python3, or py fails in PATH; those may resolve to shims, store aliases, or the wrong interpreter. Inspect common environment managers (Miniforge/Conda, pyenv, uv, venv) before reporting Python as missing.
  • If the user's fork sets a preferred Python interpreter path in AGENTS.local.md, use that first.
  • GitHub CLI (gh) is used for PR and issue workflows. If gh is not found, remind the user to install it (winget install GitHub.cli on Windows, brew install gh on macOS, gh from the distro package manager on Linux) and authenticate with gh auth login.
  • Console windows flashing during Windows test runs: a process launched as a background task owns no console. Every console child it spawns therefore asks Windows for one, and that one is shown. A suite that spawns shells continuously flashes a window roughly once a second across whatever else is on screen. The owner varies by depth, so a capture may name powershell.exe, pwsh.exe or cmd.exe. Two measures, both measured against this repository's suite:
    • Give the runner process a hidden console, which every descendant inherits so none of them allocates: launch the suite through Start-Process -WindowStyle Hidden -Wait -RedirectStandardOutput <file>. Measured: about one window per second before, zero after. This covers the whole tree and is the one that matters.
    • Keep CREATE_NO_WINDOW on the shells the suite spawns, which tests/_quiet_spawn.py installs by patching subprocess.run and subprocess.Popen. Measured on an isolated shell-to-cmd.exe chain: three windows over three runs before, zero after. It reaches only the process it is applied to, so it is a second layer rather than a substitute for the first. Setting the Windows default terminal application to Windows Console Host is worth doing as well. Windows Terminal turns each allocation into a full terminal window and does not honor SW_HIDE on it, whereas conhost does. That changes how loud the problem is rather than removing it. Settings, System, For developers, Terminal, or set DelegationConsole and DelegationTerminal under HKCU:\Console\%%Startup to {B23D10C0-E52E-411E-9D5B-C09FDF709C7D}. Opening Windows Terminal yourself is unaffected.
  • Claude Code installation: Prefer the native installer. Migrate off npm and winget when possible.
    • macOS: curl -fsSL https://claude.ai/install.sh | sh
    • Windows (PowerShell, no admin): irm https://claude.ai/install.ps1 | iex (requires Git for Windows)
    • To migrate from npm: npm uninstall -g @anthropic-ai/claude-code first. From winget: winget uninstall Anthropic.ClaudeCode first.
    • Native installs auto-update in the background by default. Use /config inside Claude Code to set the release channel (latest or stable). Run claude doctor to inspect updater status, and claude update to force an immediate update check.
    • To disable auto-updates, set DISABLE_AUTOUPDATER=1 in the environment or add "env": {"DISABLE_AUTOUPDATER": "1"} to ~/.claude/settings.json. The env var takes precedence regardless of other flags.
  • Claude Code effort level: As of Claude Code v2.1.111, the /effort slider exposes five levels: low, medium, high, xhigh, max. The persisted effortLevel key in settings.json accepts low, medium, high, and xhigh (v2.1.111 added xhigh as a valid persisted value). max remains session-only: selecting max via /effort silently does not persist. To get max as a persistent default across every project and session, set the env var CLAUDE_CODE_EFFORT_LEVEL=max in ~/.claude/settings.json under "env". The shared user/settings.json in this repo sets the env var, and bootstrap merges it into ~/.claude/settings.json, so running bootstrap once on any consuming project lands the user-level default. Runtime precedence: managed policy > CLAUDE_CODE_EFFORT_LEVEL env var > persisted effortLevel (local > project > user) > Claude Code's built-in default. When the env var is set, it outranks --effort at launch and /effort inside a session; the slash command prints a warning that the env var is overriding the live effort. When the env var is unset, --effort <level> at launch is a session-only override, /effort low|medium|high|xhigh updates the persisted user setting, and /effort max is session-only.

Local Skills Precedence

  • If the workspace contains a skills/ directory, treat repo-local skills as the default source of truth for that project.
  • Skill lookup order for every agent (Claude Code, Codex, or any future agent): when resolving a skill by name, try paths in this order, first hit wins:
    1. skills/<skill-name>/SKILL.md: project-local, hand-authored or vendored.
    2. .claude/skills/<skill-name>/SKILL.md: pack-deployed by anywhere-agents pack install. The .claude/ prefix is a historical Claude Code convention; the SKILL.md contents are agent-agnostic. A v1.0 architecture pass is the right place to revisit the directory name.
    3. .agent-config/repo/skills/<skill-name>/SKILL.md: shared config bootstrapped from upstream. This is the same lookup order encoded in the Claude Code slash-command pointers at .claude/commands/<name>.md (per the issue #6 fix), so an agent reading either the pointer file or this rule resolves the same skill the same way.
  • When using a repo-local skill, read skills/<skill-name>/SKILL.md and its local references/, scripts/, and assets/ before falling back to any globally installed copy.
  • Do not modify a globally installed skill when a repo-local skill of the same name exists, unless the user explicitly asks to update the global copy too.
  • If a repo-local skill overrides a global skill, state briefly that the local project copy is being used.

Cross-Tool Skill Sharing

  • Skills under skills/ are shared between coding agents (Codex, Claude Code, and any future agent).
  • skills/<skill-name>/SKILL.md is the single source of truth for each skill. Agent-specific config files (e.g., agents/openai.yaml) are thin wrappers and must not duplicate or override the logic in SKILL.md.
  • Claude Code has an ergonomic helper: slash-command pointers in .claude/commands/<name>.md. Each pointer file references the corresponding SKILL.md rather than duplicating its content. Codex and other agents reach the same SKILL.md content via the documented "Local Skills Precedence" lookup order above; no slash-command equivalent is required.
  • Pack-deployed skills (third-party packs installed by anywhere-agents pack install) land under .claude/skills/<name>/ as a cross-agent location. The directory name carries a historical Claude Code prefix; the SKILL.md contents are agent-agnostic and resolvable by Codex through the same lookup order. A future plan-review pass on pack-architecture.md is the right place to consider renaming the location to a vendor-neutral path.
  • Bootstrap sync should copy only the shared repo's .claude/commands/*.md files into the project .claude/commands/ directory and should not delete unrelated project-local commands.
  • When editing a skill, modify SKILL.md and its references/ or scripts/ directly. Do not create agent-specific forks of the same content.
  • If a new skill is added, create both the skills/<skill-name>/SKILL.md structure and a matching .claude/commands/<skill-name>.md pointer so Claude Code's slash-command surface stays in sync; Codex reaches the same skill through the lookup order without needing a pointer.