Skip to content

Commit 07a647e

Browse files
authored
Merge pull request #25 from escoffier-labs/feat/bootstrap-budget-doctor
feat: fail oversized bootstrap files
2 parents e50e7ef + ec7722a commit 07a647e

4 files changed

Lines changed: 74 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
## [Unreleased]
99

1010
### Added
11+
- Built-in `brigade doctor` bootstrap budget checks that fail hard when installed bootstrap files exceed conservative byte limits.
1112
- `brigade run "<task>"`, a bounded aboyeur flow that asks one rostered orchestrator to plan assignments, dispatches worker CLIs in parallel, then asks the orchestrator to synthesize the final answer.
1213
- `.brigade/roster.toml` loading for cross-model agent rosters using the user's installed CLIs (`codex`, `claude`, or `ollama:<model>`). Claude is optional, not required.
1314
- `brigade roster init` and `brigade roster doctor` to scaffold a Codex/Ollama starter roster and validate roster syntax plus installed CLI availability.
@@ -41,7 +42,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4142

4243
### Changed
4344
- Dogfood handoff defaults now use `.codex/memory-handoffs/` for new Codex-driven local configs while preserving explicit configured inbox paths such as `.claude/memory-handoffs/`.
44-
- The roadmap now treats memory/bootstrap doctor checks as daily-readiness work, with bootstrap truncation as a hard failure to prevent.
45+
- Bootstrap truncation is now treated as a hard doctor failure to prevent by moving durable detail into memory cards before agents load context.
4546
- Dogfood runs now default to a 600 second per-agent timeout for practical daily repo reviews.
4647
- The managed gitignore block now treats `.brigade/dogfood.toml` and `.brigade/runs/` as local state.
4748
- Live smoke docs now keep Codex agent execution in a trusted repo cwd while writing temporary roster, artifacts, and handoff output under `/tmp`.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ Use `--output-dir <path>` to pick the artifact directory, or `--no-artifacts` fo
168168

169169
Use `brigade work status` as the quick daily dashboard for a repo. It reports the current branch, dirty files, dogfood readiness, configured dogfood paths, latest dogfood run, and extracted next step without starting a new orchestration. Use `brigade work doctor` to check whether the repo is ready for the daily loop: dogfood config, Codex CLI, local artifact paths, handoff inbox, ignore coverage, and latest run context. Use `brigade work resume` when returning to a repo; it shows the active or latest work session, latest dogfood run, extracted next step, and the suggested command to continue. `brigade work run` is the one-command daily loop: it starts a work session, runs `brigade dogfood`, ends the session, writes a work-session Memory Handoff by default, and prints a compact recap. Pass a task to override the default next-slice review, `--title` to name the session, `--no-handoff` to skip the work handoff, or `--dogfood-handoff` to also let the underlying dogfood run write its own handoff. `brigade work start "title"` opens a local work session under `.brigade/work/<id>/`, records the starting git and dogfood context, and writes `start.md`. `brigade work note "checkpoint"` appends a timestamped note to the active session without ending it. `brigade work end --note "what happened"` closes the active session, records ending context, and writes `end.md`. Add `--handoff` to also write a Memory Handoff for the closed session; it defaults to the configured dogfood handoff inbox or `.codex/memory-handoffs`.
170170

171-
Memory and bootstrap readiness are part of the same operating-system health story. `brigade doctor` covers installed workspace structure today; the long-term daily-readiness path should include memory/bootstrap checks that fail before bootstrap files are truncated. Bootstrap truncation should be treated as a hard failure, not a cosmetic warning.
171+
Memory and bootstrap readiness are part of the same operating-system health story. `brigade doctor` checks installed bootstrap files against built-in hard byte budgets so overgrown files fail before agents load truncated context. Bootstrap truncation is treated as a hard failure to prevent, not a cosmetic warning; move durable detail into `memory/cards/` and keep bootstrap files as slim indexes.
172172

173173
Inspect local work sessions with `brigade work list`, `brigade work latest`, or `brigade work show <session-id-or-path>`. Use `brigade work recap` for a compact summary of recent sessions, or add `--since YYYY-MM-DD` for a day-range recap.
174174

src/brigade/doctor.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,19 @@
1515
FAIL = "FAIL"
1616
MANUAL = "MANUAL"
1717

18+
BOOTSTRAP_BUDGETS = {
19+
"AGENTS.md": 12_000,
20+
"CLAUDE.md": 6_000,
21+
"MEMORY.md": 7_000,
22+
"TOOLS.md": 10_000,
23+
"USER.md": 8_000,
24+
"SAFETY_RULES.md": 10_000,
25+
"INSTALL_FOR_AGENTS.md": 8_000,
26+
"SOUL.md": 8_000,
27+
"IDENTITY.md": 4_000,
28+
"HEARTBEAT.md": 5_000,
29+
}
30+
1831
from .station import DoctorContext
1932

2033

@@ -115,6 +128,35 @@ def _check_workspace_files(target: Path) -> List[CheckResult]:
115128
results.append((OK, f"bootstrap: {name}", str(path)))
116129
else:
117130
results.append((WARN, f"bootstrap: {name}", f"not present at {path}"))
131+
results.extend(_check_bootstrap_budgets(target))
132+
return results
133+
134+
135+
def _check_bootstrap_budgets(target: Path) -> List[CheckResult]:
136+
results: List[CheckResult] = []
137+
for name, limit in BOOTSTRAP_BUDGETS.items():
138+
path = target / name
139+
if not path.exists():
140+
continue
141+
if not path.is_file():
142+
results.append((FAIL, f"bootstrap-budget: {name}", f"not a file: {path}"))
143+
continue
144+
try:
145+
size = path.stat().st_size
146+
except OSError as exc:
147+
results.append((FAIL, f"bootstrap-budget: {name}", f"unreadable: {exc}"))
148+
continue
149+
detail = f"{size}/{limit} bytes"
150+
if size > limit:
151+
results.append(
152+
(
153+
FAIL,
154+
f"bootstrap-budget: {name}",
155+
f"{detail}; over hard limit, split durable context into memory/cards before agents load it",
156+
)
157+
)
158+
else:
159+
results.append((OK, f"bootstrap-budget: {name}", detail))
118160
return results
119161

120162

tests/test_doctor.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,35 @@ def test_doctor_reports_failures_on_empty_dir(tmp_target: Path, capsys):
3131
assert "[fail]" in out
3232

3333

34+
def test_doctor_fails_when_bootstrap_file_exceeds_budget(tmp_target: Path, capsys):
35+
install_selection(
36+
tmp_target,
37+
Selection(depth="workspace", harnesses=["claude"], owner="claude", includes=[]),
38+
)
39+
limit = doctor_mod.BOOTSTRAP_BUDGETS["MEMORY.md"]
40+
(tmp_target / "MEMORY.md").write_text("x" * (limit + 1))
41+
42+
rc = doctor_mod.run(target=tmp_target, harness="generic")
43+
out = capsys.readouterr().out
44+
assert rc == 1
45+
assert "[fail]" in out
46+
assert "bootstrap-budget: MEMORY.md" in out
47+
assert "over hard limit" in out
48+
49+
50+
def test_doctor_reports_bootstrap_budget_ok(tmp_target: Path, capsys):
51+
install_selection(
52+
tmp_target,
53+
Selection(depth="workspace", harnesses=["claude"], owner="claude", includes=[]),
54+
)
55+
56+
rc = doctor_mod.run(target=tmp_target, harness="generic")
57+
out = capsys.readouterr().out
58+
assert rc == 0
59+
assert "bootstrap-budget: AGENTS.md" in out
60+
assert "bootstrap-budget: MEMORY.md" in out
61+
62+
3463
def test_doctor_openclaw_reports_manual_when_config_missing(tmp_target: Path, monkeypatch, capsys):
3564
install_selection(
3665
tmp_target,

0 commit comments

Comments
 (0)