Cross-Runtime Agent-Platform Interoperability
This package is two things at once:
- A compatibility wiki, refreshed daily from official vendor docs, recording how today's agent runtimes — Codex, Claude Code, Grok, Hermes, Antigravity CLI, Cursor, and Kuma Studio — compare across skills, hooks, plugins/extensions, project-instruction files, CLI spawn (interactive vs headless), session resume, and billing. Every claim cites the vendor's own docs; absent docs are recorded as
not documented, never inferred.
- A methodology for interoperating and managing those runtimes: how to ship one repo-owned source of truth — skills, hooks, commands, scripts, references, assets, MCP/app wiring, or runtime-specific plugin metadata — without drifting between agents.
The detailed comparison lives in docs/ (start with docs/compatibility-matrix.md); the daily refresh keeps it current (docs/cloud-automation.md). The rest of this file is the authoring/interoperation methodology that turns that wiki into shippable, non-drifting packages.
Taxonomy
Use these words precisely:
- Skill: instructions the model reads when the task matches. Usually
SKILL.md plus optional scripts/, references/, and assets/. A skill can tell the model what to do, but it does not enforce tool behavior by itself.
- Hook: a harness-level guard or automation invoked around lifecycle events such as tool calls. A hook can allow, deny, ask, mutate input, or add context depending on runtime support. Hooks must be registered in the runtime config or plugin metadata; putting a hook script inside a skill folder is not enough.
- Plugin / extension: a runtime-specific packaging and trust boundary that can bundle skills, hooks, MCP servers, apps, commands, agents, or metadata. Codex and Grok document plugin packages; Antigravity documents native plugins (legacy Gemini extensions migrate in via
agy plugin import gemini); Claude documents plugins as self-contained directories with skills, agents, hooks, or a .claude-plugin/plugin.json manifest — the manifest directory is marked optional if components use default locations (a single-skill plugin may put SKILL.md at the plugin root), and when present the manifest is the direct analogue of Codex's .codex-plugin/plugin.json, bundling skills, agents, hooks, MCP servers, LSP servers, and monitors.
- Package root: the repo-owned canonical source directory we maintain. Most local "skills" in this workspace are actually plugin-like package roots because they include
SKILL.md, scripts, docs, installers, and policy.
If the task changes discovery, installation, trust, hook behavior, bundled scripts, or cross-runtime compatibility, treat it as package authoring, not just skill text editing.
Runtime Coverage
Eight runtimes are tracked — seven vendor runtimes plus one community project (gajae-code, gjc, MIT/beta by Yeachan-Heo, not an official vendor product; flagged the way Kuma Studio is, with its GitHub README as the only source). The detailed, source-cited truth lives in docs/compatibility-matrix.md and docs/plugin-packaging.md; this is the short working model:
| Runtime |
Skill surface |
Hook surface |
Plugin/package surface |
| Codex |
Repo .agents/skills/ plus user/admin/system skill roots |
User/project .codex/hooks.json or inline config hooks, plus plugin-bundled hooks |
.codex-plugin/plugin.json can bundle skills, apps, MCP servers, hooks, and marketplace metadata |
| Claude Code |
Project/user .claude/skills/, .claude/commands, add-dir skills, and skill-directory plugins |
User/project/local .claude/settings*.json hooks, plugin hooks, and skill lifecycle hooks |
.claude-plugin/plugin.json plugins can bundle skills, agents, hooks, MCP servers, LSP servers, and monitors |
| Grok / xAI |
User, project, plugin, and configured skill roots |
User, project, and plugin hook roots |
Plugins can bundle skills, agents, hooks, MCP servers, and LSP servers |
| Hermes Agent |
Skills, skill taps, and plugin-bundled skills are documented |
Gateway hooks, shell hooks, and plugin hooks are documented |
plugin.yaml plugins can bundle tools, hooks, slash commands, CLI commands, and skills; four documented roots — ~/.hermes/plugins/, project-local ./.hermes/plugins/ (needs HERMES_ENABLE_PROJECT_PLUGINS=true), bundled <repo>/plugins/, and pip entry points under hermes_agent.plugins. Plugin hooks register via ctx.register_hook(), so project-local hooks are reachable |
Antigravity CLI (agy, was Gemini CLI) |
.agents/skills/ (global ~/.gemini/antigravity-cli/skills/); skills auto-become /<name> slash commands |
Hooks in a plugin's hooks.json or primary settings.json (pre/post-tool); /hooks browses loaded hooks |
Native plugins at ~/.gemini/antigravity-cli/plugins/<name>/ (plugin.json, hooks.json, skills/, agents/, rules/) managed by agy plugin; MCP via standalone mcp_config.json |
| Cursor CLI |
Project/user .agents/skills/ and .cursor/skills/, plus Claude/Codex compatibility skill roots |
Project .cursor/hooks.json, team/enterprise hooks, and command/prompt hook events |
Plugins are documented separately; hooks include workspaceOpen plugin-path injection, but do not infer Codex-style package parity |
| Kuma Studio |
skills in canonical repo paths |
guardrail hooks that must fail loudly |
symlink or generated-config install |
gajae-code (gjc, community) |
SKILL.md skills loaded at runtime only from the canonical GJC locations, with no configuration — .gjc/skills/ (project) and ~/.gjc/agent/skills/ (user). .claude/skills/ and .codex/skills/ are import sources only: gjc skills discover reports them with the exact copy command, and a skill must be copied into a canonical .gjc location before /skill:<name> can invoke it. Trust switches skills.trustProjectSkills/skills.trustUserSkills, master skills.enabled, listing gjc skills discover; bundled deep-interview, ralplan, ultragoal, autoresearch via gjc setup defaults |
named but unspecified — the README's doc index lists docs/hooks.md and /extensions "configures skills, hooks, and MCPs" at project and user scope; no event list or format in the README |
named but unspecified — the doc index lists docs/gjc-plugins.md ("Plugin bundles") and gjc customize doctor reports plugin as a customization source; no manifest schema in the README. gajae still does not install into other CLIs ("GJC does not become a Claude Code extension") |
When a runtime capability is not documented, write not documented or unknown and require live verification before shipping behavior that depends on it.
Explicit skill invocation is not the same token across runtimes. Claude Code, Grok, and Cursor expose user-invocable skills as slash commands such as /<skill-name> (Claude/Cursor: disable-model-invocation: true makes a skill explicit-only); Codex uses /skills (selector) or $<skill-name> (mention) — typed /<skill-name> is not a documented Codex form, and allow_implicit_invocation: false in agents/openai.yaml turns off description-matching; Hermes documents no typed invocation token, but Antigravity registers each skill as a typed /<skill-name> slash command in the TUI; community gajae-code is the odd one out — it uses a colon form, /skill:<name> (e.g. /skill:deep-interview), not /<skill-name>. Full source-cited table: docs/compatibility-matrix.md → Skill Invocation. For cross-engine commands, rely on description-triggered invocation as the portable layer and treat the typed token as per-engine sugar.
CLI Spawn And Headless Launch
When one agent spawns another from a script, hook, or orchestrator, use the runtime's documented command for the mode you want — interactive and headless are reached differently. Full tables and citations live in docs/cli-invocation.md; resume is covered under Session Resume below.
| Runtime |
Interactive launch |
Headless run |
| Codex |
codex / codex "<p>" (optional PROMPT positional, per the CLI reference) |
codex exec "<p>" |
| Claude Code |
claude / claude "<q>" |
claude -p "<q>" |
| Grok / xAI |
grok |
grok -p "<p>" |
| Hermes |
hermes chat |
hermes chat -q "<q>" |
| Antigravity CLI |
agy |
agy -p "<p>" (--print/--prompt; dedicated Headless-mode page) |
| Cursor CLI |
agent (the docs now document agent; they do not state whether the older cursor-agent binary still works) |
agent -p "<p>" |
| gajae-code (community) |
gjc / gjc --tmux / gjc --tmux --worktree <branch> |
not documented (the README dropped --mode rpc; external control is the broker-bound gjc sdk session CLI, or the Coordinator MCP bridge gjc mcp-serve coordinator) |
- The mode switch is not the same shape. For Claude/Grok/Cursor/Hermes/Antigravity, headless is a flag (
-p/--print, or Hermes -q) added to the bare interactive command — so interactive = omit the flag. Codex is the exception: headless is a separate subcommand (codex exec), with no print/headless -p to drop (Codex's -p is --profile, a config-profile selector — not a prompt flag, so "Codex has no -p" is wrong; it has no headless -p), so a list of only codex exec … is not "Codex is headless-only". Antigravity (agy) gained an officially documented headless mode (a dedicated "Headless mode" page at /docs/cli/headless): agy -p/--print/--prompt "sends a single prompt to the agent, streams or returns the response, and exits", with --output-format text|json|stream-json, --json-schema, --model, --effort low|medium|high, --agent, --print-timeout (default 5m), --sandbox, --input-format text|stream-json (prompts on stdin), and headless -c/--conversation resume — the previous "TUI-only, SDK for unattended runs" verdict is retired. With --input-format stream-json (which requires --output-format stream-json) agy becomes a long-lived multi-turn process driven over a pipe, one result event per turn, rather than a one-shot per prompt.
- Output format is not uniform: Codex
--json (JSONL); Claude/Cursor/Antigravity --output-format json|stream-json; Grok --output-format json; Hermes documents no headless JSON flag.
- Gemini CLI is omitted: as of 2026-06-18 it has stopped serving AI Pro/Ultra and free individual users (replaced by Antigravity CLI,
agy); enterprise/Google Cloud keeps Gemini CLI. See docs/cli-invocation.md → transition section.
Session Resume
Same-platform resume (continue the same conversation on the same engine, by session id) is officially documented for all four worker runtimes. Per-engine resume invocation, session store, and id form live in docs/compatibility-matrix.md → Session Resume. The working model:
- The minimum to continue is the resume locator (session/thread id) plus the engine's resume invocation: Claude
claude --resume <id>, Codex CLI codex resume <id> (codex fork [<id>|--last] branches a past session into a new thread; desktop app-server: the thread/resume / thread/fork methods with the recorded thread.id), Grok grok -r/--resume <id> (with --fork-session to fork the resumed session into a new session id), Hermes hermes --resume <id>.
- Capture the locator before the worker exits, keyed by
cwd (the most stable signal every engine exposes). Session stores differ — Claude/Codex/Grok keep per-session transcript/rollout files; Hermes keeps history in SQLite ~/.hermes/state.db, so a file scan of ~/.hermes/sessions/ (which holds only API error dumps) finds nothing resumable.
- Antigravity CLI (
agy, the Gemini CLI successor) resumes with agy -c / agy --continue (most recent in the workspace) or agy --conversation <conversation-id> — both now also documented to work in headless mode (agy -p … --continue); conversations are workspace-scoped (it lists only sessions started in that cwd). -c resolves through a documented workspace-keyed cache map, ~/.gemini/antigravity-cli/cache/last_conversations.json — the one Antigravity session store the docs state.
- gajae-code documents no CLI resume flag; session ids exist only on the SDK path (allowlisted lifecycle ops
session.create/session.fork/session.resume/session.close via gjc sdk session raw, plus gjc sdk session tail <sessionId> --until-idle). It persists per-session evidence under a project .gjc/ dir and isolates work with git worktrees (gjc --tmux --worktree <branch>), but neither worktree isolation nor broker-bound external control is an interactive --resume — treat CLI resume as not documented.
- Cross-engine moves (resume one engine's session under a different engine) are a separate, harder problem and out of scope here — keep them off the same-platform path.
- When a runtime does not document resume, record
not documented and require live verification before shipping.
Model Lineup
Which models each runtime currently ships — the exact ids a caller selects today, their reasoning/effort tiers, and which models the vendor has retired — drifts on its own cadence (a new frontier model or a retirement lands independently of any skill/hook/CLI change). The detailed, source-cited record lives in docs/models/ (one file per runtime, each with a Last reviewed: stamp and its official URL); this is the short working model:
- Claude / Claude Code — current: Fable 5 (
claude-fable-5), Opus 5 (claude-opus-5, "for complex agentic coding and enterprise work"), Sonnet 5 (claude-sonnet-5), Haiku 4.5 (claude-haiku-4-5, id claude-haiku-4-5-20251001). Legacy: Opus 4.8 (→ 5), Opus 4.7, and Sonnet 4.6 (→ 5); claude-opus-4-1-20250805 retired 2026-08-05 with Opus 5 as the stated migration target. Reasoning is adaptive thinking on the current generation (Haiku 4.5: extended thinking); the --effort labels (low, medium, high, xhigh, max, ultracode) are a Claude Code caller-layer selector, not distinct vendor models. The Mythos pair (claude-mythos-5, claude-mythos-preview) is documented but invitation-only (not GA) — do not treat it as spawnable.
- Codex — current recommended family:
gpt-5.6 (the page shows the bare id only as a CLI example, not as a labelled default), with explicit Sol/Terra/Luna selectors gpt-5.6-sol, gpt-5.6-terra, and gpt-5.6-luna; gpt-5.5 is previous-generation, gpt-5.4 / gpt-5.4-mini remain under "Other models" but retire from Codex on 2026-08-31 when signing in with ChatGPT (replace with gpt-5.6-terra / gpt-5.6-luna), and gpt-5.3-codex-spark is still a text-only research preview. gpt-5.2 and gpt-5.3-codex are already deprecated. Reasoning effort is selected separately (Low through Ultra); model_reasoning_effort + service_tier stay config knobs.
- Grok — current flagship:
grok-4.6 (500k context; configurable reasoning), plus the Grok Voice API and Imagine image/video APIs. The Text API pricing table also lists grok-4.5 (500k), grok-4.3, grok-4.20-0309-reasoning, grok-4.20-0309-non-reasoning, grok-4.20-multi-agent-0309 (1M each), and grok-build-0.1 (256k). The Voice API is no longer id-less: grok-voice-think-fast-2.0 is current and grok-voice-think-fast-1.0 is marked Deprecated. Effort is documented at both layers: the CLI reference lists --effort <LEVEL>, while the API reasoning page gives grok-4.6 low/medium/high/xhigh (default high) and grok-4.5 low/medium/high (default high); reasoning cannot be disabled. A dedicated retirement page exists (/developers/migration/may-15-retirement): eight ids retired 2026-05-15 with redirects (e.g. grok-code-fast-1 → grok-build-0.1); see docs/models/grok.md.
- Gemini-Antigravity — provider-routed; ids verified against Google's official model page (https://ai.google.dev/gemini-api/docs/models, page last-updated 2026-08-14).
gemini-3.7-flash is the new Stable latest/capable Flash model for complex coding, agentic workflows, and multi-step execution; gemini-3.6-flash remains Stable as the previous generation and the page's stable-id naming example, while gemini-3.5-flash is now labelled legacy. Stable gemini-3.5-flash-lite and preview ids (gemini-3.1-pro-preview, gemini-3-flash-preview, Antigravity Agent antigravity-preview-05-2026) remain. The CLI's agy models sample additionally surfaces gemini-3.7-flash-high, gemini-3.7-flash-medium, gemini-3.6-flash-high, gemini-3.6-flash-medium, gemini-3.5-flash-medium, gemini-3.1-pro-high, and claude-sonnet-4-6 — CLI-surface slugs not on the API models page.
- Hermes — router-routed; ids seeded from downstream catalogs and
unverified this run against the vendor page. Hermes selects upstream provider models rather than shipping its own.
- Cursor — mixed: it ships Cursor-owned models (Composer 2.5 and Cursor Grok 4.6 / 4.5 from Cursor and SpaceXAI; Composer 1 no longer appears) and routes to third-party families (Anthropic through Claude Fable 5/Opus 5, OpenAI, Google through Gemini 3.7 Flash, GLM 5.2, Kimi K2.7 Code/K3), with
Auto as the default. Cursor Grok 4.6 supports low/medium/high/xhigh effort and a Fast tier, though the Start plan pins Grok 4.6 / 4.5 to a fixed medium effort in non-fast mode. Auto is still not a pricing-table row and has three documented modes — Auto Cost, Auto Balance, Auto Intelligence — with Cursor Router picking the model on Teams/Enterprise. It is not a pure router.
SSoT boundary — this folder does not own everything model-shaped. It owns current shipping ids + tiers + retirement status, verified against each vendor's official model page. It does not own: pricing/limits (the claude-api skill and vendor pricing pages), the Kuma Studio spawnable catalog (packages/shared/team.json modelCatalog — a downstream consumer that syncs from these lineups, never the reverse), or naming/phonetic-gloss standards (the Kuma vault domains/model-frontier.md). Link to those; do not duplicate. When a value cannot be confirmed against the official doc in a run, mark it unverified this run and leave it for the next daily pass — never substitute a guess or a non-vendor mirror.
Project Instruction Files
Do not assume every non-Claude runtime reads AGENTS.md. Use the officially documented project-instruction filename for the target runtime:
| Runtime |
Official project instruction/context files |
| Codex |
AGENTS.override.md, AGENTS.md, then configured project_doc_fallback_filenames |
| Claude Code |
CLAUDE.md, .claude/CLAUDE.md, CLAUDE.local.md, and .claude/rules/; Claude docs explicitly say Claude reads CLAUDE.md, not AGENTS.md |
| Grok / xAI |
AGENTS.md, Agents.md, AGENT.md, CLAUDE.md, Claude.md, CLAUDE.local.md, plus .grok/rules/ (and .claude/rules/, .cursor/rules/ for compatibility); global rules in ~/.grok/, then repo root down to cwd, deeper wins; .gitignored files are skipped |
| Hermes Agent |
.hermes.md / HERMES.md, then AGENTS.override.md, then AGENTS.md, then CLAUDE.md, then .cursorrules — one project context type loads per session on that first-match chain. AGENTS.override.md is a personal, per-directory override loaded instead of the committed AGENTS.md next to it (typically gitignored). .cursor/rules/*.mdc is a recognized file (CWD only) but is not part of the chain. SOUL.md is global identity, not project instructions |
| Antigravity CLI (was Gemini CLI) |
Reads GEMINI.md and AGENTS.md (global ~/.gemini/GEMINI.md); Gemini CLI's GEMINI.md hierarchical memory is the legacy form |
| Cursor CLI |
.cursor/rules, plus project-root AGENTS.md and CLAUDE.md |
| Kuma Studio |
AGENTS.md and CLAUDE.md are parallel repo SSoT files for shared rules |
| gajae-code (community) |
not documented — README does not document an instruction-file loader (AGENTS.md/CLAUDE.md/GEMINI.md); it reports .claude/skills/ and .codex/skills/ as skill import sources (copy-in required before use), which is neither runtime skill loading nor instruction loading. User config is ~/.gjc/config.yml, per-project state lives in .gjc/ |
Claude Code v2.1.213+ also documents /import for a one-time conversion from a supported coding agent: it appends instruction files such as AGENTS.md to the matching CLAUDE.md and carries over MCP servers, commands, subagents, and skills. This is migration, not a second live instruction source.
For cross-agent repo rules, maintain the smallest set of files that each runtime actually reads. In Kuma-style Codex/Claude/Grok/Hermes repos, that usually means repo-owned AGENTS.md plus a CLAUDE.md import/symlink or Claude-specific wrapper; add GEMINI.md only when Antigravity CLI (or legacy Gemini CLI) is a supported runtime.
The filename is only half the contract — loading mechanics differ per engine along two axes: ancestor walk-up (climb cwd → root, merging every file passed) and subdirectory discovery (nested files below cwd, loaded upfront vs on-demand). Full source-cited comparison: docs/compatibility-matrix.md → Project Instruction File Loading. The working model:
- Claude Code loads ancestor
CLAUDE.md/CLAUDE.local.md from cwd up to the filesystem root in full at launch (concatenated root → cwd, closer-to-cwd wins), and discovers nested subdirectory CLAUDE.md on-demand when it reads files there (not re-injected after /compact until that dir is touched again). So it is not "just root + cwd" — it is the whole ancestor chain eagerly plus the descendant tree lazily.
- Codex walks root → down to cwd, ≤ 1 file per dir, concatenated with closer files overriding, built once per run under a 32 KiB cap — and has no subdirectory lookahead (never reads below cwd).
- Gemini / Antigravity concatenates global + ancestor + the entire subtree below cwd into the prompt sent with every request (
.gitignore-aware) — always in context, not lazy like Claude.
- Hermes picks one project context type by first match (
.hermes.md → AGENTS.override.md → AGENTS.md → CLAUDE.md → .cursorrules; .cursor/rules/*.mdc is recognized but sits outside the documented priority chain) — but when that type is AGENTS.md and cwd is inside a git repo it now loads a merged ancestor chain: the git-root AGENTS.md first, then every intermediate directory down to cwd, each with a provenance header (## ../../AGENTS.md) and identical copies deduplicated, deeper files later so they take precedence. Outside a git repo only cwd is read, so a stray AGENTS.md in $HOME or /tmp cannot leak in. It also does on-demand discovery of the dir + 5 parents (each checked at most once per session) during file ops.
- Grok loads global
~/.grok/ rules, then every directory from the repo root down to cwd (cwd only outside a git repo), with deeper files taking precedence on conflicts. Unlike Hermes it does not stop at the first match — it reads every matching name in a directory, across a six-name family (AGENTS.md, Agents.md, AGENT.md, CLAUDE.md, Claude.md, CLAUDE.local.md) plus .grok/rules/ (.claude/rules/, .cursor/rules/ for compat). It is the one runtime that honors .gitignore for rules, which is what keeps CLAUDE.local.md personal and out of shared context. grok inspect lists what was discovered, with token counts.
- Cursor documents project-root
AGENTS.md/CLAUDE.md only; tree-walk/merge is not documented.
Implication for cross-engine repos: a module-specific instruction placed in a deep subdirectory is seen eagerly by Gemini, lazily by Claude/Hermes, and never by Codex (below cwd) — keep anything Codex must obey at or above the launch directory.
Symlink the wrapper, edit only the canonical file. When CLAUDE.md/GEMINI.md are symlinks to a repo-owned AGENTS.md, reads resolve correctly — every runtime sees the canonical content, and git stores the link as mode 120000 (a pointer, not a copy; both links share one blob). But Claude Code's Edit/Write refuses to write through a symlink (Refusing to write through symlink ... pass the real target path explicitly, verified 2026-06-05), so edits must target the real AGENTS.md; treat the symlinks as read-only. This is a feature, not a limitation: it stops an atomic-save from silently swapping the link for a divergent regular file, so the SSoT cannot drift. Use relative symlinks (ln -s AGENTS.md CLAUDE.md, never an absolute path) so they survive clone/move. Caveat: a Windows checkout without core.symlinks materializes the link as a plain text file — use a one-line stub+pointer instead of a symlink when a Windows runtime is in scope.
Core Rules
- Pick one canonical repo path first. Installed copies under
~/.claude/skills and ~/.agents/skills must be symlinks or generated config entries.
- Registration goes through the umbrella manifest,
skills.json, and nothing else. In the agent-extensions umbrella, skills.json is the single record of which skill installs from which canonical path; scripts/install/install-local.mjs reads it and generates the symlinks into every engine's skill root. Adding a skill = adding one entry there, then re-running the installer. Do not register a skill by hand-symlinking it into an engine root or by adding an engine-config entry (e.g. Codex ~/.codex/config.toml [[skills.config]]) — that is a second registration channel and it drifts. This skill states the conventions; skills.json is the data that applies them; the installer is what executes them.
- A skill whose repo also builds artifacts must point its manifest
path at the skill subfolder, not the repo root. Runtimes scan the whole skill root recursively — Codex walks ~/.agents/skills under a traversal budget and aborts with skills scan reached its traversal limit when one folder is oversized — so a repo root that carries a build cache (target/, node_modules/, dist/) gets swept into the scan and can starve discovery of other skills. Link the minimal skill folder inside the repo (<repo>/skills/<name>/ or the runtime-native subpath) so the build tree stays outside the scan root; the repo itself, its build, and its upstream remote are untouched. Precedent: kordoc links kordoc/plugins/kordoc/skills/kordoc/, not its repo root. (This is a refinement of "one canonical repo path", not a skills/ index in the umbrella root — that remains banned below.)
- Do not edit home-directory installed copies directly.
- Do not keep separate Claude and Codex versions unless a difference is explicitly documented and tested.
- Name the package layer explicitly before editing: skill-only, hook-only, plugin-like package, or generated runtime plugin. Do not let a
SKILL.md entrypoint hide installer, hook, or trust-boundary changes.
- Keep
SKILL.md body under 500 lines — a performance guideline, not a hard loading cap. Anthropic's Skill authoring best practices say "Keep SKILL.md body under 500 lines for optimal performance": once loaded, every line competes with conversation history and other context. Put deterministic behavior in scripts; move scenario-specific detail into reference/*.md linked one level deep from SKILL.md (progressive disclosure).
name: max 64 chars, lowercase/numbers/hyphens only, no XML tags, no reserved words (anthropic, claude); prefer gerund form (processing-pdfs). description: max 1024 chars, no XML tags, third person, stating both what the skill does and when to use it (trigger terms) — not the procedure.
- Quote the
description if it contains a colon-space (: ), or the skill silently fails to load. A : in an unquoted YAML scalar is parsed as a nested mapping → mapping values are not allowed in this context. Common trap: description: ... Korean triggers: 원샷, .... Wrap the whole value in single quotes (description: '...'); double inner single-quotes, double-quotes are fine inside. Validate frontmatter parses before shipping.
- Hooks are guardrails, not silent fallback paths. They should block clearly, explain why, and require an explicit operator decision for dangerous actions.
- Do not re-implement a slash surface in a host layer above the engine. A GUI/terminal wrapper that intercepts keystrokes to fake
/command creates a second input path that must re-derive session context (current target resolution, ambiguity handling) the engine-side skill already has, and it standardizes on one invocation token where runtimes differ (Claude/Grok /name vs Codex $name — see Runtime Coverage above). Forward typed input to the engine verbatim and ship the capability as a skill + CLI; reserve host-level interception for things no engine surface can do.
- Cross-agent guidance must be based on official vendor docs. If a platform does not document a feature, record it as
not documented or unknown; do not infer parity from another agent.
- Make hook scripts executable (
chmod +x) and give them a shebang. Claude runs a hook in one of two documented forms: with args set the command is spawned directly as an executable with no shell; with args omitted the whole command string is passed to a shell (sh -c, Git Bash on Windows, or PowerShell). Either way the executable path itself must be runnable, so a missing exec bit fails with Permission denied on every matching event (PreToolUse/Stop) in every session — one forgotten chmod +x silently breaks all agents at once. Codex registers as node <path> so it tolerates a missing bit, but always chmod +x for parity and commit the mode (git stores 100755). Use the args form on Claude when you want to avoid shell quoting entirely.
- Hook scripts must not assume GNU coreutils. macOS ships neither
timeout nor stat -c; a hook that calls them unguarded fails on every macOS agent — and a fail-closed || exit 0 turns that into a silent no-op that looks like "working but quiet". Detect and degrade (command -v timeout || gtimeout || plain) and use portable forms (stat -f %m || stat -c %Y).
- Keep history out of doc bodies. Changelog narrative — what was added/changed/removed and when — lives in
CHANGELOG.md plus the git tag (the version SSoT), never accreting in SKILL.md or docs/* prose. A doc body states the current truth only; when a fact changes, replace it, don't append the old one. The one exception is a verification stamp (Last reviewed: YYYY-MM-DD, verified YYYY-MM-DD): that is provenance for a live claim, not history. This is what keeps a daily-refreshed wiki from turning into a changelog as it is re-verified. A freshness stamp must advance when the claim is re-verified, even if the wording is unchanged — for a time-sensitive status claim (a status that can flip: billing paused/resumed/cancelled, an announced-but-not-yet-effective cutoff, any "currently X" status), re-confirming it on a new date is the update; a still-true status whose stamp is months old reads as wrong. A blanket "no content change → touch nothing" refresh rots exactly these claims, so carve them out.
Recommended Layout
agent-extensions/
skills.json # the manifest: each skill's id -> canonical path (single registration record)
scripts/install/install-local.mjs # reads skills.json, generates the engine-root symlinks
scripts/test/*
alex-core-invariants/ # standalone repo, own remote
safedeps/ # standalone repo, own remote
sprite-gen/ # standalone repo, own remote
skill-hook-authoring/ # root-owned skill (these conventions)
katok/ # standalone repo that ALSO builds a binary
skills/katok/SKILL.md # skills.json path -> this subfolder, so target/ stays out of the scan root
target/ # build cache (gitignored); never the link target
../my-agent-girlfriend/ # sibling repo installed via a `../` path (source owned by its own remote)
Three layers, one direction: conventions (this skill) → manifest (skills.json) → installer (install-local.mjs) → generated symlinks. A canonical source may live outside the umbrella (a sibling repo); register it with a ../ path so skills.json stays the one registration record.
Keep the umbrella flat. Do not add a repo-local skills/ or hooks/ index in the umbrella root unless there is a specific migration plan, because that creates a second registration source competing with skills.json. This is separate from a standalone repo's own internal skills/ layout (e.g. katok/skills/katok/), which is that repo's upstream structure and a valid link target. If a hook belongs to a standalone repo, reference that repo path directly from the installer and agent config.
Authoring Flow
Before adding or changing a package:
- Classify the change: skill instruction, hook guard, plugin/extension package, installer/config, or docs-only compatibility claim.
- Pick the canonical package root and the generated install paths. For a repo that also builds artifacts, the registered
path is the skill subfolder, not the repo root (see Core Rules).
- Decide whether each installed artifact is a symlink, generated config entry, copied file, or runtime-native plugin package.
- Update the canonical source first, then its entry in the umbrella manifest
skills.json (which install-local.mjs reads), then docs. Do not add a second registration channel alongside it.
- Validate discovery in every claimed runtime. For undocumented runtimes, mark support as unknown until live verification exists.
Do not move a root-level SKILL.md into a plugin subdirectory, or convert a skill folder into a runtime plugin, unless the installer, docs, validation, and rollback path change in the same commit.
Disable / Scope / Retire
Three operations, three mechanisms — disabling is per engine (Claude skillOverrides,
Grok skills-disabled/) and never touches skills.json; scoping to one engine is
engines: in the manifest and is a claim that the skill cannot run elsewhere; retiring is
the checklist below. Full decision table and per-engine mechanics:
docs/skill-lifecycle.md.
Retiring Or Renaming Artifacts
Deleting a hook, skill, command, or plugin-like package means removing every active ownership path, not just the visible file:
- Delete or rename the canonical source file/folder.
- Remove active installer registration and generated config writes.
- Remove active overlay/settings entries.
- Add the old id/path/command to the relevant retired list so future installer runs clean existing symlinks or copies.
- Remove live home-directory symlinks/copies if they are repo-owned.
- Update docs and plans that describe the artifact in present tense.
- Search repo and live config for the old id. Remaining hits should be retired lists or historical notes only.
- Run syntax/config checks and prove the installer no longer recreates the retired artifact.
- Sweep instructions that point at the old name, not just code: agent-executed
docs (
AGENTS.md/CLAUDE.md-class files, operating doctrine, skill bodies)
referencing a renamed/retired CLI verb or moved doc path fail at runtime the
moment an agent follows them. Concretely: grep doc corpora for backticked
command mentions (e.g. launcher subcommands like kuma <verb>) and for
relative links to the old path. Prefer a CI guard that re-checks this on
every test run (kuma-studio: docs-reference-integrity.test.mjs — relative
.md links must resolve; backticked launcher verbs must map to a real bin).
This rule exists because deleting only ~/.claude/hooks/<id> or only scripts/hooks/<id> can let the artifact reappear on the next setup run — and because instructions pointing at the old name keep re-teaching agents the broken path long after the code is gone.
Multi-Agent Compatibility Docs
Use these repo documents before changing compatibility claims:
docs/official-sources.json — canonical source manifest for official docs refresh.
docs/compatibility-matrix.md — current cross-agent support matrix (includes the Session Resume table).
docs/cli-invocation.md — per-runtime CLI spawn (interactive vs headless) and resume invocation syntax.
docs/plugin-packaging.md — plugin/extension packaging boundaries.
docs/completion-stack.md — native completion/verification stacks (Claude Code /goal · Stop hook · /verify; Codex Goals · Stop hook · /review), enforcement grades, and verified misreading corrections.
docs/kuma-studio-patterns.md — public Kuma Studio operating patterns that can be reused by other agents.
docs/cloud-automation.md — daily cloud automation setup (Claude Routines, with a Codex App alternative).
Daily refresh automation must read the source manifest, fetch only official URLs, update docs only when evidence changed, and leave a PR rather than pushing to main.
Cross-Agent Install Pattern
- Prefer repo-local skill roots when the runtime documents them (
.agents/skills/, .claude/skills/, .grok/skills/, .cursor/skills/) and the workflow is project-specific.
- Symlink user-wide canonical skill folders into the runtime's documented user skill root only when the workflow should apply outside one repo.
- Patch project-local hook config for project guardrails; patch user-level hook config only for personal/global guardrails.
- Backup mutated JSON config files before writing.
chmod +x every hook script before registering it (Claude either spawns the executable directly (args form) or passes command to a shell; either way no exec bit = Permission denied everywhere).
- Validate by feeding representative JSON payloads into the hook scripts — and run the script directly (
./hook.cjs ..., no node prefix) to catch a missing exec bit the way Claude would.
Hook Payload Pattern
Claude Code and Codex CLI use the same input schema for PreToolUse / PostToolUse hooks. A Bash tool call arrives as:
{
"session_id": "abc123",
"prompt_id": "prompt_abc123",
"transcript_path": "~/.claude/projects/.../transcript.jsonl",
"cwd": "/Users/me/project",
"permission_mode": "default",
"hook_event_name": "PreToolUse",
"tool_name": "Bash",
"tool_use_id": "toolu_...",
"tool_input": {
"command": "npm install foo",
"description": "Install foo",
"timeout": 120000
}
}
Notes:
tool_input.command — the shell command. Use this single field; do not read from .input.command, .arguments.command, or other variants.
cwd, session_id, prompt_id, transcript_path, permission_mode, hook_event_name, tool_name, tool_use_id are all top-level, not under tool_input. Reading tool_input.cwd returns nothing.
permission_mode is one of default, plan, acceptEdits, auto, dontAsk, bypassPermissions.
- Both engines share this schema. Codex additionally provides
turn_id and model.
Hook Decision Output
Claude Code and Codex use the same decision schema for PreToolUse. Pick one of these to block:
Modern (recommended):
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "safedeps: install not approved — run `safedeps check ...` first"
}
}
Legacy (still supported by both engines):
{"decision": "block", "reason": "safedeps: install not approved ..."}
permissionDecision accepts "allow" | "deny" | "ask" | "defer" on Claude Code. Official Codex hooks docs document only "allow" and "deny" for PreToolUse, and "defer" is not documented for Codex at all. Codex parses several other
…(truncated)
1---2name: skill-hook-authoring3description: Cross-runtime agent-platform interoperability wiki and authoring methodology, refreshed daily from official vendor docs: how Codex, Claude Code, Grok, Hermes, Antigravity CLI, Cursor, and Kuma Studio compare across skills, hooks, plugins, project-instruction files, CLI spawn, session resume, and billing, plus the rules to ship one source of truth without drifting. Use when authoring, editing, retiring, renaming, disabling/enabling, or debugging a skill / hook / slash-command / plugin; when deciding which engines a skill installs to; or when a skill is not triggering and its description needs fixing. Triggers (KR/EN): 스킬 작성/수정/폐기/삭제/이름변경, 스킬 끄기/비활성/다시 켜기, 안 쓰는 스킬 정리, 특정 엔진에서만, 스킬 발동 안 됨, description 고치기, 훅 작성, 슬래시 커맨드, 플러그인 패키징, 크로스런타임 호환; skill authoring/retire/rename/disable/enable, prune unused skills, scope a skill to one engine, skill not triggering, hook authoring, plugin packaging, cross-runtime comparison.4---56# Cross-Runtime Agent-Platform Interoperability78This package is two things at once:9101. **A compatibility wiki**, refreshed daily from official vendor docs, recording how today's agent runtimes — Codex, Claude Code, Grok, Hermes, Antigravity CLI, Cursor, and Kuma Studio — compare across skills, hooks, plugins/extensions, project-instruction files, CLI spawn (interactive vs headless), session resume, and billing. Every claim cites the vendor's own docs; absent docs are recorded as `not documented`, never inferred.112. **A methodology** for *interoperating and managing* those runtimes: how to ship one repo-owned source of truth — skills, hooks, commands, scripts, references, assets, MCP/app wiring, or runtime-specific plugin metadata — without drifting between agents.1213The detailed comparison lives in `docs/` (start with `docs/compatibility-matrix.md`); the daily refresh keeps it current (`docs/cloud-automation.md`). The rest of this file is the authoring/interoperation methodology that turns that wiki into shippable, non-drifting packages.1415## Taxonomy1617Use these words precisely:1819- **Skill**: instructions the model reads when the task matches. Usually `SKILL.md` plus optional `scripts/`, `references/`, and `assets/`. A skill can tell the model what to do, but it does not enforce tool behavior by itself.20- **Hook**: a harness-level guard or automation invoked around lifecycle events such as tool calls. A hook can allow, deny, ask, mutate input, or add context depending on runtime support. Hooks must be registered in the runtime config or plugin metadata; putting a hook script inside a skill folder is not enough.21- **Plugin / extension**: a runtime-specific packaging and trust boundary that can bundle skills, hooks, MCP servers, apps, commands, agents, or metadata. Codex and Grok document plugin packages; Antigravity documents native plugins (legacy Gemini extensions migrate in via `agy plugin import gemini`); Claude documents plugins as self-contained directories with skills, agents, hooks, or a `.claude-plugin/plugin.json` manifest — the manifest directory is marked *optional if components use default locations* (a single-skill plugin may put `SKILL.md` at the plugin root), and when present the manifest is the direct analogue of Codex's `.codex-plugin/plugin.json`, bundling skills, agents, hooks, MCP servers, LSP servers, and monitors.22- **Package root**: the repo-owned canonical source directory we maintain. Most local "skills" in this workspace are actually plugin-like package roots because they include `SKILL.md`, scripts, docs, installers, and policy.2324If the task changes discovery, installation, trust, hook behavior, bundled scripts, or cross-runtime compatibility, treat it as **package authoring**, not just skill text editing.2526## Runtime Coverage2728Eight runtimes are tracked — seven vendor runtimes plus one community project (**gajae-code**, `gjc`, MIT/beta by Yeachan-Heo, not an official vendor product; flagged the way Kuma Studio is, with its GitHub README as the only source). The detailed, source-cited truth lives in `docs/compatibility-matrix.md` and `docs/plugin-packaging.md`; this is the short working model:2930| Runtime | Skill surface | Hook surface | Plugin/package surface |31|---|---|---|---|32| Codex | Repo `.agents/skills/` plus user/admin/system skill roots | User/project `.codex/hooks.json` or inline config hooks, plus plugin-bundled hooks | `.codex-plugin/plugin.json` can bundle skills, apps, MCP servers, hooks, and marketplace metadata |33| Claude Code | Project/user `.claude/skills/`, `.claude/commands`, add-dir skills, and skill-directory plugins | User/project/local `.claude/settings*.json` hooks, plugin hooks, and skill lifecycle hooks | `.claude-plugin/plugin.json` plugins can bundle skills, agents, hooks, MCP servers, LSP servers, and monitors |34| Grok / xAI | User, project, plugin, and configured skill roots | User, project, and plugin hook roots | Plugins can bundle skills, agents, hooks, MCP servers, and LSP servers |35| Hermes Agent | Skills, skill taps, and plugin-bundled skills are documented | Gateway hooks, shell hooks, and plugin hooks are documented | `plugin.yaml` plugins can bundle tools, hooks, slash commands, CLI commands, and skills; four documented roots — `~/.hermes/plugins/`, project-local `./.hermes/plugins/` (needs `HERMES_ENABLE_PROJECT_PLUGINS=true`), bundled `<repo>/plugins/`, and pip entry points under `hermes_agent.plugins`. Plugin hooks register via `ctx.register_hook()`, so project-local hooks are reachable |36| Antigravity CLI (`agy`, was Gemini CLI) | `.agents/skills/` (global `~/.gemini/antigravity-cli/skills/`); skills auto-become `/<name>` slash commands | Hooks in a plugin's `hooks.json` or primary `settings.json` (pre/post-tool); `/hooks` browses loaded hooks | Native plugins at `~/.gemini/antigravity-cli/plugins/<name>/` (`plugin.json`, `hooks.json`, `skills/`, `agents/`, `rules/`) managed by `agy plugin`; MCP via standalone `mcp_config.json` |37| Cursor CLI | Project/user `.agents/skills/` and `.cursor/skills/`, plus Claude/Codex compatibility skill roots | Project `.cursor/hooks.json`, team/enterprise hooks, and command/prompt hook events | Plugins are documented separately; hooks include `workspaceOpen` plugin-path injection, but do not infer Codex-style package parity |38| Kuma Studio | skills in canonical repo paths | guardrail hooks that must fail loudly | symlink or generated-config install |39| gajae-code (`gjc`, community) | `SKILL.md` skills loaded at runtime only from the canonical GJC locations, with no configuration — `.gjc/skills/` (project) and `~/.gjc/agent/skills/` (user). `.claude/skills/` and `.codex/skills/` are **import sources only**: `gjc skills discover` reports them with the exact copy command, and a skill must be copied into a canonical `.gjc` location before `/skill:<name>` can invoke it. Trust switches `skills.trustProjectSkills`/`skills.trustUserSkills`, master `skills.enabled`, listing `gjc skills discover`; bundled `deep-interview`, `ralplan`, `ultragoal`, `autoresearch` via `gjc setup defaults` | named but unspecified — the README's doc index lists `docs/hooks.md` and `/extensions` "configures skills, hooks, and MCPs" at project and user scope; no event list or format in the README | named but unspecified — the doc index lists `docs/gjc-plugins.md` ("Plugin bundles") and `gjc customize doctor` reports `plugin` as a customization source; no manifest schema in the README. gajae still does not install *into* other CLIs ("GJC does not become a Claude Code extension") |4041When a runtime capability is not documented, write `not documented` or `unknown` and require live verification before shipping behavior that depends on it.4243**Explicit skill invocation is not the same token across runtimes.** Claude Code, Grok, and Cursor expose user-invocable skills as slash commands such as `/<skill-name>` (Claude/Cursor: `disable-model-invocation: true` makes a skill explicit-only); Codex uses `/skills` (selector) or `$<skill-name>` (mention) — typed `/<skill-name>` is not a documented Codex form, and `allow_implicit_invocation: false` in `agents/openai.yaml` turns off description-matching; Hermes documents no typed invocation token, but Antigravity registers each skill as a typed `/<skill-name>` slash command in the TUI; community gajae-code is the odd one out — it uses a **colon** form, `/skill:<name>` (e.g. `/skill:deep-interview`), not `/<skill-name>`. Full source-cited table: `docs/compatibility-matrix.md` → **Skill Invocation**. For cross-engine commands, rely on description-triggered invocation as the portable layer and treat the typed token as per-engine sugar.4445## CLI Spawn And Headless Launch4647When one agent **spawns another** from a script, hook, or orchestrator, use the runtime's documented command for the mode you want — interactive and headless are reached differently. Full tables and citations live in `docs/cli-invocation.md`; resume is covered under **Session Resume** below.4849| Runtime | Interactive launch | Headless run |50|---|---|---|51| Codex | `codex` / `codex "<p>"` (optional `PROMPT` positional, per the CLI reference) | `codex exec "<p>"` |52| Claude Code | `claude` / `claude "<q>"` | `claude -p "<q>"` |53| Grok / xAI | `grok` | `grok -p "<p>"` |54| Hermes | `hermes chat` | `hermes chat -q "<q>"` |55| Antigravity CLI | `agy` | `agy -p "<p>"` (`--print`/`--prompt`; dedicated Headless-mode page) |56| Cursor CLI | `agent` (the docs now document `agent`; they do not state whether the older `cursor-agent` binary still works) | `agent -p "<p>"` |57| gajae-code (community) | `gjc` / `gjc --tmux` / `gjc --tmux --worktree <branch>` | not documented (the README dropped `--mode rpc`; external control is the broker-bound `gjc sdk session` CLI, or the Coordinator MCP bridge `gjc mcp-serve coordinator`) |5859- **The mode switch is not the same shape.** For Claude/Grok/Cursor/Hermes/Antigravity, headless is a **flag** (`-p`/`--print`, or Hermes `-q`) added to the bare interactive command — so interactive = omit the flag. **Codex** is the exception: headless is a separate **subcommand** (`codex exec`), with no print/headless `-p` to drop (Codex's `-p` *is* `--profile`, a config-profile selector — not a prompt flag, so "Codex has no `-p`" is wrong; it has no *headless* `-p`), so a list of only `codex exec …` is *not* "Codex is headless-only". **Antigravity** (`agy`) gained an officially documented headless mode (a dedicated "Headless mode" page at `/docs/cli/headless`): `agy -p/--print/--prompt` "sends a single prompt to the agent, streams or returns the response, and exits", with `--output-format text|json|stream-json`, `--json-schema`, `--model`, `--effort low|medium|high`, `--agent`, `--print-timeout` (default 5m), `--sandbox`, `--input-format text|stream-json` (prompts on stdin), and headless `-c`/`--conversation` resume — the previous "TUI-only, SDK for unattended runs" verdict is retired. With `--input-format stream-json` (which requires `--output-format stream-json`) `agy` becomes a **long-lived multi-turn process** driven over a pipe, one `result` event per turn, rather than a one-shot per prompt.60- Output format is not uniform: Codex `--json` (JSONL); Claude/Cursor/Antigravity `--output-format json|stream-json`; Grok `--output-format json`; Hermes documents **no** headless JSON flag.61- Gemini CLI is omitted: **as of 2026-06-18 it has stopped serving** AI Pro/Ultra and free individual users (replaced by Antigravity CLI, `agy`); enterprise/Google Cloud keeps Gemini CLI. See `docs/cli-invocation.md` → transition section.6263## Session Resume6465Same-platform resume (continue the *same* conversation on the *same* engine, by session id) is officially documented for all four worker runtimes. Per-engine resume invocation, session store, and id form live in `docs/compatibility-matrix.md` → **Session Resume**. The working model:6667- The minimum to continue is the **resume locator** (session/thread id) plus the engine's resume invocation: Claude `claude --resume <id>`, Codex CLI `codex resume <id>` (`codex fork [<id>|--last]` branches a past session into a **new** thread; desktop app-server: the `thread/resume` / `thread/fork` methods with the recorded `thread.id`), Grok `grok -r/--resume <id>` (with `--fork-session` to fork the resumed session into a new session id), Hermes `hermes --resume <id>`.68- Capture the locator **before the worker exits**, keyed by `cwd` (the most stable signal every engine exposes). Session stores differ — Claude/Codex/Grok keep per-session transcript/rollout files; **Hermes keeps history in SQLite `~/.hermes/state.db`**, so a file scan of `~/.hermes/sessions/` (which holds only API error dumps) finds nothing resumable.69- **Antigravity CLI** (`agy`, the Gemini CLI successor) resumes with `agy -c` / `agy --continue` (most recent in the workspace) or `agy --conversation <conversation-id>` — both now also documented to work in headless mode (`agy -p … --continue`); conversations are **workspace-scoped** (it lists only sessions started in that cwd). `-c` resolves through a documented workspace-keyed cache map, `~/.gemini/antigravity-cli/cache/last_conversations.json` — the one Antigravity session store the docs state.70- **gajae-code** documents **no CLI resume flag**; session ids exist only on the SDK path (allowlisted lifecycle ops `session.create`/`session.fork`/`session.resume`/`session.close` via `gjc sdk session raw`, plus `gjc sdk session tail <sessionId> --until-idle`). It persists per-session evidence under a project `.gjc/` dir and isolates work with git worktrees (`gjc --tmux --worktree <branch>`), but neither worktree isolation nor broker-bound external control is an interactive `--resume` — treat CLI resume as `not documented`.71- **Cross-engine moves** (resume one engine's session under a *different* engine) are a separate, harder problem and out of scope here — keep them off the same-platform path.72- When a runtime does not document resume, record `not documented` and require live verification before shipping.7374## Model Lineup7576Which models each runtime **currently ships** — the exact ids a caller selects today, their reasoning/effort tiers, and which models the vendor has **retired** — drifts on its own cadence (a new frontier model or a retirement lands independently of any skill/hook/CLI change). The detailed, source-cited record lives in `docs/models/` (one file per runtime, each with a `Last reviewed:` stamp and its official URL); this is the short working model:7778- **Claude / Claude Code** — current: Fable 5 (`claude-fable-5`), Opus 5 (`claude-opus-5`, "for complex agentic coding and enterprise work"), Sonnet 5 (`claude-sonnet-5`), Haiku 4.5 (`claude-haiku-4-5`, id `claude-haiku-4-5-20251001`). Legacy: Opus 4.8 (→ 5), Opus 4.7, and Sonnet 4.6 (→ 5); `claude-opus-4-1-20250805` retired 2026-08-05 with Opus 5 as the stated migration target. Reasoning is **adaptive thinking** on the current generation (Haiku 4.5: extended thinking); the `--effort` labels (`low`, `medium`, `high`, `xhigh`, `max`, `ultracode`) are a Claude Code caller-layer selector, not distinct vendor models. The Mythos pair (`claude-mythos-5`, `claude-mythos-preview`) is documented but invitation-only (not GA) — do not treat it as spawnable.79- **Codex** — current recommended family: `gpt-5.6` (the page shows the bare id only as a CLI example, not as a labelled default), with explicit Sol/Terra/Luna selectors `gpt-5.6-sol`, `gpt-5.6-terra`, and `gpt-5.6-luna`; `gpt-5.5` is previous-generation, `gpt-5.4` / `gpt-5.4-mini` remain under "Other models" but **retire from Codex on 2026-08-31** when signing in with ChatGPT (replace with `gpt-5.6-terra` / `gpt-5.6-luna`), and `gpt-5.3-codex-spark` is still a text-only research preview. `gpt-5.2` and `gpt-5.3-codex` are already deprecated. Reasoning effort is selected separately (Low through Ultra); `model_reasoning_effort` + `service_tier` stay config knobs.80- **Grok** — current flagship: `grok-4.6` (500k context; **configurable reasoning**), plus the Grok Voice API and Imagine image/video APIs. The Text API pricing table also lists `grok-4.5` (500k), `grok-4.3`, `grok-4.20-0309-reasoning`, `grok-4.20-0309-non-reasoning`, `grok-4.20-multi-agent-0309` (1M each), and `grok-build-0.1` (256k). The Voice API is no longer id-less: `grok-voice-think-fast-2.0` is current and `grok-voice-think-fast-1.0` is marked Deprecated. Effort is documented at **both layers**: the CLI reference lists `--effort <LEVEL>`, while the API reasoning page gives `grok-4.6` `low`/`medium`/`high`/`xhigh` (default `high`) and `grok-4.5` `low`/`medium`/`high` (default `high`); reasoning cannot be disabled. A dedicated retirement page exists (`/developers/migration/may-15-retirement`): eight ids retired 2026-05-15 with redirects (e.g. `grok-code-fast-1` → `grok-build-0.1`); see `docs/models/grok.md`.81- **Gemini-Antigravity** — provider-routed; ids verified against Google's official model page (<https://ai.google.dev/gemini-api/docs/models>, page last-updated 2026-08-14). **`gemini-3.7-flash` is the new Stable latest/capable Flash model** for complex coding, agentic workflows, and multi-step execution; `gemini-3.6-flash` remains Stable as the previous generation and the page's stable-id naming example, while `gemini-3.5-flash` is now labelled legacy. Stable `gemini-3.5-flash-lite` and preview ids (`gemini-3.1-pro-preview`, `gemini-3-flash-preview`, Antigravity Agent `antigravity-preview-05-2026`) remain. The CLI's `agy models` sample additionally surfaces `gemini-3.7-flash-high`, `gemini-3.7-flash-medium`, `gemini-3.6-flash-high`, `gemini-3.6-flash-medium`, `gemini-3.5-flash-medium`, `gemini-3.1-pro-high`, and `claude-sonnet-4-6` — CLI-surface slugs not on the API models page.82- **Hermes** — router-routed; ids seeded from downstream catalogs and `unverified this run` against the vendor page. Hermes selects **upstream** provider models rather than shipping its own.83- **Cursor** — mixed: it ships **Cursor-owned** models (Composer 2.5 and Cursor Grok 4.6 / 4.5 from Cursor and SpaceXAI; Composer 1 no longer appears) *and* routes to third-party families (Anthropic through Claude Fable 5/Opus 5, OpenAI, Google through Gemini 3.7 Flash, GLM 5.2, Kimi K2.7 Code/K3), with `Auto` as the default. Cursor Grok 4.6 supports `low`/`medium`/`high`/`xhigh` effort and a Fast tier, though the Start plan pins Grok 4.6 / 4.5 to a fixed medium effort in non-fast mode. `Auto` is still not a pricing-table row and has three documented modes — Auto Cost, Auto Balance, Auto Intelligence — with Cursor Router picking the model on Teams/Enterprise. It is not a pure router.8485**SSoT boundary — this folder does not own everything model-shaped.** It owns *current shipping ids + tiers + retirement status*, verified against each vendor's official model page. It does **not** own: **pricing/limits** (the `claude-api` skill and vendor pricing pages), the **Kuma Studio spawnable catalog** (`packages/shared/team.json` `modelCatalog` — a *downstream consumer* that syncs from these lineups, never the reverse), or **naming/phonetic-gloss standards** (the Kuma vault `domains/model-frontier.md`). Link to those; do not duplicate. When a value cannot be confirmed against the official doc in a run, mark it `unverified this run` and leave it for the next daily pass — never substitute a guess or a non-vendor mirror.8687## Project Instruction Files8889Do not assume every non-Claude runtime reads `AGENTS.md`. Use the officially documented project-instruction filename for the target runtime:9091| Runtime | Official project instruction/context files |92|---|---|93| Codex | `AGENTS.override.md`, `AGENTS.md`, then configured `project_doc_fallback_filenames` |94| Claude Code | `CLAUDE.md`, `.claude/CLAUDE.md`, `CLAUDE.local.md`, and `.claude/rules/`; Claude docs explicitly say Claude reads `CLAUDE.md`, not `AGENTS.md` |95| Grok / xAI | `AGENTS.md`, `Agents.md`, `AGENT.md`, `CLAUDE.md`, `Claude.md`, `CLAUDE.local.md`, plus `.grok/rules/` (and `.claude/rules/`, `.cursor/rules/` for compatibility); global rules in `~/.grok/`, then repo root down to cwd, deeper wins; `.gitignore`d files are skipped |96| Hermes Agent | `.hermes.md` / `HERMES.md`, then `AGENTS.override.md`, then `AGENTS.md`, then `CLAUDE.md`, then `.cursorrules` — one project context type loads per session on that first-match chain. `AGENTS.override.md` is a personal, per-directory override loaded instead of the committed `AGENTS.md` next to it (typically gitignored). `.cursor/rules/*.mdc` is a recognized file (CWD only) but is not part of the chain. `SOUL.md` is global identity, not project instructions |97| Antigravity CLI (was Gemini CLI) | Reads `GEMINI.md` and `AGENTS.md` (global `~/.gemini/GEMINI.md`); Gemini CLI's `GEMINI.md` hierarchical memory is the legacy form |98| Cursor CLI | `.cursor/rules`, plus project-root `AGENTS.md` and `CLAUDE.md` |99| Kuma Studio | `AGENTS.md` and `CLAUDE.md` are parallel repo SSoT files for shared rules |100| gajae-code (community) | not documented — README does not document an instruction-file loader (`AGENTS.md`/`CLAUDE.md`/`GEMINI.md`); it reports `.claude/skills/` and `.codex/skills/` as skill **import sources** (copy-in required before use), which is neither runtime skill loading nor instruction loading. User config is `~/.gjc/config.yml`, per-project state lives in `.gjc/` |101102Claude Code v2.1.213+ also documents `/import` for a **one-time conversion** from a supported coding agent: it appends instruction files such as `AGENTS.md` to the matching `CLAUDE.md` and carries over MCP servers, commands, subagents, and skills. This is migration, not a second live instruction source.103104For cross-agent repo rules, maintain the smallest set of files that each runtime actually reads. In Kuma-style Codex/Claude/Grok/Hermes repos, that usually means repo-owned `AGENTS.md` plus a `CLAUDE.md` import/symlink or Claude-specific wrapper; add `GEMINI.md` only when Antigravity CLI (or legacy Gemini CLI) is a supported runtime.105106**The filename is only half the contract — *loading mechanics* differ per engine** along two axes: ancestor walk-up (climb cwd → root, merging every file passed) and subdirectory discovery (nested files below cwd, loaded upfront vs on-demand). Full source-cited comparison: `docs/compatibility-matrix.md` → **Project Instruction File Loading**. The working model:107108- **Claude Code** loads ancestor `CLAUDE.md`/`CLAUDE.local.md` from cwd up to the filesystem root **in full at launch** (concatenated root → cwd, closer-to-cwd wins), and discovers nested subdirectory `CLAUDE.md` **on-demand** when it reads files there (not re-injected after `/compact` until that dir is touched again). So it is *not* "just root + cwd" — it is the whole ancestor chain eagerly plus the descendant tree lazily.109- **Codex** walks *root → down to cwd*, ≤ 1 file per dir, concatenated with closer files overriding, built **once per run** under a 32 KiB cap — and has **no subdirectory lookahead** (never reads below cwd).110- **Gemini / Antigravity** concatenates global + ancestor + the **entire subtree below cwd** into the prompt sent with **every request** (`.gitignore`-aware) — always in context, not lazy like Claude.111- **Hermes** picks **one project context type** by first match (`.hermes.md` → `AGENTS.override.md` → `AGENTS.md` → `CLAUDE.md` → `.cursorrules`; `.cursor/rules/*.mdc` is recognized but sits outside the documented priority chain) — but when that type is `AGENTS.md` and cwd is inside a git repo it now loads a **merged ancestor chain**: the git-root `AGENTS.md` first, then every intermediate directory down to cwd, each with a provenance header (`## ../../AGENTS.md`) and identical copies deduplicated, deeper files later so they take precedence. Outside a git repo only cwd is read, so a stray `AGENTS.md` in `$HOME` or `/tmp` cannot leak in. It also does on-demand discovery of the dir + 5 parents (each checked at most once per session) during file ops.112- **Grok** loads global `~/.grok/` rules, then **every** directory from the repo root down to cwd (cwd only outside a git repo), with **deeper files taking precedence on conflicts**. Unlike Hermes it does *not* stop at the first match — it reads **every** matching name in a directory, across a six-name family (`AGENTS.md`, `Agents.md`, `AGENT.md`, `CLAUDE.md`, `Claude.md`, `CLAUDE.local.md`) plus `.grok/rules/` (`.claude/rules/`, `.cursor/rules/` for compat). It is the one runtime that **honors `.gitignore` for rules**, which is what keeps `CLAUDE.local.md` personal and out of shared context. `grok inspect` lists what was discovered, with token counts.113- **Cursor** documents project-root `AGENTS.md`/`CLAUDE.md` only; tree-walk/merge is **not documented**.114115Implication for cross-engine repos: a module-specific instruction placed in a deep subdirectory is seen eagerly by Gemini, lazily by Claude/Hermes, and **never** by Codex (below cwd) — keep anything Codex must obey at or above the launch directory.116117**Symlink the wrapper, edit only the canonical file.** When `CLAUDE.md`/`GEMINI.md` are symlinks to a repo-owned `AGENTS.md`, reads resolve correctly — every runtime sees the canonical content, and git stores the link as mode `120000` (a pointer, not a copy; both links share one blob). But Claude Code's Edit/Write **refuses to write through a symlink** (`Refusing to write through symlink ... pass the real target path explicitly`, verified 2026-06-05), so edits must target the real `AGENTS.md`; treat the symlinks as read-only. This is a feature, not a limitation: it stops an atomic-save from silently swapping the link for a divergent regular file, so the SSoT cannot drift. Use **relative** symlinks (`ln -s AGENTS.md CLAUDE.md`, never an absolute path) so they survive clone/move. Caveat: a Windows checkout without `core.symlinks` materializes the link as a plain text file — use a one-line stub+pointer instead of a symlink when a Windows runtime is in scope.118119## Core Rules120121- Pick one canonical repo path first. Installed copies under `~/.claude/skills` and `~/.agents/skills` must be symlinks or generated config entries.122- **Registration goes through the umbrella manifest, `skills.json`, and nothing else.** In the `agent-extensions` umbrella, `skills.json` is the single record of *which* skill installs from *which* canonical path; `scripts/install/install-local.mjs` reads it and generates the symlinks into every engine's skill root. Adding a skill = adding one entry there, then re-running the installer. Do **not** register a skill by hand-symlinking it into an engine root or by adding an engine-config entry (e.g. Codex `~/.codex/config.toml` `[[skills.config]]`) — that is a second registration channel and it drifts. This skill states the *conventions*; `skills.json` is the *data* that applies them; the installer is what *executes* them.123- **A skill whose repo also builds artifacts must point its manifest `path` at the skill subfolder, not the repo root.** Runtimes scan the whole skill root recursively — Codex walks `~/.agents/skills` under a traversal budget and aborts with `skills scan reached its traversal limit` when one folder is oversized — so a repo root that carries a build cache (`target/`, `node_modules/`, `dist/`) gets swept into the scan and can starve discovery of *other* skills. Link the minimal skill folder inside the repo (`<repo>/skills/<name>/` or the runtime-native subpath) so the build tree stays outside the scan root; the repo itself, its build, and its upstream remote are untouched. Precedent: `kordoc` links `kordoc/plugins/kordoc/skills/kordoc/`, not its repo root. (This is a refinement of "one canonical repo path", not a `skills/` index in the umbrella root — that remains banned below.)124- Do not edit home-directory installed copies directly.125- Do not keep separate Claude and Codex versions unless a difference is explicitly documented and tested.126- Name the package layer explicitly before editing: skill-only, hook-only, plugin-like package, or generated runtime plugin. Do not let a `SKILL.md` entrypoint hide installer, hook, or trust-boundary changes.127- Keep `SKILL.md` body under 500 lines — a performance guideline, **not** a hard loading cap. Anthropic's [Skill authoring best practices](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices) say "Keep SKILL.md body under 500 lines for optimal performance": once loaded, every line competes with conversation history and other context. Put deterministic behavior in scripts; move scenario-specific detail into `reference/*.md` linked **one level deep** from `SKILL.md` (progressive disclosure).128- `name`: max 64 chars, lowercase/numbers/hyphens only, no XML tags, no reserved words (`anthropic`, `claude`); prefer gerund form (`processing-pdfs`). `description`: max 1024 chars, no XML tags, third person, stating both *what* the skill does and *when* to use it (trigger terms) — not the procedure.129- **Quote the `description` if it contains a colon-space (`: `), or the skill silently fails to load.** A `: ` in an unquoted YAML scalar is parsed as a nested mapping → `mapping values are not allowed in this context`. Common trap: `description: ... Korean triggers: 원샷, ...`. Wrap the whole value in single quotes (`description: '...'`); double inner single-quotes, double-quotes are fine inside. Validate frontmatter parses before shipping.130- Hooks are guardrails, not silent fallback paths. They should block clearly, explain why, and require an explicit operator decision for dangerous actions.131- **Do not re-implement a slash surface in a host layer above the engine.** A GUI/terminal wrapper that intercepts keystrokes to fake `/command` creates a second input path that must re-derive session context (current target resolution, ambiguity handling) the engine-side skill already has, and it standardizes on one invocation token where runtimes differ (Claude/Grok `/name` vs Codex `$name` — see Runtime Coverage above). Forward typed input to the engine verbatim and ship the capability as a skill + CLI; reserve host-level interception for things no engine surface can do.132- Cross-agent guidance must be based on official vendor docs. If a platform does not document a feature, record it as `not documented` or `unknown`; do not infer parity from another agent.133- **Make hook scripts executable (`chmod +x`) and give them a shebang.** Claude runs a hook in one of two documented forms: with `args` set the `command` is **spawned directly as an executable with no shell**; with `args` omitted the whole `command` string is **passed to a shell** (`sh -c`, Git Bash on Windows, or PowerShell). Either way the executable path itself must be runnable, so a missing exec bit fails with `Permission denied` on *every* matching event (PreToolUse/Stop) in *every* session — one forgotten `chmod +x` silently breaks all agents at once. Codex registers as `node <path>` so it tolerates a missing bit, but always `chmod +x` for parity and **commit the mode** (git stores `100755`). Use the `args` form on Claude when you want to avoid shell quoting entirely.134- **Hook scripts must not assume GNU coreutils.** macOS ships neither `timeout` nor `stat -c`; a hook that calls them unguarded fails on *every* macOS agent — and a fail-closed `|| exit 0` turns that into a silent no-op that looks like "working but quiet". Detect and degrade (`command -v timeout || gtimeout || plain`) and use portable forms (`stat -f %m || stat -c %Y`).135- **Keep history out of doc bodies.** Changelog narrative — what was added/changed/removed and when — lives in `CHANGELOG.md` plus the git tag (the version SSoT), never accreting in `SKILL.md` or `docs/*` prose. A doc body states the **current** truth only; when a fact changes, replace it, don't append the old one. The one exception is a *verification* stamp (`Last reviewed: YYYY-MM-DD`, `verified YYYY-MM-DD`): that is provenance for a live claim, not history. This is what keeps a daily-refreshed wiki from turning into a changelog as it is re-verified. **A freshness stamp must advance when the claim is re-verified, even if the wording is unchanged** — for a *time-sensitive status claim* (a status that can flip: billing paused/resumed/cancelled, an announced-but-not-yet-effective cutoff, any "currently X" status), re-confirming it on a new date *is* the update; a still-true status whose stamp is months old reads as wrong. A blanket "no content change → touch nothing" refresh rots exactly these claims, so carve them out.136137## Recommended Layout138139```text140agent-extensions/141 skills.json # the manifest: each skill's id -> canonical path (single registration record)142 scripts/install/install-local.mjs # reads skills.json, generates the engine-root symlinks143 scripts/test/*144 alex-core-invariants/ # standalone repo, own remote145 safedeps/ # standalone repo, own remote146 sprite-gen/ # standalone repo, own remote147 skill-hook-authoring/ # root-owned skill (these conventions)148 katok/ # standalone repo that ALSO builds a binary149 skills/katok/SKILL.md # skills.json path -> this subfolder, so target/ stays out of the scan root150 target/ # build cache (gitignored); never the link target151 ../my-agent-girlfriend/ # sibling repo installed via a `../` path (source owned by its own remote)152```153154Three layers, one direction: **conventions** (this skill) → **manifest** (`skills.json`) → **installer** (`install-local.mjs`) → generated symlinks. A canonical source may live outside the umbrella (a sibling repo); register it with a `../` path so `skills.json` stays the one registration record.155156Keep the umbrella flat. Do not add a repo-local `skills/` or `hooks/` index **in the umbrella root** unless there is a specific migration plan, because that creates a second registration source competing with `skills.json`. This is separate from a standalone repo's *own* internal `skills/` layout (e.g. `katok/skills/katok/`), which is that repo's upstream structure and a valid link target. If a hook belongs to a standalone repo, reference that repo path directly from the installer and agent config.157158## Authoring Flow159160Before adding or changing a package:1611621. Classify the change: skill instruction, hook guard, plugin/extension package, installer/config, or docs-only compatibility claim.1632. Pick the canonical package root and the generated install paths. For a repo that also builds artifacts, the registered `path` is the skill subfolder, not the repo root (see Core Rules).1643. Decide whether each installed artifact is a symlink, generated config entry, copied file, or runtime-native plugin package.1654. Update the canonical source first, then its entry in the umbrella manifest `skills.json` (which `install-local.mjs` reads), then docs. Do not add a second registration channel alongside it.1665. Validate discovery in every claimed runtime. For undocumented runtimes, mark support as unknown until live verification exists.167168Do not move a root-level `SKILL.md` into a plugin subdirectory, or convert a skill folder into a runtime plugin, unless the installer, docs, validation, and rollback path change in the same commit.169170## Disable / Scope / Retire171172Three operations, three mechanisms — disabling is **per engine** (Claude `skillOverrides`,173Grok `skills-disabled/`) and never touches `skills.json`; scoping to one engine is174`engines:` in the manifest and is a claim that the skill *cannot run* elsewhere; retiring is175the checklist below. Full decision table and per-engine mechanics:176[`docs/skill-lifecycle.md`](docs/skill-lifecycle.md).177178## Retiring Or Renaming Artifacts179180Deleting a hook, skill, command, or plugin-like package means removing every active ownership path, not just the visible file:1811821. Delete or rename the canonical source file/folder.1832. Remove active installer registration and generated config writes.1843. Remove active overlay/settings entries.1854. Add the old id/path/command to the relevant retired list so future installer runs clean existing symlinks or copies.1865. Remove live home-directory symlinks/copies if they are repo-owned.1876. Update docs and plans that describe the artifact in present tense.1887. Search repo and live config for the old id. Remaining hits should be retired lists or historical notes only.1898. Run syntax/config checks and prove the installer no longer recreates the retired artifact.1909. Sweep *instructions* that point at the old name, not just code: agent-executed191 docs (`AGENTS.md`/`CLAUDE.md`-class files, operating doctrine, skill bodies)192 referencing a renamed/retired CLI verb or moved doc path fail at runtime the193 moment an agent follows them. Concretely: grep doc corpora for backticked194 command mentions (e.g. launcher subcommands like `kuma <verb>`) and for195 relative links to the old path. Prefer a CI guard that re-checks this on196 every test run (kuma-studio: `docs-reference-integrity.test.mjs` — relative197 `.md` links must resolve; backticked launcher verbs must map to a real bin).198199This rule exists because deleting only `~/.claude/hooks/<id>` or only `scripts/hooks/<id>` can let the artifact reappear on the next setup run — and because instructions pointing at the old name keep *re-teaching* agents the broken path long after the code is gone.200201## Multi-Agent Compatibility Docs202203Use these repo documents before changing compatibility claims:204205- `docs/official-sources.json` — canonical source manifest for official docs refresh.206- `docs/compatibility-matrix.md` — current cross-agent support matrix (includes the Session Resume table).207- `docs/cli-invocation.md` — per-runtime CLI spawn (interactive vs headless) and resume invocation syntax.208- `docs/plugin-packaging.md` — plugin/extension packaging boundaries.209- `docs/completion-stack.md` — native completion/verification stacks (Claude Code `/goal` · Stop hook · `/verify`; Codex Goals · Stop hook · `/review`), enforcement grades, and verified misreading corrections.210- `docs/kuma-studio-patterns.md` — public Kuma Studio operating patterns that can be reused by other agents.211- `docs/cloud-automation.md` — daily cloud automation setup (Claude Routines, with a Codex App alternative).212213Daily refresh automation must read the source manifest, fetch only official URLs, update docs only when evidence changed, and leave a PR rather than pushing to `main`.214215## Cross-Agent Install Pattern2162171. Prefer repo-local skill roots when the runtime documents them (`.agents/skills/`, `.claude/skills/`, `.grok/skills/`, `.cursor/skills/`) and the workflow is project-specific.2182. Symlink user-wide canonical skill folders into the runtime's documented user skill root only when the workflow should apply outside one repo.2193. Patch project-local hook config for project guardrails; patch user-level hook config only for personal/global guardrails.2204. Backup mutated JSON config files before writing.2215. `chmod +x` every hook script before registering it (Claude either spawns the executable directly (`args` form) or passes `command` to a shell; either way no exec bit = `Permission denied` everywhere).2226. Validate by feeding representative JSON payloads into the hook scripts — and run the script **directly** (`./hook.cjs ...`, no `node` prefix) to catch a missing exec bit the way Claude would.223224## Hook Payload Pattern225226Claude Code and Codex CLI use the **same input schema** for `PreToolUse` / `PostToolUse` hooks. A Bash tool call arrives as:227228```json229{230 "session_id": "abc123",231 "prompt_id": "prompt_abc123",232 "transcript_path": "~/.claude/projects/.../transcript.jsonl",233 "cwd": "/Users/me/project",234 "permission_mode": "default",235 "hook_event_name": "PreToolUse",236 "tool_name": "Bash",237 "tool_use_id": "toolu_...",238 "tool_input": {239 "command": "npm install foo",240 "description": "Install foo",241 "timeout": 120000242 }243}244```245246Notes:247248- `tool_input.command` — the shell command. Use this single field; do not read from `.input.command`, `.arguments.command`, or other variants.249- `cwd`, `session_id`, `prompt_id`, `transcript_path`, `permission_mode`, `hook_event_name`, `tool_name`, `tool_use_id` are all **top-level**, not under `tool_input`. Reading `tool_input.cwd` returns nothing.250- `permission_mode` is one of `default`, `plan`, `acceptEdits`, `auto`, `dontAsk`, `bypassPermissions`.251- Both engines share this schema. Codex additionally provides `turn_id` and `model`.252253## Hook Decision Output254255Claude Code and Codex use the **same decision schema** for `PreToolUse`. Pick one of these to block:256257Modern (recommended):258259```json260{261 "hookSpecificOutput": {262 "hookEventName": "PreToolUse",263 "permissionDecision": "deny",264 "permissionDecisionReason": "safedeps: install not approved — run `safedeps check ...` first"265 }266}267```268269Legacy (still supported by both engines):270271```json272{"decision": "block", "reason": "safedeps: install not approved ..."}273```274275`permissionDecision` accepts `"allow" | "deny" | "ask" | "defer"` on Claude Code. Official Codex hooks docs document only `"allow"` and `"deny"` for `PreToolUse`, and `"defer"` is not documented for Codex at all. Codex parses several other 276277…(truncated)