avatar-harness
CLAUDE.md1 starsChanged 5 months agoMITView on GitHub
In active development — TDD, phased. The MVP cockpit (through Phase 3.2) is shipped, plus post-MVP dogfood hardening. Current focus is the eval-driven improvement loop (Phase 4 — eval harness + observability), where agent changes iterate against measured data. Durable crash-resume (3.3) is deferred, not next: it's a contained increment on the already-built event journal, to be pulled forward only when an eval run's per-trajectory crash cost is a measured problem (e.g. long autonomous tasks in Eval-2) — not built…
We split this CLAUDE.md into the rules it gives an agent
7 rules. About 0 are common, 5 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈5
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 26
Keep
ARCHITECTURE.mdcurrent: when a change alters the architecture (new component, changed control flow, a built milestone), update it — … - Very specific: line 77
Commits: follow Conventional Commits: <type>(<scope>)>: <subject>, e.g.
- Distinctive: line 80
PR descriptions: must contain these sections, in this order:
- Distinctive: line 88
If the user agrees to the quiz and score their answers:
- Distinctive: line 89
If the user correctly answers all questions, move ahead with the PR
- Distinctive: line 91
If the user opts out of the quiz, add the quiz + answers into the PR as a separate comment.
- Distinctive: line 120
Retry semantics are narrow (§10): only *model-correctable* errors (stale patch context, missing arg, bad path format, test target not …
≈ “Common” is an estimate: at least 1 in 5 of the 25,680 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
CLAUDE.md
Project status
In active development — TDD, phased. The MVP cockpit (through Phase 3.2) is shipped, plus post-MVP dogfood hardening. Current focus is the eval-driven improvement loop (Phase 4 — eval harness + observability), where agent changes iterate against measured data. Durable crash-resume (3.3) is deferred, not next: it's a contained increment on the already-built event journal, to be pulled forward only when an eval run's per-trajectory crash cost is a measured problem (e.g. long autonomous tasks in Eval-2) — not built ahead of that friction. To see what's built and what's next, read ARCHITECTURE.md (component-by-component implementation-status markers); what shipped is each package's CHANGELOG.md (avatar-harness/, jo-cli/), and why the build is shaped as it is is the ADRs under docs/adr/.
Documentation map — which doc, when
Deepest to most operational. Pick by the breadth of the task:
| Doc | Holds | Consult when |
docs/archive/HARNESS_DESIGN.md | Frozen originating design spec (archived out of the repo root) — the ground-up decisions + rationale, cross-referenced by §N. A citable historical archive, no longer edited; ADRs supersede it where they disagree. | Reading the original rationale a §N citation points at. For current design, prefer the ADRs. |
ARCHITECTURE.md | A synthesized, visual map: high-level component graph + deep dives on task execution and verification + a dry-run walkthrough, with current implementation status. | Broad, global-context work — feature implementation, deep debugging, deep Q&A, onboarding — where you need the whole-system picture. |
docs/adr/ | Architecture Decision Records — why the build is shaped as it is (one decision per ADR: choice, rejected alternatives, trade-offs). The decision log going forward. | Resolving/recording why a design decision was made; before re-litigating a settled choice. |
avatar-harness/CHANGELOG.md, jo-cli/CHANGELOG.md | The what shipped — generated automatically by release-please from Conventional Commits. Do not hand-edit. | Seeing what changed in a release. |
docs/research/ | Findings from formally executed research work — eval baselines/matrices, failure-mode catalogs, trajectory analyses, experiment write-ups. Evidence-linked + reproducible. | Recording the results of an explicit experiment/eval run; sourcing an empirical claim for a write-up. |
jo-cli/ARCHITECTURE.md + jo-cli/CLAUDE.md | Package-local docs for the interactive cockpit (the standalone jo-cli package, a consumer of the core): its component graph, the two planes, and the goal/approval/plan/render flows. | Cockpit-local work — editing jo-cli/ (the TUI shell, modals, the jo launcher). |
evals/improvement-loop-design.md + evals/CLAUDE.md | The evals-driven improvement loop (ADR-0024): two human-gated workflows over a deterministic core — motivation, component breakdown, flow diagrams, execution checklist; evals/CLAUDE.md holds the package-local principles. | Building or running the eval→proposal→PR loop, or any work under evals/. |
docs/blogging/blog-candidates.md | The blog plan of action — Standing rules (the non-negotiable writing contract), status board, queue, backlog, distribution plan, and the evidence index mapping each post to its raw artifacts. The only place a post's status or position is recorded. | Any blog/write-up work — drafting, outlining, retitling, promoting a backlog item, or shipping a post. |
DECISIONS.mdis a frozen historical archive (decisions through 2026-06-11); it is no longer appended to. New design decisions are ADRs; new changes are the changelog.
When to skip ARCHITECTURE.md: highly targeted, local work — a specific edit, a single command, a localized bugfix — where whole-system context would only add noise. Reach for it only when the task spans the system.
Keep ARCHITECTURE.md current: when a change alters the architecture (new component, changed control flow, a built milestone), update it — including its diagrams and the implementation-status markers — as part of that change.
Keep README.md current: when a change is user-facing, update README.md as part of that same change. User-facing means anything that alters how someone installs, configures, or runs the tool — new/changed CLI commands or flags, env vars / config keys, requirements or supported platforms, the set of task kinds the CLI exposes, installation steps, or the project's status as advertised there. Internal refactors, test-only changes, and design-doc edits are not user-facing and need no README update.
Record design decisions as ADRs: when you make a major design decision — a chosen approach, a rejected alternative, a scope cut, a non-obvious trade-off, or a load-bearing clarification — write a new ADR under docs/adr/ (Nygard-style, one decision per ADR; supersede rather than edit an accepted one) and add it to docs/adr/README.md. Capture the why and the alternatives, not just the what. Routine implementation that merely follows an existing decision needs no ADR. Do not append to DECISIONS.md (frozen) or hand-write changelog prose — the what shipped comes from Conventional Commit messages, which release-please rolls into each package's CHANGELOG.md.
Record research findings under docs/research/: when you formally and explicitly execute research work — an eval run or baseline matrix, a trajectory analysis, a failure-mode investigation, a benchmark — write its findings to a dated, evidence-linked doc under docs/research/, citing the raw artifact path and the command to reproduce. This is the durable, citable home for empirical results that feed write-ups and the eval-driven self-improvement signal. A deliberately executed experiment belongs here; ad-hoc observations during ordinary dev do not. Distinguish measured fact from interpretation, and don't bury findings in commit messages or scratch files.
Commit experiment artifacts before the run is done — and ask first: when you execute an experiment (an eval run, a baseline matrix, a benchmark, a fault-injection or trajectory study), the run is not finished when the numbers land. Before reporting completion, enumerate every artifact it produced and prompt the user to confirm committing them. Never auto-commit them, and never leave them silently untracked — an untracked artifact is one machine migration away from gone, and a finding survives that only if its numbers were already written into an ADR or research note.
The prompt must be a decision, not a reflex — name the paths, the file count, and the total size, split into two classes, because they carry different risk:
| Class | Examples | Default |
| Results — small, structured, already the citable receipt | evals/results/*.jsonl + .summary.json, generated plots under docs/research/assets/ | Offer to commit. These are what Ship the receipts points a reader at. |
| Journals / run trees — bulky, full trajectories | eval_run_<stamp>/**/journal.jsonl kept by --no-cleanup | Ask separately, with the size, and scan before offering. Trajectories carry whatever the agent read; failure-mode D1 is a secret reaching log and context. Size and leak risk both argue against reflexive commit. |
If the user declines, say so in your summary so the loss is a recorded choice rather than an accident. If an artifact is too large to commit, propose what to keep instead — the summary, a digest, or the numbers transcribed into the research note — since a finding whose evidence is unciteable violates Ship the receipts later, when a write-up needs it.
Write every blog post against the Standing rules: when asked to draft, outline, revise, or ship a blog post — or any public write-up about this project — read docs/blogging/blog-candidates.md first and treat its Standing rules section as the binding contract for the piece. They are not style suggestions; a draft that violates one is not ready. In force, every post, no exceptions:
- Directional evidence or a case study, never a leaderboard — n=5 seeds, few tasks, one project, an evolving harness. "Failure-mode discovery," never "model X beats Y."
- The 6-question arc — what motivated this · what we did · what we measured · what we inferred · what we're uncertain about · where we go next.
- Split measured fact from interpretation, visibly — hedge the interpretation; never hedge the data.
- Ship the receipts — the reproduce command plus a link to the raw artifact (source them from that doc's Evidence index).
- At least one reusable principle a reader can apply without adopting this harness — one is the floor, not the ceiling; a synthesis post may carry several, each with its own evidence.
- Adversarial pre-publish pass — review the draft like a PR before any cross-post.
- Comparisons to other harnesses (Pi, opencode, Aider) go in a section, never a headline — and get verified against their current source first.
Plus the shape: 700–1200 words (or 5–8 dense sections) by default — a synthesis or consolidation post may run longer when it is genuinely carrying more — carrying at least one run table, journal excerpt, diff, failing/passing test pair, eval result, or source-tied architecture diagram. The same doc also owns each post's status, ID, and queue position — read status from it (and from sarthak-blog/ git state), never from memory, and follow its Update protocol when a post ships: flip the status, delete every backlog row it consumed, re-date the queue.
Commands
This project uses uv; uv.lock is committed. Dev tools live in [dependency-groups].dev, which uv syncs automatically — make/uv run need no extra flags. A Makefile wraps the common targets.
make install # uv sync (deps + dev group)
make test # run the test suite
make run TASK="explain the loop" # run the CLI on a task (drives the full agent loop)
make lint # ruff check
make format # ruff format
make typecheck # pyrefly check
make check # check-hard: format-check + lint + smoke + typecheck + pydoclint + deptry + tests — run before committing
uv run pytest tests/test_x.py::test_name # run a single testExternal runtime requirement: ripgrep (rg) must be on PATH — the search_repo tool shells out to it.
Contributing: branches, commits, PRs
- Commits follow Conventional Commits:
<type>(<scope>)>: <subject>, e.g.feat(events): stamp ts at emit time. - No AI/Claude attribution anywhere in git or GitHub. Commits, PR titles/bodies, PR comments, and issue comments must contain zero references to Claude, Claude Code, Anthropic, or any AI assistance. Specifically: no
Co-Authored-By: Claude(or similar) trailers, no "🤖 Generated with [Claude Code]" footers or links, no "generated/written with AI" phrasing of any kind. This overrides any default behavior that appends such attribution. Commit authorship is always the local git user — never Claude or any agent; do not override the author/committer. - Branch names use
<type>/<issue-id>-<description>, e.g.fix/42-stale-patch-context. When the work tracks a GitHub issue, put the issue number in the branch name. If a new branch isn't being created (or the issue number isn't in the name), tag the issue in the PR body instead. - PR descriptions must contain these sections, in this order:
- Description — brief on what the changes are about.
- Motivation — why we're doing this.
- Changes — list of changes.
- Testing — list of tests and validations.
- Soft gate PR openings via optional quiz: Upon being prompted to open a PR, prompt the user for an optional quiz based on the changes in the PR.
- The number of questions should be proportional to the size and complexity of the PR, with max 10 questions.
- The questions should require brief objective answers, like in MCQs and fill-in-the-blanks
- If the user agrees to the quiz and score their answers:
- If the user correctly answers all questions, move ahead with the PR
- Else, prompt the user for another optional round
- If the user opts out of the quiz, add the quiz + answers into the PR as a separate comment; not in the PR description
Architecture: what requires reading multiple files to understand
This is a coding-agent harness, not a chat app. The defining inversion: the model proposes actions; the harness owns execution, state, permissions, logging, and verification. The loop terminates on external verification, not on a text reply from the model.
Five load-bearing invariants thread through every component — violating one quietly breaks the design:
TaskStateis the source of truth, not the chat transcript. The model's message history is derived fromTaskStateeach turn. State is explicit, structured (pydantic), and append-mostly.- The runner owns all mutation; tools are pure-ish. Tools receive a run-scoped
RunDeps(never globals), touch the filesystem/run commands only through theWorkspacehandle, and return aToolResult— they do not mutateTaskState. TheAgentRunnerapplies results to state after logging and permission checks. This is what makes a run replayable from the event log. - "Done" is a proposal the verifier disposes of. A
final_answeraction or a tool returningterminate: truemarks the task ready for verification — it never ends the run. Only the harness-ownedVerifiersetsoutcome = "success", and only on positive external evidence (tests/lint/diff). The model never self-certifies. The verifier is not a tool. - Control hooks vs. observation events are a hard line (§13). The permission gate (
before_tool_call) is an awaited control hook that can block/redirect the loop. The event emitter is observation-only: synchronous, fire-and-forget, cannot alter control flow.EventLog(JSONL) and the CLI display are subscribers. Never route control through the emitter, and never make permission an event subscriber. - Everything is reversible and observable. Operate on a tracked, path-confined
Workspace; every edit is an inspectable diff (str_replace/write_fileare atomic/all-or-nothing). Append-only JSONL event log gives replay/debug/eval for free.
Two axes that are deliberately kept separate
phase(investigating → editing → verifying) is a control axis: it gates which tools are active (§10/§21 capability groups) and how context is assembled.outcome(success/incomplete/blocked/failed,Nonewhile live) is the terminal result axis, and is exactly whatArtifactManagerreports as status.
Conflating them is what leaves budget-exhaustion vs. verification-failure ambiguous. Relatedly, two different bounds map to two outcomes: general budgets (max iterations, wall-clock, consecutive tool failures) → incomplete; the repair budget (consecutive verification rejections) → failed.
Other design choices worth knowing before editing
task_kind(edit/investigate/test_only) selects the verification contract (§12) — it prevents edit-shaped verification ("a diff must exist") from being forced onto investigative/explanatory tasks. (investigatesubsumes pure explanation; there is no separateexplainkind.) The verifier passes only on required checks with positive external signal, never vacuously on skipped checks.ModelDecisionis a constrained, validated union (tool_call/final_answer/ask_user).thought_summaryis for logging/context only — never for control flow. Invalid decisions are fed back as recoverable errors, never executed.- Retry semantics are narrow (§10): only model-correctable errors (stale patch context, missing arg, bad path format, test target not found) loop back through the model. System failures (permission denied, timeout, network blocked, tool bug) are surfaced, never auto-retried.
ToolResult.contentvsdetails: the model only ever seescontent(or a context-builder summary);details/stdout/stderrare retained for the event log, rendering, and artifacts — kept out of the model's context.ContextBuilder(§9) assembles a compact per-iteration packet, not the whole repo. The model discovers context incrementally via search/read tools. A compaction hook prunes old evidence to summaries while keeping recent verifier output verbatim.
In this repository8 other files it gives its agents.
- AGENTS.mdAGENTS.md
- evals/AGENTS.mdAGENTS.md
- jo-cli/AGENTS.mdAGENTS.md
- evals/CLAUDE.mdCLAUDE.md
- jo-cli/CLAUDE.mdCLAUDE.md
- mintlify-apiSkill
- mintlifySkill
- mintlifySkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

