feat: board × radar fusion + observer dogfooding (PRD #8)#9
Merged
Conversation
Board becomes live mission control:
- New deep module board_liveness: liveness_for_tasks joins task artifacts'
runtime_session_id with scoped session discovery, extracts the latest
judge verdict, ~5s TTL cache (bounded), never raises to renderers
- Liveness dots on board cards + dashboard rows; judge summary line on
executing/qa cards; needs-human marker; /show Observer section
- bach config set (allowlisted observer knobs, typed + cross-field
validation); bach hooks install/status --project <name>
- Watcher spawn confirmation with log path; watcher stdout/stderr now
land in ~/.bach/logs/
Dogfooding fixes (loop proven end-to-end on a real session):
- hooks installer wrote a schema Claude Code silently ignored — rewritten
to the documented {matcher, hooks:[{type,command}]} shape with absolute
venv paths + migration of old entries
- sessions radar artifact join scanned ~/.bach instead of project-local
.bach/runs (ADR-002) — registry-wide scan
- zombie watcher: follow_events starved the spool when the transcript went
quiet — heartbeat ticks; spool matcher checked "type" but real events
carry hook_event_name; force_judge made one-shot; interval clock no
longer fires on first event; cold-start judge window backfilled from
transcript tail; observer same→same is a benign no-op; authority-
rejected verdicts still logged for display; codex stderr logged on
judge failure
- pre-existing NotImplementedError in the TCC skip banner (crashed the
REPL) implemented per its documented design
Acceptance evidence: full chain verified live — hooks → spool → watcher →
judge (codex, 12s, confidence 0.90) → authority-checked write → board
liveness join resolving t17 through real artifacts.
Closes #8
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements PRD #8 — and, per its dogfooding clause, the observer loop was run end-to-end on a real session before this PR, with every wiring defect that surfaced fixed in scope.
Features
board_liveness, the deep module): task ↔ session join via artifactruntime_session_id+ scoped discovery, latest judge verdict extraction, ~5s TTL cache (bounded, stale-on-failure), never raises to renderers/showObserver section, board legendbach config set(8 allowlisted observer knobs, typed + cross-field validation),bach hooks install/status --project <name>, watcher spawn confirmation +~/.bach/logs/watcher-*.logDogfooding found what unit tests couldn't
{"command", "run"}entries — a shape Claude Code silently ignores. Rewritten to the documented{matcher, hooks:[{type,command}]}schema with absolute venv paths (hooks don't have the venv on PATH) and migration of old entries.~/.bachinstead of project-local.bach/runsper ADR-002) — the Task column could never link. Registry-wide scan now.follow_eventsonly yielded on new transcript lines, so a closed session starved the spool forever. Fixed with heartbeat ticks + four follow-on bugs the heartbeat exposed (spool matcher checkedtypebut real events carryhook_event_name;force_judgere-fired every tick; the interval clock fired on the first event; cold-start judge windows had 1 unknown event — now backfilled from the transcript tail).NotImplementedErrorin the TCC skip banner crashed the REPL — implemented per its documented design.Acceptance evidence (real session, this repo)
Plus the live join:
t17: liveness=idleresolved through real artifacts + discovery.bach sessions close --pidexercised twice on real sessions (correctly refused to guess between two claude processes in one project — one of which was the implementing session itself).Tests: 1003 → 1028 passing. Review: 3 STOP + 3 DRIFT + 5 WATCH findings all fixed.
Closes #8
🤖 Generated with Claude Code