You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
bin/hud-daemon.js (1,099 lines) is the largest single module in the repo with zero tests. It implements the ADR-003 ingestion boundary: it parses every HUD event from six input dialects and decides which side effects fire (violation tracking, compliance updates, context updates, loaded-files bookkeeping). By contrast, the bridge subsystem (~3,200 lines) ships 15 Python test files, and every existing test-covering ticket (#178 hooks, #275 engine-lib, #284 workflow runners) targets other modules — the daemon is the one large subsystem with no verification gate.
The architectural gap: processLine() (bin/hud-daemon.js:298) is a hand-rolled parser whose correctness is load-bearing and untested. A single event-type typo or malformed pipe line silently drops violation tracking or compliance updates with no error — the exact silent operational degradation ADR-006's "blocked mistake vanishes" concern and ADR-003's fire-and-forget contract ("agent performance is not affected by HUD availability") both depend on not regressing. The repo's only daemon touchpoint is a path-style grep (test/lifecycle.sh:201), which verifies paths, not behavior.
Goal
Protect the daemon's event-processing logic — parsing, side-effect dispatch, and boundary thresholds — behind a unit suite that runs in CI, so a regression in event interpretation is caught in a test run instead of as an AFK-loop surprise.
Proposed scope
Expose a test seam. Refactor bin/hud-daemon.js so the pure functions (processLine, handleRead, handleViolation, handleComplianceUpdate, handleComplianceResult, handleContext, and the buffer/prune helpers) are exported (or extracted to a small sibling module) and callable without a real pipe, HTTP server, or WebSocket — the same seam pattern Harden HUD WebSocket fan-out: add backpressure to broadcast() and a daemon transport test seam #308 endorsed for the transport path. Startup (lock dir, PID file, listeners) stays in the daemon entrypoint.
Unit suite with node:test + node:assert. Built-in since Node 18 (the package.json engine floor), zero new dependencies, matching ADR-003's self-contained design. Tests must cover:
Pipe-dialect parsing: ^Read <path> line, TYPE|project|path|contexts|message pipe format, JSON payload (from write-hud-state.sh), malformed/unparseable line dropped without throwing, and an event-type typo dropping side effects (regression for silent loss).
Violation state machine: fail events transition healthy → warning at 1–2 → error at ≥3 (handleViolation).
Compliance rolling window: compliance_update combining rate via the 70/30 average, and compliance-result rate derivation from pass/fail/warn counts.
Buffer bounds: per-project event buffer capped at 500, violations map capped at 100, compliance history capped at 30.
Wire into CI. Add a hud-daemon suite to the SUITES array in test/run-all.sh (the ledger gate already requires it to emit assertion evidence), or an equivalent CI call. No change to any producer, transport, or event type.
Acceptance criteria
node --test (or equivalent) passes with tests for: parse branches, violation threshold transitions, compliance rolling average, context extraction, and buffer caps.
A deliberately-malformed event (bad dialect, typo'd type) is proven to drop safely without throwing, and a typo that loses a side effect is pinned by a regression test.
The suite runs in CI as a registered suite in test/run-all.sh and produces assertion evidence (no ledger violation).
npm start still boots the daemon with no behavioral change; npx tsc --noEmit-equivalent checks remain green for the extracted module.
Problem
bin/hud-daemon.js(1,099 lines) is the largest single module in the repo with zero tests. It implements the ADR-003 ingestion boundary: it parses every HUD event from six input dialects and decides which side effects fire (violation tracking, compliance updates, context updates, loaded-files bookkeeping). By contrast, the bridge subsystem (~3,200 lines) ships 15 Python test files, and every existing test-covering ticket (#178 hooks, #275 engine-lib, #284 workflow runners) targets other modules — the daemon is the one large subsystem with no verification gate.The architectural gap:
processLine()(bin/hud-daemon.js:298) is a hand-rolled parser whose correctness is load-bearing and untested. A single event-type typo or malformed pipe line silently drops violation tracking or compliance updates with no error — the exact silent operational degradation ADR-006's "blocked mistake vanishes" concern and ADR-003's fire-and-forget contract ("agent performance is not affected by HUD availability") both depend on not regressing. The repo's only daemon touchpoint is a path-style grep (test/lifecycle.sh:201), which verifies paths, not behavior.Goal
Protect the daemon's event-processing logic — parsing, side-effect dispatch, and boundary thresholds — behind a unit suite that runs in CI, so a regression in event interpretation is caught in a test run instead of as an AFK-loop surprise.
Proposed scope
Expose a test seam. Refactor
bin/hud-daemon.jsso the pure functions (processLine,handleRead,handleViolation,handleComplianceUpdate,handleComplianceResult,handleContext, and the buffer/prune helpers) are exported (or extracted to a small sibling module) and callable without a real pipe, HTTP server, or WebSocket — the same seam pattern Harden HUD WebSocket fan-out: add backpressure to broadcast() and a daemon transport test seam #308 endorsed for the transport path. Startup (lock dir, PID file, listeners) stays in the daemon entrypoint.Unit suite with
node:test+node:assert. Built-in since Node 18 (the package.json engine floor), zero new dependencies, matching ADR-003's self-contained design. Tests must cover:^Read <path>line,TYPE|project|path|contexts|messagepipe format, JSON payload (from write-hud-state.sh), malformed/unparseable line dropped without throwing, and an event-type typo dropping side effects (regression for silent loss).failevents transition healthy → warning at 1–2 → error at ≥3 (handleViolation).compliance_updatecombining rate via the 70/30 average, andcompliance-resultrate derivation from pass/fail/warn counts.contextevent regexes (Active contexts:/ACTIVE_CONTEXTS=).Wire into CI. Add a
hud-daemonsuite to theSUITESarray intest/run-all.sh(the ledger gate already requires it to emit assertion evidence), or an equivalent CI call. No change to any producer, transport, or event type.Acceptance criteria
node --test(or equivalent) passes with tests for: parse branches, violation threshold transitions, compliance rolling average, context extraction, and buffer caps.test/run-all.shand produces assertion evidence (no ledger violation).npm startstill boots the daemon with no behavioral change;npx tsc --noEmit-equivalent checks remain green for the extracted module.Non-goals
.unref()— owned by Harden HUD WebSocket fan-out: add backpressure to broadcast() and a daemon transport test seam #308).Boundary alignment
Proposed by: automated
source:architecture-reviewpass.