CLAUDE.md · diff

git:20261104.52037ee to git:20261105.a0bb798

9 added, 5 removed. Audit A to A.

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## What this repo is
Bearpaws is an independent, low-token skills toolkit for AI coding agents, with a focus on portability, simplicity, and practical agent support.
- Claude Code and Google Antigravity IDE are the primary supported targets. OpenCode, Grok Build, and other Agent Skills agents (Codex, Devin, Cursor, Copilot, …) are experimental unless a specific workflow has been validated. Avoid adding language that implies ongoing upstream tracking, upstream behavioral parity, or guaranteed support across every agent.
+ Claude Code and Google Antigravity IDE are the primary supported targets. OpenCode, Grok Build, Junie, and other Agent Skills agents (Codex, Devin, Cursor, Copilot, …) are experimental unless a specific workflow has been validated. Avoid adding language that implies ongoing upstream tracking, upstream behavioral parity, or guaranteed support across every agent.
Skills cover TDD, debugging, planning, code review, and parallel execution, plus a stack-agnostic onboarding skill. The plugin's job is to get the `using-bearpaws` bootstrap into the agent context so the agent learns to discover and invoke the rest of the skills.
`AGENTS.md` is a symlink to this file, so Codex and other Agent Skills agents read the same guidance.
## Repository layout
- [skills/](skills/) — one directory per skill, each with a `SKILL.md` and optional `references/`, `examples/`, `scripts/`. Flat namespace.
- [commands/](commands/) — slash commands. The current files are deprecation shims pointing users at the equivalent skills.
- [agents/](agents/) — subagent definitions (e.g. `code-reviewer`).
- - [hooks/](hooks/) — `SessionStart` hook that injects the bootstrap for Claude Code plus detected SDK-style contexts (Cursor, Devin CLI, Copilot CLI, or unknown SDK callers); [tests/hooks/](tests/hooks/) pins each payload shape. `risk-gate` (PreToolUse/PostToolUse/Stop) enforces the risk receipt and the elevated-risk review in Claude Code only; [tests/hooks/run-risk-gate-tests.sh](tests/hooks/run-risk-gate-tests.sh) pins each rule. `git-commit-msg` is a git `commit-msg` hook (`install.sh --git`) that requires the same receipt in commit messages for any harness or person; it shares the receipt format with `risk-gate` through `lib-receipt`, and [tests/hooks/run-git-gate-tests.sh](tests/hooks/run-git-gate-tests.sh) pins each rule. `git-pre-push` (same install) flags commit emails that are not GitHub noreply or on the project's `Allowed commit emails:` line, once per branch. `hooks-cursor.json` is the Cursor hook config. Hook compatibility does not imply support-tier promotion.
+ - [hooks/](hooks/) — `SessionStart` hook that injects the bootstrap for Claude Code plus detected SDK-style contexts (Cursor, Devin CLI, Copilot CLI, or unknown SDK callers); [tests/hooks/](tests/hooks/) pins each payload shape. `risk-gate` (PreToolUse/PostToolUse/Stop) enforces the risk receipt and the elevated-risk review in Claude Code only; [tests/hooks/run-risk-gate-tests.sh](tests/hooks/run-risk-gate-tests.sh) pins each rule. `git-commit-msg` is a git `commit-msg` hook (`install.sh --git`) that requires the same receipt in commit messages for any harness or person; it shares the receipt format with `risk-gate` through `lib-receipt`, and [tests/hooks/run-git-gate-tests.sh](tests/hooks/run-git-gate-tests.sh) pins each rule. `git-pre-push` (same install) flags commit emails that are not GitHub noreply or on the project's `Allowed commit emails:` line, once per remote, branch and commit set. `hooks-cursor.json` is the Cursor hook config. Hook compatibility does not imply support-tier promotion.
- [.claude-plugin/](.claude-plugin/) — Claude Code plugin manifest and dev marketplace. Copilot CLI installs from the same marketplace; Devin falls back to this manifest.
- [.cursor-plugin/](.cursor-plugin/) — Cursor plugin manifest (skills + `hooks/hooks-cursor.json`).
- [.antigravity/](.antigravity/) — Google Antigravity IDE plugin manifest (`plugin.json`) and rules (`bearpaws.md`).
- [.devin/](.devin/) — Devin CLI `hooks.v1.json` (SessionStart hook). Skills come from `.agents/skills`.
- [.agents/skills](.agents/skills) — repo-level Agent Skills discovery: a real directory of per-skill links into `skills/` (Codex ignores a symlinked skills directory, so per-skill links; verified with Codex in a plain repo). The validator keeps it in sync; a new skill needs `ln -s ../../skills/<name> .agents/skills/<name>`. `install.sh --agents --global` links skills into `~/.agents/skills/` for Codex, Devin, OpenCode, Cursor, Copilot, and others; `install.sh --grok --global` adds a Grok Build bootstrap rule in `~/.grok/rules/`.
- [scripts/](scripts/) — version-bump tooling.
- [tests/antigravity/](tests/antigravity/) — static adapter tests for Antigravity plugin integrity.
- - [tests/install/](tests/install/) — installer tests for Antigravity, Agent Skills (`--agents`), and Grok (`--grok`).
+ - [tests/install/](tests/install/) — installer tests for Antigravity, Agent Skills (`--agents`), Grok (`--grok`), Junie (`--junie`), and the git gate (`--git`).
- [tests/bump-version/](tests/bump-version/) — version-bump tooling tests (version validation, declared fields only).
- [tests/hooks/](tests/hooks/) — SessionStart payload shape per harness, escaping, and loud failure; risk-gate and git-gate decisions per rule.
- [tests/harness-wiring/](tests/harness-wiring/) — model-free checks that Codex, OpenCode, Copilot CLI, and Grok Build load the installed skills and bootstrap.
- [tests/claude-code/](tests/claude-code/) — behavioral tests that shell out to the `claude` CLI.
- [tests/skill-triggering/](tests/skill-triggering/) — naive-prompt tests that verify skills auto-trigger.
- [tests/benchmark/](tests/benchmark/) — full-session benchmark; primary metric is cost per accepted task, scored by held-out acceptance tests.
- `tests/*-eval/`, [tests/codex/](tests/codex/) — RED/GREEN behavior evals for skill changes, and the Codex conformance smoke.
- [docs/skill-structure.md](docs/skill-structure.md) — descriptive contract for current skill shape.
- [docs/agent-support.md](docs/agent-support.md) — current support tiers and evidence by agent.
- [docs/bearpaws/release-notes/](docs/bearpaws/release-notes/) — release notes, starting with the v1.0.0 public baseline; new positioning changes belong in new release-note files, not retroactive edits to historical notes.
## Support posture
| Agent | Status | Evidence |
|---|---|---|
| Claude Code | Primary | Working |
| Google Antigravity IDE | Primary | Native plugin, skills, subagents, and capability adapter |
| OpenCode | Experimental | Wiring checked in CI: repo-level and global `.agents/skills` discovery, `instructions` bootstrap resolves; live bootstrap smoke-tested |
| Grok Build | Experimental | `./install.sh --grok --global`; `grok inspect` lists the bootstrap rule and all skills (1.0.45, built from source); no live session run |
+ | Junie | Experimental | `./install.sh --junie --global` links skills into `~/.junie/skills` and prints the `~/.junie/AGENTS.md` bootstrap line (installer tests in CI); in this repo Junie reads `AGENTS.md`; no live conformance run |
| Other Agent Skills agents (Codex, Devin, Cursor, Copilot, …) | Experimental | Codex skills and `AGENTS.md` bootstrap checked in CI, activation smoke-tested; Copilot CLI installs the plugin (CI); Devin and Cursor hook payloads follow their docs, unverified live. Expanded conformance requires completed-action evidence. |
## How the bootstrap works
### Claude Code and SDK callers
The plugin manifest [.claude-plugin/plugin.json](.claude-plugin/plugin.json) registers the [hooks/hooks.json](hooks/hooks.json) `SessionStart` hook (matchers: `startup|clear`). That hook calls [hooks/run-hook.cmd](hooks/run-hook.cmd) → [hooks/session-start](hooks/session-start), which:
1. Reads [skills/using-bearpaws/SKILL.md](skills/using-bearpaws/SKILL.md). Fails loudly (exit 1, stderr) if the file is missing/empty/unreadable rather than emitting a garbage bootstrap silently.
2. Wraps it in a `<warning level="hard">` block (per the current XML-like skill structure convention).
3. Emits JSON in the platform-appropriate shape — Claude Code: `{ "hookSpecificOutput": { "hookEventName": "SessionStart", "additionalContext": "..." } }`; Devin CLI (`DEVIN_PROJECT_DIR` or `DEVIN_PLUGIN_ROOT`): the same nested `hookSpecificOutput` shape; Cursor: top-level `additional_context`; Copilot CLI and unknown SDK-style callers: top-level `additionalContext`. [tests/hooks/run-hook-tests.sh](tests/hooks/run-hook-tests.sh) pins each shape.
The same `hooks/hooks.json` registers `risk-gate` on `PreToolUse` (Bash only, to baseline the work-tree fingerprint), `PostToolUse` and `Stop`. It keeps a per-session log of edits (and review dispatches) not yet accepted by a receipt under `${CLAUDE_PLUGIN_DATA}` (or `$TMPDIR`); a Stop that allows clears it, except that elevated work marked INCOMPLETE without a review, or with an open finding, stays pending, so a later reply with receipt lines is judged again (one with no Risk or Status line passes). Edits persist across turns, including background-agent report-backs. At Stop, it blocks a reply that edited files without a risk receipt, blocks elevated work marked COMPLETE without a review dispatched after the last edit (test-file edits included) or without an empty `Open:` line, blocks any COMPLETE reply whose `Open:` lists findings (unfixed Critical or Important findings force INCOMPLETE), and blocks a `Verified:` or `Pinned:` line that claims a test run the log does not show (after the last edit, or before the first). `session-start` adds a one-line `systemMessage` when the gate is inactive. It is a no-op outside Claude Code, without `jq`, or with `BEARPAWS_ENFORCE=0`. Edits made through Bash are detected in git repos by a tree fingerprint. Design: [docs/bearpaws/plans/2026-10-11-risk-gate-design.md](docs/bearpaws/plans/2026-10-11-risk-gate-design.md).
[hooks/run-hook.cmd](hooks/run-hook.cmd) is a bash/cmd polyglot so the same file works on macOS/Linux and Windows. Hook scripts under [hooks/](hooks/) are intentionally **extensionless** — Claude Code's Windows auto-detection prepends `bash` to anything ending in `.sh`, which would double-wrap the call.
If you change the bootstrap shape or the JSON output, run a fresh Claude Code session against this checkout (registered via `--plugin-dir` or the dev marketplace) and confirm the `using-bearpaws` content arrives in the first turn.
### Google Antigravity IDE
The Antigravity plugin manifest [.antigravity/plugin.json](.antigravity/plugin.json) and rule [.antigravity/rules/bearpaws.md](.antigravity/rules/bearpaws.md) import [skills/using-bearpaws/SKILL.md](skills/using-bearpaws/SKILL.md) and [skills/using-bearpaws/references/antigravity-tools.md](skills/using-bearpaws/references/antigravity-tools.md).
Installation copies real files (no symlinks) into `~/.gemini/config/plugins/bearpaws/`:
```bash
./install.sh --antigravity --global
```
Antigravity discovers skills natively from `skills/`, loads them on demand, maps actions to native capabilities via `antigravity-tools.md`, and runs isolated subagents via `invoke_subagent`.
### Other harnesses
- **Codex, OpenCode:** skills from `.agents/skills`; the bootstrap is a line the user adds (`~/.codex/AGENTS.md`, or `instructions` in `opencode.json`). The installer prints both and never edits agent config.
- **Grok Build:** ignores SessionStart hook output, so `install.sh --grok --global` writes an owned rule, `~/.grok/rules/bearpaws.md`, that Grok loads in every project. It refuses to overwrite a `bearpaws.md` it did not create.
+ - **Junie:** `install.sh --junie --global` links skills into `~/.junie/skills` (`$JUNIE_HOME` honored) and prints the bootstrap line for `~/.junie/AGENTS.md`; it never edits that file. In this repo Junie reads `AGENTS.md` as project guidelines.
- **Copilot CLI, Cursor, Devin CLI:** run `hooks/session-start` from their plugin or hook config and get the payload shape each documents (see the table in `tests/hooks/run-hook-tests.sh`).
`tests/harness-wiring/run.sh` proves discovery and bootstrap wiring without a model; behavior still needs live conformance (`tests/codex/run-conformance.sh`).
## Version management
The plugin version is duplicated across three manifest fields. They are kept in sync by [scripts/bump-version.sh](scripts/bump-version.sh), driven by [.version-bump.json](.version-bump.json):
```bash
scripts/bump-version.sh --check # report current versions, detect drift
scripts/bump-version.sh --audit # check + grep repo for stray version strings
scripts/bump-version.sh 0.2.0 # bump every declared file
```
Never hand-edit a version in one manifest — `--check` will flag the drift and `--audit` will surface any undeclared file that mentions the old version.
## Tests
```bash
tests/schema-validator/run-validator.sh # verify XML tag whitelist, Agent Skills frontmatter, .agents/skills links, and adversarial gates
- tests/install/run-install-tests.sh # verify Antigravity, --agents, --grok, and --git installer
+ tests/install/run-install-tests.sh # verify Antigravity, --agents, --grok, --junie, and --git installer
tests/hooks/run-hook-tests.sh # SessionStart payload shape per harness (no CLI)
tests/hooks/run-risk-gate-tests.sh # risk-gate decisions per rule (no CLI; needs jq)
tests/hooks/run-git-gate-tests.sh # git commit-msg and pre-push gate decisions per rule (no CLI, no jq)
tests/bump-version/run-tests.sh # bump-version.sh rejects malformed versions, writes only declared fields, audit excludes
tests/harness-wiring/run.sh # model-free discovery/bootstrap checks for installed codex, opencode, copilot, grok
tests/antigravity/run-adapter-tests.sh # verify Antigravity adapter static assertions
tests/token-measurement/measure.sh # bootstrap and skill-body byte counts (JSON)
python3 tests/codex/test_conformance.py # Codex conformance unit tests (no CLI)
python3 tests/benchmark/test_integrity.py # benchmark isolation and scoring tests
python3 tests/review-eval/test_render.py # review-eval renderer tests
python3 tests/review-eval/test_score.py # review-eval scorer tests (blocking sections, verdict line)
+ python3 tests/drift-eval/test_score.py # drift-eval scorer tests (only the Drift: block counts)
tests/claude-code/run-skill-tests.sh # fast Claude skill-content tests (~2 min)
tests/claude-code/run-skill-tests.sh --integration # full subagent-driven-dev run (10–30 min)
tests/claude-code/run-skill-tests.sh -t test-subagent-driven-development.sh # single test
bash tests/claude-code/test-native-plan-static.sh # native Plan Mode contract (static, no CLI)
tests/claude-code/run-skill-tests.sh --verbose # stream Claude output
tests/skill-triggering/run-all.sh # verify naive prompts trigger the right skill
tests/benchmark/run.sh # cost per accepted task: bearpaws vs no plugin (see tests/benchmark/README.md)
tests/review-eval/run.sh <template> <label> # reviewer catches planted defects; labels break attempts honestly
FIXTURE=traversal AGENT_PROMPT=agents/code-reviewer.md tests/review-eval/run.sh skills/requesting-code-review/code-reviewer.md <label> # reviewer approves a minimal correct fix (also FIXTURE=minimal|overbuilt)
tests/review-eval/routing.sh # SDD routes review by risk under pressure
tests/skill-triggering/routing/run.sh skills/using-bearpaws/SKILL.md <label> # bootstrap classifies scope and risk
tests/verification-eval/run.sh skills/verification-before-completion/SKILL.md <label> # weakened tests are caught
tests/risk-eval/run.sh skills/using-bearpaws/SKILL.md <label> # elevated-risk floor: pin behavior, narrow diff, assumptions
tests/resume-eval/run.sh skills/executing-plans/SKILL.md <label> # resume reconciles plan checkboxes with git
+ tests/drift-eval/run.sh skills/finishing-a-development-branch/SKILL.md <label> # finishing flags code that drifted from a checked-off plan (CLEAN=1: no-drift control)
tests/reuse-eval/run.sh <label> # routine feature: reuse an existing helper, no speculative guards (SKILL_ROOT=<checkout>)
tests/context-eval/run.sh <label> # controller passes onboarding facts to implementers
tests/codex/run-conformance.sh # Codex adapter conformance, repo-level (exit 2 = blocked, not failed)
GLOBAL=1 tests/codex/run-conformance.sh # same, against ./install.sh --agents --global + ~/.codex/AGENTS.md line
```
- CI ([.github/workflows/ci.yml](.github/workflows/ci.yml)) runs only the model-free checks: schema validator, token measurement, hooks (SessionStart, risk-gate and git gate), install, bump-version, Antigravity adapter, the Python unit tests, the native-plan static test, and harness-wiring. Everything that shells out to a model CLI is manual.
+ CI ([.github/workflows/ci.yml](.github/workflows/ci.yml)) runs only the model-free checks: schema validator, shellcheck (`-S warning` over the hook scripts except `run-hook.cmd`, `install.sh` and `scripts/*.sh`), token measurement, hooks (SessionStart, risk-gate and git gate), install, bump-version, Antigravity adapter, the Python unit tests, the native-plan static test, and harness-wiring. Everything that shells out to a model CLI is manual.
[tests/skill-triggering/run-test.sh](tests/skill-triggering/run-test.sh) parses `stream-json` output for `"name":"Skill"` plus a matching `"skill":"..."` value — that's how it decides a skill triggered. Logs land under `/tmp/bearpaws-tests/<timestamp>/`.
## When editing skills
Skills are behavior-shaping code, not prose. Use the `bp:writing-skills` skill — it applies TDD to skill content:
1. Run a baseline pressure scenario in a fresh subagent (RED).
2. Capture the exact rationalization the agent uses to skip the right behavior.
3. Write the minimum skill text that closes that loophole (GREEN).
4. Re-run the scenario in a fresh subagent and confirm compliance.
5. Probe for new rationalizations and repeat.
The Red Flags tables, rationalization lists, and the deliberate "your human partner" phrasing in existing skills are tuned content — change them only with eval evidence that the new wording works better, not because the prose reads cleaner.
## Skill structure
Each skill is a directory under [skills/](skills/) containing `SKILL.md` with YAML frontmatter:
```markdown
---
name: skill-name-with-hyphens
description: Use when [specific triggering conditions and symptoms]
---
```
Constraints worth knowing before editing frontmatter:
- `description` is third-person and describes **when** to use the skill, not what it does. The matcher uses it to decide whether to load.
- Frontmatter total ≤ 1024 chars; `name` is letters/numbers/hyphens only.
- Heavy reference material (>100 lines) and reusable scripts go in sibling files; keep `SKILL.md` focused on the rule.
See [docs/skill-structure.md](docs/skill-structure.md), [skills/writing-skills/SKILL.md](skills/writing-skills/SKILL.md), and [skills/writing-skills/anthropic-best-practices.md](skills/writing-skills/anthropic-best-practices.md) for the full conventions. All skill bodies use a compact XML-like structure — the validator at [tests/schema-validator/run-validator.sh](tests/schema-validator/run-validator.sh) enforces the tag whitelist, frontmatter spec, and `.agents/skills` layout on every commit.
## Commit conventions
Do not include `Co-Authored-By` lines or any AI/LLM attribution in commit messages. Commits should be clean with no co-author trailers.