From 6b88e56aeb30b8c7688a0bdd8f560c3f63be8f03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Sat, 9 May 2026 16:06:52 +0200 Subject: [PATCH] chore(format): prettier sweep over phase-2 touched files + stale planning docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Picks up the prettier line-wraps the v1.5 phase-1 planning docs and codex-protocol-spec.md missed, and brings the redact.ts + insights generate route test into the project's standard form. No behaviour change — pnpm format:check now passes clean. Co-Authored-By: Claude Opus 4.7 (1M context) --- .planning/ROADMAP.md | 28 +++++++------- .planning/STATE.md | 4 +- .planning/phase-1-report.md | 6 ++- docs/codex-protocol-spec.md | 6 ++- .../insights/generate/__tests__/route.test.ts | 2 +- src/lib/logging/redact.ts | 37 +++++++++---------- 6 files changed, 44 insertions(+), 39 deletions(-) diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 1baa2fa30..0399adc00 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -3,21 +3,21 @@ Milestone: **v1.5.0** (overnight 2026-05-09 → 2026-05-10) Latest tag at start: v1.4.13 (Codex-OAuth model slug `gpt-5` patch) -| Phase | Goal | State | -| ----- | -------------------------------------------------------------------------- | ------- | -| 0 | Bootstrap — STATE+ROADMAP, git/CI/prod sanity, single chore commit | done | -| 1 | Verify Codex-OAuth end-to-end (device-start shape, prod logs, gpt-5 slug) | pending | +| Phase | Goal | State | +| ----- | -------------------------------------------------------------------------------------------------------------------------------------- | ------- | +| 0 | Bootstrap — STATE+ROADMAP, git/CI/prod sanity, single chore commit | done | +| 1 | Verify Codex-OAuth end-to-end (device-start shape, prod logs, gpt-5 slug) | pending | | 2 | v1.4.6 deferred backlog — T2.1..T2.7 (wipe scope, DST math, 5xx → 422/503, status-card test, redact regex, Backups view, /admin/users) | pending | -| 3 | End-to-end test coverage — authed dashboard, add-measurement, KI flow, doctor PDF, insights, mobile smoke, axe-core extended | pending | -| 4 | Performance audit — Playwright capture, `docs/audit/v15-performance.md`, top-3 wins inline | pending | -| 4b | Admin Panel refactor — `/admin/[section]` dynamic routes mirror Settings; sidebar Admin group; legacy hash redirects; bundle-size win | pending | -| 5 | UX polish — design-review top-10 friction points, CRITICAL/HIGH triage | pending | -| 6 | Multi-agent QA (parallel) — code-reviewer, security, visual/UX, simplify | pending | -| 7 | Pre-release verification — typecheck / lint / format / test / integration / build / e2e | pending | -| 8 | Release v1.5.0 — bump, CHANGELOG, tag, GHCR, Coolify force-pull, /api/version=1.5.0, smoke screenshots | pending | -| 9 | Docs + landing site sync to v1.5 | pending | -| 10 | Backfill GitHub releases v1.4.7..v1.4.13 from CHANGELOG | pending | -| 11 | Final summary `docs/audit/v15-summary.md` with Marc-Brief | pending | +| 3 | End-to-end test coverage — authed dashboard, add-measurement, KI flow, doctor PDF, insights, mobile smoke, axe-core extended | pending | +| 4 | Performance audit — Playwright capture, `docs/audit/v15-performance.md`, top-3 wins inline | pending | +| 4b | Admin Panel refactor — `/admin/[section]` dynamic routes mirror Settings; sidebar Admin group; legacy hash redirects; bundle-size win | pending | +| 5 | UX polish — design-review top-10 friction points, CRITICAL/HIGH triage | pending | +| 6 | Multi-agent QA (parallel) — code-reviewer, security, visual/UX, simplify | pending | +| 7 | Pre-release verification — typecheck / lint / format / test / integration / build / e2e | pending | +| 8 | Release v1.5.0 — bump, CHANGELOG, tag, GHCR, Coolify force-pull, /api/version=1.5.0, smoke screenshots | pending | +| 9 | Docs + landing site sync to v1.5 | pending | +| 10 | Backfill GitHub releases v1.4.7..v1.4.13 from CHANGELOG | pending | +| 11 | Final summary `docs/audit/v15-summary.md` with Marc-Brief | pending | Stop conditions: production red, large un-spec'd issue, context cutoff, or budget short of polish — write status doc, do not auto-rollback. diff --git a/.planning/STATE.md b/.planning/STATE.md index f72cce8a2..d5050da51 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -20,7 +20,7 @@ Last update: 2026-05-09T15:50:00+02:00 - [x] /api/version=1.4.13 confirmed (force-pulled at 13:43 UTC after GHCR builds finished) - [x] device-start endpoint returns spec-shaped response (`userCode`, `verificationUrl=https://auth.openai.com/codex/device`, `intervalSeconds`) -- [x] prod logs reviewed for codex.* events (DB row confirms 13:06 connect; v1.4.12 ai_test_body_excerpt captured the original failure) +- [x] prod logs reviewed for codex.\* events (DB row confirms 13:06 connect; v1.4.12 ai_test_body_excerpt captured the original failure) - [x] gpt-5 model accepted by chatgpt.com backend — actually NO, rejected; switched default to `gpt-5.3-codex` (commit `5df74f7`), live test against Marc's account succeeded - [x] /tmp/v15-codex-working.png captured showing `/settings/ai` with "ChatGPT connected" badge - Result: ok / commit `5df74f7 fix(ai): default Codex model to gpt-5.3-codex for ChatGPT-account auth` @@ -60,7 +60,7 @@ Last update: 2026-05-09T15:50:00+02:00 - [ ] /admin/[section]/page.tsx + admin-shell sidebar - [ ] Sections moved to /admin/ routes (system-status, services, integrations, feedback, reminders, users, api-tokens, login-overview, backups, danger-zone) - [ ] Status-card CTAs use real routes (no #anchor) -- [ ] i18n keys reorganised under admin.section..* +- [ ] i18n keys reorganised under admin.section..\* - [ ] Sidebar nav expandable Admin group - [ ] Legacy #anchor → new route redirect in proxy.ts - [ ] Bundle-size win on /admin overview verified diff --git a/.planning/phase-1-report.md b/.planning/phase-1-report.md index a33a4e5e9..6eec0d704 100644 --- a/.planning/phase-1-report.md +++ b/.planning/phase-1-report.md @@ -26,11 +26,13 @@ flipped from 1.4.12 to 1.4.13 once the new container was healthy. `POST /api/auth/codex/device-start` (with Marc's session cookie `cmox4d6fj000101p8w9ykhcnm`) returned: + ``` { "userCode":"RUNZ-DIOCO", "verificationUrl":"https://auth.openai.com/codex/device", "intervalSeconds":5 } ``` + — exact spec shape. Marc's `users.codex_connection_status` row was already `connected` (token from 13:06 UTC, expiring 14:06 UTC), so the poll path didn't need to be re-exercised. The device-poll connect @@ -43,10 +45,12 @@ it landed. `/api/ai/test` against the v1.4.13 image returned `Provider connection failed`; the `ai_test_body_excerpt` annotation captured the upstream error verbatim: + ``` {"detail":"The 'gpt-5' model is not supported when using Codex with a ChatGPT account."} ``` + v1.4.13 had switched the default from the rejected `gpt-5-codex` to the equally-rejected plain `gpt-5`. Cross-checking `codex-rs/models-manager/models.json` in `openai/codex` showed the @@ -62,7 +66,7 @@ made `/api/ai/test` succeed: `{"ok":true,"providerType":"codex", data. Commit `5df74f7` flipped the in-code default to `gpt-5.3-codex` and updated `docs/codex-protocol-spec.md` §7a with the chatgpt-account-auth allow-list constraint and the lesson that the -slugs in `model_migration.rs` are migration *prompts*, not wire slugs. +slugs in `model_migration.rs` are migration _prompts_, not wire slugs. ## Screenshot diff --git a/docs/codex-protocol-spec.md b/docs/codex-protocol-spec.md index a4bd44d7f..7f674c7eb 100644 --- a/docs/codex-protocol-spec.md +++ b/docs/codex-protocol-spec.md @@ -618,7 +618,9 @@ The ChatGPT backend ignores `model` strings the user's account doesn't have enti When authenticating via the ChatGPT-OAuth path (Bearer token + `ChatGPT-Account-ID` header, §3a), the backend rejects model slugs that are NOT in the active `codex-rs/models-manager/models.json` bundle. The rejection is HTTP 400 with body: ```json -{ "detail": "The '' model is not supported when using Codex with a ChatGPT account." } +{ + "detail": "The '' model is not supported when using Codex with a ChatGPT account." +} ``` Confirmed-rejected slugs (despite the source-tree references in the table above): @@ -631,7 +633,7 @@ Confirmed-accepted slugs on a ChatGPT Plus subscription (per `available_in_plans - `gpt-5.3-codex` — coding-optimized, accepted; HealthLog uses this as default - `gpt-5.5` / `gpt-5.4` / `gpt-5.4-mini` / `gpt-5.2` — also expected to work per plan -The `codex-rs/tui/src/model_migration.rs` references to `gpt-5-codex` etc. are *migration prompts* shown to existing users — they are NOT the slugs sent on the wire after migration. The wire slugs come from `models.json`. Always cross-check `models.json` (`gh api repos/openai/codex/contents/codex-rs/models-manager/models.json`) before picking a default. +The `codex-rs/tui/src/model_migration.rs` references to `gpt-5-codex` etc. are _migration prompts_ shown to existing users — they are NOT the slugs sent on the wire after migration. The wire slugs come from `models.json`. Always cross-check `models.json` (`gh api repos/openai/codex/contents/codex-rs/models-manager/models.json`) before picking a default. --- diff --git a/src/app/api/insights/generate/__tests__/route.test.ts b/src/app/api/insights/generate/__tests__/route.test.ts index 12d7c4a70..fec20ca65 100644 --- a/src/app/api/insights/generate/__tests__/route.test.ts +++ b/src/app/api/insights/generate/__tests__/route.test.ts @@ -113,7 +113,7 @@ describe("POST /api/insights/generate — provider error mapping", () => { it("maps a 401 from the provider to 422 with a readable message", async () => { const err = Object.assign(new Error("OpenAI request failed (401)"), { httpStatus: 401, - bodyExcerpt: "{\"error\":{\"code\":\"invalid_api_key\"}}", + bodyExcerpt: '{"error":{"code":"invalid_api_key"}}', }); makeProviderThatThrows(err); diff --git a/src/lib/logging/redact.ts b/src/lib/logging/redact.ts index 40218e9f7..714f42c4d 100644 --- a/src/lib/logging/redact.ts +++ b/src/lib/logging/redact.ts @@ -23,25 +23,24 @@ * want partial revelation of token entropy. */ export function redactSecrets(input: string): string { - return input - .replace(/Bearer\s+\S+/gi, "Bearer [REDACTED]") - .replace(/bot\d+:[A-Za-z0-9_-]+/g, "bot[REDACTED]") - // `sk-` is a common English-prefix substring (task-force, risk- - // management, disk-io). Without a word-boundary, the original - // `/sk-(?:ant-)?[A-Za-z0-9_-]+/g` over-matched and made server logs - // unreadable. Require the `sk-` token to be at the start of the - // string OR preceded by a non-alphanumeric character (whitespace, - // `=`, `{`, `,`, `:`, etc.). The minimum length-8 tail keeps a - // tiny safety margin against `sk-1`-style false-positives in code - // identifiers. Capture group 1 = the leading separator (preserved). - .replace( - /(^|[^A-Za-z0-9])sk-(?:ant-)?[A-Za-z0-9_-]{8,}/g, - "$1[REDACTED]", - ) - .replace( - /([?&])(secret|code|token|api[_-]?key)=[^&\s]+/gi, - "$1$2=[REDACTED]", - ); + return ( + input + .replace(/Bearer\s+\S+/gi, "Bearer [REDACTED]") + .replace(/bot\d+:[A-Za-z0-9_-]+/g, "bot[REDACTED]") + // `sk-` is a common English-prefix substring (task-force, risk- + // management, disk-io). Without a word-boundary, the original + // `/sk-(?:ant-)?[A-Za-z0-9_-]+/g` over-matched and made server logs + // unreadable. Require the `sk-` token to be at the start of the + // string OR preceded by a non-alphanumeric character (whitespace, + // `=`, `{`, `,`, `:`, etc.). The minimum length-8 tail keeps a + // tiny safety margin against `sk-1`-style false-positives in code + // identifiers. Capture group 1 = the leading separator (preserved). + .replace(/(^|[^A-Za-z0-9])sk-(?:ant-)?[A-Za-z0-9_-]{8,}/g, "$1[REDACTED]") + .replace( + /([?&])(secret|code|token|api[_-]?key)=[^&\s]+/gi, + "$1$2=[REDACTED]", + ) + ); } /** Apply `redactSecrets` to a possibly-undefined string. */