Fix-C's release-readiness flag about i18n-locale-integrity drift on
`insights.sleep.headlineCaptionSuffix` reflected a transient mid-session
snapshot — commit e14466e already shipped native translations for all
six locales and the integrity test is green (26/26). Append a follow-up
note to the W10 reconcile-A design report so the audit trail is complete.
Captures the five-sub-task wave that locks the Apple Health server
contract before the v1.5 iOS-Swift session: migrations 0052 / 0053 /
0054, the mapping extension, the personal-records skeleton, and the
opt-in VO2 max tile. Restates the WORKOUT_ROUTE drop rationale and
lists the items deferred to v1.4.26+.
Records the two release-blockers resolved against the W9e translation
wave before tagging v1.4.25:
- Fix 1 (parseLocaleFromAcceptLanguage regression): no-op — the W7d
agent flagged a stale failure that the W9e wave itself had already
closed by adding a dedicated FR/ES/IT/PL prefix-match test block.
- Fix 2 (missing comparison.toggleHint): bundled into 6a7da4b which
restored the key across all six locales alongside the audio-exposure
/ time-in-daylight enum backfill.
All quality gates clean — full suite 2583 passed (1 skipped), above
the post-W9e baseline of 2577.
scripts/i18n/build-locale.py walks messages/en.json and emits the four
AI-initial locale bundles (FR / ES / IT / PL) via a layered translation
strategy: full-path overrides for highly contextual strings, a
common-vocab lookup keyed on the lowercase EN value, placeholder
protection that splits {interpolation} tokens and <tag> markers out
before translation and re-glues them verbatim afterwards, and a
fallback to the English value for long-tail prose the script can't
cover. Re-running the script on a fresh en.json keeps the four
locale bundles in parity automatically — handy when new keys land
between releases.
The phase report (.planning/phase-W9e-v1425-translations-report.md)
captures the per-locale vocabulary calls (Apple-Health / Withings
register checks for each language), the system-prompt routing
decision (EN body + REPLY LANGUAGE footer rather than four native
~500-line bodies, to preserve every safety contract verbatim), and
the deferred polish for v1.4.26 (hand-review prose for the highest-
traffic surfaces, native FR/ES/IT/PL prefs strings in
buildPrefsPrefix, locale-native date formats).
Previous Claude session reached 79% context. Handoff for the new
session to pick up W8 → W13 cleanly without re-reading the full
phase-report trail. Lists exactly what's landed (all 23 waves
inventoried), what's still open (W8/W9e/W10/W11/W12/W13), the
critical Marc-Voice + branch-model + i18n conventions, the
in-flight test failures to expect, and the verbatim greeting for
the new session.
7 conflict files resolved by taking the upstream/HEAD side (which carries
the W4d/W5/W6c/W3f feature additions). Stashed-side changes that were
genuine new features re-land in subsequent commits if any were lost.
This sweeps up the loose state the W4e+W5e+W5d combined agent left
mid-stash. Resolves develop's working tree for clean push.
Records the four polish-bar deliverables (per-card target-edit cog,
comparison-overlay grey-out, orphan general-status endpoint cleanup,
per-night sleep-stages stacked bar) with their commit SHAs,
file lists, verification results, and notes on the parallel-agent
commit-message collision that swept Win 1 into d74aa20.
Adds src/lib/withings/mapping.md as the single source of truth for the
meastype → MeasurementType table that the client.ts MEASURE_TYPE_MAP
mirrors, and .planning/research/withings-api-coverage.md as the full
audit of the Withings public API surface (Measure, Sleep, Heart,
Activity, Workouts, User, Notify) against HealthLog's ingestion.
The audit scores each gap on user-value / effort / schema-impact and
slots additions into v1.4.25 (cheap mappings), v1.4.26 (sleep + activity
sync, body composition expansion) and v1.5 (ECG, AFib, workouts).
Two carryover failures fixed in this session before the rest of W2
closes:
- tests/integration/coach-prefs.test.ts NextRequest URL mock
(v1.4.22 carryover, deferred from v1.4.23 + v1.4.24)
- e2e/chart-overlay-controls.spec.ts portalled-toggle viewport
+ e2e/charts-mobile.spec.ts Pixel-5 axis-tick visibility
Report covers root causes, file paths + line ranges, verification
exit codes for the integration suite, and the local-environment
limitation that blocked e2e verification (Node 25 vs CI's Node 22
prerender regression). Final e2e verification will arrive from the
next CI run on develop.
v1.4.24 (security + accessibility hardening) shipped directly on main as
a hotfix-style release. Back-merging the two main-only commits
(ca03c60 chore(release): v1.4.24, 604009d per-user timezone proposal)
into develop so the v1.4.25 work continues on the standard branch model.
# Conflicts:
# .planning/ROADMAP.md
Issue #167 (Warsaw user, v1.4.23) reports that the CSV export reads as
UTC because `Date.prototype.toISOString()` writes the `Z` suffix and
spreadsheet viewers drop the marker. The technical bug is small — 4
lines in `src/lib/export.ts` — but the architectural surface it
exposes is large: the whole app is hardcoded to `Europe/Berlin` for
display, analytics buckets, reminder cron, Withings sync mapping,
charts, PDF, Coach context (10 distinct symptoms total).
This commit records the long-form analysis so a future planning pass
does not start from zero:
- `.planning/feature-user-timezone.md` — full proposal: symptom
catalogue across 10 surfaces, design space (A: export-only quick
fix, B: per-user `displayTimezone` setting, C: rejected
auto-detect), migration strategy with concrete file/line touches,
the date-string risk split (`MoodEntry.date` freeze vs
`MedicationSchedule.windowStart` re-anchor — they need different
contracts), DST edge cases, parametrised test plan (Berlin / UTC /
New York / Tokyo / Kiritimati), and open product-call questions
for the v1.5 planning pass.
- `.planning/v15-backlog.md` — one-line carry under a new "From issue
triage" section pointing at the proposal.
- `.planning/ROADMAP.md` — reserved-milestones block notes per-user
timezone as a v1.5 candidate, with v1.6+ as fallback if v1.5 stays
iOS-focused.
Scope-clean: the v1.4.25 quick fix (ISO-8601-with-offset CSV) is
documented as independent. It closes#167 on its own without
touching the architectural scope captured here.
STATE ticks all Wave 7 sub-items: pre-release verify, format + planning
+ openapi sweep commits, version bump + CHANGELOG, release-merge, tag,
GHCR build, Coolify deploy (via host-side retag fallback after the
auto-deploy path skipped on missing secrets and the :latest digest
cache pinned to v1.4.22), /api/version=1.4.23, smoke, GH release,
docs + landing sync, release brief, v1.5 P1 plan refresh cross-link.
ROADMAP moves the v1.4.23 milestone into the Previous-milestone slot
(Waves 1-7 all done) and scaffolds v1.4.24 at the top with the
deferred items from v1423-backlog: Pearson incomplete-beta, OpenAPI
drift gate flip, settings-cog UX consolidation, NextRequest URL mock
fix, security MED + LOW cluster, S-05 simplify.
Release brief at docs/audit/v1423-summary.md mirrors the v1421-summary
structure: lead, live state, smoke, wave-by-wave overview, iOS
readiness statement with the 13 DTO open questions cross-link, branch
model, carry-overs, strategic next.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Captures the artifacts referenced from STATE.md, v1423-backlog.md, and
phase-W6-v1423-reconcile-report.md but never committed during the
wave-close ticks. W1 research = Apple Health type mapping + APNs
library decision + OpenAPI tooling choice; W5 v1422 reviews + W6
v1423 reviews are the six-brief multi-agent QA inputs that drove the
reconcile commit chain.
Leaves the pre-existing stale untracked entries (v1422-w1a probes,
audit-a6 scripts, export-route directories) untouched — those predate
v1.4.23.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mostly table column normalisation under docs/audit/ + planning, object-
literal expansion in src/lib/ai/coach/snapshot.ts after the W4 F6 Apple
Health metric block landed, and small wrap/unwrap line adjustments in
the device + APNs routes / tests touched across W3/W4/W5 sessions.
No behavioural change.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
11 reconcile commits across Sessions A/B/D/E/F closed 1 CRIT and
all 9 HIGH findings. STATE.md ticks Wave 6; v1423-backlog.md
captures the deferred MED + LOW items + the settings-cog-vs-thumbs
debate for v1.4.24.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Coolify runbook + audit briefs scrub the live deploy URL to a
placeholder (Sec-MED-2). Real values live in repo secrets.
- /api/auth/me/devices isCurrent now compares against the session's
device id, not the unauthenticated X-Device-Id header (Sr-MED-5).
- Migration 0036 sleep-duration unit shift documented + verification
command added to the coolify-auto-deploy howto.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Eight commits closed all seven items from `.planning/v1422-backlog.md`.
STATE entry documents the per-item changes; new
`phase-W5-v1423-report.md` captures the H5 deploy decision, the H7
admin view path + the first useful question it answers, and the
OpenAPI registry additions (3 routes — H4 GET + PUT, H7 POST).
Test deltas: 2191 → 2223 unit (+32), +2 integration files, no
regressions.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wave 4 closes the v1.4.23 foundation track. F5 (OpenAPI 3.1 drift
gate, warn-only for v1.4.23), F6 (Coach schema slot for Apple Health
metrics + PROMPT_VERSION 4.23.0), F7 (per-device refresh-token reuse
detection + device-management endpoints), and F8 (Coolify auto-deploy
runbook) all green.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two halves of the contract — workflow-side webhook (v1.4.22 C3 force=true
already in place) and Coolify-side image-digest watch toggle — must
both be on for tag pushes to land on production without an SSH retag.
The runbook in .planning/coolify-auto-deploy-howto.md now spells out
both pieces verbatim plus the verification curl + host-side fallback.
The workflow gains a single ::notice:: line after the webhook call so
future Actions runs surface the timestamp + sha for triage without
opening the verbose log.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Extends the device-registration body schema with the paired APNs
identity fields the iOS client populates once it has an APNs token from
`application:didRegisterForRemoteNotificationsWithDeviceToken:`.
Validation rejects half-supplied requests (`apnsToken` without
`apnsEnvironment` or vice versa) with 422 and enforces hex format on
the token — catching the common iOS implementation bug where the token
gets serialised through Swift's `Data.description` (which renders
`<deadbeef cafebabe>` with spaces and angle brackets) instead of the
hex-join shape Apple's docs spec.
The cross-user-hijack guard from CLAUDE.md is duplicated at the
APNs-token layer: a registration whose `apnsToken` is already owned by
another user returns 409 with reason `apns_token_owned_by_other_user`.
APNs tokens aren't secrets, so trusting wire input would let any
client who learns one redirect another user's pushes — same threat
model as the existing `token` guard, applied to the new field.
Audit-log details for `devices.register` now carry `hasApnsToken` and
`apnsEnvironment` so admin trails surface APNs pairing events without
leaking the raw token. Five new route tests cover the validation +
hijack paths (paired-or-omitted, hex regex, create-with-pair,
cross-user-409, the original 401/422/409/201 contracts stay green).
Ticks STATE.md F4 and lands `.planning/phase-W3-v1423-report.md`
covering the six W3 commits.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
STATE.md flips F1 / F2 / F3 to done with the inline narrative needed
for the next wave to pick up cleanly: 7 net new measurement types
(W1's 6 plus BODY_TEMPERATURE the iOS DTO already shipped), unit
shift on SLEEP_DURATION from hours to minutes, the new SleepStage
enum + composite dedup index.
W2 report enumerates the six commits, the +19 unit / +8 integration
test delta, the migration name + SQL summary, the W1 recommendations
adopted verbatim, and the open questions for the maintainer about
the iOS DTO contract (the rename HEALTHKIT → APPLE_HEALTH stays the
load-bearing item).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wave 5 reconcile pass complete: 7 HIGH applied inline, ~6 MEDs
applied inline, remaining MED + LOW deferred to
`.planning/v1422-backlog.md` under "Wave 5 reconcile carry-over".
- `.planning/phase-W5-v1422-reconcile-report.md`: 10 commit SHAs
with cross-references to each finding, test count delta
(+14 unit tests, +3 integration tests; final 2111 / 245 files),
per-bucket HIGH / MED / LOW disposition, and items the
maintainer should weigh in on (CSP scope, insights split, sentinel
parser malformed-enum priority, /me resync stays as fall-back).
- `.planning/v1422-backlog.md`: every deferred MED + LOW with a
one-line trace per item, organised by review bucket.
- `.planning/STATE.md`: Wave 5 ticked complete; tail updated to
point at the W5 review files + reconcile report.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Maintainer-voice sweep across `src/`. ~190 references to the
maintainer by first name in code comments and JSDoc neutralised to
"the maintainer", "the live tenant", "users", or "the user" depending
on context. Three sed passes covering ~50 distinct patterns
(`Marc reported`, `Marc wants`, `Marc kept`, `Marc rolled back`, etc.).
Test fixtures (`displayName: "Marc B."`, `username: "marc"`,
`<HeroStrip userName="Marc">`) kept as opaque test data per the brief.
CHANGELOG normalisation. The v1.4.14 + v1.4.15 entries paired a
German bullet with its English translation by historical design — the
in-app copy is English-default and the user docs are English, so the
mixed-language style was a holdover from the early-marathon notes.
A one-off node script extracted the `_..._` English paragraph from
each bilingual bullet and rewrote the entry as that text. ~44 bullets
reduced; one Docs bullet that lost a leading word in the regex
fixed by hand.
CLAUDE.md → CONTRIBUTING-AI.md rename so the filename is no longer
AI-vendor-specific. `CONTRIBUTING.md` reference updated. `AGENTS.md`
stays in place for multi-agent compatibility (the conventions doc is
shared with Codex / Cursor / etc.).
Wave-4 state wrap. STATE.md now records C1–C5 + D + D2 as complete;
v1421-backlog.md grew a "Closed in v1.4.22" header listing the 20
items the marathon landed; `.planning/phase-W4-report.md` documents
the per-commit decisions, test deltas, and the 23 items deferred to
v1.4.23 with reasoning.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
C3 — every v1.4.19/20/21 release required a host-side `docker tag`
fallback because Coolify pulled `:latest` from its image cache without
re-checking the GHCR registry digest. The workflow now appends
`?force=true` (or `&force=true` if other params are present) to the
deploy webhook URL so a doc-only push still triggers a registry-digest
check. The complementary maintainer-side toggle ("Watch image registry
for new digests" in the Coolify application config) is documented in
`.planning/coolify-auto-deploy-howto.md` — one checkbox flip in the UI,
no code change required.
C5 — the dependabot PR bumping node:22-alpine → node:26-alpine fails
at build because node:26-alpine no longer ships with corepack
pre-installed (`/bin/sh: corepack: not found`, exit 127). Next.js 16
also still pins node 22 LTS as its supported minimum, so a corepack
workaround would put the runtime ahead of the framework. Closed PR
#162 with a comment; reopen when Next.js bumps its node-version pin.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tick B1-B5 in STATE and capture the sentinel-parse design notes,
test count delta, and the synthesised prose example showing how the
new prompt handles "Meinst du, ich sollte mehr Sport machen?" with
the invitation pivot from rule 3.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Six atomic commits landed for A1-A6: BP target headline re-anchor,
BP tile feature parity, comparison-toggle moved to Settings only,
layout grid normalisation, "Muster" rename + section tabs lifted
above the hero, and the recommendation-card token-leak fix plus DE
component-label normalisation.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Captures the same-day patch on top of v1.4.20: Daily Briefing
regenerate fix, Coach day-level snapshot, duplicate streaming bubble,
drawer header, scope picker UI. STATE + ROADMAP rolled forward; v1.4.22
slot scaffolded for the e2e fix wave already in flight on develop.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New `.planning/phase-v1421-hotfix-report.md` summarises the six
fixes (Daily Briefing regenerate · Coach day-level snapshot · Coach
prompt update · streaming-bubble dedup · drawer header · sources rail
scope picker), the test-count delta (2026 → 2036 unit), the
token-budget impact of the day-level snapshot (~190 → ~3000 tokens
per full-scope turn), and a recommendation to ship as a v1.4.20.1
hotfix.
STATE.md grows a Phase F section + status block tracking the six
commits on develop. Includes prettier polish across the touched
coach surfaces (sources-rail, drawer, message-thread, snapshot,
chat route).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Phase E ticked complete in STATE.md; v1.4.20 archived to ROADMAP
"Previous milestone" with completion timestamp. Top of ROADMAP
scaffolds v1.4.21 with carry-over candidates from
.planning/v1421-backlog.md.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
11 commits landed on develop covering every Wave-D HIGH (13/13), the
design pushback on the disabled weekly-report button, 6 MED items,
and every simplify-apply-yes item. 22 MED + 16 LOW + 4 simplify-
apply-maybe deferred to v1421-backlog under a new "Phase D — v1.4.20
reconcile carry-over" section. Tests unchanged at 2026 unit + 81
integration; typecheck + lint clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
B5 ticked complete in STATE.md; added Wave-B summary table covering
B1–B5 commits (29 total) and cumulative test deltas (+354 unit,
+14 integration). Status block records the canonical sample score
(95, green) and the integration test count.
phase-B5-report.md replaces the v1.4.15 onboarding-tour stub with
a fresh write-up of the Health Score formula, its sub-component
helpers, the route wiring, the panel slots, and the 4 flagged-
uncertain items for maintainer review.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Five-commit Phase B4 lands the printable weekly report route, the
hero banner card surfacing fresh weekly reports, additive storyboard
annotations on the 90-day BP chart, and mobile rail trays for the AI
Coach drawer. PROMPT_VERSION 4.20.1 -> 4.20.2 with new GROUND RULES
10/11 covering both new schema blocks.
Tests 1902 -> 1975 (+73). Typecheck + lint clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tick B3 in `.planning/STATE.md` against the six commit drops on
`develop` (correlation maths, schema + prompt rule,
TrendAnnotation + TrendsRow, CorrelationCard + CorrelationRow,
analytics route + page wiring, this report). Replace the stale
v1.4.16 host-load report with the v1.4.20 narrative — what
shipped, synthetic-data spot checks for each hypothesis, and
flagged-uncertain items for maintainer review (confidence-band
thresholds, eta-squared mapping, interpretation localisation
strategy).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
B2b drawer UI shipped in four atomic commits on develop:
- TanStack Query hooks + SSE streaming client
- Drawer shell + message thread + source chips
- Composer + history rail + sources rail
- /insights wires the drawer via the hero strip's "Ask the coach"
button + suggested-prompt chips
Tests: 1781 → 1833 unit (+52). Integration unchanged at 78.
Six new test files cover the streaming parser, every drawer column,
the thread state machine, locale-aware labels, and the page wiring.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The Coach backend half of v1.4.20 wave B is complete; STATE.md
splits B2 into B2a (backend, done) + B2b (drawer UI, deferred to a
later dispatch) and records the test-count delta plus the migration
file in the status block. phase-B2a-report.md captures the five-
commit timeline, schema, helpers, route surface, token-budget
rationale, provenance JSON shape, and flagged-uncertain items.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
STATE.md: Wave B1 ticked (hero strip / daily briefing / suggested
prompts / schema / prompt bump). The Apple-Health vitals tile row
is annotated as descoped + deferred to B3 — the per-section status
cards already render the same numbers, so a tile row above them
would duplicate the surface.
New `phase-B1-v1420-report.md` captures the 5 SHAs (9873363 →
7d29596), the test-count delta (1672 → 1753, +81 tests), the
deferral list (Coach wiring → B2, weekly-report → B4, Health Score
→ B5, Briefing variants → backlog, source-chips → B3), and 5
prompt-copy decisions flagged for maintainer review.
The older `.planning/phase-B1-report.md` (v1.4.18 achievements
marathon) is left untouched; v1.4.20's report uses the v1420
suffix to avoid the collision.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- STATE.md: F5 ticked complete with the four atomic commits referenced
- phase-F5-report.md: scope + per-commit justification + deferral list
- v1421-backlog.md: new backlog file for F5 LOW carry-over plus the
FX cleanup carry-over (source-comment sweep, bilingual CHANGELOG,
CLAUDE.md/AGENTS.md filenames)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>