docs(pwa): adopt Carol's voice in user-facing copy (#145) #173

Merged
james merged 1 commit from 145-voice-rewrite into main 2026-06-20 04:08:35 +00:00
Owner

Closes #145.

Dependency order note: the i18n migration (#146) landed first, so this PR touches messages/en.json directly — no JSX edits except wiring the previously-hardcoded aria-label="Main" on SidebarNav to a new nav.primaryAria key.

Summary

Rewrite user-facing strings to match ../carol-design/design_system_readme.mdCONTENT FUNDAMENTALS:

  1. First person. Carol speaks as "I"; system feedback stays neutral.
  2. Sentence case everywhere.
  3. Lead with the takeaway, then the detail.
  4. No emoji.

String changes

  • notes.lede: drop the dev-doc "Reference surface for the TanStack Query + Form + Table pattern (ADR-0012)" — replaced with a real Notes blurb. createTitle, empty also rewritten.
  • chat.blurb: third-person "she reviews" → first-person "I'll review"; drop the "conversational home of the product" trailer.
  • applications.blurb: "Carol's notes" → "my notes"; drop "command center" hyperbole.
  • projects.blurb: tighten phrasing.
  • network.blurb: clearer "how you met / keep in touch" phrasing.
  • offline.body: third-person "Carol can't reach its server" → first-person "I can't reach my server".
  • profile.picture.viewHint: third-person "Shown across Carol" → first-person "Used on your profile and when you chat with me".
  • account.tokens.blurb + screen.lede: re-cast in Carol's voice ("Let external agents act as you"). Drop the decorative "→" arrow from tokens.manage now that the button supplies its own affordance.
  • skills.lede: drop the dev-doc parenthetical, tighten the wording.

Other

  • Add nav.primaryAria ("Primary") and wire SidebarNav to it. That was the only hardcoded English string left in the (app) tree.
  • CLAUDE.md gets a new Conventions bullet linking the design guide as the canonical voice reference, with the four rules inline and the out-of-scope list (marketing on /, docs/*, ADRs, API error JSON, /dev/components).

Audit results

  • messages/en.json Title-Case scan after rewrite: 0 hits (excluding proper nouns).
  • grep -i "click here" across app/ + messages/: 0 hits.
  • Emoji codepoint sweep (U+1F300–U+1FAFF, U+2600–U+27BF) over messages/en.json: 0 hits.

Test plan

  • npm run lint / npx tsc --noEmit / npm test all clean (440 passed).
  • Spot-checked rendered HTML on /chat, /skills, /notes, /account/tokens — new strings appear in the rendered DOM.

🤖 Generated with Claude Code

Closes #145. **Dependency order note:** the i18n migration (#146) landed first, so this PR touches `messages/en.json` directly — no JSX edits except wiring the previously-hardcoded `aria-label="Main"` on `SidebarNav` to a new `nav.primaryAria` key. ## Summary Rewrite user-facing strings to match `../carol-design/design_system_readme.md` → _CONTENT FUNDAMENTALS_: 1. **First person.** Carol speaks as "I"; system feedback stays neutral. 2. **Sentence case everywhere.** 3. **Lead with the takeaway**, then the detail. 4. **No emoji.** ### String changes - `notes.lede`: drop the dev-doc "Reference surface for the TanStack Query + Form + Table pattern (ADR-0012)" — replaced with a real Notes blurb. `createTitle`, `empty` also rewritten. - `chat.blurb`: third-person "she reviews" → first-person "I'll review"; drop the "conversational home of the product" trailer. - `applications.blurb`: "Carol's notes" → "my notes"; drop "command center" hyperbole. - `projects.blurb`: tighten phrasing. - `network.blurb`: clearer "how you met / keep in touch" phrasing. - `offline.body`: third-person "Carol can't reach its server" → first-person "I can't reach my server". - `profile.picture.viewHint`: third-person "Shown across Carol" → first-person "Used on your profile and when you chat with me". - `account.tokens.blurb` + `screen.lede`: re-cast in Carol's voice ("Let external agents act as you"). Drop the decorative "→" arrow from `tokens.manage` now that the button supplies its own affordance. - `skills.lede`: drop the dev-doc parenthetical, tighten the wording. ### Other - Add `nav.primaryAria` ("Primary") and wire `SidebarNav` to it. That was the only hardcoded English string left in the `(app)` tree. - `CLAUDE.md` gets a new Conventions bullet linking the design guide as the canonical voice reference, with the four rules inline and the out-of-scope list (marketing on `/`, `docs/*`, ADRs, API error JSON, `/dev/components`). ### Audit results - `messages/en.json` Title-Case scan after rewrite: 0 hits (excluding proper nouns). - `grep -i "click here"` across `app/` + `messages/`: 0 hits. - Emoji codepoint sweep (U+1F300–U+1FAFF, U+2600–U+27BF) over `messages/en.json`: 0 hits. ## Test plan - [x] `npm run lint` / `npx tsc --noEmit` / `npm test` all clean (440 passed). - [x] Spot-checked rendered HTML on `/chat`, `/skills`, `/notes`, `/account/tokens` — new strings appear in the rendered DOM. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
docs(pwa): adopt Carol's voice in user-facing copy (#145)
Some checks failed
Commits / Conventional Commits (pull_request) Successful in 9s
PR / OSV-Scanner (pull_request) Successful in 26s
PR / Static analysis (pull_request) Successful in 39s
PR / Trivy (image) (pull_request) Failing after 1m0s
PR / Package age policy (soft) (pull_request) Successful in 18s
Secrets / gitleaks (pull_request) Successful in 14s
PR / Test (sqlite) (pull_request) Successful in 4m0s
PR / Typecheck (pull_request) Successful in 4m3s
PR / npm audit (pull_request) Successful in 4m6s
PR / Lint (pull_request) Successful in 4m20s
PR / Test (postgres) (pull_request) Successful in 4m56s
PR / Coverage (soft) (pull_request) Successful in 4m22s
PR / Build (pull_request) Successful in 5m12s
8ab67c5ba0
Rewrite the user-facing strings in messages/en.json to match the
design system's voice guide (../carol-design/design_system_readme.md
→ CONTENT FUNDAMENTALS). Carol now speaks first-person where she
addresses the user; sentence-case holds everywhere it already did;
the dev-doc ledes are replaced with feature copy that actually
helps a user understand the surface.

Changes:
- notes.lede: replace the TanStack reference with a real Notes
  blurb; createTitle "Create note" → "Add a note"; empty state
  rewritten too.
- chat.blurb: third-person "she reviews" → first-person "I'll
  review"; drop the dev-doc "conversational home of the product"
  trailer.
- applications.blurb: "Carol's notes" → "my notes"; drop "command
  center" hyperbole.
- projects.blurb: tighten phrasing, drop word-on-word "projects".
- network.blurb: clearer "how you met / keep in touch" phrasing.
- offline.body: third-person "Carol can't reach its server" →
  first-person "I can't reach my server".
- profile.picture.viewHint: third-person "Shown across Carol" →
  first-person "Used on your profile and when you chat with me".
- account.tokens.blurb + screen.lede: re-cast in Carol's voice
  ("Let external agents act as you"); drop decorative "→" from
  account.tokens.manage now that the button supplies its own
  affordance.
- skills.lede: drop the dev-doc parenthetical and tighten.

Add the missing nav.primaryAria key and wire SidebarNav to it so
the sidebar's aria-label is no longer the only hardcoded English
string in the (app) tree.

CLAUDE.md gets a new Conventions bullet that links the design
guide as the canonical voice reference and summarises the four
rules — first person, sentence case, lead with the takeaway, no
emoji — plus the out-of-scope list (marketing on /, docs, ADRs,
API errors, /dev/components).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Trivy (container image)

Threshold: high  ·  Total findings: 121  ·  At/above threshold: 1

critical high medium low
0 1 50 70
severity id package installed / range fix
high CVE-2026-12151 undici 6.25.0 6.27.0, 7.28.0, 8.5.0
<!-- scanner-comment: trivy --> ### Trivy (container image) **Threshold:** `high` &nbsp;·&nbsp; **Total findings:** 121 &nbsp;·&nbsp; **At/above threshold:** 1 | critical | high | medium | low | |---:|---:|---:|---:| | 0 | 1 | 50 | 70 | | severity | id | package | installed / range | fix | |---|---|---|---|---| | high | [CVE-2026-12151](https://avd.aquasec.com/nvd/cve-2026-12151) | undici | 6.25.0 | `6.27.0, 7.28.0, 8.5.0` |

📊 Test coverage

Patch coverage: 0.0% (0/1 added lines) ⚠️ (soft target ≥ 80%)

Overall (app/, lib/, db/, excluding UI per ADR-0019):

Metric Value Soft target
Lines 75.3% ≥ 50%
Branches 80.8% ≥ 75%
Functions 88.2% informational

Changed files in this PR (source only — tests excluded):

File Patch coverage Overall lines Branches
app/(app)/components/sidebar-nav.tsx 0.0% (0/1) 0.0% 0.0%

Soft thresholds per ADR-0019. Coverage is informational and does not block merge.

<!-- coverage-comment --> ## 📊 Test coverage **Patch coverage:** 0.0% (0/1 added lines) ⚠️ *(soft target ≥ 80%)* **Overall** (`app/`, `lib/`, `db/`, excluding UI per ADR-0019): | Metric | Value | Soft target | |---|---|---| | Lines | 75.3% ✅ | ≥ 50% | | Branches | 80.8% ✅ | ≥ 75% | | Functions | 88.2% | informational | **Changed files in this PR** (source only — tests excluded): | File | Patch coverage | Overall lines | Branches | |---|---|---|---| | `app/(app)/components/sidebar-nav.tsx` | 0.0% (0/1) | 0.0% | 0.0% | Soft thresholds per [ADR-0019](docs/adr/0019-coverage-soft-targets.md). Coverage is informational and does not block merge.
james merged commit 3eaa296527 into main 2026-06-20 04:08:35 +00:00
james deleted branch 145-voice-rewrite 2026-06-20 04:08:35 +00:00
Sign in to join this conversation.
No description provided.