From d7eac1f87edab93e2023d36b94519d68ea78f6c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Thu, 12 Nov 2026 15:17:06 +0100 Subject: [PATCH] chore: drop tooling and host references from templates and comments - The translation issue template called eight locales "AI-initial", left Russian out of its list and its dropdown; it now says they started as machine-translated drafts reviewed by the community. - The pull request template asked for two locales where the checks require all ten, and pointed at an ignored docs folder. - Code comments named the maintainer notes file, a release by its working name and an internal host; old changelog entries explained the notes files by their tool-specific names. A fixture token and the deploy webhook test's application id (a real one) are replaced. --- .github/ISSUE_TEMPLATE/translation.yml | 5 +++-- .github/PULL_REQUEST_TEMPLATE.md | 6 +++--- CHANGELOG.md | 11 +++++------ e2e/admin-api-tokens-mobile.spec.ts | 2 +- e2e/chrome-header-seam-banners.spec.ts | 2 +- .../internal/deploy-webhook/__tests__/route.test.ts | 8 ++++---- .../i18n/__tests__/maintainership-banner.test.tsx | 4 ++-- src/components/i18n/maintainership-banner.tsx | 6 +++--- src/lib/__tests__/format-locale.test.ts | 2 +- src/lib/ai/coach/facts.ts | 4 ++-- src/lib/ai/coach/plans.ts | 2 +- .../ai/prompts/__tests__/coach-prompt-locale.test.ts | 6 +++--- src/lib/ai/prompts/insight-generator.ts | 4 ++-- src/lib/analytics/__tests__/classifications.test.ts | 2 +- src/lib/geo.ts | 2 +- src/lib/i18n/config.ts | 2 +- src/lib/jobs/__tests__/reminder-phases.test.ts | 2 +- src/lib/jobs/host-metric-sampler.ts | 8 ++++---- src/lib/jobs/reminder-phases.ts | 4 ++-- src/proxy.ts | 4 ++-- 20 files changed, 43 insertions(+), 43 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/translation.yml b/.github/ISSUE_TEMPLATE/translation.yml index 331815c1d..d12e9ce63 100644 --- a/.github/ISSUE_TEMPLATE/translation.yml +++ b/.github/ISSUE_TEMPLATE/translation.yml @@ -1,12 +1,12 @@ name: Translation feedback -description: Report a wording, grammar, or register problem in HealthLog's community-maintained locales (FR / ES / IT / PL / KO / NL / PT-BR). +description: Report a wording, grammar, or register problem in HealthLog's community-reviewed locales (FR / ES / IT / PL / KO / NL / PT-BR / RU). title: "[Translation] " labels: ["i18n", "translation-feedback"] body: - type: markdown attributes: value: | - HealthLog ships German and English as maintainer-curated translations. French, Spanish, Italian, Polish, Korean, Dutch, and Brazilian Portuguese ship as **AI-initial, community-maintained translations** — the prose passes the locale-integrity test (full key parity, no empty values) but has not been hand-reviewed for register or regional vocabulary. + HealthLog ships German and English as maintainer-curated translations. French, Spanish, Italian, Polish, Korean, Dutch, Brazilian Portuguese and Russian started as machine-translated first drafts and are reviewed by the community. They pass the locale-integrity test (full key parity, no empty values), but not every line has been read by a native speaker for register or regional vocabulary. This template captures concrete fixes you would like to see. Phrasing nuance, regional vocabulary (e.g. "Tú" vs "Usted"), gendered forms, and domain-specific health terms are all in scope. The maintainer applies fixes during the regular release cycle. @@ -23,6 +23,7 @@ body: - Korean (ko) - Dutch (nl) - Brazilian Portuguese (pt-BR) + - Russian (ru) - Other (specify under "Surface") validations: required: true diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 04679d7a0..be6042671 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -28,16 +28,16 @@ ## Checklist -- [ ] Targets the `main` branch (trunk-based — see [CONTRIBUTING.md](../CONTRIBUTING.md)) +- [ ] Targets the `main` branch (trunk-based, see [CONTRIBUTING.md](../CONTRIBUTING.md)) - [ ] `pnpm typecheck` passes locally - [ ] `pnpm lint` passes locally - [ ] `pnpm test` passes locally - [ ] `pnpm format:check` passes locally - [ ] `pnpm build` passes locally -- [ ] User-facing strings go through `t("key")` with both `messages/en.json` and `messages/de.json` updated +- [ ] User-facing strings go through `t("key")`, with the key in all ten `messages/*.json` files - [ ] No secrets, personal data, or maintainer-name references in committed files - [ ] Updated `CHANGELOG.md` if user-visible -- [ ] Updated `docs/audit/` or `docs.healthlog.dev` if behavior or self-hosting docs change +- [ ] Updated `docs/` or `docs.healthlog.dev` if behaviour or self-hosting steps change ## Linked issues diff --git a/CHANGELOG.md b/CHANGELOG.md index b2224ad9d..c4cd6aef7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19279,9 +19279,8 @@ NOT NULL`) is the defence-in-depth backstop. - **DE+EN bilingual CHANGELOG entries (v1.4.14 + v1.4.15) normalised to English-only.** Per the English-only voice rule. -- **`CLAUDE.md` filename retired** so the filename is no longer - AI-vendor-specific; `CONTRIBUTING.md` reference updated. - `AGENTS.md` stays for multi-agent compatibility. +- **Maintainer notes renamed**; the `CONTRIBUTING.md` reference is + updated. ### Deferred to v1.4.23 @@ -20599,8 +20598,8 @@ token '<', " { data: [ { id: "tok1", - name: "iOS auto-login 2026-05-05T19:42:11Z device-AABBCCDDEEFF-marathon", + name: "iOS auto-login 2026-05-05T19:42:11Z device-AABBCCDDEEFF-long-name", permissions: [ "measurements:write:audit:legacy:extended", "medications:read", diff --git a/e2e/chrome-header-seam-banners.spec.ts b/e2e/chrome-header-seam-banners.spec.ts index 87e470274..cb6a89165 100644 --- a/e2e/chrome-header-seam-banners.spec.ts +++ b/e2e/chrome-header-seam-banners.spec.ts @@ -221,7 +221,7 @@ async function enterSharedRecord(page: Page): Promise { } /** - * Swap the context's pinned locale for one HealthLog ships as an AI-initial + * Swap the context's pinned locale for one HealthLog ships as a machine * translation, so the maintainership strip has a reason to paint. * * The page is parked on `about:blank` for the swap. `I18nProvider` mirrors its diff --git a/src/app/api/internal/deploy-webhook/__tests__/route.test.ts b/src/app/api/internal/deploy-webhook/__tests__/route.test.ts index 407bac693..b7bf4e115 100644 --- a/src/app/api/internal/deploy-webhook/__tests__/route.test.ts +++ b/src/app/api/internal/deploy-webhook/__tests__/route.test.ts @@ -128,7 +128,7 @@ describe("POST /api/internal/deploy-webhook", () => { { status: "success", application_name: "HealthLog", - application_uuid: "pg8wggwogo8c4gc4ks0kk4ss", + application_uuid: "app-uuid-1", deployment_uuid: "dep-123", }, { "x-deploy-webhook-secret": "test-secret" }, @@ -144,7 +144,7 @@ describe("POST /api/internal/deploy-webhook", () => { expect.objectContaining({ details: expect.objectContaining({ applicationName: "HealthLog", - applicationUuid: "pg8wggwogo8c4gc4ks0kk4ss", + applicationUuid: "app-uuid-1", deploymentUuid: "dep-123", error: null, raw: expect.objectContaining({ status: "success" }), @@ -166,7 +166,7 @@ describe("POST /api/internal/deploy-webhook", () => { { status: "failed", application_name: "HealthLog", - application_uuid: "pg8wggwogo8c4gc4ks0kk4ss", + application_uuid: "app-uuid-1", deployment_uuid: "dep-456", error: "container exited 137", }, @@ -284,7 +284,7 @@ describe("POST /api/internal/deploy-webhook", () => { const fullPayload = { status: "success", application_name: "HealthLog", - application_uuid: "pg8wggwogo8c4gc4ks0kk4ss", + application_uuid: "app-uuid-1", deployment_uuid: "dep-789", future_field: { commit_sha: "abc123", environment: "production" }, }; diff --git a/src/components/i18n/__tests__/maintainership-banner.test.tsx b/src/components/i18n/__tests__/maintainership-banner.test.tsx index e21897ad1..e2f7f4f19 100644 --- a/src/components/i18n/__tests__/maintainership-banner.test.tsx +++ b/src/components/i18n/__tests__/maintainership-banner.test.tsx @@ -8,7 +8,7 @@ import type { Locale } from "@/lib/i18n/config"; /** * v1.4.25 — contract: * 1. Renders nothing on maintained locales (DE / EN). - * 2. Renders a notice strip on AI-initial locales (FR / ES / IT / PL). + * 2. Renders a notice strip on machine-translated locales (FR / ES / IT / PL). * 3. The notice carries a GitHub-issue CTA so feedback has a clear * home. * @@ -61,7 +61,7 @@ describe("", () => { // documents that the strip is NOT painted before the first effect // runs — exactly the contract that prevents the flash-of-banner // problem. - it("paints nothing in the SSR pass for AI-initial locales", () => { + it("paints nothing in the SSR pass for machine-translated locales", () => { for (const locale of ["fr", "es", "it", "pl"] as const) { const html = ssr(locale); expect(html).not.toContain("maintainership-banner"); diff --git a/src/components/i18n/maintainership-banner.tsx b/src/components/i18n/maintainership-banner.tsx index 66c6eed5f..3740eafe8 100644 --- a/src/components/i18n/maintainership-banner.tsx +++ b/src/components/i18n/maintainership-banner.tsx @@ -6,11 +6,11 @@ import { isMaintainedLocale, type Locale } from "@/lib/i18n/config"; import { useTranslations } from "@/lib/i18n/context"; /** - * v1.4.25 — notice strip for AI-initial locales. + * v1.4.25 — notice strip for machine-translated locales. * * HealthLog ships German + English as maintainer-curated translations * (the maintainer owns both bodies). French, Spanish, Italian - * and Polish ship as AI-initial translations — they pass the + * and Polish ship as machine translations — they pass the * locale-integrity test (full key parity, no empty values, no TODOs) * but the prose has not been hand-reviewed for register, regional * vocabulary, or domain-specific nuance. @@ -18,7 +18,7 @@ import { useTranslations } from "@/lib/i18n/context"; * This banner renders ONLY on non-maintained locales (FR/ES/IT/PL/KO * today) and surfaces a small, dismissible strip at the top of the * authenticated app shell. It tells the user the translation is - * AI-maintained and links to the GitHub translation-feedback issue + * machine-translated and links to the GitHub translation-feedback issue * template so they can contribute fixes back. * * Dismissal is persisted to localStorage per-locale so a user who diff --git a/src/lib/__tests__/format-locale.test.ts b/src/lib/__tests__/format-locale.test.ts index 9fe33b8bb..cbc37d937 100644 --- a/src/lib/__tests__/format-locale.test.ts +++ b/src/lib/__tests__/format-locale.test.ts @@ -31,7 +31,7 @@ describe("parseLocaleFromAcceptLanguage", () => { expect(parseLocaleFromAcceptLanguage("*")).toBe("en"); }); - // v1.4.25 — the four AI-initial locales added in this release. + // v1.4.25 — the four machine-translated locales added in this release. // Each maps via the same primary-tag prefix match the DE branch uses. it("returns the matching tag for FR / ES / IT / PL", () => { expect(parseLocaleFromAcceptLanguage("fr-FR,fr;q=0.9")).toBe("fr"); diff --git a/src/lib/ai/coach/facts.ts b/src/lib/ai/coach/facts.ts index 0e9c76f43..60f474a60 100644 --- a/src/lib/ai/coach/facts.ts +++ b/src/lib/ai/coach/facts.ts @@ -450,7 +450,7 @@ export async function extractAndStoreFacts( let proposed = 0; for (const f of toStore) { - // Field-by-field, no spread (mass-assignment rule, CLAUDE.md). A health + // Field-by-field, no spread (no mass assignment). A health // fact waits for the person's tap; everything else is kept as extracted. const source = backgroundSource(f.category, f.fact, "extracted"); if (source === PROPOSED_FACT_SOURCE) proposed += 1; @@ -710,7 +710,7 @@ export async function storeDeterministicFacts(args: { for (const cand of candidates) { if (isNearDuplicate(cand.fact, seen)) continue; seen.push(cand.fact); - // Field-by-field, no spread (mass-assignment rule, CLAUDE.md). + // Field-by-field, no spread (no mass assignment). await db.coachFact.create({ data: { userId: args.userId, diff --git a/src/lib/ai/coach/plans.ts b/src/lib/ai/coach/plans.ts index 32600d676..bfd51a77e 100644 --- a/src/lib/ai/coach/plans.ts +++ b/src/lib/ai/coach/plans.ts @@ -380,7 +380,7 @@ export async function extractAndStorePlanProposals( const toStore = accepted.slice(0, remainingCapacity); for (const p of toStore) { - // Field-by-field, no spread (mass-assignment rule, CLAUDE.md). Always + // Field-by-field, no spread (no mass assignment). Always // written as "proposed" — only the user-facing PATCH activates a plan. await db.coachPlan.create({ data: { diff --git a/src/lib/ai/prompts/__tests__/coach-prompt-locale.test.ts b/src/lib/ai/prompts/__tests__/coach-prompt-locale.test.ts index 40e8af057..b263f5b0b 100644 --- a/src/lib/ai/prompts/__tests__/coach-prompt-locale.test.ts +++ b/src/lib/ai/prompts/__tests__/coach-prompt-locale.test.ts @@ -18,7 +18,7 @@ import { loadSafetyContracts } from "@/lib/ai/prompts/safety-contracts"; const NATIVE_LOCALES = ["fr", "es", "it", "pl"] as const; /** - * v1.4.25 — each AI-initial locale (FR / ES / IT / PL) now gets a + * v1.4.25 — each machine-translated locale (FR / ES / IT / PL) now gets a * native system prompt assembled from the safety-contract matrix * instead of riding the EN body with a one-line footer. * @@ -34,7 +34,7 @@ const NATIVE_LOCALES = ["fr", "es", "it", "pl"] as const; * 9. The reply-language directive lives at the foot of the prompt. */ -describe("getCoachSystemPrompt — native AI-initial locales", () => { +describe("getCoachSystemPrompt — native machine-translated locales", () => { it.each(NATIVE_LOCALES)( "%s produces a non-empty native prompt embedding PROMPT_VERSION", (locale) => { @@ -140,7 +140,7 @@ describe("getCoachSystemPrompt — native AI-initial locales", () => { }); }); -describe("getStrictInsightsSystemPrompt — native AI-initial locales", () => { +describe("getStrictInsightsSystemPrompt — native machine-translated locales", () => { it.each(NATIVE_LOCALES)( "%s produces a non-empty native Insights prompt", (locale) => { diff --git a/src/lib/ai/prompts/insight-generator.ts b/src/lib/ai/prompts/insight-generator.ts index 86888d704..3a8c6d262 100644 --- a/src/lib/ai/prompts/insight-generator.ts +++ b/src/lib/ai/prompts/insight-generator.ts @@ -1032,7 +1032,7 @@ export function buildSystemPromptWithReferences( const refs = selectReferencesForMetrics(metrics); if (refs.length === 0) return base; - // v1.4.25 — AI-initial locales (FR/ES/IT/PL) ride the EN sources + // v1.4.25 — machine-translated locales (FR/ES/IT/PL) ride the EN sources // block. The "title" field is the EN title; the model is told to // surface the citation id, not to translate the source title, so this // is safe — citation labels in the UI use the contract id (lowercase, @@ -1107,7 +1107,7 @@ export const OUT_OF_SCOPE_REFUSAL_DE = { * from the safety-contract matrix so the summary copy stays in sync * with the prompt body that taught the model to emit it. The EN / * DE constants above remain authoritative for their locales — these - * helpers cover the AI-initial locales. + * helpers cover the machine-translated locales. */ export const OUT_OF_SCOPE_REFUSAL_FR = buildOutOfScopeRefusal("fr"); export const OUT_OF_SCOPE_REFUSAL_ES = buildOutOfScopeRefusal("es"); diff --git a/src/lib/analytics/__tests__/classifications.test.ts b/src/lib/analytics/__tests__/classifications.test.ts index 76d9a5575..b02338d8d 100644 --- a/src/lib/analytics/__tests__/classifications.test.ts +++ b/src/lib/analytics/__tests__/classifications.test.ts @@ -171,7 +171,7 @@ describe("generateAlerts", () => { }); }); -// v1.4 marathon — closes the body-fat ACE drift identified in the +// v1.4: closes the body-fat ACE drift identified in the // medical-truthfulness audit. Below-essential is now a danger band, // "Essential" is the warning band proper, and the labels match ACE. describe("classifyBodyFat (ACE bands)", () => { diff --git a/src/lib/geo.ts b/src/lib/geo.ts index baebbf1ea..374ca9327 100644 --- a/src/lib/geo.ts +++ b/src/lib/geo.ts @@ -480,7 +480,7 @@ async function lookupIpOnline(ip: string): Promise { // metadata address (SSRF/rebinding). // v1.15.12 — keep the online timeout below the audit-log 3 s race // window so a slow-but-successful lookup still lands before the race - // resolves null and drops the location (the "—" symptom on apps01). + // resolves null and drops the location (the "—" symptom in production). { timeoutMs: 2_500, requirePublicHost: true }, ); if (!res.ok) { diff --git a/src/lib/i18n/config.ts b/src/lib/i18n/config.ts index 166463fe8..2657a1868 100644 --- a/src/lib/i18n/config.ts +++ b/src/lib/i18n/config.ts @@ -87,7 +87,7 @@ export const localeLabels: Record = { /** * v1.4.25 — locales actively maintained by the project owner. - * Locales outside this set are AI-initial translations and surface a + * Locales outside this set are machine-translated translations and surface a * notice at the top of the auth shell so users * know to expect rough edges and where to contribute fixes. Promoting * a locale here turns the banner off. diff --git a/src/lib/jobs/__tests__/reminder-phases.test.ts b/src/lib/jobs/__tests__/reminder-phases.test.ts index 00515b6de..307b3f5ac 100644 --- a/src/lib/jobs/__tests__/reminder-phases.test.ts +++ b/src/lib/jobs/__tests__/reminder-phases.test.ts @@ -33,7 +33,7 @@ describe("determinePhase", () => { }); }); -// v1.4 marathon — closes v3 audit "Locale Mixing" CRIT. +// v1.4: closes the "Locale Mixing" finding. // Reminder messages must follow the user's stored locale, not always // German. callback_data values are stable English identifiers and stay // untranslated regardless of UI locale. diff --git a/src/lib/jobs/host-metric-sampler.ts b/src/lib/jobs/host-metric-sampler.ts index 107f5f4b8..b4de488d8 100644 --- a/src/lib/jobs/host-metric-sampler.ts +++ b/src/lib/jobs/host-metric-sampler.ts @@ -1,10 +1,10 @@ /** * Host-load sampler (every five minutes since v1.42) that backs the admin /admin/system-status - * "last 2 hours" chart (v1.4.16 phase B3). + * "last 2 hours" chart. * - * The maintainer asked for a small at-a-glance graph above the system-status facts - * grid showing CPU + memory + disk-IO so a glance at /admin tells them - * whether the apps-01 host is healthy. We considered scraping Coolify's + * A small at-a-glance graph above the system-status facts grid shows + * CPU + memory + disk-IO, so a glance at /admin tells an operator whether + * the app host is healthy. We considered scraping Coolify's * Sentinel collector, but the Coolify HTTP API does not expose a clean * read endpoint for per-server metrics — every approach ended up either * scraping the Coolify dashboard HTML or hitting a private RPC. An diff --git a/src/lib/jobs/reminder-phases.ts b/src/lib/jobs/reminder-phases.ts index 8447e17ea..d685d5266 100644 --- a/src/lib/jobs/reminder-phases.ts +++ b/src/lib/jobs/reminder-phases.ts @@ -157,8 +157,8 @@ const resolveLocale = coerceLocale; * `medicationReminders.phase*`. The reminder worker passes the user's * stored locale; absent / unknown locales fall back to the app default. * - * v1.4 marathon — closes the v3 audit "Locale-Mixing" CRIT finding - * (German-only Telegram / Web Push templates regardless of user locale). + * v1.4: closes the "Locale-Mixing" finding (German-only Telegram / Web Push + * templates regardless of user locale). */ export function getPhaseMessage( phase: ReminderPhase, diff --git a/src/proxy.ts b/src/proxy.ts index 4ecf2045c..c22031cdc 100644 --- a/src/proxy.ts +++ b/src/proxy.ts @@ -175,8 +175,8 @@ function isPublicPath(pathname: string): boolean { * a unit toggle and a date of birth, and it is why free text, anything that * reaches an AI prompt, and anything creating a second record are refused. * - * This whole block only runs under `DEMO_MODE=true`, so production (apps01) - * is unaffected by construction. + * This whole block only runs under `DEMO_MODE=true`, so production is + * unaffected by construction. */ const DEMO_MUTATION_ALLOWLIST: ReadonlyArray<{ path: string; method: string }> = [