Reports: translate user-facing copy to English
The site is English-only; the demo narrative, exec-summary headings,
agent drill-down captions, tests-overview blurb + table headers, and
all live-* page descriptions and unavailable-notes had been mixing
Dutch into rendered output. Translated everything that ends up in
front of a reader.
Touched:
src/c51_render_reports.ts
"tdd-discipline rapport" -> "tdd-discipline report"
"wat dit getal niet meet" -> "what this number does not measure"
"Top issue dit kwartaal" -> "Top issue this quarter"
"tests overzicht" -> "tests overview"
"huidige stand per repo" -> "current state per repo"
"hoe lees je dit" -> "how to read this"
Plus the surrounding paragraphs and the four bullets at the
bottom of the tests-overview page.
src/c21_app.ts
Demo narrative blocks (changedHeading/changedBody, doingHeading
/doingBody) - the "what changed this quarter" plus "what we are
doing" storyline that anchors the demo report. /reports/live/*
page titles, descriptions, and the tests-page period label plus
unavailable-note (added in the previous commit and carried Dutch
over from chat).
No behaviour change; rendered HTML differs only in copy.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2 files changed · +40 −40
src/c21_app.ts
+16
−16
| @@ -78,15 +78,15 @@ const demoContext = () => ({ | ||
| 78 | 78 | scopeLabel: `${DEMO_REPOS} repos · ${DEMO_ORG}`, |
| 79 | 79 | bannerHtml: DEMO_BANNER_HTML, |
| 80 | 80 | narrative: { |
| 81 | - changedHeading: "wat veranderde dit kwartaal", | |
| 81 | + changedHeading: "what changed this quarter", | |
| 82 | 82 | changedBody: |
| 83 | - "Cursor's score zakte 15 punten nadat agent-mode in maart default werd; test-deletion-incidenten stegen van 2% naar 14% van refactor-commits, geconcentreerd in de `api-gateway` repo. Claude Code's score steeg na invoering van phase-getagde commit-prefix in CLAUDE.md aan het einde van januari. Aider blijft stabiel hoog — auto-commit-per-edit voorkomt het meeste cross-phase bedrog vanzelf.", | |
| 84 | - doingHeading: "wat we doen", | |
| 83 | + "Cursor's score dropped 15 points after agent-mode became default in March; test-deletion incidents climbed from 2% to 14% of refactor commits, concentrated in the `api-gateway` repo. Claude Code's score rose after a phase-tagged commit prefix was added to CLAUDE.md at the end of January. Aider stays steadily high — auto-commit-per-edit prevents most cross-phase cheating on its own.", | |
| 84 | + doingHeading: "what we're doing", | |
| 85 | 85 | doingBody: |
| 86 | - "- **Cursor in `api-gateway`**: agent-mode gedeactiveerd voor refactor-prompts, CONVENTIONS-regel \"never delete a test in a refactor commit\" gepind ([details →](/reports/demo/agents/cursor)).\n- **Claude Code uitrollen**: het CLAUDE.md-template dat in `billing-service` werkte naar de andere drie repos kopiëren.\n- **Volgende meting**: 2026-04-30, mid-Q2, om te zien of de Cursor-fix vasthoudt.", | |
| 86 | + "- **Cursor in `api-gateway`**: agent-mode disabled for refactor prompts, CONVENTIONS rule \"never delete a test in a refactor commit\" pinned ([details →](/reports/demo/agents/cursor)).\n- **Roll out Claude Code**: copy the CLAUDE.md template that worked in `billing-service` to the other three repos.\n- **Next reading**: 2026-04-30, mid-Q2, to check whether the Cursor fix holds.", | |
| 87 | 87 | }, |
| 88 | 88 | footerLinks: |
| 89 | - "[per-agent drill-down: Claude Code](/reports/demo/agents/claude-code) · [Cursor](/reports/demo/agents/cursor) · [Aider](/reports/demo/agents/aider) · [tests overzicht](/reports/demo/tests) · [back to /reports](/reports)", | |
| 89 | + "[per-agent drill-down: Claude Code](/reports/demo/agents/claude-code) · [Cursor](/reports/demo/agents/cursor) · [Aider](/reports/demo/agents/aider) · [tests overview](/reports/demo/tests) · [back to /reports](/reports)", | |
| 90 | 90 | }); |
| 91 | 91 | |
| 92 | 92 | const liveContext = async () => { |
| @@ -102,7 +102,7 @@ const liveContext = async () => { | ||
| 102 | 102 | period, |
| 103 | 103 | scopeLabel: `${LIVE_REPO_OWNER}/${LIVE_REPO_NAME} · ${live.totalCommits} commits sampled${live.unknownCount > 0 ? ` (${live.unknownCount} unattributed, excluded)` : ""}`, |
| 104 | 104 | bannerHtml: LIVE_BANNER_HTML, |
| 105 | - footerLinks: `${drillLinks ? drillLinks + " · " : ""}[tests overzicht](/reports/live/tests) · [demo preview](/reports/demo) · [back to /reports](/reports)`, | |
| 105 | + footerLinks: `${drillLinks ? drillLinks + " · " : ""}[tests overview](/reports/live/tests) · [demo preview](/reports/demo) · [back to /reports](/reports)`, | |
| 106 | 106 | }; |
| 107 | 107 | }; |
| 108 | 108 | |
| @@ -476,7 +476,7 @@ ${rows} | ||
| 476 | 476 | "/reports/demo": async () => { |
| 477 | 477 | const ctx = demoContext(); |
| 478 | 478 | const html = await renderPage({ |
| 479 | - title: "TDD-discipline rapport · Q1 2026 (demo) — tdd.md", | |
| 479 | + title: "TDD-discipline report · Q1 2026 (demo) — tdd.md", | |
| 480 | 480 | description: "Mockup of the management-level TDD-discipline report — single page, three agents, with trend and narrative.", |
| 481 | 481 | bodyMarkdown: execSummaryMd(ctx), |
| 482 | 482 | ogPath: "https://tdd.md/reports/demo", |
| @@ -487,7 +487,7 @@ ${rows} | ||
| 487 | 487 | |
| 488 | 488 | "/reports/demo/tests": async () => { |
| 489 | 489 | const html = await renderPage({ |
| 490 | - title: "Tests overzicht (demo) — tdd.md", | |
| 490 | + title: "Tests overview (demo) — tdd.md", | |
| 491 | 491 | description: "Mockup of the per-test overview: current pass/fail snapshot per repo plus test stability over the quarter.", |
| 492 | 492 | bodyMarkdown: testsOverviewMd({ |
| 493 | 493 | period: DEMO_PERIOD, |
| @@ -523,8 +523,8 @@ ${rows} | ||
| 523 | 523 | "/reports/live": async () => { |
| 524 | 524 | const ctx = await liveContext(); |
| 525 | 525 | const html = await renderPage({ |
| 526 | - title: "TDD-discipline rapport · live — tdd.md", | |
| 527 | - description: `Live discipline rapport gebouwd uit de echte commit-historie van syntaxai/tdd.md (laatste ${LIVE_FETCH_COUNT} commits, 5-min cache).`, | |
| 526 | + title: "TDD-discipline report · live — tdd.md", | |
| 527 | + description: `Live discipline report built from the real commit history of syntaxai/tdd.md (last ${LIVE_FETCH_COUNT} commits, 5-min cache).`, | |
| 528 | 528 | bodyMarkdown: execSummaryMd(ctx), |
| 529 | 529 | ogPath: "https://tdd.md/reports/live", |
| 530 | 530 | noindex: true, |
| @@ -536,14 +536,14 @@ ${rows} | ||
| 536 | 536 | const data = await buildLiveTestData(LIVE_REPO_OWNER, LIVE_REPO_NAME); |
| 537 | 537 | const ranOn = data.ranAt ? new Date(data.ranAt).toISOString().slice(0, 10) : null; |
| 538 | 538 | const period = data.runsCount === 0 |
| 539 | - ? "geen runs in bundle" | |
| 540 | - : `last run ${ranOn} · ${data.runsCount} run${data.runsCount === 1 ? "" : "s"} cumulatief`; | |
| 539 | + ? "no runs in bundle" | |
| 540 | + : `last run ${ranOn} · ${data.runsCount} run${data.runsCount === 1 ? "" : "s"} cumulative`; | |
| 541 | 541 | const unavailableNote = data.runsCount === 0 |
| 542 | - ? "Nog geen test-runs gebundeld. De volgende deploy draait `bun test --reporter=junit` op de huidige HEAD en publiceert het resultaat hier. Stabiliteit (flaky %, deletion) bouwt zich op naarmate er meer runs in de bundle staan — de demo op [/reports/demo/tests](/reports/demo/tests) toont waar het naartoe groeit." | |
| 542 | + ? "No test runs bundled yet. The next deploy will run `bun test --reporter=junit` on the current HEAD and publish the result here. Stability (flaky %, deletion) builds up as more runs land in the bundle — the demo at [/reports/demo/tests](/reports/demo/tests) shows where this is heading." | |
| 543 | 543 | : undefined; |
| 544 | 544 | const html = await renderPage({ |
| 545 | - title: "Tests overzicht · live — tdd.md", | |
| 546 | - description: `Live test-snapshot van ${LIVE_REPO_OWNER}/${LIVE_REPO_NAME} — ${data.runsCount} run${data.runsCount === 1 ? "" : "s"} gebundeld.`, | |
| 545 | + title: "Tests overview · live — tdd.md", | |
| 546 | + description: `Live test snapshot of ${LIVE_REPO_OWNER}/${LIVE_REPO_NAME} — ${data.runsCount} run${data.runsCount === 1 ? "" : "s"} bundled.`, | |
| 547 | 547 | bodyMarkdown: testsOverviewMd({ |
| 548 | 548 | period, |
| 549 | 549 | bannerHtml: LIVE_BANNER_HTML, |
| @@ -567,7 +567,7 @@ ${rows} | ||
| 567 | 567 | const entry = ctx.reports.find((r) => r.slug === slug)!; |
| 568 | 568 | const html = await renderPage({ |
| 569 | 569 | title: `${entry.name} drill-down · live — tdd.md`, |
| 570 | - description: `Live drill-down voor ${entry.name} op syntaxai/tdd.md — trend, failure-mode breakdown, recent commits.`, | |
| 570 | + description: `Live drill-down for ${entry.name} on syntaxai/tdd.md — trend, failure-mode breakdown, recent commits.`, | |
| 571 | 571 | bodyMarkdown: md, |
| 572 | 572 | ogPath: `https://tdd.md/reports/live/agents/${slug}`, |
| 573 | 573 | noindex: true, |
src/c51_render_reports.ts
+24
−24
| @@ -121,7 +121,7 @@ const agentTagHtml = (slug: AgentReport["slug"]): string => { | ||
| 121 | 121 | |
| 122 | 122 | const stabilityRow = (s: TestStability): string => { |
| 123 | 123 | const cls = s.flagged ? "test-stab-row flagged" : "test-stab-row"; |
| 124 | - const warn = s.flagged ? ` <span class="test-stab-warn" title="test-deletion of weakening dit kwartaal">⚠</span>` : ""; | |
| 124 | + const warn = s.flagged ? ` <span class="test-stab-warn" title="test-deletion or weakening this quarter">⚠</span>` : ""; | |
| 125 | 125 | return `<tr class="${cls}"> |
| 126 | 126 | <td class="test-stab-name">${escape(s.test)}<div class="test-stab-repo">${escape(s.repo)}</div></td> |
| 127 | 127 | <td class="test-stab-num green">${s.pass}</td> |
| @@ -141,8 +141,8 @@ Two views of the same shape: | ||
| 141 | 141 | - **[/reports/demo](/reports/demo)** — the polished design preview with synthetic data for three agents and four repos. Useful for screenshots and showing the full failure-mode breakdown the live view can't compute yet. |
| 142 | 142 | |
| 143 | 143 | Drill-downs: |
| 144 | -- [live drill-down per agent](/reports/live/agents/claude-code) · [tests overzicht (live: placeholder)](/reports/live/tests) | |
| 145 | -- [demo drill-down per agent](/reports/demo/agents/cursor) · [tests overzicht (demo)](/reports/demo/tests) | |
| 144 | +- [live drill-down per agent](/reports/live/agents/claude-code) · [tests overview (live)](/reports/live/tests) | |
| 145 | +- [demo drill-down per agent](/reports/demo/agents/cursor) · [tests overview (demo)](/reports/demo/tests) | |
| 146 | 146 | |
| 147 | 147 | Want a real repo on this layer? [Register a project →](/projects) — drops \`.tdd-md.json\` at the repo root, onboards in seconds. Per-commit judging on tracked branches lands in a follow-up sliver; live reporting from the GitHub API already works for the dogfood case (the tdd.md repo itself). |
| 148 | 148 | |
| @@ -186,19 +186,19 @@ ${ctx.narrative.doingBody} | ||
| 186 | 186 | |
| 187 | 187 | ` |
| 188 | 188 | : ""; |
| 189 | - return `# tdd-discipline rapport · ${ctx.period} | |
| 189 | + return `# tdd-discipline report · ${ctx.period} | |
| 190 | 190 | |
| 191 | 191 | ${ctx.bannerHtml} |
| 192 | 192 | |
| 193 | -> **Periode** ${ctx.period} · **Scope** ${escape(ctx.scopeLabel)} · ${totalCommits.toLocaleString()} AI-toegeschreven commits. | |
| 193 | +> **Period** ${ctx.period} · **Scope** ${escape(ctx.scopeLabel)} · ${totalCommits.toLocaleString()} AI-attributed commits. | |
| 194 | 194 | |
| 195 | 195 | <div class="report-tiles"> |
| 196 | 196 | ${tiles} |
| 197 | 197 | </div> |
| 198 | 198 | |
| 199 | -${narrativeBlock}## wat dit getal *niet* meet | |
| 199 | +${narrativeBlock}## what this number does *not* measure | |
| 200 | 200 | |
| 201 | -Discipline, niet code-kwaliteit. Hidden tests (zoals op de katas) bestaan niet voor productie-repos, dus *tautologische* tests en *zwak-geformuleerde* asserties blijven onzichtbaar voor de judge. Dit cijfer zegt: "de agent volgt de TDD-cyclus eerlijk". Het zegt niets over of de tests die hij schrijft het juiste beweren. Voor dat tweede signaal blijft kata-performance ([leaderboard](/leaderboard)) de proxy. | |
| 201 | +Discipline, not code quality. Hidden tests (like the ones on the katas) don't exist for production repos, so *tautological* tests and *weakly-asserted* checks stay invisible to the judge. This number says: "the agent honours the TDD cycle". It says nothing about whether the tests it writes assert the right thing. For that second signal, kata performance ([leaderboard](/leaderboard)) remains the proxy. | |
| 202 | 202 | |
| 203 | 203 | --- |
| 204 | 204 | |
| @@ -226,9 +226,9 @@ export const agentDrilldownMd = ( | ||
| 226 | 226 | |
| 227 | 227 | ${ctx.bannerHtml} |
| 228 | 228 | |
| 229 | -> Discipline-score **${a.score} / 100** <span class="report-tile-trend ${arr.cls}">${arr.glyph} ${deltaStr}</span> over ${ctx.period}. ${a.commits.toLocaleString()} commits geanalyseerd, phase-coverage **${a.phaseCoveragePct}%**. | |
| 229 | +> Discipline score **${a.score} / 100** <span class="report-tile-trend ${arr.cls}">${arr.glyph} ${deltaStr}</span> over ${ctx.period}. ${a.commits.toLocaleString()} commits analysed, phase coverage **${a.phaseCoveragePct}%**. | |
| 230 | 230 | |
| 231 | -## trend (30 dagen) | |
| 231 | +## trend (30 days) | |
| 232 | 232 | |
| 233 | 233 | <div class="${arr.cls === "down" ? "red" : arr.cls === "up" ? "green" : "muted"}"> |
| 234 | 234 | ${sparkline(a.trend)} |
| @@ -240,7 +240,7 @@ ${streakBox(a)} | ||
| 240 | 240 | |
| 241 | 241 | ${bars(a.failureMix)} |
| 242 | 242 | |
| 243 | -Top issue dit kwartaal: **${escape(a.topIssueLabel)}** (${a.topIssuePct}% van commits). | |
| 243 | +Top issue this quarter: **${escape(a.topIssueLabel)}** (${a.topIssuePct}% of commits). | |
| 244 | 244 | |
| 245 | 245 | ## recent flagged |
| 246 | 246 | |
| @@ -261,7 +261,7 @@ ${ctx.footerLinks} | ||
| 261 | 261 | |
| 262 | 262 | export const testsOverviewMd = (ctx: TestsOverviewContext): string => { |
| 263 | 263 | if (ctx.unavailableNote) { |
| 264 | - return `# tests overzicht | |
| 264 | + return `# tests overview | |
| 265 | 265 | |
| 266 | 266 | ${ctx.bannerHtml} |
| 267 | 267 | |
| @@ -275,23 +275,23 @@ ${ctx.bannerHtml} | ||
| 275 | 275 | const failing = ctx.snapshots.reduce((s, r) => s + r.failing, 0); |
| 276 | 276 | const snapshots = ctx.snapshots.map(snapshotBlock).join("\n"); |
| 277 | 277 | const stabRows = ctx.stability.map(stabilityRow).join("\n"); |
| 278 | - return `# tests overzicht | |
| 278 | + return `# tests overview | |
| 279 | 279 | |
| 280 | 280 | ${ctx.bannerHtml} |
| 281 | 281 | |
| 282 | -> Snapshot van de huidige test-stand per repo + stabiliteit van individuele tests over ${ctx.period}. Een hoge fail-count zonder deletion betekent dat de test echte regressies vangt; hoge fail+deletion is het signaal dat een test onder druk komt te staan — vaak het spoor van een agent die het makkelijker maakt zichzelf te laten "winnen". | |
| 282 | +> Snapshot of the current test state per repo + stability of individual tests over ${ctx.period}. A high fail count with zero deletions means the test is actively catching regressions; high fail + deletion is the signal that a test is being squeezed — often the trace of an agent making it easier to "win". | |
| 283 | 283 | |
| 284 | -## huidige stand · per repo | |
| 284 | +## current state · per repo | |
| 285 | 285 | |
| 286 | 286 | <div class="test-snapshots"> |
| 287 | 287 | ${snapshots} |
| 288 | 288 | </div> |
| 289 | 289 | |
| 290 | -**Totaal**: ${total.toLocaleString()} tests · <span class="green">${passing.toLocaleString()} passing</span> · <span class="${failing > 0 ? "red" : "muted"}">${failing.toLocaleString()} failing</span>. | |
| 290 | +**Total**: ${total.toLocaleString()} tests · <span class="green">${passing.toLocaleString()} passing</span> · <span class="${failing > 0 ? "red" : "muted"}">${failing.toLocaleString()} failing</span>. | |
| 291 | 291 | |
| 292 | -## test-stabiliteit · q1 2026 | |
| 292 | +## test stability · ${ctx.period} | |
| 293 | 293 | |
| 294 | -Top 12 meest-flappende tests dit kwartaal, met aantal pass/fail/deleted-events en de agent die de test het laatst heeft gebroken. | |
| 294 | +Top tests by failure activity this period, with pass/fail/deleted counts and the agent who last broke the test. | |
| 295 | 295 | |
| 296 | 296 | <table class="test-stability"> |
| 297 | 297 | <thead> |
| @@ -300,7 +300,7 @@ Top 12 meest-flappende tests dit kwartaal, met aantal pass/fail/deleted-events e | ||
| 300 | 300 | <th class="num">pass</th> |
| 301 | 301 | <th class="num">fail</th> |
| 302 | 302 | <th class="num">del</th> |
| 303 | - <th>laatst gebroken door</th> | |
| 303 | + <th>last broken by</th> | |
| 304 | 304 | </tr> |
| 305 | 305 | </thead> |
| 306 | 306 | <tbody> |
| @@ -308,14 +308,14 @@ ${stabRows} | ||
| 308 | 308 | </tbody> |
| 309 | 309 | </table> |
| 310 | 310 | |
| 311 | -> ⚠ markeert tests waarbij dit kwartaal een test-deletion of weakening-event is gedetecteerd. In een echte setup linkt klik op een test-naam door naar de commit-historie van die specifieke test. | |
| 311 | +> ⚠ marks tests where a test-deletion or weakening event has been detected this period. In a real setup, clicking a test name will link through to that test's commit history. | |
| 312 | 312 | |
| 313 | -## hoe lees je dit | |
| 313 | +## how to read this | |
| 314 | 314 | |
| 315 | -- **Veel pass, weinig fail, 0 del**: gezond. Test doet wat hij moet, niemand sloopt 'm. | |
| 316 | -- **Veel fail, 0 del**: test vangt actief regressies. Goed nieuws — discipline werkt. | |
| 317 | -- **Fail én del > 0**: test wordt onder druk gezet. Coach de agent die 'm gebroken heeft (klik op het tag-icoon). | |
| 318 | -- **Snapshot rood + stabiliteit hoog**: bekende, langlopende kapotte test. Apart onderwerp, niet per se een agent-probleem. | |
| 315 | +- **Lots of pass, few fail, 0 del**: healthy. The test does what it should, nobody is sabotaging it. | |
| 316 | +- **Lots of fail, 0 del**: the test is actively catching regressions. Good news — discipline is working. | |
| 317 | +- **Fail and del > 0**: the test is under pressure. Coach the agent that broke it (click the tag icon). | |
| 318 | +- **Snapshot red + stability high**: a known, long-running broken test. Separate concern, not necessarily an agent problem. | |
| 319 | 319 | |
| 320 | 320 | --- |
| 321 | 321 | |