Releases: braedonsaunders/bb-plugin-ultragoal
Releases · braedonsaunders/bb-plugin-ultragoal
Release list
v0.17.8 — ghost-turn recovery and persistent goal chips
What changed
- Recovers OpenCode UltraGoal roots from ghost-turn and duplicate
turn.submitfailures before compact/continue. - Prevents wedge recovery and progress check-ins from racing a second start.
- Revives transiently blocked roots and treats already-active / missing ACP session failures as recoverable.
- Keeps the left-sidebar UltraGoal chip for every durable goal state—running, paused, blocked, limited, or complete—until the goal is cleared, matching the right pane.
- Replaces the failure-prone sidebar crew payload with a lightweight validated projection and adds regression coverage.
Verification
- 27 tests passing
- TypeScript check passing
- BB plugin build passing
- SDK 0.4.8 compatibility check passing
- Package dry-run passing
v0.17.4 — blocked goals still land work
- Landed work is recorded even while the goal reads blocked. "Blocked" almost always means the ROOT thread died, but slice completion and the ready-queue scheduler both refused to run in that state — so a worker could fix a defect, commit it, and call slice_done while the plugin silently discarded the completion and never merged the branch. Completion, integration, and staffing now proceed for blocked goals; only paused/complete stop the machinery.
v0.17.3 — compact repeatedly-dying roots
- Repeated root deaths trigger context compaction: a root that needs reviving more than once is usually drowning in its own session (turn submission fails under giant-context load — the openbooks root died three times in an hour at 800M+ tokens). The second and later revivals request bb's thread compaction before resuming.
v0.17.2 — errored roots revive themselves
- Errored roots revive themselves: a provider turn failure left the orchestrator thread in error state indefinitely — auto-resume (0.16.3) only reconciled the goal once the root ran again, and nothing restarted it. The pulse now revives an errored root with exponential backoff (2m doubling to a 30m cap, reset on a real turn), completing the self-healing set: workers three-strike restaff, wedged root turns get stopped, blocked goals reconcile on recovery, and dead roots restart.
v0.17.1 — long decision questions raise their card
- Decision cards raise for long questions: the interaction title caps at 160 characters and a full-length question was rejected outright — the keeper retried every pulse for ten minutes while the owner saw nothing. Titles now truncate (the card body always renders the full question from the payload), and a failing prompt backs off ten minutes instead of retry-spamming.
v0.17.0 — completion is a report, not a label
Completion is a report, not a status label:
- update_goal complete now REQUIRES a delivery summary — what shipped, where it lives (URLs, final HEAD SHA, deploy state), and how it was verified. It is stored durably on the goal.
- The pane renders a completion report when a goal finishes: a check header with the objective, a stats grid (slices delivered, findings fixed, decisions answered, workers, tokens, duration), the delivery summary as Markdown, and the full Delivered list.
bb ultragoal statusprints the summary.
v0.16.4 — root-turn watchdog
- Root-turn watchdog: an orchestrator that stays "active" while its timeline stops growing for 10 minutes is wedged in a provider turn, with queued steers piling up unprocessed behind it. Workers already had the three-strike retire; the root now gets stopped and auto-continued, which also flushes its message queue. (Field case: a root sat "Working…" for 20 minutes with zero output and a growing steer backlog while its goal showed no open work.)
v0.16.3 — recovery reconciles goal status
- A blocked or usage-limited goal auto-resumes when its root thread runs again. thread.failed marked the goal blocked on any turn error (including transient infrastructure failures like "Command turn.submit failed"), but nothing flipped it back when the root recovered — the pane read Blocked/Stopped over a healthy, restarted thread. Recovery counts as a wake event; paused goals stay paused (user intent).
v0.16.2 — durable intake cursor
- The intake cursor is durable (goals.intake_row_id): the in-memory cursor re-baselined on every plugin reload and silently swallowed the first owner message after each reload — during active plugin development that was most of them. First-ever sighting per goal still baselines without replaying history; after that, no owner message is ever skipped.
v0.16.1 — the integration branch is local main, never origin
- The worker brief names the integration branch precisely: rebase onto the LOCAL default branch (worktrees share the project checkout's refs), never onto origin/* — origin lags the integration branch by design (pushing is the orchestrator's act) and can deliberately diverge from it during a history rewrite. (Field case: "rebase onto the latest default branch" was ambiguous; a worker resolved it as origin/main mid-rewrite-prep, hit unrelated histories, and had to abort — the orchestrator papered over it with a per-goal memory note that is now the contract.)