cmd_run refuses to start on a dirty main tree (src/bmad_loop/cli.py:1703):
if not verify.worktree_clean(paths.repo_root):
print("git worktree is not clean — commit or stash first", file=sys.stderr)
return 1
cmd_resume (src/bmad_loop/cli.py:2273) has no equivalent check — worktree_clean appears in
cmd_validate, cmd_run and cmd_sweep, and nowhere in the resume path.
Whether that asymmetry is intended is worth stating one way or the other. There is a coherent
argument for it: a resume continues a run whose worktrees already exist, and under
[scm] isolation = "worktree" the main checkout is explicitly expected to be usable while a run
is in flight (docs/FEATURES.md: "the main checkout stays free while a run is in flight"), so
demanding a clean tree to resume would refuse the very workflow the feature invites. There is also
an argument against: under isolation = "none" a resume drives the loop in the main checkout,
where pre-existing dirt is the same hazard cmd_run refuses over.
This surfaced while scoping #460. The gate is what bounds that issue's practical reach — a fresh
run cannot begin over pre-existing dirt, so the reachable triggers are dirt appearing after the
run starts, plus every resume — and that reasoning only holds while the asymmetry is deliberate
and documented. Right now it is neither confirmed nor written down.
Cheapest resolution may be a comment at the resume path plus a line in docs/FEATURES.md, rather
than a behavior change.
cmd_runrefuses to start on a dirty main tree (src/bmad_loop/cli.py:1703):cmd_resume(src/bmad_loop/cli.py:2273) has no equivalent check —worktree_cleanappears incmd_validate,cmd_runandcmd_sweep, and nowhere in the resume path.Whether that asymmetry is intended is worth stating one way or the other. There is a coherent
argument for it: a resume continues a run whose worktrees already exist, and under
[scm] isolation = "worktree"the main checkout is explicitly expected to be usable while a runis in flight (
docs/FEATURES.md: "the main checkout stays free while a run is in flight"), sodemanding a clean tree to resume would refuse the very workflow the feature invites. There is also
an argument against: under
isolation = "none"a resume drives the loop in the main checkout,where pre-existing dirt is the same hazard
cmd_runrefuses over.This surfaced while scoping #460. The gate is what bounds that issue's practical reach — a fresh
runcannot begin over pre-existing dirt, so the reachable triggers are dirt appearing after therun starts, plus every
resume— and that reasoning only holds while the asymmetry is deliberateand documented. Right now it is neither confirmed nor written down.
Cheapest resolution may be a comment at the resume path plus a line in
docs/FEATURES.md, ratherthan a behavior change.