Workflow rules for AI coding agents (Claude Code, Cursor, Aider, etc.) working
in this repo. These are about process, not code style — for code style see
internal/ENGINEERING_STANDARDS.md and internal/ENGINEERING_BEST_PRACTICES.md.
- Read the section of
internal/PLAN.mdthat covers what you're about to do. Don't work ahead — the plan is sequenced for a reason (earlier modules are dependencies of later ones, and earlier modules are easier to verify in isolation). - Re-read
internal/ENGINEERING_STANDARDS.mdif it's been more than a few tasks since you last did. The dependency policy in particular is easy to forget. - Check the existing code for prior art. If a similar pattern already exists in the repo, follow it. Consistency beats cleverness.
Act without asking when:
- The task is mechanical (rename, refactor with no semantic change, fix a clippy warning, add a missing test).
- The plan or standards docs unambiguously specify what to do.
- You're exploring with read-only tools (running
cargo check, reading files, running tests).
Ask before acting when:
- The task requires adding a new dependency. (Standards doc requires human approval; do not skip this.)
- The task seems to require
unsafecode. Propose the design first. - You discover a discrepancy between the plan and what the code needs. Don't silently "fix" the plan; flag it.
- You're about to make a change >300 lines or touching >5 files in one commit. Propose the breakdown first.
- The user's request seems to conflict with a standards doc rule. Ask which wins; don't guess.
Never do without asking:
- Add a runtime dependency not on the allowlist.
- Introduce
asyncruntimes other than the one chosen in the plan. - Reformat or "clean up" files unrelated to your task.
- Commit changes to
internal/PLAN.mdorinternal/ENGINEERING_STANDARDS.md. These are human-curated.
- One logical change per commit. "Add ranged downloader + add tests for it" is one commit. "Add ranged downloader + refactor error types" is two.
- Commit message format: imperative subject ≤72 chars, blank line, body
explaining why (not what — the diff shows what). Reference the plan
section when relevant:
Implements PLAN.md §3.2. - Run
cargo fmt && cargo clippy -- -D warnings && cargo testbefore every commit. If any of those fail, the commit is not ready. - Never commit
target/,.env, or files in.gitignore. Never commit generated test fixtures larger than a few KB; generate them in the test.
Stuck = you've tried two reasonable approaches and neither works, OR you're about to do something that contradicts a standards doc rule, OR you're guessing at API behavior.
Do not:
- Add
#[allow(dead_code)]or#[allow(clippy::...)]to make warnings go away. Fix the underlying issue or ask. - Add a dependency to "make it work" (see Dependency Policy).
- Stub out functionality with
todo!()and pretend the task is done.todo!()is fine as a deliberate placeholder when the plan says "implement this in the next task," but call it out in your response. - Disable failing tests. If a test is wrong, fix the test. If the code is wrong, fix the code. If you can't tell which, ask.
Do:
- Summarize what you've tried and what failed.
- Quote the relevant docs sections that constrain the solution.
- Propose 2-3 paths forward with tradeoffs.
- Wait for direction.
- Tests are not optional. Every public function gets a unit test; every module gets at least one integration test exercising its public API.
- A bug fix without a regression test reproducing the bug is incomplete.
- If the existing tests don't catch a class of bugs you're worried about,
add property tests or fuzz targets. See
ENGINEERING_BEST_PRACTICES.md§Testing for the patterns we use. cargo testmust pass on every commit.cargo test --releaseand any--ignoredlong-running tests must pass before merging a plan section.
The RAR3 and RAR5 decoders are clean-room implementations. peel
is licensed MIT OR Apache-2.0; the unRAR license is non-OSI and
GPL-incompatible, so even reading the unrar source would
contaminate the derivation. This is a hard rule, not an "ask first"
rule.
- Do not read, copy, paraphrase, or port from RARLAB's
unrar— source, comments, identifiers, table contents, magic constants. Don't open the tree. libarchive's RAR readers (LGPL-2.1, OSI) may be referenced as an external spec when the wire format requires one — read, not vendored or linked. Cite the file/section in your commit message or the relevantPLAN_rar*.mdplan when you do.- Test fixtures are produced with a license-purchased copy of
RARLAB's
rarencoder. Theunrarbinary is a benchmark comparator only, never an implementation reference.
This rule binds all future RAR work — new phases, follow-ons,
optimisation passes, bug fixes. If you find yourself wishing you
could check unrar for "the right answer," stop and ask the human.
- When you finish a task, summarize: what you did, what you tested, what you didn't do that someone might expect you to have done, and what should happen next per the plan.
- Don't editorialize the codebase ("this code is messy"). If you have concerns, file them as tracked TODOs with rationale.
- If you discover the plan is wrong or incomplete, say so explicitly and propose a revision. Don't quietly diverge from it.
- Choosing the project's overall architecture. The plan defines it.
- Deciding which optimizations to pursue.
OPTIMIZATIONS.mdis a deferred list, not a TODO list. - Adding "nice to have" CLI flags, logging verbosity levels, config file formats, etc. unless the plan or the user asks for them.
- Migrating to newer/shinier crates without a documented reason.
The point of these rules is to keep the project on track and the codebase coherent across many sessions. When you follow them, the human reviewing your output spends time on actual decisions instead of cleanup.