ECC/tests/hooks
Jamkris 086e44c964 fix(hooks): log fail-open breadcrumb on parse/read errors in metrics bridge
coderabbitai flagged: the two `catch` blocks in `readSessionCost`
silently swallowed every failure mode. A malformed `costs.jsonl`
row, a permission error opening the file, or any other unexpected
I/O failure would silently return zero cost — masking real
problems and feeding stale or zero numbers into
`ecc-context-monitor.js` (which then injects them as
`additionalContext` into the live model turn).

Fix two things, both fail-open-preserving:

1. **Inner JSON.parse catch** — count malformed lines and write
   one aggregated breadcrumb per call:

     [ecc-metrics-bridge] skipped N malformed line(s) in <path>

   Aggregating (rather than per-line) keeps a log-flooded
   `costs.jsonl` diagnosable without overwhelming stderr.

2. **Outer fs.readFileSync catch** — write a breadcrumb on real
   errors, but stay silent on `ENOENT`. The "no costs.jsonl yet"
   case is genuinely normal (no Stop event has fired this session)
   and producing noise on every PreToolUse before the first Stop
   would be reviewer-visible spam. All other error codes
   (`EACCES`, `EISDIR`, `EMFILE`, …) get:

     [ecc-metrics-bridge] failing open after <name> reading <path>: <msg>

In both cases the function still returns the zero-cost fallback
so the bridge never breaks tool execution — only the
diagnosability changes.

Two new regression tests in
`tests/hooks/ecc-metrics-bridge.test.js`:

  ✓ readSessionCost writes a stderr breadcrumb when malformed
    lines are skipped — feeds 4 rows (2 valid, 2 malformed),
    asserts the last valid row still wins AND captured stderr
    contains "skipped 2 malformed line(s)".

  ✓ readSessionCost stays silent when costs.jsonl does not exist
    (ENOENT) — uses a fresh tmp HOME with no metrics dir, asserts
    zero return AND empty stderr.

Test count: 16 → 18; `npm test` green; `yarn lint` clean.
2026-05-17 21:41:24 -04:00
..
auto-tmux-dev.test.js feat: add C++ language support and hook tests (#539) 2026-03-16 14:31:49 -07:00
bash-hook-dispatcher.test.js fix: consolidate bash hooks without fork storms 2026-04-14 21:23:57 -07:00
block-no-verify.test.js fix: close block-no-verify bypass holes 2026-05-12 22:28:12 -04:00
check-hook-enabled.test.js feat: add C++ language support and hook tests (#539) 2026-03-16 14:31:49 -07:00
config-protection.test.js fix: integrate recent hook and docs PRs (#1905) 2026-05-14 21:37:28 -04:00
continuous-learning-observe-runner.test.js fix: route continuous learning observe hooks through node 2026-04-29 21:28:59 -04:00
cost-tracker.test.js fix: integrate recent hook and docs PRs (#1905) 2026-05-14 21:37:28 -04:00
design-quality-check.test.js feat: add web frontend rules and design quality hook 2026-04-02 17:33:17 -07:00
detect-project-worktree.test.js fix(tests): resolve Windows CI test failures (#701) 2026-03-20 03:37:21 -07:00
doc-file-warning.test.js refactor: address reviewer feedback 2026-03-29 10:09:02 +08:00
ecc-context-monitor.test.js fix: add context monitor cost warning opt-out 2026-05-17 01:53:57 -04:00
ecc-metrics-bridge.test.js fix(hooks): log fail-open breadcrumb on parse/read errors in metrics bridge 2026-05-17 21:41:24 -04:00
ecc-statusline.test.js chore: update statusline ANSI color palette 2026-05-15 23:18:01 -04:00
evaluate-session.test.js fix: remove unused execFileSync import (no-unused-vars ESLint) 2026-02-18 07:15:53 +05:30
gateguard-fact-force.test.js fix(hooks): close grouped command bypasses in gateguard (#1912) 2026-05-15 01:39:15 -04:00
governance-capture.test.js fix: resolve blocker PR validation regressions 2026-03-25 01:34:29 -04:00
hook-flags.test.js feat: add C++ language support and hook tests (#539) 2026-03-16 14:31:49 -07:00
hooks.test.js fix: scope SessionStart context injection 2026-05-11 22:56:29 -04:00
insaits-security-monitor.test.js test: relax InsAIts monitor timeout 2026-05-11 19:38:21 -04:00
insaits-security-wrapper.test.js test: harden InsAIts wrapper fake Python shim 2026-05-12 01:13:01 -04:00
mcp-health-check.test.js test: stabilize MCP stderr probe timeout 2026-05-12 01:13:01 -04:00
observe-subdirectory-detection.test.js fix: salvage remaining stale queue fixes (#1754) 2026-05-11 16:41:08 -04:00
observer-memory.test.js fix: reduce observer hook scanner signatures 2026-05-16 15:26:25 -04:00
plugin-hook-bootstrap.test.js test: cover hook bootstrap and InsAIts monitor 2026-04-29 17:45:22 -04:00
post-bash-hooks.test.js feat: add C++ language support and hook tests (#539) 2026-03-16 14:31:49 -07:00
pre-bash-commit-quality.test.js fix: run pre-bash linters through windows wrappers 2026-04-29 18:59:10 -04:00
pre-bash-dev-server-block.test.js fix: integrate recent hook and docs PRs (#1905) 2026-05-14 21:37:28 -04:00
pre-bash-reminders.test.js feat: add C++ language support and hook tests (#539) 2026-03-16 14:31:49 -07:00
quality-gate.test.js feat: add C++ language support and hook tests (#539) 2026-03-16 14:31:49 -07:00
session-activity-tracker.test.js test: cover session activity tracker edge paths 2026-04-29 18:15:51 -04:00
stop-format-typecheck.test.js perf(hooks): batch format+typecheck at Stop instead of per Edit (#746) 2026-03-31 14:12:12 -07:00
suggest-compact.test.js fix: integrate recent hook and docs PRs (#1905) 2026-05-14 21:37:28 -04:00
test_insaits_security_monitor.py test: cover hook bootstrap and InsAIts monitor 2026-04-29 17:45:22 -04:00