Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,24 @@ breaking changes may land in a minor release.
`failed` or `dirty` — never an exception message, which `diagnose` would refuse to emit at all.
The `--json` key is additive and always present, so `STATUS_SCHEMA_VERSION` is unchanged.

- **`validate` now reports a binary that is on PATH but will not run (#294).** The
`adapter.binary` gate asked `shutil.which`, which a dead WSL/npm shim satisfies — it is a real
file with the execute bit — so validate went green on an install that could not start a session,
and the opencode adapter's own "binary not found" error sent the user to `bmad-loop validate` to
be told everything was fine. Each binary named by a **packaged** profile is now run once as
`<binary> --version`; a nonzero exit or a launch fault reports the new check id
`adapter.binary-unrunnable`, carrying the resolved path and the return code. A project overlay's
profile is resolved and reported found but never launched: its fields are project-supplied, and
validate is the command used to decide whether a checkout is safe to run at all, so a clone's own
config cannot choose which binary it launches. The gate bounds which NAME is probed, not what
that name resolves to — resolution runs through the user's `PATH`, and a probed name resolves to
whatever the session launch would itself run. That boundary is the profile's provenance and not the spelling of
`binary`, because a bare name still resolves into the checkout whenever a checkout-local
directory is on `PATH`. The severity is `warning`, so validate's exit code is
unchanged for a live CLI that merely answers `--version` oddly, and `adapter.binary` keeps its
existing found/absent meaning. The check id is additive, so `VALIDATE_SCHEMA_VERSION` is
unchanged.

### Changed

- **Files the orchestrator replaces by name now land at `0600`.** Those writes pass
Expand Down Expand Up @@ -50,6 +68,10 @@ breaking changes may land in a minor release.

### Fixed

- **The zero-token OpenCode live smoke skips stale or broken shims (#294).** Its availability
gate now requires `opencode --version` to succeed before starting a server; runnable installs
still fail loudly when the pinned API contract drifts.

- **Policy loading now enforces the declared timeout and result-less Stop nudge minima (#648).**
The valid `session_timeout_min = 1` and `stop_without_result_nudges = 0` boundaries remain
accepted, while smaller values now raise `PolicyError`.
Expand Down
2 changes: 1 addition & 1 deletion docs/FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ See [README.md](../README.md) for the narrative overview and [setup-guide.md](se
### Setup & install

- `bmad-loop init` installs the three `bmad-loop-*` skills (`bmad-loop-setup`, `bmad-loop-resolve`, `bmad-loop-sweep`, into `.claude/skills/` and/or `.agents/skills/`), the hook relay, `.bmad-loop/policy.toml`, and a gitignore covering the runs dir, plugin caches, and policy.toml itself (per-machine config). Flags: `--cli` (repeatable), `--no-skills`, `--force-skills`.
- `bmad-loop validate` preflights every prerequisite: BMAD config, sprint-status, git, the selected terminal-multiplexer backend (listing all detected when more than one is registered), CLI binary, hook registration, and the review skills the installed dev primitive actually invokes (reporting which name it resolved) — derived from its `customize.toml` review layers (or from `step-04-review.md` on releases that name reviewers inline), so both the merged `bmad-review` topology and the standalone-hunter one validate, and configured layers naming an uninstalled skill are caught — plus its `customize.toml`.
- `bmad-loop validate` preflights every prerequisite: BMAD config, sprint-status, git, the selected terminal-multiplexer backend (listing all detected when more than one is registered), CLI binary (**probed, not just resolved**: a name that is on `PATH` but fails `--version`, typically a dead WSL/npm shim, adds an `adapter.binary-unrunnable` finding at warning severity — `adapter.binary` itself still reports ok, and validate's exit code is unchanged — [#294](https://github.com/bmad-code-org/bmad-loop/issues/294); only **packaged** profiles are probed — a project overlay's binary is resolved but never launched, so a clone cannot choose which binary this diagnostic launches; resolution still goes through your `PATH`, so what a probed name resolves to is whatever the session launch would itself run), hook registration, and the review skills the installed dev primitive actually invokes (reporting which name it resolved) — derived from its `customize.toml` review layers (or from `step-04-review.md` on releases that name reviewers inline), so both the merged `bmad-review` topology and the standalone-hunter one validate, and configured layers naming an uninstalled skill are caught — plus its `customize.toml`.
- The preflight also **names the multiplexer selection reason wherever selection resolves** (`mux.selection`, e.g. `platform default for win32`), not only when a `BMAD_LOOP_MUX_BACKEND`/`[mux] backend` choice forced it. A `fallback` selection is reported as a warning (its own label says no available backend matches this platform); a selection that outright failed is carried by `mux.preflight`, and a detection that failed by `mux.backends-detected` at warning — so a missing `mux.selection` line is normally explained by another finding (the historical unregistered-tmux fallback is the one silent exception; see the `--json` contract note in `documents.py`). On top of that, `host.win32-on-wsl-path` warns when a **native-Windows interpreter is working on a `\\wsl.localhost\...` project** ([#332](https://github.com/bmad-code-org/bmad-loop/issues/332) — see [multiplexer-backends.md](multiplexer-backends.md) for why WSL can hand a bash prompt the Windows build). Both are diagnostics only: neither changes which backend is selected (psmux _is_ correct for a `win32` interpreter) and neither flips validate's exit code. `bmad-loop diagnose` carries the same two facts in its Environment block as `sys.platform` and `win32 on WSL distro path` (`yes`/`no`).
- Non-invasive: drives the upstream dev primitive unmodified — there is no fork to keep in sync — and review is just a re-invocation of it on the `done` spec. Your standard BMAD install is never modified.

Expand Down
Loading