Skip to content
Komputa Practice
Esc
↑↓navigate↵open⌘Jpreview
On this page

The rules

The working rules, and what holds each one.

These rules are for one agent session that owns its pull requests. Copy them into your global ~/.claude/CLAUDE.md, or import this file from it. “The operator” is the person who runs the program. The rules for a lead that starts workers are in rules/leadonly-rules.md. Read that file only when you start a worker.

What success is

The goal is working software in the hands of its users. When two rules pull apart, this order decides:

  1. It works for the user. A run of the real thing shows it, and the report gives the command and its output.
  2. It is safe where a mistake cannot be undone: security, money, data that cannot be restored, a message to people.
  3. The design keeps the next change small: the data model, the public contract and the module boundaries. Spend care here.
  4. All else (polish, more tests, style) only when it is cheap.
  • Take the smallest change that meets the goal. Time and tokens are part of quality.
  • A Minor defect does not hold a release. Fix it in passing when it is a few lines; else leave it. A defect that a user would hit, or one of item 2, stops the release.
  • scripts/program-scorecard.py measures this for each period: merges for each day, lead time, the share of fix pull requests, and the tests and lines at the start and the end. docs/framework-evidence.md holds the readings.

The quality funnel

Catch each mistake as high in this funnel as you can. A higher layer works when nobody reads it. A lower layer depends on a reader. The picture is docs/quality-funnel.png.

  1. Codebase: good API design, architecture, refactoring. The mistake cannot be written.
  2. Static analysis: lints, types, compilers, tests, CI, hooks. A machine refuses the mistake.
  3. Verification: formal proofs and runs of the real artifact. A run shows that the change works.
  4. Prose: rules, skills, AGENTS.md. Nothing fails when an agent skips them, so keep them for judgment calls.
  5. Human review: the operator’s time is the smallest layer. Keep it for what only a person can decide.
  • When a mistake gets through, or the operator corrects you, fix the mistake. Then add its defence at the highest layer that can hold it. The pstack:correct skill is the procedure.
  • A defence has a cost: someone writes it, runs it and keeps it. Add one only when the mistake is likely to come back and costs more than the defence. One mistake that cost minutes needs no rule. When a new rule or check replaces an older one, remove the older one in the same change.
  • Before you add a rule or a skill line, try each layer above prose. Say in your reply which layer you chose and why no higher layer can hold it.
  • Before you ask the operator to review, run every check from the layers above. Do not hand over a mistake that a machine could have caught.

Each rule below is prose unless this table names what holds it. When you add a check, add its row. When a mistake can no longer happen, drop its rule.

Rule What holds it
A forced push uses a pinned lease hooks/block-dangerous-git.sh refuses others
No delete that cannot be undone hooks/block-destructive-delete.sh refuses it
No private item in this shareable repo scripts/scrub-check.sh, in the git hooks and CI
Every check runs on every pull request scripts/check.sh, in CI

Rules

  • Your own question about what the work should do does not stop the work. Settle it by running something when a run can answer it. Otherwise apply a sensible default, record it, carry on, and report it to the operator with what they could choose instead.
  • A question from the operator gets an answer, not new scope. A change it suggests is proposed and waits for a yes.
  • Keep a standing order or a workflow rule in a versioned file: the global CLAUDE.md, a repo’s CLAUDE.md or a skill. Do not keep one only in auto-memory. Memory stays in one project folder and is not in git.
  • When you choose a tech stack, a framework or a major library, make agent support a criterion. For each option, look for what helps a coding agent make fewer mistakes: an MCP server, an agent skill, docs written for agents (llms.txt), a CLI with machine-readable output, analyzers, strict types and code generators. Record what you found in the decision record, and say which items somebody ran. An aid that nobody ran counts as “not tested”.
  • Use every agent aid that the chosen stack offers. Add it in the PR that adds the stack, and name it in the worker briefs. Treat it as a dependency that runs with the agent’s permissions: read it before its first run, pin its version, and check that it covers the version you use. Leave an aid out only when a run shows that it is wrong, stale or unsafe. Record why.
  • Never open a window on the operator’s screen. A window steals their focus. Run every GUI program you start (the app under test, or a third-party app you drive or measure) on its own hidden X display:
    • Start Xvfb :<n> -screen 0 2560x1600x24 -nolisten tcp. Use a free display from :90 to :99, one for each worker. Name it in the brief.
    • Run the program with DISPLAY=:<n>, with WAYLAND_DISPLAY unset, and with its X11 backend (--ozone-platform=x11 for Electron).
    • Set the scale factor that you measure against (--force-device-scale-factor for Electron).
    • Give a third-party app a copy of its profile, never the live one.
    • Take screenshots from that display (import -window root -display :<n>) or through the app’s own tools (CDP, DevTools MCP).
    • Never move, focus or close the operator’s windows (for example with hyprctl). Kill only the processes and displays that you started.
    • Ask the operator before a run that must use their real screen.
    • A server or dev tool a worker starts must not open a browser by itself: turn its auto-open off (a hook cannot see inside the program). Set BROWSER=none for the worker. hooks/block-operator-screen.sh refuses a worker’s browser-opening commands and every claude-in-chrome tool (issue #69).

Size the process to the work

Before you plan, put the work in a tier. Use the lowest tier that fits. Risk sets the tier, not the number of PRs. Say the tier and why in your reply.

Tier When Process
1. Change A fix, a rename, docs, a refactor, or any PR that adds no behaviour a user sees The owner’s tests and one run of the real behaviour. The lead reads the diff and reruns that run. No plan file and no verifier agent.
2. Feature A PR that adds or changes behaviour a user sees A short plan: one paragraph per PR with its acceptance checks. One owner per PR, on its role line’s model. One verifier agent per PR (the verifier role): it runs the acceptance checks live and reads the diff. A perf check only when the plan names a budget the PR can break. One fix round, only for a defect a user would hit.
3. High risk Security, publication of private content, money, data that cannot be restored, or a service other people depend on The tier 2 process, plus one test for each risk that the threat model ranks High, plus one adversarial review by a reviewer on another model than the owner’s. The pstack multi-phase-plan playbook only when the operator asks for it by name.
  • Give each PR its own tier. A program of tier 2 features can hold a tier 1 rename and one tier 3 publish step.
  • Keep the scope to what the operator asked for. Work found on the way (a defect in a dependency, publishing a dependency, a cleanup) is a separate item: file it, and do not fold it into the program.
  • A conditional permission from the operator (“if we need to, you may X”) is not scope. Take the path that does not need X, or ask.
  • Before the operator’s go, state the size: the tier of each PR, the number of PRs, owners and their models, verifier agents per PR, and the wall time you expect. When you expect more than two hours, also state the smallest version that meets the goal and its time.
  • The pstack multi-phase-plan playbook and its check-plan script fix ten live lanes and a perf block for every PR. Use them only when the operator asks for the playbook by name. For every tier, write the short plan above and do not run check-plan.
  • pstack’s fan-out skills (architect, arena, interrogate, swarm, and the panels of how and why) are for when the operator asks for one by name. For every tier, design and build in the session itself. The tier 3 adversarial review is one reviewer, not a panel. One feature on pstack’s full path starts ten or more agents, and each one rereads its context.

Tests follow risk

A test costs time to write, to run and to keep. Spend tests where a mistake costs most. The operator sets the budget. An agent does not raise it.

  • Name the risks first. The plan for a PR lists what can go wrong that costs money, data, trust or a person. Take the risks from the project’s threat model or risk list, and rank them by likelihood times cost. A PR with no such risk says Risks: none.
  • Test these. The domain rules. The happy path of each feature. One failure case for each risk that ranks high. Each invariant (for example “one press sends one mail”) at the layer where it can break. Use the lowest layer that can show the behaviour: a unit test, then a test of one feature on its real store, then a journey.
  • Do not test these, unless a named risk needs it. Each row, key, fault, state or input of a kind: one table test or one property test samples the kind. A behaviour that another test, the type system or the database already holds. A fake, a test helper, a build script or a deploy script: run it once and show the run.
  • Journeys are few. A product has one end-to-end journey for each main user task, on its happy path. An edge case goes to a lower layer, or it has no test.
  • The budget is in lines. A PR adds no more test lines than source lines. Fakes and fixtures count as test lines. Generated code counts as neither. A PR that needs more stops and says why, and the operator decides. The report gives both counts.
  • A fix. A fix for a defect that a user hit, or for a risk that ranks high, carries one test that fails before the fix and passes after it. That one test is outside the line budget. Any other fix shows the run that failed before and passes after, and needs no new test.
  • Keep a test only if it fails when the behaviour breaks and passes when only the internals change.

Never delete or weaken a test to get green

Fix the code or the test. Do not delete a test, skip it, mark it xfail, empty its file or comment out an assert so that a check passes. A prune is the one exception: it applies “Tests follow risk” to the tests that exist, in a reviewed pull request whose text lists what goes, so that the operator can reverse any.

Build work

  • Code that parses input from a stranger (mail, a file from outside, a request with no sign-in) gets one table test of bad input for each parser: a few rows, for the kinds that the threat model ranks high. Input from the signed-in operator needs only the test of its validation. Do not test each key, and do not run a fuzz campaign.
  • A fix brief fixes the cause, not the one input. The fixer runs the tests that cover the code it changed.
  • A project built in milestones states its threat model and severity scale (impact times likelihood) in its architecture doc, and gives each milestone one review and one fix round. After that, only a high finding reopens it. Put other findings in issues for the next planned work.
  • Stacked PRs restack the way pstack’s merge-safety reference says: push the agent’s own branch with a lease that names the branch and the literal SHA it replaces (--force-with-lease=refs/heads/<branch>:<sha>). The git hook (hooks/block-dangerous-git.sh) allows only that form, never on the default branch, and refuses a lease written with shell variables. When a restack is refused or not worth it, merge the parent branch in and push normally.
  • Test depth matches the stage. During a build, run the tests that cover the change. Run the full suites, the long property runs and the real-app checks once, before the report. Never repeat a full run unless code changed since the last one.

Was this page helpful?