5.6 KiB
Sleep awake selection and PDF V1 evidence
TRAINLOG_SLEEP_AWAKE_SELECTION_PDF_V1=PASS on 2026-09-24.
The Web now derives the agenda, selected-night heart-rate overlay, and vector
PDF rows from one pure temporal projection. It retains every structured
long_awake interval separately from point-in-time night_get_up events,
medication intakes, and sleep ranges. Factual sleep intervals determine sleep
duration when present. Otherwise the displayed Couché +45 minutes to Levé -10
minutes range supplies a presentation-only duration after subtracting the union
of overlapping structured awakenings; no estimate is persisted.
One agenda row is the effective selection. A click updates the detail dates,
editor snapshot, and HR context in memory without issuing a write. PDF preview
and download receive the same explicit inclusive range over each entry's
night_start_date, and all observations are recomputed from that subset. The
range initially spans the loaded agenda period; later detail/HR selection does
not alter it. Each of the 24 hour labels is centered in the equal visual cell
it names, using the same grid beneath every 18:00-to-18:00 agenda row; there is
no ambiguous duplicate 18 at the right edge.
A real-data follow-up found that using UTC revision created_at as the visual
offset source moved +02:00 events two hours left. The agenda now derives one
row-wide offset from factual bedtime/event data. Regression coverage mixes UTC
metadata with +02:00 events and keeps the 04:45 final get-up at its local
04:45 position. French night headings render DD/MM/YYYY.
Automated validation
- Web targeted suites: 34/34 passed.
- Complete Web suite after the range/axis follow-up: 209/209 passed.
npm run typecheck: passed.npm run build: passed.- Embedded production bundle
meson compile -C build: passed. - The tests cover multiple awakening intervals in agenda/HR projection, exact factual sleep duration, estimated duration with awakening subtraction, selection dates/HR identity, no write on selection, identical preview/export subsets, PDF interval geometry, medications, point markers, and no-HR fallback without an invented BPM curve.
Read-only real-data smoke
The rebuilt user Web service was exercised through real headless Firefox at
http://trainlog.perf/analyse?section=sleep without a Sleep mutation.
- The real 2026-09-23 → 2026-09-24 row contains no factual
sleepinterval; its displayed estimated band now reports5 h 14 min 16 s, not—. - The real 2026-09-22 → 2026-09-23 row renders its structured awakening in both the agenda and the no-invented-HR detail overlay.
- Selecting that row updates the detail inputs to exactly 2026-09-22 and 2026-09-23.
- Firefox export produced one PDF page whose extracted text contains only
22/09/2026,au 23/09/2026, and1 nuit; it contains no 24/09 row. - The selected-subset observation is
Sommeil déclaré : 6 h,Longs réveils : 1,Siestes : 1, andPrises de médicaments : 7. - Raster inspection confirms the long-awake band remains visibly distinct inside the sleep timeline and point/medication markers retain their positions.
The original Web change affected no database schema, synchronization artifact, frozen format, or Android behavior; the follow-up below deliberately corrects the Android capture semantics without changing those compatibility boundaries.
Android capture correction and real-night repair
Follow-up visual review established that Android one-tap Réveil had produced
three punctual night_get_up facts for 2026-09-23 → 2026-09-24, so there was
no structured interval for the shared projection to color. The user selected
an explicit 30-minute no-further-action policy. Future taps now create a
long_awake interval from the factual tap through +30 minutes; another tap
inside the window extends that same interval, while Levé clamps it to the
factual final-get-up timestamp. This is product policy, not BPM/RR inference.
Before repair, separate desktop and Android backups were retained under
~/.local/share/trainlog/backups/sleep-wake-window-20260924T0733/:
- desktop SHA-256:
ac2246dc699a5e11e9d8b52c4cad0f096dfc08191f54b6a86c44ce72f623c39c; - Android SHA-256:
a1a9017875757f27264556ea62a9d27a98f2efad17ca0234fb10f4095170a98a.
The real night was advanced causally, retaining its stable entry_id, to:
01:35:43.554104 → 02:05:43.554104;04:11:59.245980 → 04:14:28.358915(bounded by Levé).
Android and desktop current revision is
slr_d6cac4c6-dab7-4327-bc06-5cc95f7a2dfa. Its repaired linear ancestry
retains desktop revision slr_2bbf573d-4262-49b0-896e-1bcabf3b002a, including
the existing TB sleep and wake qualities.
Android database round-trip hashes matched, integrity/foreign-key checks passed,
and the non-destructive app update preserved first-install identity while
advancing the private build to versionCode 49.
The first post-repair full-generation attempts correctly rejected an already published Android archive whose embedded ancestry still named the pre-desktop mobile parent. Both live databases are repaired and aligned, but that stale transport archive remains rejected until the normal archive-capacity recovery retires it; no successful synchronization receipt is claimed by this evidence.
Post-correction validation passed 312 Android JVM tests (five optional skips),
assembleDebug, 208 Web tests, typecheck, and build. Real Firefox then observed
two orange agenda bands, two orange HR bands, Réveils 2 · 32 min 29 s, and two
orange PDF intervals. The selected-only PDF reports Sommeil déclaré : 4 h 44 min 16 s after subtracting the repaired awakening intervals from the visual
estimate.