feat: remote metrics HTTP reporter (spec 003) + cleanups
Summary
Implements spec 003 — remote metrics reporter: forward each metric/cycle event to a configurable remote monitoring server in parallel with the existing stdout JSON reporter. Also bundles a handful of quality-of-life improvements that came up while building it.
Commits
-
feat(reporter)— newHttpReporter(infrastructure) +CompositeReporter(domain) fan events out to N reporters; wired throughmain.py, gated byREMOTE_REPORTER_ENABLED. Failures log but never block the next poll cycle. -
feat(config)— relaxREAD_INTERVAL_SECONDSvalidation from the hard== 30invariant to> 0. Unblocks the existingconfig.tomlvalue of10. Default still30. -
feat(metrics)— bumppowerandreactive_powerrounding from 1 → 3 decimals (x.xxx), matching the DDS238-1-ZN's native 0.001 kW resolution. -
perf(tests)— replacesubprocess.Popenintest_entrypoint_configuration.pywith fork-basedmultiprocessingcalls intomain(). Full pytest suite drops 4.75s → ~1.0s (-78%) with identical coverage (signal delivery preserved via real child PID). -
docs(constitution)— bump constitution to v1.2.0: formalize Todoist task ID naming (`[T###] `), description, and full `Backlog → In progress → Done` lifecycle plus `Blocked - Waiting for` semantics. Mirrored in `tasks-template.md`. -
chore(config)— enable remote reporter and resolve hostname via `vandalsweb.internal`. -
chore(claude)— local Claude Code settings tweak.
Test plan
-
`make py/pytest` — 110/110 pass in ~1.0s -
Smoke run inside container with `REMOTE_REPORTER_ENABLED=true` against a stubbed remote server; confirm `metric_read_succeeded` events POSTed. -
Verify `READ_INTERVAL_SECONDS=10` from `config.toml` no longer raises at startup. -
Confirm power readings in stdout JSON now show 3 decimals.