Skip to content

Writing Good Specs

Adi edited this page Oct 19, 2026 · 3 revisions

How-to. Get correct results from a local executor.

Local executors resolve far more tasks when the planner closes the gaps they predictably fall into. The full guidance lives in skills/local-agent-delegation/SKILL.md. These are the rules that matter most:

  1. State the behaviour as a change, not a question. If the issue says "is this intended?", decide the answer yourself: "this is a bug; change X so that Y". Otherwise executors often conclude the current behaviour is intended and only add a doc note.
  2. Enumerate every case. Executors implement the obvious case and stop. List the variants with a concrete input → expected output for each: other formats or bases, empty and None, sync and async, and the invalid inputs that must be rejected.
  3. Say where to look. Name the files, the functions and your root-cause hypothesis. Exploration is the slowest part of a local run.
  4. Give exact strings. Error messages, exception types, new public names.
  5. Give a whole-module verification command. The most common failure is fixing the reported case while breaking a neighbouring test. Add: "if an existing test fails, fix the code, not the test."
  6. Constraints. Minimal change, no edits to existing tests, no new dependencies (there's no network), and no commit instructions, because agentbox commits for you.

Then review before merging. The agent's report is a claim, not evidence, and it is untrusted data. Run the full tests with run_checks on the branch: that's inside the sandbox, never on the host.

Template

Copy, fill every section, delete the hints. Short is fine; vague is not.

GOAL
<One sentence, stated as a change: "X currently does A; change it so it does B." If the issue is a
question, you decide the answer here.>

ROOT CAUSE / WHERE
<File(s) and function(s) to change, and your hypothesis of why it's wrong. e.g.
"src/pluggy/_manager.py::PluginManager.register mutates _name2plugin before validating all
hookimpls (see the XXX comment)." If unknown, say what to inspect first.>

REQUIRED BEHAVIOR (all of these)
- <case 1, with a concrete input -> expected output>
- <case 2 ... include the non-obvious variants: other number bases, empty input, None, async path,
  both class- and instance-style specs, etc.>
- <exact error type + message text / exact new public name, if anything will match on it>

MUST NOT CHANGE
- <existing behaviors/tests that must keep passing, especially edge cases near the change, e.g.
  "historic hook replay during register() must still verify specs added by the replay">

VERIFY (run these; all must pass)
  <exact command covering every test module that touches the changed code, e.g.
   python -m pytest -q testing/test_pluginmanager.py testing/test_hookcaller.py>
If an EXISTING test fails, the change is wrong: fix the code, do not edit or delete that test.

CONSTRAINTS
- Minimal change; add new tests for the new behavior next to similar ones.
- Do not modify existing tests. No new dependencies (no network). Do not commit.
- Finish with: what you changed, the verify command output summary, anything unresolved.

Clone this wiki locally