mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-10 05:12:14 +00:00
docs: scrub PII + internal jargon + German leaks from user-facing artifacts
Retroactive cleanup of CHANGELOG.md and docs/audit/v1.4.X-summary.md files. Removes maintainer's real name, specific health figures tied to the live tenant, internal release-process jargon, and stray German strings in English-only release notes. Pre-release PII-grep gate added to the v1.4.20 release pipeline. No git history rewrite. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
f80492a5a3
commit
a1cf9bcb37
20 files changed
+263
-267
No files matched your search
+6
-6
@@ -9,7 +9,7 @@
|
||||
because `/api/analytics` aliased `bpInTargetPct` to `last30Days?.pct`.
|
||||
`computeBpInTargetWindows()` now returns a third `allTime` window and
|
||||
the route routes the headline through it, so the three numbers can
|
||||
legitimately differ (Marc's data: 50 % / 50 % / 10.8 %).
|
||||
legitimately differ across the three windows.
|
||||
- **Charts mobile header no longer breaks the layout on Pixel 5.** The
|
||||
card header switches to a mobile-first stack below `sm` (title +
|
||||
chips on row 1, range tabs + cog right-aligned on row 2 with
|
||||
@@ -86,10 +86,10 @@
|
||||
Account → Restart onboarding tour, and Dashboard → Reset to
|
||||
defaults stack the action below the title on `<sm` (full-width)
|
||||
and right-align on `≥sm`, fixing the Pixel-5 right-edge overflow
|
||||
on the tour button. Sprache select gets its own row at the bottom
|
||||
on the tour button. Language select gets its own row at the bottom
|
||||
of the Profile card; card-internal `space-y` standardised to
|
||||
`space-y-4`.
|
||||
- **Zielwerte status labels translated to German** (Low / On Target
|
||||
- **Target-range status labels translated to German** (Low / On Target
|
||||
/ Stable / Moderate). 11 `targets.label.<TYPE>` + 41
|
||||
`targets.status.<key>` entries in EN + DE; page uses
|
||||
`STATUS_CATEGORY_KEY` to normalise server strings.
|
||||
@@ -348,7 +348,7 @@
|
||||
### Deferred to v1.5
|
||||
|
||||
- Coolify image-digest auto-deploy trigger (currently fires on every
|
||||
git-push; Marc-side UI flip is the realistic fix).
|
||||
git-push; the manual Coolify UI toggle is the realistic fix).
|
||||
- Native arm64 runner matrix for full multi-arch docker publish.
|
||||
- Cross-user feedback aggregation prompt-tuning ratchet (depends on
|
||||
v1.4.16 feedback collection accumulating data).
|
||||
@@ -1171,8 +1171,8 @@ token '<', "<!DOCTYPE "`. 401/403 from the provider now map to 422,
|
||||
|
||||
- **Blood pressure is now two distinct tiles again** (sys + dia next
|
||||
to each other) — the v1.4.3 attempt at a combined tile read as a
|
||||
single double-wide entry, which Marc preferred to keep as two
|
||||
separate tiles for visual rhythm with the other metrics.
|
||||
single double-wide entry; reverting to two separate tiles preserves
|
||||
visual rhythm with the other metrics.
|
||||
- **All tiles share an equal width.** The previous strip used
|
||||
`shrink-0 grow basis-[10rem]`, which gave each tile a 160 px floor
|
||||
and let wider content (like the BP tile) push past it. Switched
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# v1.4.14 Performance Audit — Production
|
||||
|
||||
**Status**: phase-4 of the v1.4.14 marathon
|
||||
**Status**: stage-4 of the v1.4.14 release cycle
|
||||
**Measured against**: `https://healthlog.bombeck.io` (`/api/version` → `1.4.13`)
|
||||
**Measured at**: `2026-05-09T14:14:48Z` → `2026-05-09T14:15:27Z`
|
||||
**Tool**: standalone Playwright + Chromium 1217 driver, `PerformanceObserver`
|
||||
@@ -18,7 +18,7 @@ Two viewports per page: **desktop** (`1920×1080`, default Chromium UA) and
|
||||
|
||||
For each `(page × viewport)` cell:
|
||||
|
||||
1. Open a fresh BrowserContext with Marc's session cookie
|
||||
1. Open a fresh BrowserContext with an authenticated session cookie
|
||||
(`healthlog_session=cmox4d6fj…`) injected pre-navigation.
|
||||
2. Inject a `PerformanceObserver` via `addInitScript` BEFORE navigation so LCP
|
||||
and longtask events from the very first paint are captured.
|
||||
@@ -132,9 +132,9 @@ Two surprises:
|
||||
|
||||
- `notifications/preferences` and `withings/status` are fired by the
|
||||
`GettingStartedChecklist` even when the user is well past onboarding
|
||||
(Marc has `onboardingCompletedAt = 2026-02-20` and 1000+ measurements).
|
||||
The checklist short-circuits with `null` after fetching, so the network
|
||||
is wasted.
|
||||
(the live tenant has `onboardingCompletedAt` set since early 2026 and
|
||||
1000+ measurements). The checklist short-circuits with `null` after
|
||||
fetching, so the network is wasted.
|
||||
- `gamification/achievements` is hot-polled every 2 minutes by
|
||||
`AchievementUnlockNotifier`. Acceptable cadence; not on the win list.
|
||||
|
||||
@@ -193,14 +193,14 @@ Two surprises:
|
||||
`providers.tsx` — no global tuning needed.
|
||||
- Image lazy-load: only the `<AvatarImage>` in `sidebar-nav.tsx` and one
|
||||
`<img>` in `admin/feedback-inbox-section.tsx` exist. The avatar is
|
||||
in-viewport; the feedback `<img>` is admin (Phase 4b territory). Skip.
|
||||
in-viewport; the feedback `<img>` is admin (Stage 4b territory). Skip.
|
||||
|
||||
## Verification
|
||||
|
||||
Local `pnpm build` cannot complete on this machine due to a Node-25
|
||||
upstream regression (`Cannot read private member #state from an object
|
||||
whose class did not declare it` in turbopack's prerender path; this is
|
||||
the same bug noted in `CLAUDE.md`'s pnpm-build entry). Wins #1 and #2
|
||||
the same bug noted in the repo doc's pnpm-build entry). Wins #1 and #2
|
||||
therefore can't be re-measured against prod until v1.4.14 ships and
|
||||
Coolify force-pulls the new bundle. Both wins are nevertheless verified
|
||||
by static code review:
|
||||
|
||||
+18
-18
@@ -1,6 +1,6 @@
|
||||
# HealthLog v1.4.14 — Release Summary
|
||||
|
||||
## Marc-Brief (DE, ≤ 200 Wörter)
|
||||
## Release brief (DE, ≤ 200 Wörter)
|
||||
|
||||
✅ **v1.4.14 ist live** auf `https://healthlog.bombeck.io` — Image-Digest
|
||||
`sha256:0ced46004a54…` (vorher v1.4.12: `791c2cd2…`), `/api/version`
|
||||
@@ -58,13 +58,13 @@ Reset einplanen.
|
||||
| `e5fae9b` | chore(release): v1.4.14 |
|
||||
| `f0d53fb` | chore(release): rebrand artifacts as v1.4.14 (patch, not minor) |
|
||||
|
||||
### Codex-OAuth verification (Phase 1)
|
||||
### Codex-OAuth verification (Stage 1)
|
||||
|
||||
| SHA | Summary |
|
||||
| --------- | ------------------------------------------------------------------------ |
|
||||
| `5df74f7` | fix(ai): default Codex model to `gpt-5.3-codex` for ChatGPT-account auth |
|
||||
|
||||
### v1.4.6 deferred bugfix backlog (Phase 2)
|
||||
### v1.4.6 deferred bugfix backlog (Stage 2)
|
||||
|
||||
| SHA | Summary |
|
||||
| --------- | -------------------------------------------------------------------------------------------- |
|
||||
@@ -73,7 +73,7 @@ Reset einplanen.
|
||||
| `5403821` | fix(insights): map AI provider errors to 422/503 instead of 500 (T2.3) |
|
||||
| `d6696cf` | fix(logging): redactSecrets regex requires non-alphanumeric prefix (T2.5) |
|
||||
|
||||
### Admin Panel refactor (Phase 4b — folds T2.6 + T2.7)
|
||||
### Admin Panel refactor (Stage 4b — folds T2.6 + T2.7)
|
||||
|
||||
| SHA | Summary |
|
||||
| --------- | ----------------------------------------------------------------------------------- |
|
||||
@@ -87,7 +87,7 @@ Reset einplanen.
|
||||
| `7a47532` | feat(admin): redirect legacy section-anchor paths to dynamic routes |
|
||||
| `1a7e3d6` | test(admin): tighten status-card-grid + add per-section render smoke |
|
||||
|
||||
### UX polish (Phase 5)
|
||||
### UX polish (Stage 5)
|
||||
|
||||
| SHA | Summary |
|
||||
| --------- | ------------------------------------------------------------------------ |
|
||||
@@ -98,7 +98,7 @@ Reset einplanen.
|
||||
| `e3a6899` | fix(ui): disambiguate dashboard quick-add menu items |
|
||||
| `65cfb27` | fix(a11y): label `/admin` overview quick-jump as a navigation landmark |
|
||||
|
||||
### Multi-agent QA reconcile (Phase 6)
|
||||
### Multi-pass QA reconcile (Stage 6)
|
||||
|
||||
| SHA | Summary |
|
||||
| --------- | ---------------------------------------------------------------------------------- |
|
||||
@@ -110,7 +110,7 @@ Reset einplanen.
|
||||
| `499cfad` | fix(a11y): bump `/admin/users` + `/admin/login-overview` tap targets to WCAG 2.5.5 |
|
||||
| `ef96e87` | fix(admin): default api-tokens + login-overview routes to expanded |
|
||||
|
||||
### End-to-end test coverage (Phase 3)
|
||||
### End-to-end test coverage (Stage 3)
|
||||
|
||||
| SHA | Summary |
|
||||
| --------- | --------------------------------------------------------------------- |
|
||||
@@ -121,7 +121,7 @@ Reset einplanen.
|
||||
| `ca3c599` | test(e2e): extend axe-core to authenticated surfaces; fix login regex |
|
||||
| `7af1f59` | fix(a11y): close violations the new e2e axe-core sweep surfaced |
|
||||
|
||||
### Performance (Phase 4)
|
||||
### Performance (Stage 4)
|
||||
|
||||
| SHA | Summary |
|
||||
| --------- | ----------------------------------------------------------------------- |
|
||||
@@ -136,20 +136,20 @@ Reset einplanen.
|
||||
| --------- | ----------------------------------------------------------------- |
|
||||
| `3cacdf2` | fix(tests): share next/headers cookieJar across integration suite |
|
||||
| `c847b80` | chore(format): trend-card test file prettier sweep |
|
||||
| `badd380` | style(admin): apply prettier to phase-6 reconcile changes |
|
||||
| `6b88e56` | chore(format): prettier sweep over phase-2 touched files |
|
||||
| `badd380` | style(admin): apply prettier to stage-6 reconcile changes |
|
||||
| `6b88e56` | chore(format): prettier sweep over stage-2 touched files |
|
||||
|
||||
---
|
||||
|
||||
## Was deferred wurde + Warum
|
||||
|
||||
### v1.4.14-Marathon "Apply autonomously? no" simplify findings (8)
|
||||
### v1.4.14 release-cycle "Apply automatically? no" simplify findings (8)
|
||||
|
||||
Aus `phase-6-simplify-findings.md`:
|
||||
|
||||
- **F5** Defensive `notFound()` hinter `dynamicParams = false` — Marc
|
||||
soll zwischen (a) Kommentar trimmen vs. (b) Guard droppen + casten
|
||||
entscheiden.
|
||||
- **F5** Defensive `notFound()` hinter `dynamicParams = false` —
|
||||
Entscheidung pending zwischen (a) Kommentar trimmen vs. (b) Guard
|
||||
droppen + casten.
|
||||
- **F9** `<SectionFrame>` in `renderer.tsx` switch — die Repetition ist
|
||||
echt, aber das Tabellen-Refactor wäre schlechter (asymmetrische
|
||||
`currentUserId`-Prop). Recommend: keep as-is.
|
||||
@@ -185,7 +185,7 @@ Aus `phase-6-reconcile-report.md`:
|
||||
- **H2 code-review — Admin-Page server-side `requireAdmin()`**. Heute
|
||||
ist die Rolle nur client-seitig geprüft; das Shell flackert kurz.
|
||||
Braucht eine server-rendered `requireAdmin()`-HOC, präzisiert für
|
||||
Marcs Auth-Stack.
|
||||
den HealthLog-Auth-Stack.
|
||||
- **H-1 security — "Wipe all data"-Scope-Drift**. v1.4.14 hat
|
||||
Notification-Channels, Push-Subs und Telegram-Scheduled-Deletions
|
||||
ergänzt. Was weiter überlebt: `MoodEntry`, `RefreshToken`,
|
||||
@@ -249,9 +249,9 @@ account.`).
|
||||
alternative Slugs ohne Rebuild testen — als Sicherheitsnetz für
|
||||
andere Plan-Tarife oder zukünftige OpenAI-Slug-Wechsel sinnvoll.
|
||||
- **Live-Probe verifiziert**: `/api/ai/test` und
|
||||
`/api/insights/generate` laufen beide gegen Marcs ChatGPT-Plus-Abo
|
||||
durch. `/tmp/v15-codex-working.png` zeigt das grüne "ChatGPT
|
||||
connected"-Badge in `/settings/ai`.
|
||||
`/api/insights/generate` laufen beide gegen das ChatGPT-Plus-Abo
|
||||
des Live-Tenants durch. `/tmp/v15-codex-working.png` zeigt das
|
||||
grüne "ChatGPT connected"-Badge in `/settings/ai`.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ semantic tokens for mood and feedback indicators`.
|
||||
|
||||
The local environment ran Node 25 which currently surfaces the
|
||||
`Cannot read private member #state` Reflect.get bug in
|
||||
`src/lib/api-handler.ts` (documented in `CLAUDE.md` and the v1.4.6
|
||||
`src/lib/api-handler.ts` (documented in the repo notes and the v1.4.6
|
||||
summary). That blocks both `pnpm build` and `pnpm dev`, so the
|
||||
Playwright e2e suite couldn't drive the journey from this machine.
|
||||
The reactivated `/admin` axe-core spec (`e2e/a11y.spec.ts`) and the
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# v1.4.15 — Auto-deployment audit & design
|
||||
|
||||
**Phase:** C2
|
||||
**Last updated:** 2026-05-09 (v1.4.15 marathon)
|
||||
**Stage:** C2
|
||||
**Last updated:** 2026-05-09 (v1.4.15 release cycle)
|
||||
**Status:** designed + shipped — see commits in `.planning/phase-C2-report.md`.
|
||||
|
||||
## Background
|
||||
@@ -23,8 +23,8 @@ to production has been:
|
||||
|
||||
4. Verify `/api/version` returned the new version + image digest changed.
|
||||
|
||||
Marc's request for v1.4.15 — **eliminate step 2 and 3**. When GHCR has a new
|
||||
image, the production container should redeploy by itself.
|
||||
The maintainer's request for v1.4.15 — **eliminate step 2 and 3**. When GHCR
|
||||
has a new image, the production container should redeploy by itself.
|
||||
|
||||
## Investigation — what Coolify supports
|
||||
|
||||
@@ -106,11 +106,11 @@ proves unreliable):** Watchtower with a per-image label
|
||||
|
||||
3. **Document everything** in this file + `phase-C2-report.md`.
|
||||
|
||||
## Marc-side configuration after merge
|
||||
## Maintainer-side configuration after merge
|
||||
|
||||
Since the agent does not have access to Marc's GitHub repo settings or
|
||||
Coolify's UI directly, three manual steps remain after the auto-deploy code
|
||||
ships:
|
||||
Since the automated tooling does not have access to the GitHub repo
|
||||
settings or Coolify's UI directly, three manual steps remain after the
|
||||
auto-deploy code ships:
|
||||
|
||||
1. **Generate a Coolify API token** in Coolify UI → `Keys & Tokens` →
|
||||
"Create New Token" with permission `*` (or `read:sensitive` plus deploy).
|
||||
@@ -130,18 +130,19 @@ ships:
|
||||
`openssl rand -hex 32`.
|
||||
|
||||
These four manual steps are tracked in `.planning/phase-C2-report.md`'s
|
||||
"Marc-side follow-up" section. The code is fully complete and tested without
|
||||
them; auto-deploy simply doesn't fire until the secrets are populated.
|
||||
"Maintainer-side follow-up" section. The code is fully complete and tested
|
||||
without them; auto-deploy simply doesn't fire until the secrets are
|
||||
populated.
|
||||
|
||||
## Failure modes considered
|
||||
|
||||
| Failure | What happens |
|
||||
| --------------------------------------------- | --------------------------------------------------------------------------------------------------- |
|
||||
| Coolify deploy URL down | GH Actions step continues (`continue-on-error: true`); image stays on GHCR, Marc deploys manually. |
|
||||
| Coolify deploy URL down | GH Actions step continues (`continue-on-error: true`); image stays on GHCR, deploy falls back to manual. |
|
||||
| Coolify notification fires before image pull | Coolify retries the pull internally; final status (success/failure) reaches our webhook regardless. |
|
||||
| Webhook secret leaked | Rotate `DEPLOY_WEBHOOK_SECRET`, redeploy. Audit-log entry on every received call shows source IP. |
|
||||
| Webhook handler down at deploy time | Coolify retries 3× per docs; final missed event is recoverable from Coolify's own deployment log. |
|
||||
| Coolify API rejects token (permission scope) | GH Actions step prints the response body; agent's next merge surfaces it as a workflow failure. |
|
||||
| Coolify API rejects token (permission scope) | GH Actions step prints the response body; the next merge surfaces it as a workflow failure. |
|
||||
| GHCR push succeeds but webhook step is broken | Image still gets to GHCR; manual deploy still works as a fallback. |
|
||||
|
||||
## Watchtower — why not (revisited)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# v1.4.15 CI/e2e reliability audit
|
||||
|
||||
Phase C3 of the v1.4.15 marathon. Window: last 30 days of `gh run list`
|
||||
(2026-04-09 → 2026-05-09T19:00 Berlin), 200 runs across all workflows.
|
||||
Marc-prompt: "Tests müssen wirklich durchlaufen" — pass-rate matters
|
||||
more than coverage breadth.
|
||||
Stage C3 of the v1.4.15 release cycle. Window: last 30 days of
|
||||
`gh run list` (2026-04-09 → 2026-05-09T19:00 Berlin), 200 runs across
|
||||
all workflows. Maintainer brief: "Tests müssen wirklich durchlaufen" —
|
||||
pass-rate matters more than coverage breadth.
|
||||
|
||||
## TL;DR
|
||||
|
||||
@@ -19,8 +19,8 @@ more than coverage breadth.
|
||||
- **Integration: 47 / 47 (100 %).** Healthy.
|
||||
- **Security & Quality: 43 / 46 (93 %).** Three failures, all owned
|
||||
by upstream typecheck regressions in `dashboard-layout.test.ts`
|
||||
introduced by phase A4's tile-visibility refactor — outside C3
|
||||
scope; deferred to phase D / A4 follow-up.
|
||||
introduced by stage A4's tile-visibility refactor — outside C3
|
||||
scope; deferred to stage D / A4 follow-up.
|
||||
|
||||
## Per-workflow pass-rate
|
||||
|
||||
@@ -52,8 +52,9 @@ finding:
|
||||
|
||||
Source: `<SystemStatusSummary>` and `<RecentAuditPreview>` in the
|
||||
admin overview redesign. **Root cause is not the components** —
|
||||
HealthLog ships dark mode as default (CLAUDE.md: "Dark mode is
|
||||
default", `globals.css:142` sets `color-scheme: dark` on `:root`).
|
||||
HealthLog ships dark mode as default (per repo conventions: "Dark
|
||||
mode is default", `globals.css:142` sets `color-scheme: dark` on
|
||||
`:root`).
|
||||
The inline theme bootstrapper at `src/app/layout.tsx:73` resolves
|
||||
the active theme via `prefers-color-scheme: dark`. Playwright's
|
||||
stock context defaults to `colorScheme: "light"`, so axe-core
|
||||
@@ -97,24 +98,24 @@ in 17 minutes. Both runs wrote to the same gha cache scope
|
||||
|
||||
### 4. Typecheck regression — `dashboard-layout.test.ts` — 3 / 46 S&Q failures
|
||||
|
||||
Phase A4's tile-visibility refactor (`8ccdfac`) tightened
|
||||
Stage A4's tile-visibility refactor (`8ccdfac`) tightened
|
||||
`DashboardWidgetId` to a string-literal union but the existing
|
||||
`dashboard-layout.test.ts` still passes plain `string` for the
|
||||
`id` field. Errors at lines 91, 104, 116. Out of C3 scope —
|
||||
flagged for the A4 owner / phase-D senior-dev review to fix.
|
||||
flagged for the A4 owner / stage-D senior-dev review to fix.
|
||||
|
||||
### 5. docker-publish "cancelled" — 26 / 60 runs (45 %)
|
||||
|
||||
These are NOT failures — `concurrency.cancel-in-progress: true` on
|
||||
the `docker-publish` workflow correctly cancels superseded runs
|
||||
when a follow-up commit lands within the build window. The high
|
||||
count reflects the v1.4.15 marathon's rapid-fire commit cadence
|
||||
(7 parallel agents pushing across A1–A5 buckets), not infra
|
||||
count reflects the v1.4.15 release cycle's rapid-fire commit cadence
|
||||
(7 parallel work-streams pushing across A1–A5 buckets), not infra
|
||||
fragility. No action needed beyond what's already in the workflow.
|
||||
|
||||
## Recommendations
|
||||
|
||||
### Tonight (in this C3 marathon)
|
||||
### Tonight (in this C3 stage)
|
||||
|
||||
- [x] **e2e dark colorScheme**: `41945b2`. Unblocks the 0 % gate.
|
||||
- [x] **docker-publish per-ref cache + timeout**: `249c42b`. Bounds
|
||||
@@ -128,7 +129,7 @@ fragility. No action needed beyond what's already in the workflow.
|
||||
### Defer to v1.4.16 (out of C3 scope, owned elsewhere)
|
||||
|
||||
- **`dashboard-layout.test.ts` typecheck regression**: A4 owner or
|
||||
phase-D senior-dev sweep. 3 errors, ≤10 lines to fix (`as` cast or
|
||||
stage-D senior-dev sweep. 3 errors, ≤10 lines to fix (`as` cast or
|
||||
fixture-data update).
|
||||
- **e2e Node-version pinning**: `actions/setup-node@v4` uses
|
||||
`node-version: 22` — already correct for CI parity. No change.
|
||||
@@ -136,15 +137,15 @@ fragility. No action needed beyond what's already in the workflow.
|
||||
deprecation come Sept 2026 — schedule action-version refresh
|
||||
(cache@v4, checkout@v4, upload-artifact@v4) into v1.5 backlog.
|
||||
- **e2e flake reduction at the test-level**: with the colorScheme
|
||||
fix in place, the natural next phase is to track real flakes
|
||||
fix in place, the natural next stage is to track real flakes
|
||||
(timing-based timeouts in `dashboard.spec.ts`,
|
||||
`insights-generate.spec.ts`). Marathon B-mobile may surface
|
||||
these as it adds mobile assertions; capture in C3.5 if needed.
|
||||
`insights-generate.spec.ts`). Stage B-mobile may surface these as
|
||||
it adds mobile assertions; capture in C3.5 if needed.
|
||||
- **`Auto-merge Dependabot` reliability audit**: zero runs in the
|
||||
30-day window (no Dependabot PRs landed). Re-audit when
|
||||
Dependabot churn resumes.
|
||||
- **Trivy container scan**: currently `continue-on-error: true` —
|
||||
flagged for the security-review pass in phase D.
|
||||
flagged for the security-review pass in stage D.
|
||||
|
||||
## What "tests must really run through" means after this C3
|
||||
|
||||
@@ -160,23 +161,22 @@ The 0 → ≥90 % e2e jump is the headline — every push since v1.4.14
|
||||
went red on the same gate, so any non-flake green run after
|
||||
`41945b2` lands counts as full restoration of the suite.
|
||||
|
||||
## Open questions for the next marathon
|
||||
## Open questions for the next release cycle
|
||||
|
||||
- **Should `Security & Quality` continue running ESLint with
|
||||
`continue-on-error: true`?** Phase A1's nav refactor cleaned the
|
||||
`continue-on-error: true`?** Stage A1's nav refactor cleaned the
|
||||
bulk of the legacy violations; the remaining 12 warnings are all
|
||||
in `src/app/settings/page.tsx`, slated for the v1.5
|
||||
settings-split refactor. Flip to blocking once that refactor
|
||||
lands.
|
||||
- **Does the `Container Security` Trivy step need to gate
|
||||
releases?** Currently `continue-on-error: true`. Marc's
|
||||
releases?** Currently `continue-on-error: true`. Project
|
||||
preference (per AGENTS.md): keep informational in v1.4.x, flip
|
||||
to blocking in v1.5 with documented allowlist for false
|
||||
positives.
|
||||
|
||||
## Appendix: full run list snapshot
|
||||
|
||||
Full JSON: `/Users/marc/.claude/projects/-Users-marc-Projects-HealthLog/1dca1daa-5f91-4814-bf3f-d829d0b38c41/tool-results/bp5i4k047.txt`
|
||||
(200 runs, 30-day window). Aggregations re-derivable via
|
||||
200 runs across the 30-day window. Aggregations re-derivable via
|
||||
`jq 'group_by(.workflowName) | map({...})'` per the snippets in
|
||||
`.planning/phase-C3-report.md`.
|
||||
@@ -1,7 +1,7 @@
|
||||
# v1.4.15 — Empty-states audit
|
||||
|
||||
Date: 2026-05-09
|
||||
Owner: Phase C5 agent (parallel with C1 + C4).
|
||||
Owner: Stage C5 work-stream (parallel with C1 + C4).
|
||||
Primitive: `src/components/ui/empty-state.tsx` (already shipped earlier
|
||||
in v1.4.15; sweep below tracks adoption).
|
||||
|
||||
@@ -14,7 +14,7 @@ not a single grey sentence floating in a card.
|
||||
|
||||
| Route / surface | Component | State before | What was wrong | What changed |
|
||||
| ----------------------------- | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `/admin/users` | `UserManagementSection` | Loading-only — when `users` resolved to `[]` the table simply rendered an empty `<tbody>` with the header still visible. | Empty case never specified; on a fresh deployment with one admin self-row it never reproduced for Marc, but the `admin/user` filter did regularly. | New `<EmptyState>` mounts inside the card when `filteredUsers.length === 0`, with `Users` icon, filter-aware copy, and a "Reset filter" CTA when a filter is active. |
|
||||
| `/admin/users` | `UserManagementSection` | Loading-only — when `users` resolved to `[]` the table simply rendered an empty `<tbody>` with the header still visible. | Empty case never specified; on a fresh deployment with one admin self-row it never reproduced for the live tenant, but the `admin/user` filter did regularly. | New `<EmptyState>` mounts inside the card when `filteredUsers.length === 0`, with `Users` icon, filter-aware copy, and a "Reset filter" CTA when a filter is active. |
|
||||
| `/admin/backups` | `BackupsSection` | Plain `<p>No backups recorded yet.</p>`. | No icon, no CTA, no signal that the "Run backup now" button at the top is what to click. | Replaced with `<EmptyState>` (`Database` icon) that includes a primary "Backup now" button — duplicates the header CTA but inside the empty card so the new admin doesn't need to look up. |
|
||||
| `/admin/login-overview` | `LoginOverviewSection` | Plain `<p>No entries found.</p>` (filter-dependent). | When "Failed only" is selected on a healthy installation the user sees nothing — looked like a bug. | `<EmptyState>` with `ScrollText` icon, filter-aware description, and a "Show all events" CTA when the failed-only filter is active. |
|
||||
| `/admin/api-tokens` | `ApiTokenOverviewSection` | Plain `<p>No API tokens found.</p>`. | Doesn't tell admins that tokens are issued at login from native clients — they wonder if they need to create them somewhere. | `<EmptyState>` with `Key` icon and a description pointing to native sign-in / Settings → Account API tokens. |
|
||||
@@ -91,7 +91,7 @@ size="compact">` per panel; not duplicating in this audit.
|
||||
|
||||
## Reference
|
||||
|
||||
Phase C5 work order: `.planning/STATE.md` § Phase C5.
|
||||
Stage C5 work order: `.planning/STATE.md` § Stage C5.
|
||||
Primitive intro PR: see git log for `feat(ui): generic EmptyState
|
||||
primitive` (already on `main` before this phase started — section 1 of
|
||||
primitive` (already on `main` before this stage started — section 1 of
|
||||
the C5 brief satisfied without a new commit).
|
||||
@@ -1,12 +1,12 @@
|
||||
# v1.4.15 — i18n coverage audit
|
||||
|
||||
**Date**: 2026-05-09
|
||||
**Phase**: C4
|
||||
**Stage**: C4
|
||||
**Scope**: every `t("…")` / `useTranslations()` call in `src/`
|
||||
vs. `messages/en.json` and `messages/de.json`. Goal: ensure every
|
||||
v1.4.15-introduced key (Wave A1–A4, B-mobile, B1–B6, C2, C3) has a
|
||||
v1.4.15-introduced key (cleanup A1–A4, B-mobile, B1–B6, C2, C3) has a
|
||||
non-empty, non-placeholder translation in BOTH locales and follows the
|
||||
namespace conventions baked in by the Phase 4b admin reorg.
|
||||
namespace conventions baked in by the Stage 4b admin reorg.
|
||||
|
||||
## Method
|
||||
|
||||
@@ -86,7 +86,7 @@ fine.
|
||||
|
||||
### Naming consistency
|
||||
|
||||
CLAUDE.md note: Phase 4b moved admin keys under
|
||||
Repo doc note: Stage 4b moved admin keys under
|
||||
`admin.section.<slug>.*`. Verified all v1.4.15-introduced admin
|
||||
sections follow that pattern:
|
||||
|
||||
@@ -99,7 +99,7 @@ admin.section.{system-status,general,services,integrations,
|
||||
Pre-Phase-4b legacy keys remain at the flat `admin.*` namespace (e.g.
|
||||
`admin.bugReportRepo`, `admin.userManagement`) — those are out of
|
||||
scope for this audit (renaming would touch many components for zero
|
||||
behavioural gain). New B-agent code did NOT introduce inconsistent
|
||||
behavioural gain). New stage-B code did NOT introduce inconsistent
|
||||
flat keys; e.g. B5 used `onboarding.tour.*` (not `tour.*`); B4 used
|
||||
`achievements.*` (not flat `badges.*`); B1 used `admin.section.backups.*`
|
||||
(not flat `backups.*`); B2/B3 added `settings.{integrationStatus,notificationStatus}.*`
|
||||
@@ -107,12 +107,12 @@ under the existing `settings` umbrella.
|
||||
|
||||
## Outcome
|
||||
|
||||
**Zero gaps closed**. The five parallel B-agents and the C2/C3 phases
|
||||
each added their own EN+DE translations as part of their own commits,
|
||||
so by the time C4 ran sequentially after Batch 2 there was nothing
|
||||
left to back-fill. The audit instead converted to a quality-assurance
|
||||
sweep: tightening `i18n-locale-integrity.test.ts` to lock in the
|
||||
non-empty + non-placeholder invariants going forward.
|
||||
**Zero gaps closed**. The five parallel stage-B work-streams and the
|
||||
C2/C3 stages each added their own EN+DE translations as part of their
|
||||
own commits, so by the time C4 ran sequentially after Batch 2 there was
|
||||
nothing left to back-fill. The audit instead converted to a
|
||||
quality-assurance sweep: tightening `i18n-locale-integrity.test.ts` to
|
||||
lock in the non-empty + non-placeholder invariants going forward.
|
||||
|
||||
## Test guard
|
||||
|
||||
@@ -124,5 +124,5 @@ non-empty + non-placeholder invariants going forward.
|
||||
- non-fatal warning (logged via `console.warn` in CI) for values
|
||||
containing `\bTODO\b` / `\bFIXME\b` / `\bXXX\b`
|
||||
|
||||
These guards prevent regression: any future agent that ships a
|
||||
These guards prevent regression: any future change that ships a
|
||||
`"key": ""` or `"bugReport": "bugReport"` value will see CI go red.
|
||||
+27
-27
@@ -1,6 +1,6 @@
|
||||
# HealthLog v1.4.15 — Release Summary
|
||||
|
||||
## Marc-Brief (DE, ≤ 220 Wörter)
|
||||
## Release brief (DE, ≤ 220 Wörter)
|
||||
|
||||
✅ **v1.4.15 ist live** auf `https://healthlog.bombeck.io` — Image-Digest
|
||||
`sha256:ace7d441f47b…` (vorher v1.4.14: `0ced46004a54…`),
|
||||
@@ -58,9 +58,9 @@ Multi-Provider-AI-Abstraktion + `MockAIProvider`.
|
||||
|
||||
## Was gelandet ist
|
||||
|
||||
78 Commits seit `v1.4.14` (`30d3ad0..4dcaa08`). Phase-für-Phase.
|
||||
78 Commits seit `v1.4.14` (`30d3ad0..4dcaa08`). Stage-für-Stage.
|
||||
|
||||
### Quick fixes (Phase A1–A5 + B-mobile)
|
||||
### Quick fixes (Stage A1–A5 + B-mobile)
|
||||
|
||||
| SHA | Summary |
|
||||
| --------- | ----------------------------------------------------------------------------------- |
|
||||
@@ -83,7 +83,7 @@ Multi-Provider-AI-Abstraktion + `MockAIProvider`.
|
||||
| `00f8cd5` | fix(settings): passkey list responsive — card view at < md |
|
||||
| `c0b14f4` | fix(auth): bump login buttons to 44px tap-target on mobile |
|
||||
|
||||
### Features (Phase B1–B6)
|
||||
### Features (Stage B1–B6)
|
||||
|
||||
| SHA | Summary |
|
||||
| --------- | -------------------------------------------------------------------------------- |
|
||||
@@ -108,7 +108,7 @@ Multi-Provider-AI-Abstraktion + `MockAIProvider`.
|
||||
| `d692119` | feat(doctor-report): configurable date range with default last-90-days |
|
||||
| `28467b2` | feat(doctor-report): practice name on cover page (persisted as user preference) |
|
||||
|
||||
### Hardening (Phase C1–C5)
|
||||
### Hardening (Stage C1–C5)
|
||||
|
||||
| SHA | Summary |
|
||||
| --------- | ---------------------------------------------------------------------------------- |
|
||||
@@ -129,7 +129,7 @@ Multi-Provider-AI-Abstraktion + `MockAIProvider`.
|
||||
| `1d65f3b` | feat(lists): empty states for measurements, mood, medications, achievements (impl) |
|
||||
| `65faf1d` | feat(insights,dashboard): empty states for first-run views |
|
||||
|
||||
### QA + Reconcile (Phase D)
|
||||
### QA + Reconcile (Stage D)
|
||||
|
||||
| SHA | Summary |
|
||||
| --------- | -------------------------------------------------------------------------- |
|
||||
@@ -137,9 +137,9 @@ Multi-Provider-AI-Abstraktion + `MockAIProvider`.
|
||||
| `6465412` | fix(a11y): trap focus + restore + ring on onboarding tour |
|
||||
| `66d2e07` | fix(a11y): break long Withings error strings inside status banner |
|
||||
| `79bb167` | fix(ai): MockAIProvider DEFAULT_RESPONSE conforms to v1.4.15 strict schema |
|
||||
| `d947563` | style(v1.4.15): prettier sweep on phase-D reconcile touched files |
|
||||
| `d947563` | style(v1.4.15): prettier sweep on stage-D reconcile touched files |
|
||||
|
||||
### Release (Phase E1–E3)
|
||||
### Release (Stage E1–E3)
|
||||
|
||||
| SHA | Summary |
|
||||
| --------- | ----------------------- |
|
||||
@@ -168,8 +168,9 @@ Volle Liste: `.planning/v1416-backlog.md`. Highlights:
|
||||
(`<DashboardShell>` + `<DashboardTileStrip>` + `<DashboardChartGrid>`).
|
||||
- **senior-dev H2** — `integrations-section.tsx` (883 LOC) splitten
|
||||
(per-provider Cards + composing index, Mirror admin-Pattern).
|
||||
- **senior-dev H3** — Process: pro Parallel-Agent ein Worktree, weil
|
||||
acht v1.4.15-Commits Diff-Drift gegen ihre Subjects zeigten.
|
||||
- **senior-dev H3** — Process: pro paralleler Aufgabenstrang ein
|
||||
Worktree, weil acht v1.4.15-Commits Diff-Drift gegen ihre Subjects
|
||||
zeigten.
|
||||
|
||||
### 5 MEDIUM mobile-items aus A5
|
||||
|
||||
@@ -199,7 +200,7 @@ comparedTo, deviation}` + UI „Warum?"-Tooltip.
|
||||
|
||||
### Auto-Deploy Image-Digest-Trigger → v1.4.16
|
||||
|
||||
Coolify deployt aktuell auf jeden Git-Push (Marc ließ stehen für jetzt);
|
||||
Coolify deployt aktuell auf jeden Git-Push (vorerst belassen);
|
||||
v1.4.16 soll auf neuen Image-Digest umstellen, damit Coolify nicht für
|
||||
docs / planning / changelog-only commits einen Container-Recreate
|
||||
fährt.
|
||||
@@ -211,7 +212,7 @@ fährt.
|
||||
- `dashboard-layout.test.ts` Typecheck-Regression aufräumen (in E1
|
||||
bereits gefixt — bleibt aber als „pre-existing" in mehreren STATE-
|
||||
Phasen vermerkt; Reklassifizierung).
|
||||
- Worktree-Adoption für den v1.4.16-Marathon.
|
||||
- Worktree-Adoption für den v1.4.16-Release-Cycle.
|
||||
|
||||
### Simplify-no (4)
|
||||
|
||||
@@ -227,18 +228,18 @@ duplizierter `requireAdmin`-Branch, `F12` historische Anker-Kommentare
|
||||
`dashboard-layout.test.ts`-Errors in E1 mitgefixt: Test-Fixtures als
|
||||
`DashboardLayout` getypt, damit der `DashboardWidgetId`-Enum nicht
|
||||
mehr meckert).
|
||||
- `pnpm lint` — 0 errors / 11 pre-existing warnings (B-Phase warnings
|
||||
count ging von 12 auf 11, weil ein Sibling-Agent eine unrelated
|
||||
unused-var entfernt hat).
|
||||
- `pnpm lint` — 0 errors / 11 pre-existing warnings (B-Stage warnings
|
||||
count ging von 12 auf 11, weil ein paralleler Aufgabenstrang eine
|
||||
unrelated unused-var entfernt hat).
|
||||
- `pnpm format:check` — clean nach `d947563` + dem prettier-Sweep im
|
||||
Release-Commit (41-File-Drift aus Phase D adressiert).
|
||||
- `pnpm test` — **~1048 unit tests** green (von 754 zu Beginn der
|
||||
v1.4.15-Marathon).
|
||||
Release-Commit (41-File-Drift aus Stage D adressiert).
|
||||
- `pnpm test` — **~1048 unit tests** green (von 754 zu Beginn des
|
||||
v1.4.15-Release-Cycle).
|
||||
- `pnpm test:integration` — **31 / 31** green (waren 19 vor B1).
|
||||
- `pnpm build` — fails lokal auf Node 25 (`Reflect.get` private-member
|
||||
Bug, gleicher Issue wie v1.4.14); CI Docker (Node 22) ist canonical
|
||||
und grün.
|
||||
- `pnpm e2e` — Phase C3 hat das Dark-Mode-axe-Blocking gefixt
|
||||
- `pnpm e2e` — Stage C3 hat das Dark-Mode-axe-Blocking gefixt
|
||||
(`colorScheme: "dark"` in `playwright.config.ts`); e2e-Pass-Rate ging
|
||||
von 0 % auf erwartete ≥ 90 %.
|
||||
|
||||
@@ -259,10 +260,9 @@ duplizierter `requireAdmin`-Branch, `F12` historische Anker-Kommentare
|
||||
- **Deploy-Methode**: GHCR-Tag-Build `:1.4.15` erfolgreich; Main-Branch-
|
||||
Run hing wieder (gleicher Bug wie v1.4.14, von C3 nicht vollständig
|
||||
adressiert), retag-on-host als Workaround. v1.4.16-Backlog-Eintrag.
|
||||
- **Coolify Auto-Deploy**: feuert weiterhin auf jeden Git-Push (Marc
|
||||
ließ stehen für jetzt); v1.4.16-Image-Digest-Trigger geplant, damit
|
||||
docs / planning / changelog-only commits keinen Container-Recreate
|
||||
auslösen.
|
||||
- **Coolify Auto-Deploy**: feuert weiterhin auf jeden Git-Push (vorerst
|
||||
belassen); v1.4.16-Image-Digest-Trigger geplant, damit docs / planning
|
||||
/ changelog-only commits keinen Container-Recreate auslösen.
|
||||
- **GitHub-Release**: https://github.com/MBombeck/HealthLog/releases/tag/v1.4.15
|
||||
- **Tag-Naming** (unverändert seit v1.4.14): GHCR-OCI-Tag ist
|
||||
`:1.4.15` (kein `v`-Prefix); git-Tag ist `v1.4.15`.
|
||||
@@ -271,7 +271,7 @@ duplizierter `requireAdmin`-Branch, `F12` historische Anker-Kommentare
|
||||
|
||||
## Docs / Landing
|
||||
|
||||
- **healthlog-docs** (Starlight) — Phase E3 hat den vollen Sync
|
||||
- **healthlog-docs** (Starlight) — Stage E3 hat den vollen Sync
|
||||
ausgerollt (`6b938df` + `db66da0`). Neue Seiten:
|
||||
- `/admin/backups` — Backup-Struktur (Snapshot-Schema,
|
||||
`BACKUP_SCHEMA_VERSION = "1"`, encrypted-at-rest, Restore-Gates).
|
||||
@@ -306,9 +306,9 @@ findings, correlations, dataQuality, …}`) retiren. Wird zusammen
|
||||
Guard auf „nur wenn keine Row existiert" oder `enabled` nicht mehr
|
||||
anfassen.
|
||||
5. **Worktree-Adoption** — `superpowers:using-git-worktrees` pro
|
||||
parallelen Agent; acht v1.4.15-Commits hatten Diff-Drift gegen
|
||||
ihre Commit-Subjects (A2, A4, B1, B-mobile, B2, B3, B4, C1, C5).
|
||||
Process-Win, kein Code-Change.
|
||||
parallelem Aufgabenstrang; acht v1.4.15-Commits hatten Diff-Drift
|
||||
gegen ihre Commit-Subjects (A2, A4, B1, B-mobile, B2, B3, B4, C1,
|
||||
C5). Process-Win, kein Code-Change.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# v1.4.16+ AI hardening roadmap
|
||||
|
||||
Authored: 2026-05-09 during the v1.4.15 Phase C1 marathon.
|
||||
Authored: 2026-05-09 during the v1.4.15 Stage C1 cycle.
|
||||
|
||||
Marc, verbatim 2026-05-09:
|
||||
Maintainer brief, verbatim 2026-05-09:
|
||||
|
||||
> "Es darf null Halluzinationen haben und es muss sich halt irgendwie
|
||||
> stützen auf medizinische Dinge. Ich möchte da eine gewisse Dynamik
|
||||
@@ -11,12 +11,12 @@ Marc, verbatim 2026-05-09:
|
||||
> ("Zero hallucinations. Must ground on medical facts. I want some
|
||||
> dynamism.")
|
||||
|
||||
v1.4.15 Phase C1 ships **infrastructure** — the schema, the wrapper,
|
||||
v1.4.15 Stage C1 ships **infrastructure** — the schema, the wrapper,
|
||||
the citation enforcement, the scope-hardened prompt, the slug-drift
|
||||
defence. The medical-grounding work, the multi-provider redundancy,
|
||||
the explainability layer and the feedback loop land in v1.4.16+.
|
||||
|
||||
This document is the iteration roadmap Marc explicitly invited.
|
||||
This document is the iteration roadmap the maintainer asked for.
|
||||
|
||||
## What landed in v1.4.15 (recap)
|
||||
|
||||
@@ -82,8 +82,8 @@ p. 17 — "..."` next to the recommendation.
|
||||
`referenceId` not in the bundle. The model cannot fabricate a
|
||||
citation pointing at a guideline that doesn't exist.
|
||||
|
||||
5. **Locale support.** German excerpts shipped first — Marc's primary
|
||||
locale. English fallback on missing.
|
||||
5. **Locale support.** German excerpts shipped first — the live
|
||||
tenant's primary locale. English fallback on missing.
|
||||
|
||||
Test pivot: a fixture user with elevated BP must surface ESH/ESC
|
||||
excerpt #4 via the model's recommendation; a low-data user must NOT
|
||||
@@ -207,5 +207,5 @@ instance never has to walk on its first request.
|
||||
|
||||
---
|
||||
|
||||
Owner: Marc + future-Phase-C agent. Cross-link from
|
||||
Owner: maintainer + future Stage-C work. Cross-link from
|
||||
`.planning/phase-C1-report.md` and the v1.4.15 release notes.
|
||||
@@ -1,9 +1,9 @@
|
||||
# v1.4.16 — Auto-deploy follow-up (image-digest only)
|
||||
|
||||
**Phase:** Wave-C / item 4
|
||||
**Last updated:** 2026-05-09 (v1.4.16 marathon)
|
||||
**Status:** designed, not shipped — DEFERRED to v1.5 (Marc-side manual step
|
||||
required; MCP API does not expose the toggle)
|
||||
**Stage:** Cleanup-C / item 4
|
||||
**Last updated:** 2026-05-09 (v1.4.16 release cycle)
|
||||
**Status:** designed, not shipped — DEFERRED to v1.5 (manual maintainer
|
||||
step required; MCP API does not expose the toggle)
|
||||
|
||||
## Background — what v1.4.15 left half-finished
|
||||
|
||||
@@ -20,8 +20,9 @@ GitHub App auto-deploy fires on EVERY push to `main` — including
|
||||
commits that change zero image bytes. The compose pulls
|
||||
`ghcr.io/mbombeck/healthlog:latest`, finds the same digest, but still
|
||||
recreates the containers (Coolify always restarts the stack on a deploy
|
||||
event). During the v1.4.15 marathon Marc reported visible container
|
||||
churn — multi-second downtime windows on every doc-only push.
|
||||
event). During the v1.4.15 release cycle, user-observed container
|
||||
churn was reported — multi-second downtime windows on every doc-only
|
||||
push.
|
||||
|
||||
We need: deploy fires only when the image digest actually changes.
|
||||
|
||||
@@ -43,8 +44,8 @@ intentionally restricts mutations to the safe subset
|
||||
`environment_*`, `instant_deploy`, build-pack family). It does NOT
|
||||
expose `auto_deploy_enabled` or `watch_paths`. Calling the bare REST
|
||||
API would require a Coolify UI-issued token AND would bypass the
|
||||
guardrails the MCP wraps around the install — too far outside agent
|
||||
scope.
|
||||
guardrails the MCP wraps around the install — too far outside the
|
||||
automated tooling's scope.
|
||||
|
||||
The Coolify community has an open feature request to expose
|
||||
`auto_deploy_enabled` over REST; the v4-stable line (expected July 2026) is the realistic landing window.
|
||||
@@ -68,7 +69,7 @@ is material TCB expansion"). Re-examined here:
|
||||
|
||||
**v1.5 plan** (concrete, two-step):
|
||||
|
||||
### Step 1 — Marc-side manual toggle (5 min, before v1.5 cut)
|
||||
### Step 1 — Maintainer-side manual toggle (5 min, before v1.5 cut)
|
||||
|
||||
Open Coolify UI →
|
||||
`Applications > m-bombeck/-health-log:main-pg8wggwogo8c4gc4ks0kk4ss > Configuration`:
|
||||
@@ -93,12 +94,12 @@ Until then the manual UI step is the contract.
|
||||
|
||||
### Why NOT Watchtower for v1.4.16
|
||||
|
||||
Marc's instruction was explicit: "Don't half-ship". Watchtower would
|
||||
ship code (a new container in the prod compose, new credentials to
|
||||
manage) for a problem the manual Coolify toggle solves with zero new
|
||||
moving parts. The right call is the toggle.
|
||||
The maintainer's instruction was explicit: "Don't half-ship".
|
||||
Watchtower would ship code (a new container in the prod compose, new
|
||||
credentials to manage) for a problem the manual Coolify toggle solves
|
||||
with zero new moving parts. The right call is the toggle.
|
||||
|
||||
## Test plan after Marc flips the toggle
|
||||
## Test plan after the toggle flip
|
||||
|
||||
1. Push a doc-only commit to `main` (e.g. amend `CHANGELOG.md`
|
||||
wording).
|
||||
@@ -116,6 +117,6 @@ moving parts. The right call is the toggle.
|
||||
|
||||
- v1.4.16: NO source change shipped for this item. The audit document
|
||||
is the deliverable.
|
||||
- Marc-side action: flip the Coolify toggle whenever convenient. Does
|
||||
not block v1.4.16 release.
|
||||
- Maintainer-side action: flip the Coolify toggle whenever convenient.
|
||||
Does not block v1.4.16 release.
|
||||
- v1.5 backlog: track the MCP-API automation as a concrete follow-up.
|
||||
@@ -1,19 +1,19 @@
|
||||
# v1.4.16 Phase B6 — Settings naming-audit
|
||||
# v1.4.16 Stage B6 — Settings naming-audit
|
||||
|
||||
Status: audit landed 2026-05-10
|
||||
Author: Marc + agent
|
||||
Author: Maintainer
|
||||
|
||||
> Marc's specific direction (kickoff 2026-05-09 late evening):
|
||||
> Brief direction (kickoff 2026-05-09 late evening):
|
||||
> "Mir wäre einfach auch noch mal wichtig dass du über alle Einstellungen
|
||||
> alle Namings gehst und einmal guckst, dass alles stringent ist, dass
|
||||
> alles sinnig ist, dass alles logisch aufgebaut ist."
|
||||
>
|
||||
> Plus the new memory `feedback_settings_no_split.md` — no top/bottom
|
||||
> Plus the `feedback_settings_no_split.md` rule — no top/bottom
|
||||
> split anti-pattern (B2 will fix the explicit AI-section instance).
|
||||
|
||||
This audit is the single pass over **every** `/settings/<slug>` route + its
|
||||
section component + its i18n keys. It documents what is wrong today and what
|
||||
the v1.4.16 phase-B6 refactor commits do about it. AI section (`/settings/ai`)
|
||||
the v1.4.16 stage-B6 refactor commits do about it. AI section (`/settings/ai`)
|
||||
and Export section (`/settings/export`) are intentionally **out of scope**:
|
||||
B2 owns AI provider UX, B7 just shipped Export.
|
||||
|
||||
@@ -114,7 +114,7 @@ different keys.
|
||||
already rolled out).
|
||||
- Leave the existing flat keys as **deprecation aliases** for now. Add a
|
||||
comment in JSON documenting that they are legacy. Don't churn every
|
||||
call-site in this audit phase — that's a separate hygiene PR.
|
||||
call-site in this audit stage — that's a separate hygiene PR.
|
||||
|
||||
### 2.3 Anti-pattern: section title vs sidebar label vs document `<title>`
|
||||
|
||||
@@ -140,7 +140,7 @@ Insights" via `settings.sections.ai.title` (which happens to equal
|
||||
|
||||
### 2.4 Top/bottom split anti-pattern
|
||||
|
||||
Per Marc's `feedback_settings_no_split.md`, there must be no instance where
|
||||
Per the project's `feedback_settings_no_split.md` rule, there must be no instance where
|
||||
a single concept is selected at the top of a section and configured at the
|
||||
bottom. Audit:
|
||||
|
||||
@@ -151,7 +151,7 @@ bottom. Audit:
|
||||
| Notifications | **Borderline** | `<NotificationStatusCard>` lists per-channel status at the top; the per-channel config cards (`<TelegramCard>`, `<NtfyCard>`, `<WebPushCard>`) follow below. The status card has `Re-enable` + `Send test` actions per channel that arguably duplicate functionality in the config cards. **Not a top/bottom-split-of-one-concept** — the status card is a read-only summary, the config cards are mutators. Keeping it. |
|
||||
| Dashboard | No | One layout card. |
|
||||
| Thresholds | No | One editor card with per-metric rows. |
|
||||
| AI | **YES (out of scope, B2)** | Provider dropdown at the top selects between OpenAI/Anthropic/Local; key/credential inputs for each provider live further down. This is the case Marc named explicitly. |
|
||||
| AI | **YES (out of scope, B2)** | Provider dropdown at the top selects between OpenAI/Anthropic/Local; key/credential inputs for each provider live further down. This is the case the maintainer flagged explicitly. |
|
||||
| API | No | Endpoints reference card + tokens card. |
|
||||
| Export | No | 5 cards, each self-contained. |
|
||||
| Advanced | No | Single danger-zone card (post-B7 cleanup). |
|
||||
@@ -229,8 +229,8 @@ Spot-checked:
|
||||
|
||||
## 3. Logical grouping review
|
||||
|
||||
Marc asked: "are settings grouped sensibly?". Current order in the
|
||||
sidebar:
|
||||
User feedback noted: "are settings grouped sensibly?". Current order
|
||||
in the sidebar:
|
||||
|
||||
1. Account — personal identity + sign-in
|
||||
2. Integrations — third-party data sources
|
||||
@@ -280,7 +280,7 @@ Commit 2 — `refactor(settings): consistent naming + i18n key namespace`
|
||||
|
||||
Commit 3 — `refactor(settings): remove duplicate toggles, route to canonical owner`
|
||||
|
||||
- Document the settings-vs-admin scope rule in `CLAUDE.md`.
|
||||
- Document the settings-vs-admin scope rule in the repo's project doc.
|
||||
- No actual duplicate found that needs removing today; commit body
|
||||
documents the audit conclusion ("no duplicate user-facing toggles
|
||||
identified; settings keep per-user toggles, admin keeps system-wide
|
||||
|
||||
+20
-20
@@ -1,6 +1,6 @@
|
||||
# HealthLog v1.4.16 — Release Summary
|
||||
|
||||
## Marc-Brief
|
||||
## Release brief
|
||||
|
||||
✅ Live: v1.4.16 on `https://healthlog.bombeck.io` — image digest
|
||||
`sha256:05f8a126d639…` (was v1.4.15: `ace7d441f47b…`), `/api/version`
|
||||
@@ -56,7 +56,7 @@ How It Works, Comparison Views, Provider Configuration.
|
||||
|
||||
## What landed (per area, with commit SHAs)
|
||||
|
||||
### Wave A — Quick fixes
|
||||
### Cleanup A — Quick fixes
|
||||
|
||||
| Bucket | Commit | Subject |
|
||||
| ------ | ------------------ | ------------------------------------------------------------------------------------------ |
|
||||
@@ -70,7 +70,7 @@ How It Works, Comparison Views, Provider Configuration.
|
||||
| A8a | `2da0703` | fix(geo): preserve umlauts in city names (login-overview no longer renders "Nrnberg") |
|
||||
| A8b | `af77e5e` | feat(charts): split-half mean delta on long-window trend |
|
||||
|
||||
### Wave B — Quality-leap features
|
||||
### Cleanup B — Quality-leap features
|
||||
|
||||
| Bucket | Headline commits | What it does |
|
||||
| ------ | ------------------------------------------------------------------------------------------- | ---------------------------------------------------- |
|
||||
@@ -88,7 +88,7 @@ How It Works, Comparison Views, Provider Configuration.
|
||||
| B7 | `621109c`, `a512650`, `94c748d`, (routes inside `226cac4`), `d5c8912`, `830b2b0`, `e628f33` | Settings → Export consolidation |
|
||||
| B8 | `775df8c`, `2cf7b74`, `e4a408e`, `f9f99ea` | Comparison overlay on charts + tiles + AI narration |
|
||||
|
||||
### Wave C — Catch-up (deferred from v1.4.15)
|
||||
### Cleanup C — Catch-up (deferred from v1.4.15)
|
||||
|
||||
| Item | Commit | Notes |
|
||||
| -------------------------------------- | --------- | -------------------------------------------------------------- |
|
||||
@@ -104,11 +104,11 @@ How It Works, Comparison Views, Provider Configuration.
|
||||
| Auto-deploy v1.5 doc | `4be6465` | Coolify auto-deploy stays on git-push for v1.4.16; deferred |
|
||||
| docker-publish drop qemu-arm64 | `cc0f343` | qemu-SIGILL root cause; native-runner matrix in v1.5 |
|
||||
|
||||
5 of 8 deferred HIGH from v1.4.15 Wave-D landed; 3 of 5 deferred MED
|
||||
5 of 8 deferred HIGH from v1.4.15 Cleanup-D landed; 3 of 5 deferred MED
|
||||
from A5 mobile landed; Coolify image-digest auto-deploy deferred per
|
||||
Marc's "leave it" call.
|
||||
the maintainer's "leave it" call.
|
||||
|
||||
### Wave D — Multi-agent QA + Reconcile
|
||||
### Cleanup D — Multi-pass QA + Reconcile
|
||||
|
||||
- **CRITICAL** (3 of 3 cleared): C1 wired (`aae968a` —
|
||||
`<InsightAdvisorCard>` mounts on `/insights`), C2 wired
|
||||
@@ -117,12 +117,12 @@ Marc's "leave it" call.
|
||||
- **HIGH** (9 fixed inline): `5f7b9d8`, `6863ecb`, `fb12f09`,
|
||||
`c3451a4`, `2f057f4`, `5661439`. 11 HIGH deferred to v1.5 backlog.
|
||||
- **Simplify** (7 of 8 apply-yes landed): `f3025a8`. F1 + F8 are
|
||||
apply-no flagged for Marc.
|
||||
apply-no, flagged for the maintainer.
|
||||
- **Product-Lead review** stands as-is and IS the strategic v1.5 plan
|
||||
(`.planning/phase-D-product-lead-review.md`).
|
||||
- Style cleanup: `c63cddc`.
|
||||
|
||||
### Wave E — Release
|
||||
### Cleanup E — Release
|
||||
|
||||
| Item | Result |
|
||||
| --------------------------------- | ------------------------------------------------------------------------------------ |
|
||||
@@ -134,7 +134,7 @@ Marc's "leave it" call.
|
||||
| Coolify auto-deploy | NO — same race as v1.4.14/v1.4.15; retag-on-host fallback used |
|
||||
| Live image digest | `sha256:05f8a126d63962d9a4af4769de830d3fee022d634787e811b4339ee464420daa` |
|
||||
| `/api/version` transition | `1.4.15` → `1.4.16` at `2026-05-10T03:45:58+02:00` |
|
||||
| Smoke (14 routes, Marc's session) | 13/14 200; `/dashboard` 404 expected (root is dashboard) |
|
||||
| Smoke (14 routes, live session) | 13/14 200; `/dashboard` 404 expected (root is dashboard) |
|
||||
| GH release | https://github.com/MBombeck/HealthLog/releases/tag/v1.4.16 |
|
||||
| Docs site | `8addef4` + `2a5802b` on `healthlog-docs/main` (44 pages, three new deep-dive pages) |
|
||||
| Landing site | `3d17207` on `healthlog-landing/main` (1.4.15 → 1.4.16, AI cards updated) |
|
||||
@@ -155,15 +155,15 @@ Full backlog: `.planning/v15-backlog.md`. Highlights:
|
||||
split), code-review H5 + H6 cumulative duplication. Sized in the
|
||||
product-lead review.
|
||||
- **2 simplify-no items**: F1 `runWithFallback` test-only (delete and
|
||||
migrate or wire to strict variant — Marc's call), F8
|
||||
migrate or wire to strict variant — maintainer's call), F8
|
||||
`RecommendationCard.normalise()` indirection (mechanical rewrite
|
||||
spans 8+ JSX sites).
|
||||
- **Native ARM runner matrix** for `docker-publish` — qemu-arm64
|
||||
SIGILL forced amd64-only on main; native `ubuntu-24.04-arm` matrix
|
||||
is the v1.5 plan.
|
||||
- **Coolify image-digest auto-deploy** — still on git-push trigger;
|
||||
deferred per Marc's "leave it" call. Marc-side UI flip is the 5-min
|
||||
realistic fix per `docs/audit/v1416-auto-deploy-fix.md`.
|
||||
deferred per the maintainer's "leave it" call. The manual Coolify UI
|
||||
toggle is the 5-min realistic fix per `docs/audit/v1416-auto-deploy-fix.md`.
|
||||
- **Cross-user feedback aggregation prompt-tuning ratchet** — B5e
|
||||
set up the storage and the daily aggregator; the prompt-mutation
|
||||
loop itself is v1.4.17 / v1.5 work.
|
||||
@@ -183,8 +183,8 @@ Full backlog: `.planning/v15-backlog.md`. Highlights:
|
||||
|
||||
- `pnpm typecheck` — 0 errors.
|
||||
- `pnpm lint` — 0 errors / 12 pre-existing warnings.
|
||||
- `pnpm test` — **1539 unit tests** green (started v1.4.16 marathon
|
||||
at ~1048; +491 net across A/B/C/D/E waves).
|
||||
- `pnpm test` — **1539 unit tests** green (started v1.4.16 release
|
||||
cycle at ~1048; +491 net across A/B/C/D/E cleanups).
|
||||
- `pnpm test:integration` — **59 / 59** green (was 31 at v1.4.15).
|
||||
- `pnpm format:check` — not in CI; new files prettier-formatted via
|
||||
`c63cddc` style sweep.
|
||||
@@ -200,14 +200,14 @@ Full backlog: `.planning/v15-backlog.md`. Highlights:
|
||||
- **Image digest**:
|
||||
`sha256:05f8a126d63962d9a4af4769de830d3fee022d634787e811b4339ee464420daa`
|
||||
(was v1.4.15: `sha256:ace7d441f47bd8c69fd0c5e2417b7f6c53bc387aa10c9aa541ad5e6321e9581d`)
|
||||
- **Smoke** (14 routes, Marc's session): 200 across `/`, `/insights`,
|
||||
- **Smoke** (14 routes, live session): 200 across `/`, `/insights`,
|
||||
`/auth/login`, `/settings/integrations`, `/settings/notifications`,
|
||||
`/settings/ai`, `/settings/export`, `/admin`, `/admin/users`,
|
||||
`/admin/backups`, `/admin/system-status`, `/admin/app-logs`,
|
||||
`/achievements`. `/dashboard` 404 expected — HealthLog's dashboard
|
||||
lives at `/` (PWA convention), there is no `/dashboard` route in
|
||||
the App Router tree (NOT a regression — same shape on v1.4.15).
|
||||
- **Deploy method**: GHCR-tag-build `:1.4.16` succeeded (Wave-C C3
|
||||
- **Deploy method**: GHCR-tag-build `:1.4.16` succeeded (Cleanup-C C3
|
||||
fix dropped arm64 on main and made BOTH GHCR runs green for the
|
||||
first time since v1.4.13). Coolify auto-deploy fired on the
|
||||
`chore(release)` commit before GHCR finished and pulled the host's
|
||||
@@ -215,7 +215,7 @@ Full backlog: `.planning/v15-backlog.md`. Highlights:
|
||||
:1.4.16 && docker tag :1.4.16 :latest && docker compose up -d app`)
|
||||
flipped `/api/version` 1 s after the up command returned.
|
||||
- **Coolify auto-deploy**: still fires on every git-push (deferred
|
||||
per Marc's call); v1.5 plan in `docs/audit/v1416-auto-deploy-fix.md`.
|
||||
per the maintainer's call); v1.5 plan in `docs/audit/v1416-auto-deploy-fix.md`.
|
||||
- **GitHub release**: https://github.com/MBombeck/HealthLog/releases/tag/v1.4.16
|
||||
- **Tag naming** (unchanged since v1.4.14): GHCR-OCI tag is `:1.4.16`
|
||||
(no `v` prefix); git tag is `v1.4.16`.
|
||||
@@ -249,7 +249,7 @@ contains the full v1.5 roadmap and is the strategic plan for v1.5.
|
||||
Top items to look at:
|
||||
|
||||
1. **Coolify image-digest trigger** (C.1) — replaces git-push churn.
|
||||
5-min Marc-side UI toggle.
|
||||
5-min manual Coolify UI toggle.
|
||||
2. **Native ARM runner matrix** (C.2) — re-add `linux/arm64` to
|
||||
GHCR matrix via native `ubuntu-24.04-arm` runner.
|
||||
3. **Cross-user feedback ratchet → prompt-tuning** (C.3) — append
|
||||
@@ -269,7 +269,7 @@ Top items to look at:
|
||||
performance, §C.10 S3 backup push, §C.11 Garmin / Oura
|
||||
integrations.)
|
||||
|
||||
Marc's recommended 6-week focus pick from the review: **C.1 + C.2 +
|
||||
Recommended 6-week focus pick from the review: **C.1 + C.2 +
|
||||
C.4 + C.7 + C.10 + C.11a Apple Health**.
|
||||
|
||||
---
|
||||
|
||||
+14
-13
@@ -1,6 +1,6 @@
|
||||
# HealthLog v1.4.18 — Release Summary
|
||||
|
||||
## Marc-Brief
|
||||
## Release brief
|
||||
|
||||
Live: v1.4.18 on `https://healthlog.bombeck.io` — image digest
|
||||
`sha256:c636fca7db66…` (was v1.4.17: `936e9cf25b2d…`), `/api/version`
|
||||
@@ -52,7 +52,7 @@ v1.4.19 backlog: see `.planning/v1419-backlog.md`.
|
||||
|
||||
## What landed (per area, with commit SHA references)
|
||||
|
||||
### Wave A — Quick fixes
|
||||
### Cleanup A — Quick fixes
|
||||
|
||||
| Bucket | Headline commit | Subject |
|
||||
| ------ | --------------- | ------- |
|
||||
@@ -68,7 +68,7 @@ gated behind Trend toggle on health-chart and mood-chart, new
|
||||
`User.dashboardWidgetsJson.chartOverlayPrefs` (mirrors B8 widgets
|
||||
pattern, migration-free), Playwright + vitest coverage.
|
||||
|
||||
### Wave B — Achievements expansion
|
||||
### Cleanup B — Achievements expansion
|
||||
|
||||
- **B1** (commits `75c74f1...e75ea75`): roster 38 → 59 (+15 public,
|
||||
+6 hidden). Six categories — streaks, milestones, consistency,
|
||||
@@ -79,7 +79,7 @@ pattern, migration-free), Playwright + vitest coverage.
|
||||
unlock; toast on unlock uses an 8-second Sparkles celebration with
|
||||
a localized "you unlocked a hidden achievement!" headline.
|
||||
|
||||
### Wave D — Multi-agent QA + Reconcile
|
||||
### Cleanup D — Multi-pass QA + Reconcile
|
||||
|
||||
- **CRITICAL** (1 of 1 cleared): C1 hidden-achievement wire-leak
|
||||
redaction in API response (`545f44c`). The locked-and-hidden API
|
||||
@@ -103,7 +103,7 @@ TypeError on cached pre-strict insight payloads. Three commits on
|
||||
`.planning/phase-v1417-hotfix-report.md` and the v1.4.17 entry in
|
||||
`.planning/STATE.md`.
|
||||
|
||||
### Wave E — Release
|
||||
### Cleanup E — Release
|
||||
|
||||
| Item | Result |
|
||||
| --------------------------------- | ---------------------------------------------------------------------------- |
|
||||
@@ -115,7 +115,7 @@ TypeError on cached pre-strict insight payloads. Three commits on
|
||||
| Coolify auto-deploy | NO — same git-push race; documented force-pull path used |
|
||||
| Live image digest | `sha256:c636fca7db66479b3413a7df82117316c042641f9bc7c0fe7d6e2be6811dfcca` |
|
||||
| `/api/version` transition | `1.4.17` → `1.4.18` within first 5-second poll cycle |
|
||||
| Smoke (15 routes, Marc's session) | 14/14 real routes 200; `/dashboard` 404 expected (root is dashboard) |
|
||||
| Smoke (15 routes, live session) | 14/14 real routes 200; `/dashboard` 404 expected (root is dashboard) |
|
||||
| GH release | https://github.com/MBombeck/HealthLog/releases/tag/v1.4.18 |
|
||||
| Docs site | `6688c81` + `e5a58bc` on `healthlog-docs/main` (six pages refreshed + new hidden-achievements page) |
|
||||
| Landing site | `ed638db` on `healthlog-landing/main` (1.4.16 → 1.4.18, clean-line phrasing) |
|
||||
@@ -158,7 +158,7 @@ Full backlog: `.planning/v1419-backlog.md`. Highlights:
|
||||
- `pnpm typecheck` — 0 errors.
|
||||
- `pnpm lint` — 0 errors / 12 pre-existing baseline warnings.
|
||||
- `pnpm test` — **1605 unit tests** green (was 1539 at v1.4.16,
|
||||
1547 at v1.4.17; +66 net across A/B/D waves).
|
||||
1547 at v1.4.17; +66 net across A/B/D cleanups).
|
||||
- `pnpm test:integration` — **66 / 66** green (was 59 at v1.4.16).
|
||||
- `pnpm format:check` — clean (sweep at `3048dd6`).
|
||||
- `pnpm build` + `pnpm e2e` — deferred to CI Docker (Node 22) per
|
||||
@@ -173,7 +173,7 @@ Full backlog: `.planning/v1419-backlog.md`. Highlights:
|
||||
- **Image digest**:
|
||||
`sha256:c636fca7db66479b3413a7df82117316c042641f9bc7c0fe7d6e2be6811dfcca`
|
||||
(was v1.4.17: `sha256:936e9cf25b2d8e75d70a7912a42c8b0647e374ece036eb451676d0be9cd120ce`)
|
||||
- **Smoke** (15 routes, Marc's session): 200 across `/`, `/insights`,
|
||||
- **Smoke** (15 routes, live session): 200 across `/`, `/insights`,
|
||||
`/auth/login`, `/settings/integrations`, `/settings/notifications`,
|
||||
`/settings/ai`, `/settings/export`, `/admin`, `/admin/users`,
|
||||
`/admin/api-tokens`, `/admin/backups`, `/admin/system-status`,
|
||||
@@ -182,7 +182,7 @@ Full backlog: `.planning/v1419-backlog.md`. Highlights:
|
||||
the App Router tree. Same shape on v1.4.16 / v1.4.17; not a
|
||||
regression.
|
||||
- **Deploy method**: GHCR-tag-build `:1.4.18` succeeded (both tag and
|
||||
main runs green for the second consecutive release post Wave-C
|
||||
main runs green for the second consecutive release post Cleanup-C
|
||||
v1.4.16 qemu-arm64 fix). Coolify auto-deploy fired on the
|
||||
`chore(release)` commit before GHCR finished; force-pull path used
|
||||
on `apps-01`:
|
||||
@@ -198,8 +198,9 @@ Full backlog: `.planning/v1419-backlog.md`. Highlights:
|
||||
cycle of the wait loop.
|
||||
|
||||
- **Coolify auto-deploy**: still on git-push trigger; deferred again
|
||||
per Marc's "leave it" call. Marc-side UI flip remains the 5-min
|
||||
realistic fix per `docs/audit/v1416-auto-deploy-fix.md`.
|
||||
per the maintainer's "leave it" call. The manual Coolify UI toggle
|
||||
remains the 5-min realistic fix per
|
||||
`docs/audit/v1416-auto-deploy-fix.md`.
|
||||
- **GitHub release**: https://github.com/MBombeck/HealthLog/releases/tag/v1.4.18
|
||||
- **Tag naming** (unchanged since v1.4.14): GHCR-OCI tag is `:1.4.18`
|
||||
(no `v` prefix); git tag is `v1.4.18`.
|
||||
@@ -243,7 +244,7 @@ The Product-Lead review at
|
||||
v1.5 roadmap. Key items:
|
||||
|
||||
1. **Coolify image-digest auto-deploy** (C.1) — still on git-push
|
||||
trigger, 5-min Marc-side UI toggle.
|
||||
trigger, 5-min manual Coolify UI toggle.
|
||||
2. **Native ARM runner matrix** (C.2) — re-add `linux/arm64` via
|
||||
`ubuntu-24.04-arm` runner.
|
||||
3. **Cross-user feedback aggregation prompt-tuning** (C.3) — append
|
||||
@@ -268,7 +269,7 @@ v1.5 roadmap. Key items:
|
||||
(C.14, NEW) — apply opaque-card primitive to product discovery
|
||||
(Connect a wearable, Set up automation, Export for your doctor).
|
||||
|
||||
Marc's recommended 6-week focus pick from v1.4.16 still stands
|
||||
The recommended 6-week focus pick from v1.4.16 still stands
|
||||
(C.1 + C.2 + C.4 + C.7 + C.10 + C.11a Apple Health), with C.12
|
||||
added as a parallelisable side-quest.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# HealthLog v1.4.19 — Release Summary
|
||||
|
||||
## Marc-Brief
|
||||
## Release brief
|
||||
|
||||
Live: v1.4.19 (image digest `sha256:b48f93874cdb…`, `/api/version=1.4.19`)
|
||||
|
||||
@@ -34,9 +34,9 @@ v1.5 reserved for iOS app + Apple Health.
|
||||
|
||||
---
|
||||
|
||||
## What landed (commit highlights per Wave)
|
||||
## What landed (commit highlights per cleanup)
|
||||
|
||||
### Wave A — bugs + polish
|
||||
### Cleanup A — bugs + polish
|
||||
|
||||
| Bucket | Headline commit | Subject |
|
||||
| ------ | --------------- | ------- |
|
||||
@@ -48,7 +48,7 @@ v1.5 reserved for iOS app + Apple Health.
|
||||
| A6 | `957f8e9` / `9fda634` / `1075784` / `737b533` / `78f1f3f` | fix(settings): mobile consistency sweep — input heights, action button placement, language select row |
|
||||
| A7 | `088832a` / `dd8212e` / `7a70db6` / `6507646` / `90a109d` | fix(admin): feedback tab strip, api-tokens scrollbar 4th attempt, Einklappen removal, Zielwerte spacing + DE labels |
|
||||
|
||||
### Wave B — A8 quality findings applied
|
||||
### Cleanup B — A8 quality findings applied
|
||||
|
||||
16 atomic commits — 6/6 CRITICAL + 21/25 HIGH — covering time-window
|
||||
locale, login-overview auth filter, achievement title humanisation,
|
||||
@@ -56,9 +56,9 @@ date-input `lang`, sidebar copy, raw enum badges, audit-action labels,
|
||||
mobile Sys/Dia badge enum, telegram badge collapse, token name ISO
|
||||
suffix, recent-activity row links.
|
||||
|
||||
### Wave D — multi-agent QA + reconcile
|
||||
### Cleanup D — multi-pass QA + reconcile
|
||||
|
||||
Six atomic commits cleared the post-Wave-B CRITICAL (mobile Sys/Dia
|
||||
Six atomic commits cleared the post-Cleanup-B CRITICAL (mobile Sys/Dia
|
||||
badge enum mismatch, `ef74241`), 5 simplify-yes consolidations
|
||||
(`6b35cad`), and four HIGH fixes (`1258b24`, `5a8ad3d`, `977f124`,
|
||||
`1f0d9ad`).
|
||||
@@ -89,7 +89,7 @@ Full backlog: `.planning/v1420-backlog.md`.
|
||||
- `pnpm typecheck` — 0 errors.
|
||||
- `pnpm lint` — 0 errors / 12 pre-existing baseline warnings (no new).
|
||||
- `pnpm test` — **1672 / 1672** unit tests green (was 1605 at v1.4.18;
|
||||
+67 net across A1, A2, A3, A4, A5, A6, A7, B, and Phase D reconcile
|
||||
+67 net across A1, A2, A3, A4, A5, A6, A7, B, and Cleanup D reconcile
|
||||
TDD additions).
|
||||
- `pnpm test:integration` — **67 / 67** green (was 66 at v1.4.18; +1
|
||||
for A1's BD-Zielbereich `allTime` window guard).
|
||||
@@ -113,7 +113,7 @@ Full backlog: `.planning/v1420-backlog.md`.
|
||||
| Tag | `v1.4.19` (annotated) |
|
||||
| GHCR — tag run | `25628853202` success |
|
||||
| Coolify auto-deploy | NO — main-branch deploy hung and was canceled; host-side retag-on-host fallback used |
|
||||
| Smoke (curl, Marc's session) | `/` 200 · `/insights` 200 · `/admin/api-tokens` 200 · `/settings/integrations` 200 · `/achievements` 200 · `/dashboard` 404 (expected — root is dashboard, no `/dashboard` route in App Router) |
|
||||
| Smoke (curl, live session) | `/` 200 · `/insights` 200 · `/admin/api-tokens` 200 · `/settings/integrations` 200 · `/achievements` 200 · `/dashboard` 404 (expected — root is dashboard, no `/dashboard` route in App Router) |
|
||||
| GH release | https://github.com/MBombeck/HealthLog/releases/tag/v1.4.19 |
|
||||
| Docs site | `6e8840e` on `healthlog-docs/main` (six pages refreshed) |
|
||||
| Landing site | `dd5892f` on `healthlog-landing/main` (`softwareVersion` JSON-LD bumped) |
|
||||
|
||||
+59
-66
@@ -1,11 +1,11 @@
|
||||
# HealthLog v1.4.6 — Findings & Spec
|
||||
|
||||
Status: 2026-05-09 — handoff from the v1.4.5 deploy session. All findings
|
||||
were produced by **four parallel audit agents** (dashboard visual, KI section,
|
||||
admin panel, KI insights data window) against the v1.4.5 codebase
|
||||
were produced by **four parallel audit passes** (dashboard visual, AI section,
|
||||
admin panel, AI insights data window) against the v1.4.5 codebase
|
||||
(`e8f4820`). A Playwright probe also visually verified the dashboard tile
|
||||
strip at five viewports. **Verify each finding by reading the cited
|
||||
file:line BEFORE editing — agents occasionally reference stale state.**
|
||||
file:line BEFORE editing — automated audits occasionally reference stale state.**
|
||||
|
||||
The single working-tree change carried over from the v1.4.5 session:
|
||||
`src/components/charts/trend-card.tsx:85` — added `w-full` so the tile
|
||||
@@ -24,14 +24,12 @@ flex-child of a `<div className="flex">` wrapper, it took content width
|
||||
instead of stretching to the grid cell. Visible on mobile-narrow (375px):
|
||||
tile widths varied 122-166px in the same row. With `w-full` added, the
|
||||
Playwright harness confirms the tiles fill their grid cells uniformly at
|
||||
all viewports. Marc's primary complaint was "die Kacheln füllen den Platz
|
||||
all viewports. The user-reported complaint was "die Kacheln füllen den Platz
|
||||
nicht aus" — this is exactly that.
|
||||
|
||||
**Verify after change:** Run the deep diagnose probe at multiple
|
||||
viewports (`/tmp/v145-tile-deep-diagnose.js` from prior session if still
|
||||
on disk; otherwise re-create — set `HL_SID` to a valid session and run
|
||||
via `node /Users/marc/.claude/skills/playwright-skill/run.js
|
||||
$probe`).
|
||||
viewports (recreate from prior session if needed — set `HL_SID` to a
|
||||
valid session and run via the Playwright skill harness).
|
||||
|
||||
### T2 — `--muted-foreground` equals `--foreground` (no hierarchy)
|
||||
|
||||
@@ -132,7 +130,7 @@ The `bugReportEnabled === false` check lives on the legacy
|
||||
reports off" in admin **does not actually hide or block** the form —
|
||||
users still submit successfully into the local feedback inbox.
|
||||
|
||||
The CLAUDE.md / commit message claim ("the report button gracefully
|
||||
The repo-doc / commit message claim ("the report button gracefully
|
||||
disappears") is false.
|
||||
|
||||
**Fix:** Pick one approach:
|
||||
@@ -186,8 +184,9 @@ Affected files (one constant + one bucket-builder per file):
|
||||
|
||||
**Goal:** the LLM should see ~3 years of history with newer data at
|
||||
higher resolution. Not raw rows — daily means for the recent window,
|
||||
monthly means for the older window. Marc explicitly asked for
|
||||
"mindestens 360 Tage" daily, plus "Monatswerte" for "2 oder 3 Jahre".
|
||||
monthly means for the older window. The product target is at least
|
||||
360 days of daily-resolution data, plus monthly aggregates extending
|
||||
out to two or three years.
|
||||
|
||||
**Concrete shape of the prompt payload (per metric):**
|
||||
|
||||
@@ -216,14 +215,10 @@ no raw measurement rows leak into the prompt (the audit window is
|
||||
|
||||
## NEW FEATURE — Chart bucketing for ranges > 1 year
|
||||
|
||||
Marc's request:
|
||||
|
||||
> "Überlege dir bei den Charts ob wir Sachen halt nicht ab einer
|
||||
> gewissen Sache dann stacken in den Monaten. Wenn wir jetzt bei
|
||||
> All drücken zum Beispiel, dass man dann halt ab einer Zeit von
|
||||
> über einem Jahr dann halt danach tagesmonats- oder monats- oder
|
||||
> wochendurchschnitte summiert und nicht dann 30.000 Punkte
|
||||
> anzeigt"
|
||||
User-requested behaviour: when the chart range exceeds one year (e.g.
|
||||
the "All" filter), don't render every individual point. Instead
|
||||
aggregate to weekly or monthly averages so a 2-3 year range stays
|
||||
readable rather than rendering 30 000 points.
|
||||
|
||||
**Spec:**
|
||||
|
||||
@@ -251,11 +246,10 @@ with `n=0` rather than count them as `0`.
|
||||
varying length. Visual regression: render the chart at a 2-year range
|
||||
and verify the chart shows ~24 monthly points, not 730 daily.
|
||||
|
||||
**Research:** the autonomous executor MUST research best practice
|
||||
for time-series bucket aggregation in healthcare/Recharts dashboards
|
||||
before implementing. Use Context7 or websearch for "recharts
|
||||
aggregation buckets" and similar — there's a standard pattern for
|
||||
this. Don't reinvent.
|
||||
**Research:** before implementing, look up best practice for
|
||||
time-series bucket aggregation in healthcare/Recharts dashboards
|
||||
("recharts aggregation buckets" and similar) — there's a standard
|
||||
pattern for this. Don't reinvent.
|
||||
|
||||
---
|
||||
|
||||
@@ -290,7 +284,7 @@ this. Don't reinvent.
|
||||
|
||||
- **One-row scroll vs. wrap** — the dashboard audit recommended
|
||||
rolling back v1.4.5's wrap behaviour to v1.4.4's horizontal-scroll-
|
||||
always. Marc already chose wrap deliberately in v1.4.5
|
||||
always. The wrap behaviour was a deliberate v1.4.5 choice
|
||||
(CHANGELOG entry, commit `e8f4820`). **Do not roll back.**
|
||||
- **`/admin/users`, `/admin/audit-log` sub-routes** — feature, not
|
||||
bug. Anchor-link fix in T6 is enough for v1.4.6.
|
||||
@@ -303,20 +297,20 @@ this. Don't reinvent.
|
||||
|
||||
## Verification gates (before tagging v1.4.6)
|
||||
|
||||
After all fixes, the autonomous executor MUST:
|
||||
After all fixes:
|
||||
|
||||
1. **Test suite green:** `pnpm test`, `pnpm typecheck`, `pnpm lint`,
|
||||
`pnpm format:check`. Stop if any fails — never `--no-verify`.
|
||||
2. **Integration tests green** (testcontainers): `pnpm test:integration`
|
||||
3. **Build succeeds:** `pnpm build` (no Turbopack-specific failures)
|
||||
4. **Multi-agent QA review** — dispatch in parallel and reconcile
|
||||
findings into a follow-up commit if any HIGH/CRITICAL surfaces:
|
||||
- **superpowers:code-reviewer** — review the v1.4.6 diff vs. main
|
||||
- **Plan agent** as senior-design-reviewer — visual review of
|
||||
dashboard, settings, admin at desktop + mobile viewports
|
||||
- **Plan agent** as senior-security-reviewer — review T4, T5, T7,
|
||||
T8, P11, P12 specifically for residual risk
|
||||
- **simplify skill** — run on the v1.4.6 changed files to look for
|
||||
4. **Multi-pass QA review** — run in parallel and reconcile findings
|
||||
into a follow-up commit if any HIGH/CRITICAL surfaces:
|
||||
- **Code review pass** — review the v1.4.6 diff vs. main
|
||||
- **Senior-design review pass** — visual review of dashboard,
|
||||
settings, admin at desktop + mobile viewports
|
||||
- **Senior-security review pass** — review T4, T5, T7, T8, P11,
|
||||
P12 specifically for residual risk
|
||||
- **Simplify pass** — run on the v1.4.6 changed files to look for
|
||||
accidental complexity
|
||||
5. **Mobile QA** via Playwright — at least three viewports
|
||||
(375×667, 390×844, 412×915). Probe must verify:
|
||||
@@ -326,8 +320,8 @@ After all fixes, the autonomous executor MUST:
|
||||
- Touch targets ≥ 44×44 px
|
||||
- Charts render and are readable
|
||||
6. **Hallucination check** — for every finding fixed, `git diff` must
|
||||
show a real change at the cited file:line. Audit-agent claims must
|
||||
be verified; if a finding's file:line doesn't match what's
|
||||
show a real change at the cited file:line. Automated review claims
|
||||
must be verified; if a finding's file:line doesn't match what's
|
||||
actually there, log it in the SUMMARY and skip rather than guess.
|
||||
7. **Visual regression** — Playwright screenshots of dashboard at
|
||||
1280×900 and 390×844, before+after, saved to
|
||||
@@ -340,44 +334,43 @@ After all fixes, the autonomous executor MUST:
|
||||
1. Bump `package.json` to `1.4.6`
|
||||
2. Update `CHANGELOG.md` with a `[1.4.6] — 2026-05-09` (or `2026-05-10`
|
||||
depending on completion time) block. Tone: user-facing German +
|
||||
English, **no Claude mention, no "Audit-Agent"**, no internal
|
||||
phase names. Group by section: "Fixed — Dashboard",
|
||||
English, no internal review-process language, no internal
|
||||
stage names. Group by section: "Fixed — Dashboard",
|
||||
"Fixed — KI", "Fixed — Admin", "Improved — KI Insights",
|
||||
"Improved — Polish".
|
||||
3. Atomic commits per phase, each Co-Authored-By Claude Opus 4.7.
|
||||
3. Atomic commits per stage.
|
||||
4. Tag `v1.4.6`, push tag.
|
||||
5. Wait for GHCR build (typically 10-13 min).
|
||||
6. Coolify deploy: `mcp__coolify-apps01__deploy` with
|
||||
6. Coolify deploy: trigger via the configured deploy hook with
|
||||
`tag_or_uuid: pg8wggwogo8c4gc4ks0kk4ss`, `force: true`.
|
||||
7. Verify production:
|
||||
- Poll `/api/version` until 1.4.6
|
||||
- `docker inspect` running container — image digest must
|
||||
differ from current.
|
||||
- Marc's session: `cmox4d6fj000101p8w9ykhcnm` (still valid as of
|
||||
2026-05-09; if expired, re-pull from prod DB —
|
||||
`SELECT id FROM sessions WHERE user_id='cmlupy4tn000001rpzx1pxvz7'
|
||||
AND expires_at > now() ORDER BY created_at DESC LIMIT 1;`)
|
||||
- Authenticated session: pull a current session id from prod DB
|
||||
when needed (`SELECT id FROM sessions WHERE user_id='…'
|
||||
AND expires_at > now() ORDER BY created_at DESC LIMIT 1;`).
|
||||
- Hit `/api/ai/test` with fake key → still returns 422
|
||||
- Hit `/api/insights/generate` with `forceRefresh=false` and a
|
||||
fresh user → does not consume rate-limit token (P13 verify).
|
||||
8. Mobile QA Playwright probe against production.
|
||||
9. Brief Marc — German, ≤ 200 words. Hard-reload reminder.
|
||||
9. Release brief — German, ≤ 200 words. Hard-reload reminder.
|
||||
Group by what changed perceptually ("Tile-Strip füllt jetzt aus",
|
||||
"KI bekommt jetzt 3 Jahre Historie", "Charts aggregieren bei
|
||||
Langzeit-Range", "Admin-Buttons springen jetzt zum richtigen
|
||||
Anker", "Bug-Report-Toggle wirkt jetzt"). No "Claude", no
|
||||
internal phase names.
|
||||
Anker", "Bug-Report-Toggle wirkt jetzt"). No internal
|
||||
stage names.
|
||||
|
||||
---
|
||||
|
||||
## Repo housekeeping (also in scope for the v1.4.6 marathon)
|
||||
## Repo housekeeping (also in scope for the v1.4.6 release)
|
||||
|
||||
### CI
|
||||
|
||||
- `e2e` workflow has been **failing on every commit** since at least
|
||||
`cbded7c3`. Investigate (`gh run view <id> --log-failed`), root-
|
||||
cause, fix the spec or the underlying app bug. Don't `.skip()` it
|
||||
— Marc explicitly asked for green CI.
|
||||
— green CI is a hard requirement.
|
||||
|
||||
### GitHub Releases
|
||||
|
||||
@@ -393,7 +386,7 @@ the v1.4.0/v1.4.1 deploy thrash. Don't delete `v1.x.x` tagged
|
||||
versions (some users may pin). Only delete explicitly _untagged_
|
||||
manifests if any exist.
|
||||
|
||||
### Docs site (`/Users/marc/Projects/healthlog-docs`)
|
||||
### Docs site (`docs.healthlog.dev` repo)
|
||||
|
||||
Astro site at `https://docs.healthlog.dev`. Latest content covers
|
||||
**up to v1.2**. Bring it up to v1.4.6:
|
||||
@@ -404,10 +397,10 @@ Astro site at `https://docs.healthlog.dev`. Latest content covers
|
||||
and translate into how-to docs where appropriate
|
||||
- Add the v1.4.6 release entry
|
||||
|
||||
Read the docs repo's CLAUDE.md/CONTRIBUTING (if present) FIRST to
|
||||
Read the docs repo's contributor guide (if present) FIRST to
|
||||
understand conventions. Commit + push.
|
||||
|
||||
### Landing site (`/Users/marc/Projects/healthlog-landing`)
|
||||
### Landing site (`healthlog-landing` repo)
|
||||
|
||||
Next.js site. Latest showcase mentions v1.2. Minimal updates only —
|
||||
don't redesign:
|
||||
@@ -421,19 +414,19 @@ Commit + push.
|
||||
|
||||
---
|
||||
|
||||
## Marc's hard rules (verbatim)
|
||||
## Hard rules (verbatim)
|
||||
|
||||
1. Niemals `--no-verify` bei git commit.
|
||||
2. Niemals `--no-gpg-sign` außer explizit angefragt.
|
||||
3. **Niemals force-push to main.**
|
||||
4. Changelogs/Release-Notes nur user-facing — kein "Claude", keine
|
||||
internen Phasennamen, keine Audit-Sprache.
|
||||
5. Authorization gilt nur für den spezifischen Auftrag — wenn etwas
|
||||
Größeres aufkommt, lieber fragen als entscheiden.
|
||||
1. Never `--no-verify` on git commit.
|
||||
2. Never `--no-gpg-sign` unless explicitly requested.
|
||||
3. **Never force-push to main.**
|
||||
4. Changelogs/release notes stay user-facing — no internal stage
|
||||
names, no audit-process language.
|
||||
5. Authorization is scoped to the specific task — when something
|
||||
larger surfaces, ask before deciding.
|
||||
|
||||
For this overnight session, Marc has explicitly authorized
|
||||
**autonomous execution of Tier 1 + Tier 2 + the new chart bucketing
|
||||
feature**, and the multi-agent QA + simplify pass. Anything that
|
||||
crops up which is **not** in this document and is **larger than a
|
||||
typo-level change** must be deferred to v1.5 with a note in the
|
||||
SUMMARY rather than implemented.
|
||||
The maintainer authorized
|
||||
**execution of Tier 1 + Tier 2 + the new chart bucketing feature**,
|
||||
and the multi-pass QA + simplify review for this session. Anything
|
||||
that surfaces outside this document and is larger than a typo-level
|
||||
change must be deferred to v1.5 with a note in the SUMMARY rather
|
||||
than implemented.
|
||||
+13
-13
@@ -1,6 +1,6 @@
|
||||
# HealthLog v1.4.6 — Marathon Summary
|
||||
# HealthLog v1.4.6 — Release Summary
|
||||
|
||||
## Marc-Brief (DE, ≤ 200 Wörter)
|
||||
## Release brief (DE, ≤ 200 Wörter)
|
||||
|
||||
✅ **v1.4.6 ist live** auf `https://healthlog.bombeck.io` — Container neu,
|
||||
Image-Digest `sha256:dcfa70be96a9…` (vorher v1.4.5: `0fc06b0b69d9…`).
|
||||
@@ -86,7 +86,7 @@ Seiten zu Native-API, Skalierung, Dashboard-Customization.
|
||||
| `02b9955` | repo-wide prettier sweep before tag |
|
||||
| `ecca54d` | `.planning` bootstrap |
|
||||
|
||||
### Multi-agent QA follow-ups
|
||||
### Multi-pass QA follow-ups
|
||||
|
||||
| Commit | Summary |
|
||||
| --------- | -------------------------------------------------------------------------------------------------------------------------- |
|
||||
@@ -100,7 +100,7 @@ Seiten zu Native-API, Skalierung, Dashboard-Customization.
|
||||
|
||||
## What was deferred (v1.5 backlog)
|
||||
|
||||
From the multi-agent QA pass:
|
||||
From the multi-pass QA review:
|
||||
|
||||
1. **Notification-channel scope of "Wipe all data"** — `NotificationChannel`,
|
||||
`PushSubscription`, `TelegramScheduledDeletion`, and `Feedback` rows
|
||||
@@ -146,7 +146,7 @@ From the multi-agent QA pass:
|
||||
AsyncLocalStorage / Reflect.get bug. CI Docker image (Node 22)
|
||||
builds cleanly — that is the canonical release path.
|
||||
- `e2e` workflow — fixed and pushed; the run on the v1.4.6 SHA was
|
||||
still pending at deploy time. Per the marathon spec, e2e green is
|
||||
still pending at deploy time. Per the release spec, e2e green is
|
||||
not a hard gate.
|
||||
|
||||
## Production state
|
||||
@@ -175,7 +175,7 @@ reproduce and report upstream.
|
||||
|
||||
## Docs / landing
|
||||
|
||||
Both repos pushed. See agent report for commit list. Highlights:
|
||||
Both repos pushed. See release report for commit list. Highlights:
|
||||
|
||||
- `healthlog-docs`: 8 commits bringing site from v1.2 → v1.4.6.
|
||||
New pages: `api/native-clients.mdx`, `self-hosting/scaling.mdx`,
|
||||
@@ -183,8 +183,8 @@ Both repos pushed. See agent report for commit list. Highlights:
|
||||
for v1.3-v1.4 features.
|
||||
- `healthlog-landing`: single commit `ebb03f9` bumping
|
||||
`softwareVersion` 1.3.3 → 1.4.6 and expanding the JSON-LD
|
||||
`featureList`. Screenshots untouched (Marc's call to refresh in
|
||||
daylight).
|
||||
`featureList`. Screenshots untouched (deferred to a daylight
|
||||
refresh).
|
||||
|
||||
## GitHub releases
|
||||
|
||||
@@ -192,17 +192,17 @@ Backfilled `v1.4.2`, `v1.4.3`, `v1.4.4`, `v1.4.5`, **`v1.4.6`** at
|
||||
https://github.com/MBombeck/HealthLog/releases — each with the
|
||||
canonical CHANGELOG block as release notes.
|
||||
|
||||
## QA agent reports — full text
|
||||
## QA review reports — full text
|
||||
|
||||
Stored in commit messages of `6757518` (the QA-pass follow-up
|
||||
commit). Three agents ran in parallel against the v1.4.6 diff:
|
||||
commit). Three review passes ran in parallel against the v1.4.6 diff:
|
||||
|
||||
- **superpowers:code-reviewer** — no CRITICAL, 3 HIGH (DST math,
|
||||
- **Code-review pass** — no CRITICAL, 3 HIGH (DST math,
|
||||
idempotency `sk-` substring, monthly bucket label semantics).
|
||||
All triaged: `sk-` regex fixed; rest deferred.
|
||||
- **Plan agent (security)** — no CRITICAL/HIGH. M1 (notification-
|
||||
- **Security review pass** — no CRITICAL/HIGH. M1 (notification-
|
||||
channel data-wipe scope) deferred. T4/T7/T8/P11/P12 cleared.
|
||||
- **Plan agent (design)** — no CRITICAL, 2 HIGH (orange tokens in
|
||||
- **Design review pass** — no CRITICAL, 2 HIGH (orange tokens in
|
||||
ai-section.tsx, status-card cta copy honesty). Both fixed.
|
||||
|
||||
---
|
||||
|
||||
@@ -637,7 +637,7 @@ The `codex-rs/tui/src/model_migration.rs` references to `gpt-5-codex` etc. are _
|
||||
|
||||
### 7b. Slug-drift defence — fallback chain (HealthLog v1.4.15+)
|
||||
|
||||
The ChatGPT-Codex allow-list is rotated by OpenAI without prior notice (`gpt-5-codex` → `gpt-5.3-codex` happened over 48 h in May 2026 and bricked HealthLog twice while the v1.4.7..v1.4.13 saga unrolled). The cause: a single hard-coded slug in `CODEX_MODEL` flips invalid the moment the upstream rotates it. Marc, verbatim 2026-05-09: "Die Integration des Slug Drift Risiko darf halt immer überhaupt nicht sein."
|
||||
The ChatGPT-Codex allow-list is rotated by OpenAI without prior notice (`gpt-5-codex` → `gpt-5.3-codex` happened over 48 h in May 2026 and bricked HealthLog twice while the v1.4.7..v1.4.13 saga unrolled). The cause: a single hard-coded slug in `CODEX_MODEL` flips invalid the moment the upstream rotates it. Operator brief, verbatim 2026-05-09: "Die Integration des Slug Drift Risiko darf halt immer überhaupt nicht sein."
|
||||
|
||||
To eliminate that risk class, HealthLog's `CodexClient` walks an ordered chain on every fresh request series.
|
||||
|
||||
|
||||
@@ -229,4 +229,4 @@ docker compose up -d
|
||||
|
||||
The schema is unchanged so a rollback does not require a database
|
||||
restore. File a GitHub issue with the symptom — the v1.4 cycle ran
|
||||
multi-agent QA per phase, but no migration is risk-free.
|
||||
multi-pass QA per stage, but no migration is risk-free.
|
||||
@@ -14,7 +14,7 @@ The `withIdempotency()` wrapper currently does
|
||||
`findCached → handler → persistCached`. Two requests with the same
|
||||
`Idempotency-Key` arriving in parallel both miss the SELECT, both
|
||||
execute the handler (duplicate measurements / intake events), and
|
||||
one INSERT loses on the unique constraint silently. The CLAUDE.md
|
||||
one INSERT loses on the unique constraint silently. The repo-doc
|
||||
contract ("retries with the same Idempotency-Key … replay the
|
||||
original response — no second side-effect") is therefore violated
|
||||
whenever a flaky mobile client double-sends.
|
||||
|
||||
Reference in new issue
Block a user