Files
tireless/CLAUDE.md
rob thijssen ddb2574bbe docs: state the purpose, the autonomy boundary and the dogfooding plan
design.md described what tireless does to an issue but never what it is for, and
in one place said the opposite of the intent: §1 assigned "identifying what
should be worked on" to the operator, which is the thing discovery automates.
A reader — human or agent — would have concluded the system is human-triggered
only and never built the lane.

Rewrite §1 around continuous multi-repo development. Add §2.5, the autonomy
boundary, as a table of which transitions are automatic and which are human,
with the alternatives considered and why they lose. Add §2.6 on anchoring
discovery to a tracking issue rather than making Job.issue a sum type, and what
that buys. Add stage 6 for the lane, renumbering scheduling to 7 and hardening
to 8, with the reasoning for placing a cheap stage late.

Add §10 on tireless working on tireless: that a merged PR restarts the runner
that opened it and why that is survivable but not free, which areas must be
routed to the stronger lane because they are constraint-bearing, and the four
questions dogfooding is expected to answer.

Two new invariants. Admission is inherited (§2.5), and every constraint must be
reachable from a binary's startup path — the rule the previous commit's orphaned
guards violated.

AGENTS.md symlinks CLAUDE.md: both agents look for their own filename, the
implementation prompts tell them to, and a symlink is the only version of this
that cannot drift.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013TxK1CWPkFXqdcXMJ4hVe6
2026-08-07 15:36:54 +03:00

4.4 KiB

tireless — agent instructions

Read doc/plan/design.md before making changes. It carries the constraints, the staged plan, and the reasoning behind decisions that look arbitrary in isolation.

House conventions live in ~/git/architecture (generic.md is the baseline). This project's deliberate deviations are listed at the bottom of readme.md.

tireless works on tireless. This repo is its own first subject, so changes here are both the product and the test of it. If you are an agent working from a tireless-authored issue, design.md §10 says what that implies — in particular, that some areas of this repo are constraint-bearing and are routed deliberately.

Invariants — do not "clean these up"

These are terms-of-service and safety constraints expressed as code. Each has tests. If one seems redundant, read design.md §3 before touching it.

  1. Never construct a request to a model provider. Agents are spawned as the vendor's own binary and authenticate themselves. Adding an HTTP client that talks to api.anthropic.com would break the arrangement that lets a subscription back this app.

  2. Never read or forward agent credentials. has_credentials() stats ~/.claude.json and nothing more. Do not parse it, copy it, or pass its contents anywhere.

  3. Never set ANTHROPIC_API_KEY. It reaches Claude Code only if an operator put it in the unit environment. Its presence selects pay-as-you-go; its absence selects the subscription. That choice is the operator's.

  4. Never point the OpenCode lane at Anthropic. assert_not_anthropic is checked at startup against both provider id and base URL. Local gateways that merely serve an Anthropic-compatible surface (helexa cortex) are fine and are tested for.

  5. Never let a lane run unbounded. Every agent invocation passes through tireless_core::budget::Governor. Provider rate-limit signals are checked first and are authoritative.

  6. Postgres is the authority on claims, not forge labels. Labels are a best-effort mirror. Do not make a decision by reading a label that could be made by reading the database.

  7. Never use --system-prompt for Claude Code; append instead. Replacing Claude Code's default discards the tool-use scaffolding that makes it a coding agent. SYSTEM_PROMPT_FLAG is --append-system-prompt for this reason.

  8. The four prompts in prompt/ are one set — edit them together. plan.cc.md emits the structure implement.oc.md consumes and tireless_core::plan::validate enforces. Changing one alone breaks the handoff silently, as a bad pull request rather than an error. Bump contract-version: in all four plus SYSTEM_PROMPT_CONTRACT_VERSION together; PromptSet::load refuses a mismatched set.

  9. A plan is validated, not trusted. Never enqueue implementation work from a plan that has not passed plan::validate. The Acceptance (runnable stopping condition) and Out of scope (boundary) requirements exist because a small model needs them; do not relax them because a plan looks fine to a human reader.

  10. Admission is inherited, never invented. tireless may apply the opt-in label only to an issue descended from one a human opted in. may_opt_in(JobKind::Discover) is false and must stay false: it is the only thing standing between "proposes work" and "generates its own work indefinitely". See design.md §2.5. This is not a policy to relax once the system is trusted — the failure it prevents is unbounded, not merely wrong.

  11. Every constraint above is reachable from a binary's startup path. A guard that exists as a tested function nobody calls is not a guard. If you add one, wire it into Config::validate or tireless_agent::preflight::run so it cannot be bypassed by a caller that forgot.

Quality gate

Before considering a change complete:

cargo fmt --all
cargo clippy --all-targets --all-features -- -D warnings
cargo test --workspace
cd dashboard && npm run lint && npm run build

This exact block is what a plan targeting this repo should use as its runnable Acceptance (design.md §10.3).

Commits

Conventional Commits (type(scope): subject), imperative, under ~70 chars. Commit autonomously when the work is a coherent, complete unit; hold off when follow-ups on the same topic are likely. See generic.md §12.