Skip to content

v0.9.0 — kind-aware background work (shell task quiescence + follow-up turns)

Latest

Choose a tag to compare

@dmora dmora released this 14 Jul 17:20
· 1 commit to main since this release
b2cb99b

Background shell tasks (Claude Code run_in_background) are now first-class, kind-tagged pending work — consumers can distinguish "turn ended, truly done" from "turn ended, background work pending" and relay the auto-resumed follow-up turn instead of dropping it. Closes #61. Full design: docs/designs/2026-07-13-issue-61-background-shell-tasks.md.

⚠️ Breaking changes

  • Message.Subagents *SubagentStatsMessage.Background *BackgroundStats — kind-tagged []TaskCounts with comma-ok Kind(k); a kind's absence means untracked, {0,0} means tracked-and-quiescent. Deliberately no union Pending(): a union gate hangs on never-terminating shell work (dev servers).
  • MessageSubagentResultMessageTaskResult — kind-neutral; a background bash completion is not a "subagent result".
  • MessageBackgroundTasks now carries all task kinds via new Message.Tasks []BackgroundTask{ID, Kind, Description}; the Tools overload is gone. A bash-only snapshot is no longer indistinguishable from "no background work".

New

  • BackgroundKind open vocabulary: BackgroundSubagent (expected to terminate), BackgroundShell (may never terminate — gate with a timeout); unknown backend kinds pass through sanitized.
  • cli.WithShellTracking() opt-in, gated by the ShellFeedBackend capability marker — only backends with a native background-task feed (Claude) ever stamp shell counts; feed-less backends structurally cannot report a false "tracked and quiescent".
  • Tracker: per-kind books with per-kind caps (128 pending / 32 stamped ids), first-observation-wins kind immutability, remove-before-add snapshot application, counters move only on genuine set mutations.

Consumer contract (ADR-7)

  • Subagents: wait until Background.Kind(BackgroundSubagent) drains to zero (unchanged policy).
  • Shell: never gate quiescence on it — watch with a timeout; if the task exits in the window, drain the auto-resumed follow-up turn. A test suite finishing → verdict captured; a dev server → timeout lapses, finish cleanly. Bounded-vs-unbounded within "shell" is unknowable to the library; the consumer's timeout is the arbiter.
  • Drain to quiescence before the next Send — buffered follow-up results otherwise misattribute to the next prompt.
  • Shell stamps are actionable only on persistent (streaming) subprocesses; teardown with pending work abandons it.

Verification

Per-kind e2e assertions on live-captured fixtures (checked into testdata/backgroundtask/), property-tested tracker invariants, adversarial review (two independent passes), make qa green.

Migration: msg.Subagents.Pending()counts, ok := msg.Background.Kind(agentrun.BackgroundSubagent); ok && counts.Pending() > 0.

Full changes: v0.8.1...v0.9.0

What's Changed

  • feat: kind-aware background work — shell task quiescence + follow-up turns (#61, v0.9.0) by @dmora in #63

Full Changelog: v0.8.1...v0.9.0