install: the rollback's sibling-scan decline claims a flag it may never have set
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 84/100
Research direction
Start in src/bmad_loop/install.py:1963-1968 and compare Block A with the hedged wording in _shield_undo_extension's tail. Check the shield bullet in docs/FEATURES.md and update the existing Block-A reason tests. Done means the sibling-scan report no longer overclaims flag provenance while rollback behavior remains unchanged.
Written by the indexing model from the issue text.
Description
_shield_undo_extension's sibling-scan decline clause (src/bmad_loop/install.py:1963-1968)
reports the flag as a settled fact:
if dependent is not None:
return (
"; extensions.worktreeConfig was deliberately LEFT enabled — "
f"{dependent} exists, so another worktree's shield depends "
"on the flag and unsetting it would stop git reading that file"
)
"was deliberately LEFT enabled" asserts both that the flag is enabled and that this call
is what left it that way. Neither is guaranteed on the path that reaches it.
Why it can be false. One of the two call sites is the enable's own raise path
(install.py:2617-2627):
try:
enabled = git_bytes(worktree, "config", "extensions.worktreeConfig", "true")
...
except GitError as e:
enable_fault = str(e)
rolled_back = _shield_undo_extension(worktree, git_dir, common_dir)
GitError there covers a spawn failure (GitSpawnError) and a timeout, so the write may
have produced nothing at all. If a sibling config.worktree then exists, the scan declines
and this clause claims a flag that may be:
- absent — the enable never ran, and nothing set it; or
- operator-authored — set outside bmad-loop, which the function's own docstring already
says is possible ("an operator, an older bmad-loop, orgit sparse-checkoutcan set the
same flag outside it").needs_enableis probe-derived and cannot tell "we enabled it"
from "we both thought we did".
The asymmetry. The tail of the same function (install.py:1995-2004) already carries the
hedge discipline for exactly this reason, and says so in a comment:
# Both clauses HEDGE whether this shield set the flag, and must: reached from the
# enable's own raise, a spawn failure can kill the enable and this unset alike,
# having written nothing at all. ...
return (
"; extensions.worktreeConfig could NOT be "
f"rolled back ({detail}) — if this shield set the flag, the repository keeps "
"a permanent format change that shields nothing"
)
The comment says "Both clauses HEDGE" — Block B's wording does, Block A's never did.
Impact. Reporting only; the rollback's behavior is correct either way (declining to
unset a flag a sibling depends on is the right call, whoever set it). What is wrong is the
journaled/notified reason an operator reads: it can send them looking for a permanent
repo-format change this run did not make, or describe their own deliberate config line as
something bmad-loop left behind.
Suggested fix. Give Block A the same conditional voice as Block B — e.g. name the
observed dependency and hedge the provenance ("… is left as it stands", "if this shield set
the flag …") rather than asserting deliberately LEFT enabled. Docs that quote the
guarantee (docs/FEATURES.md shield bullet: "surviving in two cases the reason
distinguishes") should be checked for the same overclaim, and the existing Block-A reason
tests updated with it.
Provenance. Found during the #394 / #396 / #403 shield-transaction program while reading
_shield_undo_extension for #394 and #396. Deliberately left alone there — it is
pre-existing, wording-only, and outside all three issues' scope — and filed here instead.
- Dominant language
- Python
- Stars
- 137
- Forks
- 60
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 44
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from bmad-code-org/bmad-loop
-
area:adapters enhancement good first issue P3
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
bmad-code-org/bmad-loop#780 · 2 comments ·
-
Re-cut test_merge_stray_dirt_escalates_with_clear_message to pin the hazard-first refusal lead-in Openarea:engine bug P3
Difficulty 2/5 1-3 hours Newbie friendliness 87/100
bmad-code-org/bmad-loop#683 ·
-
area:adapters area:psmux bug P4
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
bmad-code-org/bmad-loop#673 · 7 comments · 1 reaction ·
-
area:tui enhancement P4
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
bmad-code-org/bmad-loop#666 · 1 comment · 1 reaction ·
-
bug P4
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
bmad-code-org/bmad-loop#665 · 2 comments · 1 reaction ·
All issues in bmad-code-org/bmad-loop
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100