Skip to content

Add a node:test unit suite for the HUD daemon event-ingestion pipeline to protect ADR-003 side-effect correctness #328

Description

@arndvs

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

  1. 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.

  2. 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.
    • context event regexes (Active contexts: / ACTIVE_CONTEXTS=).
    • Buffer bounds: per-project event buffer capped at 500, violations map capped at 100, compliance history capped at 30.
  3. 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.

Non-goals

Boundary alignment

  • ADR-003 (binding): HUD is read-only/observational; this adds no producer-side behavior and does not influence agents.
  • ADR-007 (accepted): a recorded design behavior (event side effects) is currently enforcement-by-prose; this adds the missing check.

Proposed by: automated source:architecture-review pass.

Metadata

Metadata

Assignees

No one assigned

    Labels

    source:architecture-reviewPRDs proposed by the automated architecture-review workflow

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions