Repository navigation
Configuration
build-loop reads project-local config from .build-loop/config.json and per-run state from .build-loop/state.json. Durable cross-run knowledge lives in the build-loop memory root (bootstrapped by build-loop-install, overridable with --memory-dest).
build-loop-install bootstraps the memory root with public templates and ensures projects/<slug>/raw/ exists for each --project <slug>. The memory root holds durable lessons, decisions (MADR/ADR), patterns, and per-project context that Assess reads and Learn writes. Override the location with --memory-dest <path>; skip it entirely with --skip-memory.
The canonical active memory store is the companion repo tyroneross/build-loop-memory. Legacy .episodic/ paths are migration/archive inputs only.
Model selection is data-driven, not hard-coded:
-
references/model-taxonomy.json— the index and durable source of truth: the two-axis (segment × tier) classification of every model. -
scripts/resolve_agent_model.py— resolves a role's concrete model live at dispatch and overrides agent frontmatter. -
scripts/sync_agent_model_defaults.py --apply— regenerates each agent's recommendedmodel:fallback from the index (never hand-edit frontmatter).
Adopt a new or different-provider model by classifying it once and reordering the cell in the index, then re-running the sync — no agent edits.
| Env var | Default | Effect |
|---|---|---|
BUILD_LOOP_OUTAGE_TTL_SECONDS |
1800 |
How long a recorded model-unavailable outage suppresses that model before auto-expiry on read. |
A model observed unavailable falls back to the next host-reachable model in its tier; a frontier/judgment role degrades at most to the thinking tier and never below the floor. Recording/clearing run through scripts/dispatch_fallback.py; expiry is pruned on read in scripts/model_resolver.py.
Tunables live under coordinationPolicy in .build-loop/config.json (loader scripts/rally_point/coordination_policy.py). Out-of-range values are ignored, never a hard failure.
As of v0.36.0 the coordination layer is a thin facade over the canonical Rust rally binary that fails loud when the binary is unavailable. Every coordination envelope carries a capability_level — full, degraded-breadcrumb, or unavailable. Full-only operations (claim / reclaim / lead / reap / liveness / before_write / checkpoint) are permitted only at full capability; a binary-less but supported host may write only capability-marked presence/handoff breadcrumbs.
Fetch-on-install: when no system/sibling/PATH binary is found, build-loop fetches the host-platform asset from the pinned agent-rally-point release, SHA256-verifies it (fail-closed), strips the macOS quarantine xattr, version-pins, and caches under $XDG_CACHE_HOME/build-loop/rally. An unsupported host (no matching asset) yields a loud coordination_unavailable: unsupported_host, never a silent mirror.
| Key | Default | Effect |
|---|---|---|
| half-life (decay) | 48h |
Weight 0.5 ** (age_hours / half_life) on coordination changes; orders history fresh-first. |
| archive floor |
0.05 (≈14d) |
Changes below this weight are excluded unless --include-archived. |
reclaim_small_minutes |
30 |
Lease window for small (single-file / effort XS·S) lead claims. |
reclaim_large_minutes |
120 |
Lease window for large (multi-file / effort M·L·XL) lead claims. |
Size-scaling is opt-in (pass work_size / effort / owns); with no size signal the lease window stays the historical cadence.
scripts/inject_dependency_cooldown.py enforces a minimum package release age, writing a different native key per package manager (npm min-release-age in days; pnpm minimumReleaseAge in minutes; yarn npmMinimalAgeGate in minutes). npm has no native exclude — on npm the allowlist is enforced by a PreToolUse backstop hook that stays engaged even when native config is active. pip/cargo are not covered in v1. See FAQ for the per-PM key table and gotchas.