AGENTS.md · git:20260905.5296a02 · 2026-09-05 · sha256 b6030293cd02b4ac
AGENTS.md git:20260905.5296a02A
Immutable. This exact content is served forever at /api/v1/blob/b6030293cd02b4ac.
# Repository contract ## Repository file Edit `AGENTS.md`, never `CLAUDE.md`. `CLAUDE.md` is a symlink, so replacing it forks the two files. ## Canonical baseline Make every persona or doctrine change in `system-prompt-baseline.md`; it is the only source of truth. The Claude Code loader resolves no references, so each of the six output styles under `plugins/odin-core/output-styles/` embeds the full baseline as its tail, byte-identical from its second `<role>` through EOF. The generator owns that tail; never hand-propagate it: 1. Edit `system-prompt-baseline.md` without changing an output style below its charter `<role>`. 2. Run `python3 scripts/sync-baseline.py`. It replaces each style from its second `<role>` through EOF and preserves the persona preamble above it. 3. Run `python3 scripts/sync-baseline.py --check`. Exit 0 means all styles match; exit 1 names drifted files; exit 2 means the canonical file or a required two-`<role>` layout is missing. 4. Stage and commit the canonical file and all six styles together. Never hand-edit `plugins/odin-core/output-styles/benchmark.md`. Its margin-runner v0.5.5 header marks it as generated. The baseline generator may change only the embedded cascade below the runner preamble; a hand edit above that region requires explicit user authorization. ## Submodule publishing Commit and push from this repository, not its parent `~/.claude`, because this tree is a Git submodule. This checkout's `.git` is an unwritable submodule pointer, so git operations must run in a clone inside `.outline/worktree/<name>`, never in `/tmp`, where work is easily lost. Never force-push, and that includes every `--force-with-lease` variant: a lease protects the remote from a stale overwrite and protects nothing from a rewrite you intended. On a branch with an open pull request, rewriting history strands every inline review comment on commits that no longer exist, and no permission error tells you that. If a push is rejected as non-fast-forward, the answer is to fetch and rebase or to ask, never to reach for a force variant. ## The skill tree A skill is authored once, at `plugins/<plugin>/skills/<slug>/SKILL.md`. That path is its only home, and the directory states which plugin owns the skill. Do not add a membership registry, a second skill tree, or a per-plugin copy: the earlier model kept all three in sync and each one drifted. Adding a skill means creating `plugins/<plugin>/skills/<slug>/SKILL.md` and running `just render`. Moving a skill between plugins means moving its directory. Nothing else records membership. For a batch of moves, or for creating, merging, or retiring a plugin, run the `retaxonomize-plugins` skill; it rewrites `catalog/plugins.json`, replaces retired ids in authored files, regenerates, and proves the gates. Each harness reads the immediate children of `skills/`, so a skill nested deeper than `skills/<slug>/` never loads. ## Distribution surfaces Five harness surfaces are supported, and no others: Claude Code, Codex, Cursor, Grok, and Kimi. Nothing is published to a package registry, and no npm artifact belongs in this tree. A flat Devin mirror of these same skills is exported to the outline repository, which publishes nothing and installs nothing. `catalog/plugins.json` owns plugin identity: name, description, category, tags, and directory. Every manifest and registry is generated from it. Keep every plugin and marketplace version at the single `releaseVersion` literal `2.1.0`; never bump only some manifests. Treat these as generator-owned and never hand-edit them: - `plugins/*/.claude-plugin/plugin.json`, `plugins/*/.codex-plugin/plugin.json`, `plugins/*/.cursor-plugin/plugin.json`, `plugins/*/.grok-plugin/plugin.json`, `plugins/*/.kimi-plugin/plugin.json`, `plugins/*/README.md`, `plugins/*/LICENSE`, `plugins/*/NOTICE` - `.claude-plugin/marketplace.json`, `.codex-plugin/marketplace.json`, `.cursor-plugin/marketplace.json`, `.grok-plugin/marketplace.json`, `.kimi-plugin/marketplace.json` - `plugins/*/skills/*/agents/openai.yaml` - the plugin table under `## Plugins` in the root `README.md`, and nothing else in that file - `docs/specs/skill-index.md` To change one, change its generator or `catalog/plugins.json`, run `just render`, and commit input and output together. Each harness dotdir manifest declares only what its own defaults do not already resolve: Kimi needs `skills`, and Codex and Grok need `mcpServers` where a plugin ships the dotless `mcp.json`. Do not add component declarations a harness resolves by convention. Bump `releaseVersion` by one patch (`+0.0.1`) for every change that ships a skill, output style, manifest, or attribution; bump the minor version only on explicit request. Three authored copies carry the literal, and the bump commit updates all three: `catalog/plugins.json`, the literal in this file, and the sentence under the skill count in the root `README.md`. Run `just render` and commit the catalog with its generated output. Do not change `releaseVersion` for tooling-only changes such as pre-commit hooks or formatter configuration, or for edits to this file alone. Do not add or backfill `CHANGELOG.md` entries for routine version work; a bump that ships a skill or behavior change gets one entry. A plugin id names a job someone is doing or a stack they are working in. A tier suffix such as `-advanced` is not a job, and a grab-bag id that collects whatever fits is not one either; split by job instead. `scripts/check-plugin-surfaces.mjs` rejects a tier-suffixed id, so the rule fails a commit rather than a review. ## Devin skill mirror The outline repository carries a flat copy of every skill at `.devin/skills/<slug>/`, the project-scope path Devin reads. `scripts/sync-outline-skills.mjs` generates it from this tree, so it is an export of the same skills rather than a sixth distribution surface. Regenerate it with `just sync-outline`. The default target is the sibling checkout `../outline-driven-development`, resolved from this tree's own parent directory, so from a clone under `.outline/worktree/` it points at a directory that does not exist; pass `--target <path-of-the-real-outline-checkout>` there. The script mirrors exactly the files git tracks under each skill directory, prunes anything under `.devin/skills/` that the plugin tree no longer carries, and refuses a target that does not hold both `manifest.json` and `.git`. Never hand-edit the mirror. Edit the skill under `plugins/<plugin>/skills/<slug>/` and resync, because the next run reverts an edit made in the mirror. A skill whose `SKILL.md` is untracked is a sync error, not a skip. Add the file to git first. The mirror lives in another repository with its own history, so commit it there, in its own commit, and never from this repository. ## Skill metadata Frontmatter carries `name` and `description` and little else. `name` must equal the directory name, or `gh skill install` drops the skill. `description` must open with a trigger a model can route on; `scripts/check-skill-routes.mjs` accepts `Use when ` and its listed variants and rejects `Use when,` or a bare imperative, and its first sentence becomes the generated `short_description`. Single-quote every frontmatter value containing `: `. Strict YAML parsers reject an unquoted colon-space even though Claude Code's loader accepts it, so it ships silently broken. Do not add a `license` field to a skill. This tree has mixed provenance and attribution lives in `licenses/NOTICE`; a uniform value would misstate the provenance of adapted skills. ## Verification Before a commit, run `just check`; it runs every hook in `.pre-commit-config.yaml` over the whole tree (`prek run --all-files`) and can repair the style cascade, so read `git status` afterwards. `just verify` adds `gh skill publish --dry-run`, which validates all 605 skills against the Agent Skills specification; its `recommended field missing: license` advisories are accepted, not fixed. Do not invent language test commands or add CI without an explicit request; this repository has no build, no unit-test suite, and no GitHub Actions workflow. Test persona or doctrine changes in a fresh Claude Code session. The canonical baseline and output styles load only at session start, so the current session cannot verify them. ## Prompt audit Run the `prompt-optimizer` skill in audit mode when a prompt, skill, output style, or tool description changes behavior, and again at each model release. Publish its report and proposed diff. Apply only high- and medium-confidence hunks with explicit consent, and leave low-confidence and flagged items in the report. Ground every prompting claim in a current vendor guide. Re-fetch the guides in `plugins/odin-skills/skills/prompt-optimizer/references/prompt-guides.md` before an audit run, at each model release, and whenever a row is older than one release cycle. Update the index in the same change: stamp each re-read row `Verified <ISO date>`, move a superseded guide to the legacy-avoid rows and name its successor, and add the new model's guide as a current row. A claim whose row is stale is unverified: report it and keep it out of any applied diff. ## External harness carriers Propagate every shared doctrine change to `~/.codex/AGENTS.md` and `~/.omp/agent/AGENTS.md` with `just sync-carriers`, and prove it with `just sync-carriers-check` (`scripts/check-carriers.py` is the same gate as a pre-commit hook). The baseline generator does not touch these carriers. Each carrier holds every shared section of the baseline byte for byte, `<change_discipline>` included. The four tool-layer sections, `<git>`, `<directives>`, `<code_tools>`, and `<thinking>`, differ by design and are compared for presence only: Codex shells out through `rtk`; omp and Claude Code provide native file tools. Edit both carriers in place. Never commit them from this repository, and never stage `~/.codex/config.toml`; their owning repositories live outside this submodule. ## Writing style Write content under this tree so each section is independently actionable: state a needed rule where the reader needs it, and let no sentence send the reader back to an earlier passage for it. Prefer a short repeated rule to a decorative inter-file pointer. Use a cross-reference only when the target itself is required for correct behavior, such as the byte-identical canonical baseline span. ## Voice Every skill in this tree is authored in one register, set by the ODIN doctrine in `system-prompt-baseline.md` and the spine taste anchors. `docs/specs/voice.md` is the contract. The spine itself is user-private, at `~/.claude/skills/spine/`. Read it when authoring; never edit it from this repository, and never vendor a copy into this tree. `docs/specs/voice.md` carries what an editor needs without loading it. Passing `scripts/check-voice.py` is not passing the register. That script sees formatting tells, not absent conviction; whether a section earns its place is the spine audit's judgment, not a regular expression's.