tickets: an injected plan_halt result for a built plan escalates with stopped-attempt wording
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 36/100
Hướng nghiên cứu
Start with the plan-halt flow in src/bmad_loop/tickets_engine.py around _drive_story and the result handling at lines 1418-1437; then compare the expected status check in src/bmad_loop/verify.py with result synthesis in src/bmad_loop/devcontract.py. Reproduce with the supplied MockAdapter script and compare the injected plan_halt case with overrun-synth. Done means a supported adapter or reproducible race is identified, or the inconsistent result gets a clearer diagnostic without weakening verification.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Status (needs confirmation)
- Observed (3/3, engine seam): for an unrefined
plan_checkpointticket, a leg-1 session (aMockAdapterresult injected by the script) that builds and commits pastHalt after planning.behaves as follows:- without
plan_haltin its result, the run pausesplan-checkpointwith "plan review owed for 1.1: the skill implemented before the plan checkpoint" (the dedicated path); - with
"plan_halt": truein its result, it pausesescalationwith "ACTION REQUIRED — manual recovery needed (committed work present) … attempt was stopped with auto-rollback OFF". Thedev-decisionisretrywith "spec status is 'built', expected 'ready-for-dev'".
- without
- Observed control: a leg 1 that honours the halt (plan at
ready-for-dev,plan_halt: true, nothing committed) pausesplan-checkpoint"plan checkpoint for 1.1: review the spec, then resume". - Measured additional control: production
devcontract.synthesize_result(..., plan_halt=True, success_statuses=("built",))omitsplan_haltfor the same built plan, and the engine then pauses with "plan review owed". It setsplan_haltforready-for-dev. A live build-auto/GenericDevAdapter run was not performed, and no operator path producing the contradictory marker has been demonstrated. - Still needed: demonstrate a supported adapter or a reproducible result/plan race that supplies
plan_halt: truewhile the bound plan isbuilt. A skill merely ignoring the halt does not establish that precondition. If you have seen such a result from a real session, please confirm here with the result JSON and the pause stage and message.
Summary
With an injected MockAdapter result containing plan_halt: true and a committed built plan, verification rejects the plan's status and the run pauses for manual recovery. The same built plan processed by production result synthesis reaches the dedicated "plan review owed" pause. No confirmed normal build-auto failure is shown. The guide's promise holds in every row (no bmad-loop commit happens and the run pauses); what differs is the pause: with the flag set, the overrun becomes a failed attempt and an escalation that says the attempt "was stopped" and asks for manual recovery of committed work, instead of the "plan review owed" pause that TicketsEngine._drive_story has for an overrun.
Environment
bmad-loop a5a8f097, Windows 11 10.0.26200, PowerShell 7.6.6 (SHELL unset), Python 3.13.2; TicketsEngine with MockAdapter as an engine seam (not a live generic-adapter validation; no coding CLI); Linux: not run, platform parity unmeasured.
Steps to reproduce
From a bmad-loop checkout at a5a8f097 after uv sync --all-extras, in PowerShell 7 with SHELL removed. Save the script outside the checkout as $env:TEMP\overrun-repro\repro_overrun.py, then run from the checkout root (the script imports the test helpers from tests). Each run creates its sandbox under $env:TEMP.
Remove-Item Env:SHELL -ErrorAction SilentlyContinue
$env:PYTHONUTF8 = '1'
$s = "$env:TEMP\overrun-repro\repro_overrun.py"
uv run python $s overrun-flag # trigger: injected plan_halt on a built plan
uv run python $s overrun # control: no plan_halt
uv run python $s halt # control: the halt honoured
uv run python $s overrun-synth # control: bmad-loop's own result synthesis for the built plan
import json, os, subprocess, sys, tempfile
from pathlib import Path
mode = sys.argv[1]
root = Path(tempfile.mkdtemp(prefix=f"overrun-{mode}-"))
os.environ["BMAD_LOOP_STATE_DIR"] = str(root.parent / (root.name + "-state"))
sys.path.insert(0, "tests")
import conftest as C
from bmad_loop import verify
from bmad_loop.adapters.base import SessionResult
from bmad_loop.adapters.mock import MockAdapter
from bmad_loop.bmadconfig import load_paths
from bmad_loop.journal import Journal, load_state
from bmad_loop.model import RunState
from bmad_loop.policy import GatesPolicy, NotifyPolicy, Policy, ReviewPolicy
from bmad_loop.tickets_engine import TicketsEngine
git = lambda cwd, *a: subprocess.run(["git", "-C", str(cwd), *a], capture_output=True, text=True, check=True).stdout.strip()
lay = C.install_bmad_v7(root)
(root / "src.txt").write_text("original\n", encoding="utf-8")
(root / ".gitignore").write_text(C.V7_GITIGNORE, encoding="utf-8")
C.write_ticket_tree(lay, (C.EpicSpec(1, "epic-cart", "Cart", (C.EntrySpec(1, "Cart model", plan_checkpoint=True),)),))
C._commit_template(root)
plan = Path(C.run_tickets(lay, "find", "1.1")["plan"])
def leg1(spec):
cwd, base = Path(spec.cwd), verify.rev_parse_head(Path(spec.cwd))
if mode.startswith("overrun"): # ignores "Halt after planning.", builds and commits its own work
(cwd / "src.txt").write_bytes(b"cart model\n")
plan.write_bytes(f"---\nticket: 1\nstatus: built\nbaseline_revision: '{base}'\n---\n\n# plan\n".encode())
git(cwd, "add", "-A"); git(cwd, "commit", "-q", "-m", "build 1.1")
status = "built"
else: # honours the halt
plan.write_bytes(f"---\nticket: 1\nstatus: ready-for-dev\nbaseline_revision: '{base}'\n---\n\n# plan\n\nsteps\n".encode())
status = "ready-for-dev"
result = {"workflow": "auto-dev", "spec_file": str(plan), "status": status}
if mode in ("halt", "overrun-flag"):
result["plan_halt"] = True
if mode == "overrun-synth": # control: bmad-loop's own result synthesis for the same built plan
from bmad_loop.devcontract import synthesize_result
result = synthesize_result(plan, story_key="1.1", plan_halt=True, success_statuses=("built",)).result_json
print(" synthesized:", {"status": result.get("status"), "plan_halt": result.get("plan_halt")})
return SessionResult(status="completed", result_json=result)
run_dir = root / ".bmad-loop" / "runs" / "r1"
state = RunState(run_id="r1", project=str(root), started_at="now", initiative=lay.initiative, initiative_folder=str(lay.initiative_folder))
TicketsEngine(paths=load_paths(root, want_tickets=True),
policy=Policy(gates=GatesPolicy(mode="none"), notify=NotifyPolicy(desktop=False, file=True), review=ReviewPolicy(enabled=False)),
adapter=MockAdapter([leg1] * 3), run_dir=run_dir, journal=Journal(run_dir), state=state).run()
st = load_state(run_dir)
print(f"{mode}: paused_stage={st.paused_stage}\n reason: {(st.paused_reason or '').splitlines()[0][:160]}")
print(" journal:", [json.loads(l)["kind"] for l in (run_dir / "journal.jsonl").read_text(encoding="utf-8").splitlines()])
Observed (Windows; trigger and the first two controls 3/3, the synthesis control in its own runs):
overrun-flag: paused_stage=escalation
reason: **ACTION REQUIRED — manual recovery needed (committed work present)**
journal: ['story-start', 'plan-halt', 'session-start', 'session-end', 'dev-decision', 'rollback-manual-required', 'run-paused']
overrun: paused_stage=plan-checkpoint
reason: plan review owed for 1.1: the skill implemented before the plan checkpoint — review the spec, then resume
journal: ['story-start', 'plan-halt', 'session-start', 'session-end', 'dev-decision', 'checkpoint-pause', 'run-paused']
halt: paused_stage=plan-checkpoint
reason: plan checkpoint for 1.1: review the spec, then resume
journal: ['story-start', 'plan-halt', 'session-start', 'session-end', 'plan-halt-proof-of-work-skipped', 'dev-decision', 'checkpoint-pause', 'run-paused']
synthesized: {'status': 'built', 'plan_halt': None}
overrun-synth: paused_stage=plan-checkpoint
reason: plan review owed for 1.1: the skill implemented before the plan checkpoint — review the spec, then resume
journal: ['story-start', 'plan-halt', 'session-start', 'session-end', 'dev-decision', 'checkpoint-pause', 'run-paused']
Source
At a5a8f097:
src/bmad_loop/tickets_engine.py:1002-1034(_drive_story): the comment says "a session that overran the halt still owes the review"; a false return from_dev_phaseexits before either checkpoint pause (_pause_plan_checkpoint,_pause_plan_review_owed).src/bmad_loop/tickets_engine.py:1418-1437: takesbool(result["plan_halt"]), setstask.plan_checkpoint_pending, and passes that flag toverify_dev_tickets.src/bmad_loop/verify.py:9445-9456: selectsPLAN_HALT_STATUS(ready-for-dev) for a marked result andPLAN_BUILTotherwise, so a markedbuiltplan fails (observed as thedev-decisionretry reason).src/bmad_loop/devcontract.py:163-164: "the seam is gated onplan_halt, never on the status alone",PLAN_HALT_STATUS = "ready-for-dev".src/bmad_loop/devcontract.py:635-639: result synthesis marks only a cleanready-for-devresult (if plan_halt and status == PLAN_HALT_STATUS and not escalations: result["plan_halt"] = True);src/bmad_loop/adapters/generic.py:3013-3031calls that synthesizer with the dispatched plan-halt flag.src/bmad_loop/recovery_flow.py:2604-2625: the "stopped" and committed-work recovery wording observed.
Suggested fix
Not validated: consider clearer diagnostic wording for inconsistent adapter results. Do not relax the expected-status verification or route contradictory results to plan approval without a demonstrated supported user path and an explicit contract decision.
- Ngôn ngữ chính
- Python
- Star
- 160
- Fork
- 68
- Merge trung bình
- 1 ngày 6 giờ
- Pull request đã merge (30 ngày)
- 90
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của bmad-code-org/bmad-loop
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 69/100
bmad-code-org/bmad-loop#973 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
bmad-code-org/bmad-loop#965 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
bmad-code-org/bmad-loop#835 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
area:adapters area:psmux bug P4
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
bmad-code-org/bmad-loop#673 · 8 bình luận · 1 reaction ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 4/5 1-2 ngày Mức phù hợp với người mới 49/100
bmad-code-org/bmad-loop#971 ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của bmad-code-org/bmad-loop
Issue tương tự
-
[Bug]: `hermes plugins update` clones an entire monorepo twice - `subdir` is resolved but dropped at both catalog-update call sitesCó thể đã có người làm @HootRock đã nhận hôm nay. Đang mởcomp/cli P2 type/perf
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
NousResearch/hermes-agent#142417 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
bug enhancement python
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 85/100
DewaldOosthuizen/tech-cheat-sheets-and-notes#392 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
Maintainer thường phản hồi trong vòng 1 ngày
-
bug p2
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Restore postgresql_vm_test_charm actions.yaml change (removed in canonical/postgresql-operator#2054)Đang mở
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 85/100
canonical/postgresql-single-kernel-library#390 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 2 ngày