From fa47a9ab8864c9efbadeb0bff9c1fe799f0d1651 Mon Sep 17 00:00:00 2001 From: Mao Nakamoto <41178744+maonakamoto@users.noreply.github.com> Date: Wed, 26 Aug 2026 13:59:00 +0200 Subject: [PATCH] =?UTF-8?q?docs:=20record=20the=20page=20walk=20=E2=80=94?= =?UTF-8?q?=20what=20it=20found=20and=20why=20greps=20could=20not?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The backlog described two rounds; there have been three. The third came from opening all 33 public pages in a browser instead of reading the code, and the distinction matters enough to write down: greps and typechecks were green throughout, while the site was serving donation buttons pointing at another organisation, two nav entries rendering , a 404 in the live FAQ, a tenure claim on an org founded two years ago, and three different causes of one doubled page title. Records what the refocus settled (services catalogue, Über uns, navGroup as the placement SSOT) so it is not re-litigated, and adds the four gates from this pass — each mutation-proved, because a gate that has never been seen red is a claim rather than a check. Two items promoted to "needs a human decision", both because they are claims about the world that the repository cannot answer: - Praktikum + Wiedereinstieg name HEKS, AOZ and two municipalities as partners. If evig runs those programmes they belong with pillar 4 and deserve prominence; if they came across with the code, naming four real organisations is worse than merely off-thesis. - /karriere is invisible to nav, footer and sitemap, and carries the only hardcoded-German PageHero on the site, so it is also the one page that cannot be translated. And education is now stated as the biggest gap rather than a bullet: George has said teaching will be a large part of what evig does, and /workshops renders "0 Workshops" while /blog renders nothing. The seeded workshops use legacy category strings matching none of the ten canonical ids, are written in formal "Sie" against the site's "du", and have no instances outside e2e-seed.ts — so even with rows there would be no dates and no registration. New process notes: a cancelled deploy is not a failed one (a newer merge supersedes it, and a watcher checking only "not success" cries wolf), and measure the rendered output rather than reasoning about the framework — two of the three doubled titles were missed by reasoning about Next's title.template and found by curling . Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --- docs/AUDIT_BACKLOG_2026-08.md | 115 ++++++++++++++++++++++++++-------- 1 file changed, 88 insertions(+), 27 deletions(-) diff --git a/docs/AUDIT_BACKLOG_2026-08.md b/docs/AUDIT_BACKLOG_2026-08.md index 2a953338d..b3edae9a0 100644 --- a/docs/AUDIT_BACKLOG_2026-08.md +++ b/docs/AUDIT_BACKLOG_2026-08.md @@ -1,9 +1,10 @@ -# Deep-dive audit — 2026-08-24, refocus pass 2026-08-25 +# Deep-dive audit — 2026-08-24, refocus 2026-08-25, page walk 2026-08-26 -Two rounds. The first (PRs #358, #359, #368–#377) was correctness and gate -hygiene. The second (#379, #381, #382, #383) was the strategic refocus onto -**AI for all** — hardware, technicians, Linux/open source, retraining, and -adoption in organisations. +Three rounds. The first (PRs #358, #359, #368–#377) was correctness and gate +hygiene. The second (#379, #381–#385, #387) was the strategic refocus onto +**AI for all**. The third (#388, #389, #391) came from opening all 33 public +pages in a browser rather than reading the code, and found things no gate +could see. This file records what is **still open**, so the next session starts from the findings rather than re-deriving them. @@ -16,11 +17,24 @@ findings rather than re-deriving them. - **`evig repairs` is now `evig technicians`** (#382). The old name described the service; the new one describes what the user is looking for — a person. - **The homepage states five pillars** (#381), driven by `src/config/pillars.ts`. - It no longer opens with a donation funnel or a recycling cycle. + It no longer opens with a donation funnel or a recycling cycle, and (#385) + no longer says the same thing three times. - **The "not a charity" line is gone** (#379). evig is a gemeinnütziger Verein *in Gründung*; saying what it is not contradicted its own legal page. - **evig does not ask for printers** (#382). Category `'60'` stays in erfassung for existing inventory rows; the donation copy no longer solicits new ones. +- **The services catalogue is four entries** (#389): webDesign (kept — real + revenue, George's explicit call), linuxOpenSource, openSourceSolutions and + the new aiAdoption at `/services/ai-robotics`. hardwareRecycling and + buildYourComputer were removed; computerRepair and dataRecovery redirect to + `/it-hilfe`, because evig is where you FIND a technician, not the shop that + charges CHF 70/h. +- **Über uns is five items in two sections** (#389), not nine unsectioned ones. + `evig ai` and `Abos teilen` live under Marktplatz — three ways to get + something, not three parts of an org chart. +- **Service placement is data** (#389). Each service declares + `navGroup: 'services' | 'learn'` once; both menus derive from it. A service + in two menus, or none, fails `services-nav.test.ts`. ## Needs a human decision (not started) @@ -36,10 +50,22 @@ behaves behind Caddy. Left in place on purpose. issuing routes exist, redemption (`validateAndComputeDiscount`, `recordRedemption`) was never wired into checkout. Finish or remove. -**Pillar 5 (`adoption`) has no page.** It points at `/contact` deliberately — -writing a consulting service page for work nobody has scoped would be the -claim the honesty rule exists to prevent. When there is a real engagement to -describe, it belongs in `SERVICE_CONFIGS`, not as a bespoke page. +**Praktikum + Wiedereinstieg — does evig actually run these?** +`/get-involved/internships` and `/get-involved/work-reintegration` describe +real integration programmes and name partners: HEKS, AOZ, the *Verein für +berufliche und soziale Integration Bezirk Uster* and the *Arbeitsintegrations- +stelle der Gemeinde Rüti*. If evig runs them they belong with pillar 4 +(training) and should be much more prominent. If they came across with the +code from Revamp-IT, they are commitments evig cannot honour and naming those +four organisations is worse than off-thesis. **Only George can answer this**; +nothing in the repo distinguishes the two cases. + +**`/karriere` is invisible and monolingual.** Not in the nav, not in the +footer, not in the sitemap — reachable only from the three get-involved CTAs +(`?track=volunteer|intern|reintegration`). Its hero is the only hardcoded +German `PageHero` on the site (`title="Karriere bei evig"`), so it is also the +one page that cannot be translated. Decide: surface it properly and i18n it, +or fold it into get-involved. ## Ratcheted debt (gated, may fall, must not rise) @@ -47,10 +73,22 @@ describe, it belongs in `SERVICE_CONFIGS`, not as a bespoke page. |---|---|---| | `lint:chrome` | 3 | hand-rolled card shells (2 justified + 1 doc comment) | | `lint:docs` | 68 | stale paths in older reference docs; CLAUDE.md/README held at 0 | -| `compliance:i18n-hardcoded` | ~1.7k | hardcoded strings, mostly in older components | +| `compliance:i18n-hardcoded` | 2430 src / 84 msg | was ~2531/706; the msg drop is real leaks fixed, the src drop is the deleted `community.ts` tree | | `compliance:i18n` | 175 | missing translation keys | | `compliance:i18n-leaks` | ja/ko/ru | untranslated leaks per locale | +## Gates added in this pass (each mutation-proved) + +| gate | catches | +|---|---| +| `navigation-links-resolve.test.ts` | a nav entry with an empty or malformed href — two shipped as `<a href="">` for months | +| `services-nav.test.ts` (rewritten) | a service in two menus or none, now that `navGroup` decides placement | +| `workshops-config-matches-messages.test.ts` | the German category labels in config drifting from the message files | +| `page-titles-not-doubled.test.ts` | a title string carrying "\| evig" when the layout template already appends it | + +**Every one was proved by planting the defect back and watching the gate name +it.** A gate that has never been seen red is a claim, not a check. + ## Known gate limitations — do not read green as clean - **`i18n-hardcoded` only sees QUOTED string literals.** A German sentence as @@ -80,28 +118,38 @@ describe, it belongs in `SERVICE_CONFIGS`, not as a bespoke page. ## Found but not fixed (from the audit sweeps) ### Content / IA -- **`/karriere` + `/karriere/[slug]`** are orphaned from nav AND footer, absent - from the sitemap, and **fully hardcoded German with no i18n namespace** — - a straight violation of the i18n SSOT rule. +- **EDUCATION IS THE BIGGEST GAP.** George has said teaching and retraining + will be a large part of what evig does, and today `/workshops` renders + **"0 Workshops · Aktuell sind keine Workshops geplant"** while `/blog` + renders nothing at all. The page is DB-driven; the only workshop rows in + version control are 6 seeds in `001-unified-auth.sql` whose categories are + legacy strings matching none of the 10 canonical ids, written in formal + "Sie" against the site's informal "du", and **no `workshop_instances` are + seeded anywhere except `e2e-seed.ts`** — without instances there are no + dates and registration is impossible. Meanwhile the 43-entry open-source + registry (1029 lines, real, indexed) is the largest teaching asset evig + owns; #388 moved it and the Linux page into Lernen, which is a signpost, + not a fix. Seeding real workshops in the `retraining` category is the + single highest-value content job left. - **Near-duplicate recruiting pages**: `/get-involved/technical-experts` vs `/get-involved/it-hilfe-techniker` — same shape, same namespace, different - sub-keys. The latter has zero inbound links and is not in the sitemap. + sub-keys. The latter has **zero inbound links anywhere** and is not in the + sitemap. Technician recruiting also exists at `/profil/techniker` and in the + `/it-hilfe` hub's offerHelp block: four doors, one job. - **Five `notFound()` stubs** kept deliberately ("hidden until real"): `/space`, `/about/finances`, `/about/impact`, `/about/press`, `/transparenz/kennzahlen`. Behaviourally identical to not existing; they document intent. `ROUTES.public.transparenzKennzahlen` was removed in #382. -- **`home.actions.sell`** is a *buy* card labelled `01 / SHOP` under a key - named `sell` — key/content drift. `home.finalCta` still sends everyone to - the shop rather than to the pillar they came for. -- **`/vision` is now in the nav** (#381), but "Über uns" is overloaded at - 8 items, mixing identity, division pages, trust pages and a Zürich subsidy - programme. -- **"Dienstleistungen" splits pillars 3 and 5 across a Hardware/Software axis** - that maps to neither, and lists `Hardware-Recycling` as a peer of - `Reparatur` — recycling is a consequence, not a service headline. -- **Pillar 4 is buried**: `src/config/workshops.ts` already defines a - `retraining` category with real strings, rendered as one of ten equal filter - chips. No landing page, no nav entry, absent from `workshops.meta`. +- **`home.actions.*` is gone** (#385) along with the section it fed, so the + `sell`-key-on-a-buy-card drift went with it. `home.finalCta` now closes on + the thesis rather than the shop. +- **A German typo in production copy**: `getInvolved.itHilfeTechniker.description` + reads "kann anderen das Leben **leichtern**" (should be "erleichtern" or + "leichter machen"). +- **`/so-funktionierts` and `/reparaturbonus` left the nav** (#389) but both + pages remain. Reparaturbonus describes a City of Zürich subsidy evig does + not administer and, per the page's own FAQ, cannot redeem. Worth deciding + whether it earns its 445 lines. ### Correctness - **Workshop capacity** computed three ways; free registrations do not @@ -165,6 +213,19 @@ salvaging — some failures may now be different failures. - **CI green is not live.** Every merge here was re-probed against https://evig.orangecat.ch — which is how the stale divisions subtitle was caught, rendering under a heading that correctly read "3 Bereiche". +- **A cancelled deploy is not a failed deploy.** GitHub cancels an in-flight + deploy when a newer commit lands on main, and a watcher that only checks + "not success" reports a false alarm. Read `conclusion` and treat + `cancelled` as "superseded", then verify the NEXT run. +- **OPEN THE PAGES.** The third round found things no gate could see, only + because the site was loaded in a browser: two nav entries rendering + `<a href="">`, donation buttons pointing at another organisation's Ko-fi, + a 404 in the live FAQ, "16+ Jahre" on a two-year-old org, a wrapped price, + and three different causes of a doubled page title. Greps and typechecks + had all been green throughout. Budget a page walk per refocus. +- **Measure the output, don't reason about the framework.** Two of the three + doubled titles were missed by reasoning about Next's `title.template` + resolution and found by curling the rendered `<title>`. ## Repo state