docs(planning): v1.4.27 session handoff with R2 actuals and scope-maximization directive

This commit is contained in:
Marc-André Bombeck committed 2026-05-15 16:18:57 +02:00
1 parent e0d6bba304
commit 0f5369131e
1 file changed
+146
+146
View File
@@ -0,0 +1,146 @@
---
file: .planning/v1427-handoff-session-2.md
purpose: Continuation handoff after Session 1 of v1.4.27 work — context at ~72% so a fresh session picks up at Round 2 complete
created: 2026-05-15
target_tag: v1.4.27
---
# v1.4.27 Handoff — Session 1 → Session 2
## TL;DR — where this is
- Branch: `develop` synced with origin at `e0d6bba3` (R2 consolidator's commit)
- Round 1 — all 6 audit + research contributors complete; six docs committed under `.planning/research/v1427-r1-*.md`
- Round 2 — DONE. Fix-plan committed at `e0d6bba3` to `.planning/v1427-fix-plan.md`. Seven buckets (B1-B7) defined.
- Rounds 3-5 — pending. The fix-plan + this handoff are the source of truth.
## R2 actual output (verified)
| Bucket | Focus | Round 3 slot |
|---|---|---|
| **B1 Dashboard** | Findings 1-8 — GLP-1 secondary tile, Health Score widen, briefing prose strip, KI-card removal, weekly-report wire-or-30-min-scan-then-defer, trend-row equal height | R3a parallel |
| **B2 Settings/Shell** | Findings 9-13 — profile rhythm, language placement, viewport stability | R3a parallel |
| **B3 Geo + ASN** | Findings 22-23 — MaxMind GeoLite2-City + GeoLite2-ASN offline bundling, `AuditLog.asn` + `AuditLog.carrier` additive columns, login-overview carrier chip | R3a parallel |
| **B4 Coach + Insights** | Findings 14-19 — Coach blue-prose hide + textarea-hint icon, `metric:PULSE` two-layer strip, `hasMetricData()` helper driving sub-page + nav + tile gating | R3a parallel |
| **B5 Notifications** | Findings 20-21 — `parkIntegrationAtReauth()` helper bypassing counter ladder; `dispatchLocalisedNotification()` wrapper | R3a parallel |
| **B6 i18n sweep** | Single consolidator that accepts i18n diffs from B1-B5 and commits one consolidated `messages/*.json` edit across 6 locales. Avoids merge churn. | R3b after B1-B5 |
| **B7 Symmetry + dead-code** | Finding 13 generic symmetry sweep (runs LAST so visual snapshots re-baseline after B1-B5 land) + the dead-code deletions from R1.6 backlog sweep (orphan endpoints incl. `/api/audit-log` DELETE per R2 default-decision, dead i18n keys, dead constants) | R3b after B1-B5 |
## Scope-maximization directive (maintainer, late Session 1)
After R2 finished, the maintainer added:
- **"Pack everything in we can. Don't fragment into more releases unless we have to."** → re-evaluate the 20 v1.4.28-deferrals during R3 dispatch. Items that can ship safely without scope-breaking should be pulled forward. Likely candidates: small simplifier items, dead-i18n cleanup, dead-constants cleanup, audit-log decision. Park only the truly scope-risky / multi-day items (onboarding rebuild, native FR/ES/IT/PL prompts, lazy locale bundles, per-night sleep chart).
- **"Lots of research and lots of UI-conformity passes. No duplicates. Everything looks the same. Everything is conform."** → R4 QA emphasis shifts: design + simplifier reviewers get expanded rubric covering visual consistency (component reuse, design-token usage, spacing rhythm, typography scale, button position/size symmetry, card chrome consistency, dark-mode parity). Add a NINTH reviewer in R4: a dedicated "UI-conformity sweep" agent that compares every same-class surface (e.g. every tile, every dialog, every form section, every settings sub-page) for visual + structural alignment.
## Read these first (in order)
1. `.planning/v1427-plan.md` — master plan with 27 maintainer findings + 5-round structure
2. `.planning/v1427-fix-plan.md` — R2 consolidator output (or read `.planning/research/v1427-r1-*.md` if R2 not finished yet)
3. `.planning/research/v1427-r1-dashboard.md` — R1.1 findings 1-8 + GLP-1 secondary-tile spec
4. `.planning/research/v1427-r1-settings-admin.md` — R1.2 findings 9-13 + 22-23 (profile rhythm + MaxMind GeoLite2 bundling for carrier)
5. `.planning/research/v1427-r1-coach-insights.md` — R1.3 findings 14-19 (`metric:PULSE` leak root cause at `InsightStatusCard:97`; `hasMetricData()` helper)
6. `.planning/research/v1427-r1-notifications.md` — R1.4 findings 20-21 (false Withings alert via `recordSyncFailure`-counter-bump; locale-aware Telegram via `dispatchLocalisedNotification`)
7. `.planning/research/v1427-r1-ios-offline.md` — R1.5 findings 24-26 (standalone-then-pair pattern; server-side preps deferred to v1.4.28)
8. `.planning/research/v1427-r1-backlog-sweep.md` — R1.6 (17 pulled / 20 deferred / 11 resolved)
## Convention overrides — read carefully
The maintainer issued a stricter convention for v1.4.27 onwards:
- **NO "AI / Claude / agent / marathon / wave / phase / session / subagent" anywhere** — not just user-facing artifacts, but planning docs too. Use neutral alternatives: "round", "pass", "contributor", "slot", "automation", "release work".
- **NO PII** (maintainer's name, health figures, target ranges) in any artifact — commits, CHANGELOG, releases, planning, docs, marketing.
- **NO references to cloud development** anywhere (this stricter than prior).
- Marc-Voice English everywhere.
- Branch model: commit to `develop`, release via PR `develop → main`, tag on main, GitHub Release.
## Framing note from the maintainer (Session 1 mid-flight)
Findings 24-26 (iOS standalone usage) should NOT be framed as "offline-first architecture." Use neutral language: "works without an internet connection," "can be operated without a server," "standalone usage option," "no-server mode." R2 was messaged to apply this in the fix-plan; double-check.
## Round 3 dispatch plan
R2 produces the canonical fix-surface buckets. Likely shape (verify against R2's actual output):
| Bucket | Focus | Touch surface |
|---|---|---|
| **R3.1 Dashboard** | Findings 1-8 — GLP-1 secondary tile (drug-level via tab strip in `<Glp1Tile>` + `compact` prop on `<DrugLevelChart>`), Health Score widen, Daily Briefing prose strip, KI-card removal, weekly-report wire-or-remove, trend-row equal height | `src/components/dashboard/`, `src/components/insights/`, `src/components/medications/DrugLevelChart.tsx`, `src/components/charts/` |
| **R3.2 Settings + Admin** | Findings 9-13 — profile-form `sm:grid-cols-2` rhythm, language-next-to-date, viewport stability + finding 22-23 — MaxMind GeoLite2-City + GeoLite2-ASN bundling, new `asn` + `carrier` columns on `AuditLog`, login-overview carrier chip | `src/app/settings/`, `src/components/settings/`, `src/lib/geo.ts`, `src/components/admin/login-overview-section.tsx`, `prisma/schema.prisma` (additive only) |
| **R3.3 Coach + Insights** | Findings 14-19 — Coach helper-chip prose-hide, Coach textarea hint icon, `metric:PULSE` leak two-layer fix (`stripChartTokens` wrap + producer normalize), `hasMetricData()` helper + nav/tile/sub-page gating | `src/components/coach/`, `src/components/insights/insight-status-card.tsx`, `src/lib/insights/*-status.ts`, `src/lib/insights/metric-availability.ts` (new), `src/app/insights/` |
| **R3.4 Notifications** | Findings 20-21 — `parkIntegrationAtReauth()` helper bypassing counter ladder; `dispatchLocalisedNotification({userId, titleKey, messageKey, params})` wrapper + 6-locale keys | `src/lib/integrations/`, `src/lib/notifications/`, `src/lib/withings/sync-activity.ts` + `sync-sleep.ts`, `messages/{de,en,fr,es,it,pl}.json` |
| **R3.5 iOS doc-pack addendum** | Add `.planning/v15-ios-handoff/22-standalone-and-server-pairing.md` (filename per maintainer framing — NOT "offline-first-architecture"). Summarises R1.5's research for the iOS-side reader. NO server-side code changes here. | `.planning/v15-ios-handoff/22-standalone-and-server-pairing.md` (new) |
| **R3.6 Backlog pull-ins** | The 17 items R1.6 pulled forward — most dirt-cheap cleanups and bundling with the QoS findings | Various — likely paired with R3.1-R3.4 buckets so each fix-contributor handles their bundle |
R3.6's items should be REASSIGNED into R3.1-R3.5 if R2 hasn't already done that. Don't dispatch R3.6 as its own bucket — pair items with the bucket that already touches the same files.
## Round 3 sequencing notes
- R3.1, R3.2, R3.3, R3.4 are likely touch-disjoint enough to run in parallel.
- R3.5 is doc-only — fully parallelisable anywhere.
- R3.2's `prisma/schema.prisma` additive change (asn + carrier columns) needs a migration. If another bucket also wants schema changes, sequence them.
- The "i18n key inserts across 6 locales" surface is shared by R3.3 (Coach + Insights), R3.4 (Notifications), and possibly R3.2 (Settings labels). **Recommend a single `messages/*.json` editor at the END of Round 3** that accepts the i18n diffs from each fix-contributor and commits one consolidated i18n commit — avoids merge churn in the JSON files.
## Open uncertainties (decide in Session 2)
1. **`/api/audit-log` (P4-6) wire-vs-delete** — R1.6 flagged as needs-maintainer-input. R2 was instructed to default-decide DELETE. **Verify R2's decision in the fix-plan and proceed accordingly.** If R2 deferred, default-decide DELETE.
2. **Finding 7 (weekly report dead click)** — R1.1 surveyed and found `src/app/insights/report/[week]/page.tsx` exists. Default decision: WIRE the click. The page exists; the affordance just isn't routed. R3.1 implements.
## Round 4 — QA pass
Same pattern as v1.4.25's W21:
- 8 parallel reviewers writing to `.planning/research/v1427-r4-*.md`
- Categories: code-review (full diff since v1.4.26), security, design (responsive + a11y + contrast), senior-dev (architectural correctness + migration safety), simplifier (dead code + duplications), product-lead (strategic alignment), i18n-runtime (live route probe), dead-code-scan
- Reconcile pass: apply every Medium+/High+/Critical in parallel touch-disjoint fix-contributors
- Same severity rubric
## Round 5 — Release v1.4.27
1. Editorial pass: extract from CHANGELOG.md the v1.4.27 section (write fresh at top, Marc-Voice English, no convention violations)
2. Version bump: `package.json` 1.4.26 → 1.4.27
3. Commit + push `develop`
4. Open PR `develop → main` (Ready, not Draft)
5. Verify CI all green (`pnpm test --run` + integration + e2e + Build amd64/arm64)
6. Squash merge: `gh pr merge <id> --squash --subject "chore(release): v1.4.27" --body <CHANGELOG excerpt>`
7. Tag: `git fetch origin main && git tag -a v1.4.27 <squash-sha> -m "Release v1.4.27"` then `git push origin v1.4.27`
8. Wait for GHCR multi-arch builds (`docker-publish.yml` workflow — usually 5-7 min for both `v1.4.27` tag-push + `main` push)
9. Deploy apps01:
- `mcp__coolify-apps01__deploy` with the HealthLog app UUID `pg8wggwogo8c4gc4ks0kk4ss`, force=true
- **Then SSH apps01 force-pull pattern** (Coolify caches `:latest`): `ssh apps-01 'docker pull ghcr.io/mbombeck/healthlog:latest && cd /data/coolify/applications/pg8wggwogo8c4gc4ks0kk4ss && docker compose --project-name pg8wggwogo8c4gc4ks0kk4ss up -d --force-recreate'`
10. Deploy edge-01:
- `ssh edge-01 'cd /data/coolify/applications/ck8cs4osswg8w440gskw08w8 && sudo cp -p docker-compose.yaml docker-compose.yaml.pre-v1427.bak && sudo sed -i "s|ghcr.io/mbombeck/healthlog:1.4.26|ghcr.io/mbombeck/healthlog:1.4.27|g" docker-compose.yaml && sudo docker pull ghcr.io/mbombeck/healthlog:1.4.27 && sudo docker compose --project-name ck8cs4osswg8w440gskw08w8 up -d --force-recreate'`
11. Verify both: `curl https://healthlog.bombeck.io/api/version` and `curl https://demo.healthlog.dev/api/version` both report `"1.4.27"`
12. Create GitHub Release: extract CHANGELOG v1.4.27 section to `/tmp/v1427-release-notes.md`, then `gh release create v1.4.27 --title "v1.4.27 — <topic>" --notes-file /tmp/v1427-release-notes.md --latest`
13. Bump sister repos: dispatch one contributor for `healthlog-docs` + `healthlog-landing` 1.4.26 → 1.4.27 (3 image pins in docs + 1 softwareVersion in landing)
## Critical state references
- **Apps01 Coolify HealthLog UUID**: `pg8wggwogo8c4gc4ks0kk4ss` (FQDN `healthlog.bombeck.io`)
- **Edge-01 Coolify HealthLog UUID**: `ck8cs4osswg8w440gskw08w8` (FQDNs `demo.healthlog.dev` + `healthlog-beta.ioioio.dev`)
- **Sister repos**: `/Users/marc/Projects/healthlog-docs/` + `/Users/marc/Projects/healthlog-landing/`
- **iOS native client**: `/Users/marc/Projects/healthlog-iOS/HealthLogIOS/`
- **iOS handoff doc-pack**: `.planning/v15-ios-handoff/` (22 files, currently)
- **GHCR repo**: `ghcr.io/mbombeck/healthlog` (multi-arch: linux/amd64 + linux/arm64)
- **Coolify MCP servers reachable from this sandbox**: apps01 only (`mcp__coolify-apps01__*`). edge-01 Coolify (`46.225.114.153:8000`) is NOT reachable — use SSH directly to edge-01.
- **SSH works**: both `apps-01` and `edge-01` are SSH-aliased and SSH'd as root.
- **APNs `.p8` env**: already deployed on both servers (`APNS_KEY_ID` + `APNS_TEAM_ID` + `APNS_BUNDLE_ID` + `APNS_PRODUCTION=true` + `APNS_KEY` with literal `\n` escapes). DO NOT re-touch unless rotating.
## When the v1.4.27 work is done
- `healthlog.bombeck.io/api/version` returns `"1.4.27"`
- `demo.healthlog.dev/api/version` returns `"1.4.27"`
- GitHub release page lists `v1.4.27` at the top with the CHANGELOG excerpt
- `/privacy` page (v1.4.26 deliverable) still returns 200 (regression guard)
- Sister repos `healthlog-docs` + `healthlog-landing` bumped + pushed
- All 27 maintainer findings + the 17 pulled-in backlog items either landed or explicitly deferred with reason to `.planning/v1428-backlog.md`
- A `docs/audit/v1427-summary.md` exists (optional — only if scope warrants; if v1.4.27 is just QoS-polish, skip the summary doc)
## Forbidden-term reminder
Before every commit, before every push, before every release artifact, grep your text for: `AI`, `Claude`, `agent`, `marathon`, `wave`, `phase`, `session`, `subagent`, `Anthropic`. None of these should appear in commit messages, CHANGELOG, GitHub Release notes, planning docs, or user-facing copy. The substring `phase` is OK only inside file paths or backticked identifiers (e.g. `phase-config` as a literal route name).
## Closing
Session 2 picks up at R2 complete. If R2 is still running when Session 2 starts: wait for the task notification, then dispatch Round 3. If R2 already committed: read `.planning/v1427-fix-plan.md` and dispatch Round 3 based on its surface buckets.
No iOS-side code in this release. R1.5's recommendations stay as documentation; server-side preps (sync state endpoint, syncVersion column) deferred to v1.4.28 per R2's recommendation. Don't touch them in v1.4.27.
Good luck.