Agent-facing rules for working on Coven Code. Mirrors and extends src-rust/.claude/CLAUDE.md; when the two disagree, the rule closer to the code wins.
- Keep answers short and concise
- No emojis in commits, issues, PR comments, or code
- No fluff or cheerful filler text
- Technical prose only, be kind but direct (e.g., "Thanks @user" not "Thanks so much @user!")
- When the user asks a question, answer it first before making edits or running implementation commands.
- Read files in full before making wide-ranging changes, before editing files you have not already fully inspected, and when the user asks you to investigate or audit something. Do not rely only on search snippets for broad changes.
- No
.unwrap()/.expect()on fallible operations in production paths — propagate viaResultor pattern-match.unwrapis acceptable in tests and in cases where the invariant is statically obvious and commented. - Avoid speculative
.clone()— borrow first, clone only when ownership is actually needed. Same applies to.to_string()on&str. - No
unsafeblocks without a// SAFETY:comment explaining the invariant. - Single-line helper functions with a single call site are forbidden; inline them instead.
- Don't guess external API shapes. Read the crate source under
~/.cargo/registry/or checkcargo doc --open. For Anthropic and Codex wire formats, thecrates/api/src/providers/<provider>.rsfiles are the authoritative reference inside this repo. - NEVER use type erasure to silence the compiler — no
Box<dyn Any>, noserde_json::Valueshoved through a typed boundary just because the right type is annoying to derive. If a type is hard to express, ask the user. - NEVER remove or downgrade code to fix compiler errors from outdated dependencies; bump the dependency in
Cargo.tomlorsrc-rust/Cargo.tomlworkspace deps instead. - Always ask before removing functionality or code that appears to be intentional.
- Do not preserve backward compatibility unless the user explicitly asks for it.
- Never hardcode keybinding checks inline (e.g.
key == KeyCode::Char('s') && mods.ctrl()). All keybindings must flow through the configurable keybinding system incrates/core/src/keybindings.rs— add a default there. - NEVER modify generated files directly. Generated artefacts in this repo:
src-rust/Cargo.lock— regenerated by cargo; for version bumps usescripts/bump-version.py.npm/package.jsonversionfield — also stamped bybump-version.py.
Run from src-rust/ unless noted.
- After Rust changes (not docs):
cargo check --workspace— fix every error and warning before committing. - Clippy:
cargo clippy --workspace --all-targets -- -D warnings. Fix lints; do not#[allow(...)]without justification. - Format:
cargo fmt --all. Run before committing. - Tests:
cargo test --workspacefor everything,cargo test --package claurst-<crate>for a single crate,cargo test --package claurst-<crate> -- <pattern>for a specific test. - Avoid running
cargo build --releaseorcargo run --releaseunless you specifically need optimised output — debug builds andcargo checkare 10× faster. - If you create or modify a test, run it and iterate until it passes.
- For TUI changes: validate by hand with
cargo run -- "test prompt"(interactive) orcargo run -- --print "test"(headless). The--printmode is faster for verifying non-TUI logic. - Don't run blocking interactive commands you can't exit — the agent will hang. If you must, capture output with
--printmode or pipe intohead.
The ratatui frontend is sensitive to terminal size and key encoding. For repeatable manual tests use tmux:
# Build a debug binary once
cargo build
# 80×24 session
tmux new-session -d -s coven-code-test -x 80 -y 24
tmux send-keys -t coven-code-test "./target/debug/coven-code" Enter
# Give it time to redraw, then capture
sleep 2 && tmux capture-pane -t coven-code-test -p
# Drive input
tmux send-keys -t coven-code-test "your prompt here" Enter
tmux send-keys -t coven-code-test Escape
tmux send-keys -t coven-code-test C-o # ctrl+o
# Cleanup
tmux kill-session -t coven-code-testOn Windows hosts, prefer cargo run -- --print "..." against the headless path. The Windows console has known quirks with the kitty keyboard protocol — see crates/tui for the push/pop workaround.
When posting issue/PR comments:
- Write the full comment to a temp file and use
gh issue comment --body-fileorgh pr comment --body-file. - Never pass multi-line markdown directly via
--bodyin shell commands. - Preview the exact comment text before posting.
- Post exactly one final comment unless the user explicitly asks for multiple comments.
- If a comment is malformed, delete it immediately, then post one corrected comment.
- Keep comments concise, technical, and in the user's tone.
When creating issues, add labels that map to the relevant crate(s) — for example crate:tui, crate:api, crate:tools, crate:mcp, crate:acp. If an issue spans multiple crates, add all relevant labels.
When closing issues via commit, include fixes #<number> or closes #<number> in the commit message — GitHub closes the issue automatically on merge to main.
Coven Code supports exactly two providers: Claude (Anthropic) and Codex
(OpenAI Codex via ChatGPT OAuth). The provider layer lives in
crates/api/src/providers/ (anthropic.rs, codex.rs) and is registered in
crates/api/src/registry.rs. Auth flows live in crates/core/src/oauth_config.rs,
codex_oauth.rs, and device_code.rs. Adding other providers is out of scope.
Coven Code uses a single workspace version stamped across every surface (Cargo workspace, Cargo.lock entries for the 12 claurst* crates (internal crate names, intentionally preserved), npm/package.json, README badge, docs, ACP registry template). Versioning is forward-only — the release workflow refuses to ship a tag less than or equal to the highest existing tag.
This repo runs parallel agents in worktrees under .claude/worktrees/. Multiple agents may be modifying different files in the same checkout simultaneously. You MUST follow these rules:
- ONLY commit files YOU changed in THIS session. Never commit unless the user has explicitly asked you to commit (see
src-rust/.claude/CLAUDE.md— the rule is "NEVER EVER commit"). - ALWAYS include
fixes #<number>orcloses #<number>in the commit message when there is a related issue or PR. - NEVER use
git add -Aorgit add .— these sweep up changes from other agents. - ALWAYS use
git add <specific-file-paths>listing only files you modified. - Before committing, run
git statusand verify you are only staging YOUR files. - Track which files you created/modified/deleted during the session.
- Cargo.lock counts as yours if and only if your edits to
Cargo.tomlcaused it to change.
These can destroy other agents' work:
git reset --hard— destroys uncommitted changesgit checkout ./git restore .— destroys uncommitted changesgit clean -fd— deletes untracked filesgit stash— stashes ALL changes including other agents' workgit add -A/git add .— stages other agents' uncommitted workgit commit --no-verify— bypasses required checks; never allowed- Force-push to
main— never allowed; the patch-release workflow is the only thing that may force-move tags, and it does so via the workflow runner, not from your shell
# 1. Check status
git status
# 2. Stage only your files
git add src-rust/crates/api/src/providers/foo.rs
git add docs/providers.md
# 3. Commit (only when the user has asked)
git commit -m "feat(api): add foo provider"
# 4. Push (pull --rebase if needed, but NEVER reset/checkout)
git pull --rebase && git push- Resolve conflicts in YOUR files only.
- If a conflict touches a file you didn't modify, abort the rebase and ask the user.
- NEVER force-push.
If the user's instructions conflict with the rules above, ask for confirmation that they want to override the rules. Only then execute their instructions.