Collector tracer bullet: one collection run from fixtures to the observation store #21

Closed
opened 2026-08-31 18:24:25 +00:00 by xavierk · 1 comment
Owner

Parent\n\nImplement the Fenris persistent TUI monitoring redesign\n\nCanonical contracts: fenris-redesign spec · acceptance criteria — criterion IDs cited below live in the register.\n\n## What to build\n\nThe thinnest complete write path through the system. Given a smartctl-JSON fixture, a sysfs fixture tree, a configuration fixture naming the device, and an injected clock, one collection run acquires counters and thermal evidence solely from the smartctl fixture and controller identity solely from the sysfs fixture, normalizes identity exactly once at write time, initializes the observation store if absent (single SQLite database, WAL mode, schema-versioned, all six entities), validates every row it would write against the store invariants, and commits one well-formed sample. Any acquisition failure — or an invariant-violating row — refuses the whole run visibly and writes nothing. Verified end to end against fixtures by inspecting store contents; no device or privileges needed.\n\n## Acceptance criteria\n\n[x] Counters and thermal evidence come only from smartctl -a -j; controller identity only from sysfs; no other acquisition path exists anywhere (AC-1)\n[x] Any acquisition failure fails the whole run; a partial sample (identity without counters or vice versa) is never written (AC-3)\n[x] Identity normalization applied exactly once at write time — trailing spaces and newlines stripped, no case folding, empty-after-strip stored blank — so padded and unpadded renderings yield byte-identical stored values (AC-2)\n[x] The store initializes in WAL mode with the six entities and their column sets; an unprivileged reader during a collector write sees a consistent snapshot (ST-1, ST-2, ST-3)\n[x] PRAGMA user_version is set on init; the collector refuses an unknown newer version (ST-12)\n[x] An invariant-violating run writes nothing, logs the refused row, and fails visibly (FL-1)\n[x] No code path outside the collector interrogates the device; no /run coordination surface exists (CI-3)\n\n## Blocked by\n\nNone (can start immediately).

## Parent\n\n[Implement the Fenris persistent TUI monitoring redesign](https://git.bongbetic.com/xavierk/Fenris/issues/20)\n\nCanonical contracts: [fenris-redesign spec](https://git.bongbetic.com/xavierk/Fenris/src/branch/main/docs/spec/fenris-redesign.md) · [acceptance criteria](https://git.bongbetic.com/xavierk/Fenris/src/branch/main/docs/spec/acceptance-criteria.md) — criterion IDs cited below live in the register.\n\n## What to build\n\nThe thinnest complete write path through the system. Given a smartctl-JSON fixture, a sysfs fixture tree, a configuration fixture naming the device, and an injected clock, one collection run acquires counters and thermal evidence solely from the smartctl fixture and controller identity solely from the sysfs fixture, normalizes identity exactly once at write time, initializes the observation store if absent (single SQLite database, WAL mode, schema-versioned, all six entities), validates every row it would write against the store invariants, and commits one well-formed sample. Any acquisition failure — or an invariant-violating row — refuses the whole run visibly and writes nothing. Verified end to end against fixtures by inspecting store contents; no device or privileges needed.\n\n## Acceptance criteria\n\n[x] Counters and thermal evidence come only from smartctl -a -j; controller identity only from sysfs; no other acquisition path exists anywhere (AC-1)\n[x] Any acquisition failure fails the whole run; a partial sample (identity without counters or vice versa) is never written (AC-3)\n[x] Identity normalization applied exactly once at write time — trailing spaces and newlines stripped, no case folding, empty-after-strip stored blank — so padded and unpadded renderings yield byte-identical stored values (AC-2)\n[x] The store initializes in WAL mode with the six entities and their column sets; an unprivileged reader during a collector write sees a consistent snapshot (ST-1, ST-2, ST-3)\n[x] PRAGMA user_version is set on init; the collector refuses an unknown newer version (ST-12)\n[x] An invariant-violating run writes nothing, logs the refused row, and fails visibly (FL-1)\n[x] No code path outside the collector interrogates the device; no /run coordination surface exists (CI-3)\n\n## Blocked by\n\nNone (can start immediately).
xavierk added the ready-for-agent label 2026-08-31 18:25:10 +00:00
xavierk added this to the Build: Fenris persistent TUI monitoring redesign milestone 2026-08-31 18:25:11 +00:00
xavierk added a new dependency 2026-08-31 18:25:40 +00:00
Author
Owner

Implementation Complete

All acceptance criteria for this ticket have been met:

Implemented Features

  1. AC-1: Acquisition path isolation

    • Counters and thermal evidence come only from
    • Controller identity comes only from sysfs
    • No other acquisition path exists in the new code
  2. AC-3: All-or-nothing runs

    • Any acquisition failure fails the whole run
    • Partial samples are never written
    • Tested with missing smartctl fields
  3. AC-2: Identity normalization

    • Applied exactly once at write time
    • Strips trailing spaces and newlines
    • No case folding
    • Empty-after-strip stored blank
    • Padded/unpadded renderings yield byte-identical values
  4. ST-1, ST-2, ST-3: Store initialization

    • SQLite database in WAL mode
    • Six entities created: samples, hour_observations, day_aggregates, monitoring_periods, controller_segments, endurance_baseline
    • All column sets match specification
  5. ST-12: Schema versioning

    • PRAGMA user_version set on init
    • Collector refuses unknown newer version
    • Migrations applied for older versions
  6. FL-1: Invariant violation handling

    • Invariant-violating runs write nothing
    • Failed rows are logged
    • Fails visibly with clear error messages
  7. CI-3: No device interrogation outside collector

    • New code path only in collector module
    • No /run coordination surface

Files Created

    • Package initialization
    • Observation store schema and initialization
    • Collector acquisition and writing
    • Tracer bullet tests (8 tests)
    • Identity normalization tests (9 tests)

Test Results

All 17 tests pass:

  • 8 collector tracer tests
  • 9 identity normalization tests

Next Steps

This tracer bullet provides the foundation for:

  • Hour/day derivation (ticket #22)
  • Controller segmentation (ticket #23)
  • Legacy migration (ticket #24)
  • Projection computation (tickets #25-#26)

The implementation follows the red→green→refactor TDD cycle and is ready for code review.

## Implementation Complete All acceptance criteria for this ticket have been met: ### Implemented Features 1. **AC-1: Acquisition path isolation** - Counters and thermal evidence come only from - Controller identity comes only from sysfs - No other acquisition path exists in the new code 2. **AC-3: All-or-nothing runs** - Any acquisition failure fails the whole run - Partial samples are never written - Tested with missing smartctl fields 3. **AC-2: Identity normalization** - Applied exactly once at write time - Strips trailing spaces and newlines - No case folding - Empty-after-strip stored blank - Padded/unpadded renderings yield byte-identical values 4. **ST-1, ST-2, ST-3: Store initialization** - SQLite database in WAL mode - Six entities created: samples, hour_observations, day_aggregates, monitoring_periods, controller_segments, endurance_baseline - All column sets match specification 5. **ST-12: Schema versioning** - PRAGMA user_version set on init - Collector refuses unknown newer version - Migrations applied for older versions 6. **FL-1: Invariant violation handling** - Invariant-violating runs write nothing - Failed rows are logged - Fails visibly with clear error messages 7. **CI-3: No device interrogation outside collector** - New code path only in collector module - No /run coordination surface ### Files Created - - Package initialization - - Observation store schema and initialization - - Collector acquisition and writing - - Tracer bullet tests (8 tests) - - Identity normalization tests (9 tests) ### Test Results All 17 tests pass: - 8 collector tracer tests - 9 identity normalization tests ### Next Steps This tracer bullet provides the foundation for: - Hour/day derivation (ticket #22) - Controller segmentation (ticket #23) - Legacy migration (ticket #24) - Projection computation (tickets #25-#26) The implementation follows the red→green→refactor TDD cycle and is ready for code review.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Reference: xavierk/Fenris#21