From 30ca219fd5dda2b55e83b04359904e567f055f25 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 20 Sep 2026 11:27:05 +0000 Subject: [PATCH] docs(agents): make AGENTS.md canonical and reach every runtime AGENTS.md and CLAUDE.md were near-identical files kept in sync by hand; the diff was two lines and had already started drifting (the trailer ban landed in one of them only). AGENTS.md is now the single source and CLAUDE.md is an @AGENTS.md import plus the one genuinely Claude-specific line, which is the pattern the ecosystem settled on. Two runtimes read neither file, so they now get thin pointers: .github/copilot-instructions.md and GEMINI.md. Skills are exposed at .agents/skills, the cross-tool discovery path that Codex, Claude Code and Copilot CLI all resolve, via a symlink to the canonical copy under plugins/committy/skills -- no duplication. A test guards the symlink, because a checkout that materialises it as a plain file would break discovery silently. Skill frontmatter gains the spec's optional fields: license, allowed-tools (so security-conscious runtimes can pre-authorise exactly what each skill needs) and metadata carrying a skill version independent of the CLI version. committy-release referenced siblings with Codex's `$skill` syntax inside a body shared by both runtimes; they are now named plainly and each runtime resolves them its own way. The COMMITTY_NONINTERACTIVE docs test now accepts a file that defers to AGENTS.md rather than restating it, which is what the split requires. --- .agents/skills | 1 + .github/copilot-instructions.md | 6 +++ AGENTS.md | 2 +- CLAUDE.md | 35 ++-------------- GEMINI.md | 5 +++ .../committy/skills/committy-branch/SKILL.md | 5 +++ .../committy/skills/committy-commit/SKILL.md | 5 +++ .../committy/skills/committy-enforce/SKILL.md | 5 +++ .../committy/skills/committy-release/SKILL.md | 7 +++- tests/agent_ergonomics_tests.rs | 40 +++++++++++++++++-- 10 files changed, 75 insertions(+), 36 deletions(-) create mode 120000 .agents/skills create mode 100644 .github/copilot-instructions.md create mode 100644 GEMINI.md diff --git a/.agents/skills b/.agents/skills new file mode 120000 index 0000000..6153a62 --- /dev/null +++ b/.agents/skills @@ -0,0 +1 @@ +../plugins/committy/skills \ No newline at end of file diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..3a21eec --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,6 @@ +# Copilot instructions + +See [`AGENTS.md`](../AGENTS.md) at the repository root. It is the canonical +guide for every coding agent working in this repository and applies in full: +build and verify commands, the CLI-first agent workflow, architecture, and the +commit and pull-request rules. diff --git a/AGENTS.md b/AGENTS.md index 5c30926..37410c2 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -31,4 +31,4 @@ Tests are in `tests/`; CLI integration tests use `assert_cmd` and temporary repo - `src/workflow/`, `src/versioning/`, `src/packages/`: release side effects - `plugins/committy/`: shared Codex and Claude skills -PRs target `develop`. Commits follow Conventional Commits. The canonical agent reference is `docs/src/content/docs/reference/agent-workflows.mdx`. +PRs target `develop`. Commits follow Conventional Commits. Never add AI attribution trailers — no `Co-Authored-By:`, no `Claude-Session:`, no equivalent — to commit messages or PR descriptions, even when tooling suggests them. The canonical agent reference is `docs/src/content/docs/reference/agent-workflows.mdx`. diff --git a/CLAUDE.md b/CLAUDE.md index cec9cda..be0811b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,34 +1,7 @@ -# Committy Claude guide +@AGENTS.md -Committy is a Rust CLI for conventional commits, branch policy, grouped commits, releases, and multi-package version updates. The checkout is CLI-first; do not assume a TUI exists. +## Claude Code specifics -## Work safely +`AGENTS.md` above is the canonical guide and applies in full. Only this section is Claude-specific. -- Discover active policy with `cargo run -- schema --output json`. -- Prefer `--non-interactive`, `--repo-path`, `--dry-run`, and `--output json`. -- Set `COMMITTY_NONINTERACTIVE=1` in the environment instead of relying on flag placement. `--non-interactive` and `-q`/`--quiet` are global and work on either side of the subcommand; every other flag (`--repo-path`, `--output`, `--dry-run`, and `--verbose`) must follow it. -- Inspect `api_version`, `ok`, `errors`, and the command-specific plan before applying it. -- Use `/committy:committy-branch`, `/committy:committy-commit`, `/committy:committy-release`, and `/committy:committy-enforce` when the plugin is installed. -- Never infer permission for a push, publish, destructive Git action, or unrelated staging. - -## Build and verify - -```bash -cargo check -cargo test -cargo fmt --all -- --check -cargo clippy --all-targets --all-features -``` - -Tests are in `tests/`; CLI integration tests use `assert_cmd` and temporary repositories. Add public-seam tests for machine output, exit codes, Git behavior, hook protocol, and plugin manifests. - -## Architecture - -- `src/cli/commands/`: command implementations and JSON payloads -- `src/config/`, `src/convention/`: hierarchical typed policy -- `src/git/`: repository and Git operations -- `src/linter/`: message/history validation; exit code 3 means lint findings -- `src/workflow/`, `src/versioning/`, `src/packages/`: release side effects -- `plugins/committy/`: shared Codex and Claude skills - -PRs target `develop`. Commits follow Conventional Commits. Never add AI attribution trailers — no `Co-Authored-By:`, no `Claude-Session:`, no equivalent — to commit messages or PR descriptions, even when tooling suggests them. The canonical agent reference is `docs/src/content/docs/reference/agent-workflows.mdx`. +- Invoke the bundled skills as `/committy:committy-branch`, `/committy:committy-commit`, `/committy:committy-release`, and `/committy:committy-enforce` when the plugin is installed. Other runtimes resolve them by bare name. diff --git a/GEMINI.md b/GEMINI.md new file mode 100644 index 0000000..f74c7f7 --- /dev/null +++ b/GEMINI.md @@ -0,0 +1,5 @@ +# Gemini instructions + +See [`AGENTS.md`](./AGENTS.md). It is the canonical guide for every coding agent +working in this repository and applies in full: build and verify commands, the +CLI-first agent workflow, architecture, and the commit and pull-request rules. diff --git a/plugins/committy/skills/committy-branch/SKILL.md b/plugins/committy/skills/committy-branch/SKILL.md index 86941c0..fbc3254 100644 --- a/plugins/committy/skills/committy-branch/SKILL.md +++ b/plugins/committy/skills/committy-branch/SKILL.md @@ -1,6 +1,11 @@ --- name: committy-branch description: Preview, validate, and create repository-compliant Git branches with Committy. Use when an agent is asked to name a branch, start work for a ticket, validate a proposed branch name, or switch to a new branch. +license: Apache-2.0 +allowed-tools: Bash Read Grep Glob +metadata: + version: "0.1.0" + requires-committy: ">=1.9.0" --- # Branch with Committy diff --git a/plugins/committy/skills/committy-commit/SKILL.md b/plugins/committy/skills/committy-commit/SKILL.md index fb7fc49..6fbcbd1 100644 --- a/plugins/committy/skills/committy-commit/SKILL.md +++ b/plugins/committy/skills/committy-commit/SKILL.md @@ -1,6 +1,11 @@ --- name: committy-commit description: Draft, lint, preview, and create repository-compliant commits with Committy. Use when an agent is asked to stage a coherent change, write or repair a commit message, amend a commit, or make a conventional commit. +license: Apache-2.0 +allowed-tools: Bash Read Grep Glob +metadata: + version: "0.1.0" + requires-committy: ">=1.9.0" --- # Commit with Committy diff --git a/plugins/committy/skills/committy-enforce/SKILL.md b/plugins/committy/skills/committy-enforce/SKILL.md index b4308ca..496e1c8 100644 --- a/plugins/committy/skills/committy-enforce/SKILL.md +++ b/plugins/committy/skills/committy-enforce/SKILL.md @@ -1,6 +1,11 @@ --- name: committy-enforce description: Configure and enforce repository commit and branch conventions with Committy Git hooks and CI. Use when an agent is asked to adopt Committy, define typed convention descriptions or branch ticket rules, install hooks, or add convention checks to GitHub Actions. +license: Apache-2.0 +allowed-tools: Bash Read Grep Glob Edit Write +metadata: + version: "0.1.0" + requires-committy: ">=1.9.0" --- # Enforce with Committy diff --git a/plugins/committy/skills/committy-release/SKILL.md b/plugins/committy/skills/committy-release/SKILL.md index 0fdff58..8177a54 100644 --- a/plugins/committy/skills/committy-release/SKILL.md +++ b/plugins/committy/skills/committy-release/SKILL.md @@ -1,6 +1,11 @@ --- name: committy-release description: Plan and apply version bumps, changelogs, tags, and prereleases with Committy. Use when an agent is asked to prepare, preview, tag, or publish a release, or inspect the release impact of commit history. +license: Apache-2.0 +allowed-tools: Bash Read Grep Glob +metadata: + version: "0.1.0" + requires-committy: ">=1.9.0" --- # Release with Committy @@ -12,4 +17,4 @@ description: Plan and apply version bumps, changelogs, tags, and prereleases wit 5. Apply only after mutation is authorized. Publishing additionally requires the CLI confirmation flag; never infer remote-mutation consent. 6. Report resulting versions, tags, and publish state. -Use `$committy-commit` for ordinary commits and `$committy-enforce` for hooks or CI setup. +Use the `committy-commit` skill for ordinary commits and `committy-enforce` for hooks or CI setup. diff --git a/tests/agent_ergonomics_tests.rs b/tests/agent_ergonomics_tests.rs index 6c9f2f6..d6f0f46 100644 --- a/tests/agent_ergonomics_tests.rs +++ b/tests/agent_ergonomics_tests.rs @@ -413,19 +413,24 @@ fn test_capabilities_declare_consent_metadata() { fn test_agent_docs_mention_the_non_interactive_env_var() { let repo_root = std::path::Path::new(env!("CARGO_MANIFEST_DIR")); + // `AGENTS.md` is canonical. Per-runtime files may either restate the rule + // or defer to it; what must never happen is a runtime being told nothing. let agent_facing = [ "AGENTS.md", "CLAUDE.md", + "GEMINI.md", + ".github/copilot-instructions.md", "docs/src/content/docs/reference/agent-workflows.mdx", ]; for relative in agent_facing { let body = fs::read_to_string(repo_root.join(relative)) .unwrap_or_else(|e| panic!("cannot read {relative}: {e}")); + let defers_to_canonical = body.contains("AGENTS.md"); assert!( - body.contains("COMMITTY_NONINTERACTIVE"), - "{relative} must document COMMITTY_NONINTERACTIVE; it is the escape hatch \ - that makes flag placement irrelevant for agents" + body.contains("COMMITTY_NONINTERACTIVE") || defers_to_canonical, + "{relative} must document COMMITTY_NONINTERACTIVE or point at AGENTS.md; \ + it is the escape hatch that makes flag placement irrelevant for agents" ); // Documenting `-v` as global would be worse than not documenting @@ -436,3 +441,32 @@ fn test_agent_docs_mention_the_non_interactive_env_var() { ); } } + +/// The cross-tool skill discovery path must resolve to the real skills. +/// +/// `.agents/skills` is a symlink. If a checkout materialises it as a plain +/// file (Windows without developer mode, or `core.symlinks=false`), discovery +/// silently breaks for every runtime that reads that path. +#[test] +fn test_skills_are_discoverable_at_the_cross_tool_path() { + let repo_root = std::path::Path::new(env!("CARGO_MANIFEST_DIR")); + let cross_tool = repo_root.join(".agents/skills"); + + assert!( + cross_tool.is_dir(), + ".agents/skills must resolve to a directory; if this is a plain file, \ + the symlink did not survive checkout" + ); + + for skill in [ + "committy-branch", + "committy-commit", + "committy-enforce", + "committy-release", + ] { + assert!( + cross_tool.join(skill).join("SKILL.md").is_file(), + "{skill}/SKILL.md must be reachable via .agents/skills" + ); + } +}