Skip to content
Merged
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ breaking changes may land in a minor release.
- Write each OpenCode 2.x provider-error event to `logs/<task-id>.provider-errors.log`;
classify rate-limit and transport outages there as environment faults and quota
failures as a blocking usage limit (#847).
- Render OpenCode 2.x forms in the `[bmad]` transcript: a `form ask` line naming the form
and its questions when one parks the turn, then `form reply` or `form cancelled`.
- Add the `subagent_transcript_dir` CLI profile field: a subagent transcript tree whose
writes count as session activity for the idle notice (#858).
- Name the tool call an idle Claude session is waiting on: `session-idle` carries
Expand Down Expand Up @@ -218,6 +220,25 @@ breaking changes may land in a minor release.

### Fixed

- Count OpenCode 2.x subagent (child) session tokens, at every nesting depth, in recorded
usage and the budget guard's samples; a failed child walk is a `usage-capture-failed`
(`stage=children`) fault, never a parent-only figure. A child still running at capture
is journaled as `usage-child-active` (DW-540).
- Ignore an Antigravity `Stop` sent with `fullyIdle: false` (a yield to a foreground
subagent) instead of completing the session while the subagent still works; the
relay forwards `fully_idle`, and `hook-stop-yield-ignored` journals the skip.
- Ignore an Antigravity subagent conversation's `Stop` instead of letting its final turn end
complete the parent early: the new profile key `subagent_spawn_marker` identifies a child
by the spawn file its parent wrote, and `subagent-stop-ignored` journals each child.
- Count an Antigravity subagent's writes as its parent's activity, so a parent blocked on a
long foreground subagent no longer journals a false `session-idle`: the idle notice walks
each child conversation the parent's `subagent_spawn_marker` files list.
- Classify OpenCode 2.x provider 5xx errors (`provider.internal`), rejected credentials
(`provider.auth`) and unroutable models (`provider.no-route`) as environment faults
instead of charging the session as a code failure.
- Let sandboxed Codex sessions commit under worktree isolation: grant them write access to
the linked worktree's gitdir and the main repo's `.git`. `validate` warns only when
`extra_args` drops the grant or the profile's grant misses either path.
- Pause a tickets resume at `ticket-tree` (`binding-moved`) when an in-flight unit's ticket
was moved with `tickets.py move` or its plan is gone, naming the old and new ref and plan,
instead of re-dispatching a ref the tree no longer holds (DW-575).
Expand Down
4 changes: 2 additions & 2 deletions docs/FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ bmad-loop drives a BMAD sprint unattended: a deterministic Python loop launches
- `bmad-loop resume` re-runs the probes; if they pass, the withheld session launches with no rollback, and otherwise the run pauses again unchanged.
- A verify command exiting 126, 127 or `[verify] env_fault_rc` is an environment fault, not a code failure.
- A non-completed session whose log tail matches its profile's `env_fault_patterns` pauses instead of spending a dev attempt.
- opencode is classified from model-free files only: the server's stdout, plus on OpenCode 2.x the adapter-written `provider-errors.log` (one line per provider-error event). Its 2.x environment-fault patterns cover the `provider.rate-limit` and `provider.transport` error types; `provider.quota` is a usage limit.
- opencode is classified from model-free files only: the server's stdout, plus on OpenCode 2.x the adapter-written `provider-errors.log` (one line per provider-error event). Its 2.x environment-fault patterns cover the `provider.rate-limit`, `provider.transport`, `provider.internal` (a provider 5xx), `provider.auth` and `provider.no-route` error types; `provider.quota` is a usage limit, and error types the session's own request can cause (`provider.invalid-request`, `provider.invalid-output`) stay unclassified.
- A pattern match is overruled when the session's tracked token usage is nonzero; that session is charged like any failure.
- A session that times out, stalls or crashes after a live usage-limit sighting pauses with a `usage limit:` reason and is never charged, whatever its token usage. A live sighting is a match for the profile's `usage_limit_patterns` or `usage_wait_patterns` from one of two sources: the visible pane of a tmux-hosted CLI such as claude, on an idle session at stall-grace expiry or when the timeout fires; or an opencode 2.x provider-error line, matched as the adapter writes it while the session runs (opencode's shipped profile lists `provider.quota` there as a blocking limit). The same line found only in the log tail stays subject to the overrule.
- When the usage-limit line names a reset time, the pause reason ends its evidence with `; resets <time>` (ISO-8601 when the time resolves, the raw text otherwise).
Expand Down Expand Up @@ -358,7 +358,7 @@ bmad-loop drives a BMAD sprint unattended: a deterministic Python loop launches
- A stage inherits the base mode even when it switches client; `[adapter.<stage>] permission_mode` overrides it.
- `bmad-loop resolve` sessions, where a human is present, keep the bypass flags whatever the mode.
- `validate` reports each role's permission posture as `adapter.permission-mode`, suggesting `sandboxed` for an unsandboxed role without worktree isolation when the profile maps it. The note is advisory: a worktree is not a security boundary.
- Sandboxed Codex under `scm.isolation = "worktree"` is a warning: the sandbox keeps a linked worktree's gitdir read-only, so git add and commit fail.
- A sandboxed Codex session in a linked worktree (`scm.isolation = "worktree"`) gets exact-path write grants for that worktree's gitdir and the main repo's shared `.git`, so git add and commit work. `validate` warns only when the grant cannot ride: an `extra_args` override replaces the mode's args and drops it, or the profile's mode declares no `linked_worktree_args` or a grant missing `{gitdir}` or `{common_dir}`.
- `tickets.store-sandbox` also warns when a sandboxed role writes a ticket store outside its cwd.
- **Config:** `[adapter] permission_mode`, `[adapter.dev]` / `[adapter.review]` / `[adapter.triage]` / `[adapter.retro]` `permission_mode`; profile table `[permission_modes.<mode>]`
- **Tested by:** `tests/test_policy.py`, `tests/test_profile.py`, `tests/test_runsetup.py`, `tests/test_cli.py`, `tests/test_codex_trust.py`, `tests/test_install.py`
Expand Down
Loading
Loading