5e10351683
Implements the remaining observers from RFC #58548 (@thebizfixer), accepted as the design basis in the #64231 batch disposition: - on_kanban_worker_spawned: fires in the dispatch loop after spawn_fn returns and the worker PID is durably persisted (the RFC timing contract), in both the ready and review lanes. - on_kanban_worker_exited: tick-derived from detect_crashed_workers; fires after every reclaim/accounting txn has committed, carrying exit_kind / exit_code / outcome / retry_status. - on_kanban_worker_stale_claim: fires when release_stale_claims reclaims a TTL-expired claim; live-PID claim extensions and deferred reclaims stay silent. - on_kanban_task_updated: task-mutation boundary observer carrying changed_fields (field names only); fired by assign_task, set_model_override, and set_reasoning_effort, and by the dashboard plugin API's direct-SQL priority/title/body editors (single and bulk) through the new kanban_db.notify_task_updated seam. - on_kanban_dispatch_tick: re-port of PR #56066 (@laboratoiresonore), renamed per the taxonomy and fired strictly AFTER _dispatch_tick_lock is released; the sweeper found the original fired inside the lock, where a slow subscriber could extend the single-writer critical section and stall a sibling dispatcher. All five are observer-only (return values ignored), fire after the relevant write txn commits, and short-circuit on has_hook() so nothing is built when no consumer registers; every fire site is fully best-effort so a broken plugin can never break dispatch or a task mutation. No config surface added. Existing plugins and hook payloads are untouched. Mutation-boundary scope: every user-facing task-FIELD editor fires (assignee, priority, title, body, model/provider override, reasoning effort). Deliberately not wired: status transitions (they belong to the lifecycle hook family), dispatcher bookkeeping columns (worker_pid, workspace_path, claim columns — surfaced through the worker hooks instead), link/comment/attachment tables (not task-row writes), and the dispatcher's default-assignee auto-assign (already surfaced via DispatchResult.auto_assigned_default in the tick payload). notify_task_updated is the seam for wiring further paths. Docs: new rows plus a detail section in the shipped plugin-hook catalog. Tests: 30 new (9 worker lifecycle, 8 dispatch tick, 8 task updated, 5 dashboard mutation boundary), including a lock-probe contract test that fails if the tick hook ever fires inside the dispatch lock. Refs: RFC #58548, #64231 batch disposition, folds #56066.