feat: explainable longitudinal pattern summaries with cited records (#34) #76

Closed
rockachopa wants to merge 0 commits from timmy/34-explainable-pattern-summaries into main
pull from: timmy/34-explainable-pattern-summaries
Member

Closes #34

What changed

The home "Timmy noticed" line was a single assertive sentence. It is now an explainable summary:

  • src/summary.js builds a windowed (last 28 days) summary from confirmed ledger records only.
    Every statement carries the entryIds it was built from: a frequency line plus one line per Bristol
    grouping present in the window.
  • A window with both firm and loose logs is reported as mixed, not as whichever side is larger.
  • Fewer than 3 confirmed logs in the window returns insufficient: true, no statements, and copy that
    says it is too sparse — the summary refuses to describe a trend it cannot support.
  • app.js renders that card and a pattern-source sheet: following a citation opens exactly the cited
    records (data-summary-record), with the window stated. Static content, so no role="status" live
    region was added (an earlier attempt collided with the capture-status live region in
    tests/mobile-capture.acceptance.mjs; removed rather than weakening that test).
  • Boundary copy travels with the summary: it reports what was logged and when, never a cause, a food
    ruling, or a health verdict.

Tests

  • tests/summary.test.js (unit): citations resolve to real in-window records, per-bucket citation sets,
    mixed-pattern line, out-of-window exclusion, no causal/diagnostic/food wording, sparse refusal.
  • tests/pattern-summary.acceptance.mjs (real browser): sparse window shows the refusal with zero
    statement lines; a 5-log window (4 in-window + 1 old) renders the cited lines; following the typical
    citation lists exactly rec-typical-1/2/3.
  • Gated in CI (npm run test:pattern-summary), the unit suite, check:syntax, and the release builder
    (acceptance run + longitudinal_pattern_summary manifest gate + on-camera captions).

Verification run in this branch

  • npm test → 154 pass / 0 fail
  • npm run test:pattern-summary → PASS
  • npm run test:ui|photo|mobile-capture|sleek|manual-fallback|provisional|followup|vision-refusal|worker-readiness → all PASS
  • npm run check:syntax, npm run check:diff → OK
  • node scripts/record_release_demo.mjs → real-browser recording (WebM, 163.9s) whose caption receipt
    contains the two new gated captions; the citation check throws if the cited record set is wrong.

Demo path

scripts/record_release_demo.mjs now seeds fictional multi-day sample logs into the app's own local
ledger contract, shows the summary, follows a citation, and then replays the sparse-window refusal. The
on-camera caption states the seeding and that no real health data is involved. No UI was invented for the
video, and no product boundary moved.

Evidence screenshots: artifacts/pattern-summary-home-mobile.png, -records-mobile.png, -insufficient-mobile.png.

Closes #34 ## What changed The home "Timmy noticed" line was a single assertive sentence. It is now an explainable summary: - `src/summary.js` builds a windowed (`last 28 days`) summary from confirmed ledger records only. Every statement carries the `entryIds` it was built from: a frequency line plus one line per Bristol grouping present in the window. - A window with both firm and loose logs is reported as **mixed**, not as whichever side is larger. - Fewer than 3 confirmed logs in the window returns `insufficient: true`, no statements, and copy that says it is too sparse — the summary refuses to describe a trend it cannot support. - `app.js` renders that card and a pattern-source sheet: following a citation opens exactly the cited records (`data-summary-record`), with the window stated. Static content, so no `role="status"` live region was added (an earlier attempt collided with the capture-status live region in `tests/mobile-capture.acceptance.mjs`; removed rather than weakening that test). - Boundary copy travels with the summary: it reports what was logged and when, never a cause, a food ruling, or a health verdict. ## Tests - `tests/summary.test.js` (unit): citations resolve to real in-window records, per-bucket citation sets, mixed-pattern line, out-of-window exclusion, no causal/diagnostic/food wording, sparse refusal. - `tests/pattern-summary.acceptance.mjs` (real browser): sparse window shows the refusal with zero statement lines; a 5-log window (4 in-window + 1 old) renders the cited lines; following the typical citation lists exactly `rec-typical-1/2/3`. - Gated in CI (`npm run test:pattern-summary`), the unit suite, `check:syntax`, and the release builder (acceptance run + `longitudinal_pattern_summary` manifest gate + on-camera captions). ## Verification run in this branch - `npm test` → 154 pass / 0 fail - `npm run test:pattern-summary` → PASS - `npm run test:ui|photo|mobile-capture|sleek|manual-fallback|provisional|followup|vision-refusal|worker-readiness` → all PASS - `npm run check:syntax`, `npm run check:diff` → OK - `node scripts/record_release_demo.mjs` → real-browser recording (WebM, 163.9s) whose caption receipt contains the two new gated captions; the citation check throws if the cited record set is wrong. ## Demo path `scripts/record_release_demo.mjs` now seeds **fictional** multi-day sample logs into the app's own local ledger contract, shows the summary, follows a citation, and then replays the sparse-window refusal. The on-camera caption states the seeding and that no real health data is involved. No UI was invented for the video, and no product boundary moved. Evidence screenshots: `artifacts/pattern-summary-home-mobile.png`, `-records-mobile.png`, `-insufficient-mobile.png`.
rockachopa added 1 commit 2026-10-14 08:13:28 +00:00
feat: explainable longitudinal pattern summaries with cited records (#34)
Quality gates / quality (pull_request) Successful in 2m59s
d670360560
The home insight card now reports the confirmed-log count and form
groupings for a window, every line names the exact confirmed records it
was built from, and following a citation opens those records. A window
below the minimum states that it is too sparse instead of describing a
trend, and a window with both firm and loose logs says it is mixed rather
than picking a winner. No line explains a cause, rules on food, or offers
a health verdict.

- src/summary.js: window filtering, insufficient-data guard, per-form
  lines, mixed-pattern line, boundary copy, record citations
- app.js: explainable home card plus a pattern-source sheet listing the
  cited records
- tests/summary.test.js, tests/pattern-summary.acceptance.mjs: unit and
  real-browser coverage, gated in CI and the release builder
- scripts/record_release_demo.mjs: fictional multi-day sample logs,
  citation follow-through, and the sparse-window refusal on camera
timmy closed this pull request 2026-10-16 12:02:14 +00:00

Pull request closed

Please reopen this pull request to perform a merge.
Sign in to join this conversation.