Skip to content
harness-mini

Top-level map

Architecture

How harness-mini is laid out and how work flows through it.

Repository layout

AGENTS.md              # ~100-line map injected every run (table of contents)
ARCHITECTURE.md        # this file
VERSION                # canonical version (e.g. 0.7.1)
init.sh                # additive, idempotent installer (new vs existing)
bin/
  harness.sh           # front-door CLI: version · update · release · report · doctor · status
  _harness_lib.sh      # shared helpers (managed set, checksums, semver compare)
  ctx.sh               # context % estimate vs the 40% threshold
  ctx-hook.sh          # opt-in (Claude Code) PostToolUse ctx sampler → checkpoint nudge
  trace.sh             # append runtime JSONL (best-effort, never blocks)
  ralph.sh             # ralph-loop driver (work → check → repeat)
  model.sh             # resolve each sub-agent's model tier (builder upgrades to the top tier)
skills/                # source skills: skills/<name>/SKILL.md → .claude/skills/
agents/                # source sub-agents: <name>.md → .claude/agents/
docs/
  principles.md        # golden principles + Five-Step core-mind
  smart-dumb.md        # the 40% occupancy contract
  assumptions.md       # load-bearing assumptions as hypotheses-with-a-test
  exec-plans/
    active/            # in-flight plans + decision logs (committed)
    completed/         # archived plans (committed)
  references/          # *-llms.txt distillates of the source blogs
bench/cib/             # context-intelligence benchmark — the live test of the 40% line
tests/run.sh           # zero-dep TDD suite for bin/* and init.sh
harness/
  manifest.md          # neutral pointer list for non-Claude CLIs
  harness.lock         # version + pristine checksums of managed files
.trace/
  checkpoints/         # COMMITTED — decisions, milestones, handoffs
  evals/               # COMMITTED — eval verdicts (tier · verdict · criteria)
  garden-backlog.md    # COMMITTED — out-of-scope smells awaiting a sweep
  runtime/             # GITIGNORED — ephemeral per-run JSONL

bin/harness.sh is the front door: version (which also reports whether a newer harness-mini exists), update (checksum-guarded sync that keeps your edits) and release, plus doctor (an install health check), status (current work state for a cold resume), and report (a pure-shell aggregator over .trace/ — stage advances, the context trend vs the 40% line, eval pass/fail and rework loops, checkpoint count — so the thresholds are tuned by data, not vibes).

status ends with a single ready: <ready|warning|blocked> — <next>verdict (OpenHarness dry-run idea, Mini-shaped) so a cold session doesn't re-derive "what next" from raw facts. blocked only for an install-broken tree or an active done plan without verdict: pass; warnings cover no plan, garden DUE, .new conflicts, behind-latest, and partial resume. Resumable is plan-scoped — foreign checkpoints no longer lie. Assumption A6 in docs/assumptions.md.

On a fresh session the routing gate and stage-viewer run harness.sh version first, so the agent checks for a newer release before routing work and offers an update if one exists — surfaced as a semver verdict from version, an update: line in status, and a WARN (never a FAIL) from doctor. Best-effort: silent offline.

Lifecycle FSM

intake → prd → issues → implement ⇄ evaluate → checkpoint → done
                           ↑___________|   (loop until criteria pass)
       garden ──── runs orthogonally, on signals (cadence + backlog) ────
  • State lives in each docs/exec-plans/active/<plan>.md frontmatter (stage:).
  • Transition authority: agents work freely within a stage, but only the main agent (via stage-viewer) advances the FSM. No sub-agent may mark its own output “done” — the evaluator gate plus main-agent control is the anti-self-praise firewall, extended across the whole lifecycle. Evaluation is tiered by risk (L0 self-check · L1 lightweight reviewer · L2 full Opus); the firewall is the separate context, not the model. The gate has teeth: every evaluation writes a committed verdict to .trace/evals/<plan>-NNN.md, and stage-viewer won't promote a plan to done without a verdict: pass doctor fails any that slips through.
  • Plan-stage write ban (convention only — no permission engine): while stage is intake / prd / issues, do not edit product code. Documented in stage-viewer + the planner; assumption A7. The walking skeleton starts at implement.

Coding contract: horizontal + vertical (slice-coding)

  • Vertical— build one feature as a thin walking skeleton end-to-end (it runs, it's tested) before starting the next feature. Depth-first, value-first.
  • Horizontal — respect a fixed layer stack with forward-only dependencies. The reference stack (adapt per project):
Types → Config → Repo → Service → Runtime → UI

Cross-cutting concerns (auth, telemetry, feature flags, connectors) enter through a single explicit Providers seam. Nothing depends “backward.”

The rule: a vertical slice proves the path; then expand horizontally across features within the same layered contract. Enforce mechanically where the project allows (lint / structure tests); the generator reads this before writing code. Once the skeleton passes evaluate, the parallel-slices skill fans that horizontal expansion out to several generators at once — gated on disjoint file footprints.

New vs existing project (set by init.sh)

  • new → generative bootstrap: seed 0001-intake.md, run the founder funnel (founder-check → five-step → to-prd → to-issues).
  • existing → recon graft: seed 0001-recon.md, the explorer maps the codebase into ARCHITECTURE.md; skip the founder funnel; install additively without overwriting anything.

Either way, install seeds a routing gateinto each CLI's always-on file — CLAUDE.md, .cursor/rules/, AGENTS.md — so the harness is preferred by default: route non-trivial work through stage-viewer first, and when a harness skill and another tool both fit, the harness skill wins. Additive and idempotent — an existing CLAUDE.md is never clobbered.