Skip to content

feat: give a finished session a record, and show it in Review - #163

Merged
PurpleSentinel merged 1 commit into
mainfrom
feature/session-record
Aug 20, 2026
Merged

PurpleSentinel merged 1 commit into
mainfrom
feature/session-record

Conversation

@PurpleSentinel

Copy link
Copy Markdown
Contributor

Part of #137 and #142. Stage A of the session record: the record exists and is shown. Stage B
puts it on the card.

The gap

The device ran a full session and forgot all of it the moment you double-tapped.

Most of the fix was connecting parts that already existed. SessionReviewController takes
a SessionSummaryProvider; SessionSummaryV1 already carried duration, overrun, completion
reason and integrity. Nothing implemented the provider, so the router passed nullptr.

MemorySummaryStore is that provider — last eight sessions, newest first, refusing anything
that fails the summary validator so a malformed record cannot reach Review and be rendered as
though it were real.

Three gaps, all wiring

  • imu_meter_.update(input, false) — that argument is session_active, hardcoded. Correct
    when written, because no session existed on the device; stale for three merges. Peaks
    described everything since boot.
  • The router dropped vertical_g, computed by the calibration since fix(imu): track attitude with the gyroscope so tilt is not reported as G #146.
  • SessionSummaryV1 had no G fields, so a scoped peak had nowhere to live.

Then Review turned out to be invisible

Reported as "no data in review". The probe showed the record was stored, the model populated
and the routing correct:

REVIEWPROBE after capture   status=1 count=1 title='SESSION 1 OF 1' duration='DURATION 00:18'
REVIEWPROBE entering review status=1 count=1 title='SESSION 1 OF 1'

Two separate faults:

  1. Every data row used Typography::caption — 0.82 mm on this 311 PPI panel, against 10 mm
    for the countdown. The data was on screen the whole time at a twelfth the height. This is
    Driver-facing typography is too small to read on the physical panel #127, and it was not merely ugly: it was hiding a working feature.
  2. The peaks never reached the view model. I added them to the record and the store and did
    not carry them to the screen, so the G data genuinely was not there at any size. My
    omission, and nothing asserted that the model carries what the summary holds.

Rows are 1.65 mm now with a 2.82 mm peak headline, and the peaks block occupies the space lap
rows will take once there is a receiver, so only one is ever up.

Decisions

  • Up and down peaks are separate — a kerb throws the car up, a compression loads it down.
  • Peaks reset when a session starts, not when a trigger arms. A driver waiting on a launch
    has not started; carrying the device to the car is not the session.
  • Sessions are marked degraded_gnss — true, and Review should say so rather than present
    a lap-less session as complete.
  • Old peaks are not migrated. Anything recorded before fix(imu): track attitude with the gyroscope so tilt is not reported as G #146 latched tilt as acceleration
    with left and right swapped. kImuMeterSchemaVersion → 2 and kLogFormatVersion → 3 refuse
    them by version: they are wrong, not old.

Verification

37 host suites (one new) and 70 simulator tests. New coverage for newest-first ordering,
bounded history, refusal of records that fail their own validator, peaks on every axis, and
session scoping including that peaks survive the end of a session — which is when they are read.

Confirmed on the panel across several sessions, ending with the record read back at 330 s
uptime and Review rendering it. Probe removed and its absence verified on the final image.

Deliberately not here

It is in RAM. Eight sessions, gone on power cycle. The card is Stage B, and that is where
the SD write path finally gets exercised before GNSS lands on top of it at 25 Hz.

#162, raised from this work: the recorded peak inherits the radar's 2 g display clamp. Safe
for the horizontal axes on a real car, not safe vertically — a kerb passes 2 g easily and would
be recorded as exactly 2.00, a clamp presented as a measurement.

The device ran a full session - countdown, overrun, rest, launch trigger - and forgot
all of it the moment the driver double-tapped. Nothing was recorded and Review showed
nothing, which is the difference between a timer and something worth taking to a track
day.

Most of this was connecting parts that already existed. SessionReviewController takes a
SessionSummaryProvider and SessionSummaryV1 already carried duration, overrun, completion
reason and integrity; nothing implemented the provider, so the router passed nullptr.
MemorySummaryStore is that provider, holding the last eight sessions newest first and
refusing anything that fails the summary validator, so a malformed record cannot reach
Review and be rendered as though it were real.

Three gaps were wiring rather than logic. The meter was told session_active was false,
hardcoded - correct when written, because no session existed on the device, and stale for
three merges since - so peaks described everything since boot and were scoped to nothing.
The router computed vertical G and dropped it before the meter saw it. And the summary
record had no G fields, so even a scoped peak had nowhere to live.

Up and down peaks are held apart because a kerb throws the car up and a compression loads
it down, and those are different events. Peaks reset when a session starts rather than
when a trigger arms: a driver waiting on a launch has not started, and carrying the device
to the car is not the session.

Review was then found to be rendering its summary at 0.82 mm, a twelfth the height of the
countdown, which is why a session that had been recorded correctly read as an empty
screen. The rows are 1.65 mm now with a 2.82 mm peak headline. The peaks block occupies
the space lap rows will take once there is a receiver, so only one of them is ever up.

Sessions are marked degraded_gnss, which is true and which Review should say rather than
present a lap-less session as complete. Peaks recorded before the gravity reference was
gyro-tracked latched tilt as acceleration and had left and right swapped, so both schema
versions move and older records are refused rather than migrated: they are wrong, not old.

This is deliberately in RAM. Nothing survives a power cycle, and the card is next.

Part of #137 and #142

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@PurpleSentinel
PurpleSentinel merged commit 8ec206f into main Aug 20, 2026
3 checks passed
@PurpleSentinel
PurpleSentinel deleted the feature/session-record branch August 20, 2026 22:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants