Skip to content

fix(platform-objects): restore the declared title on the System Overview by-action table and pin the default-locale bundle to the source - #8767

Merged
hotlong merged 3 commits into
mainfrom
claude/issue-8721-widget-recent-events-title-parity
Aug 14, 2026
Merged

fix(platform-objects): restore the declared title on the System Overview by-action table and pin the default-locale bundle to the source#8767
hotlong merged 3 commits into
mainfrom
claude/issue-8721-widget-recent-events-title-parity

Conversation

@hotlong

@hotlong hotlong commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Fixes #8721

widget_recent_events was converted into an ADR-0021 single-form — a dataset-bound breakdown of sys_audit_log events by action — but all four hand-authored locale bundles kept serving the title the widget had before that conversion. The translation is what renders, so the declared string reached nobody in any locale. Its description had drifted the same way, one field over.

What changed

1. The four stale bundle values. Leaf-value edits only — this half is hand-authored and regenerating it would delete roughly 40 runtime-contributed nav translations per locale (scripts/i18n-extract.config.ts documents why).

locale was now
en Recent Audit Events Event Volume by Action
zh-CN 最近审计事件 按操作统计的事件量
ja-JP 最近の監査イベント アクション別イベント件数
es-ES Eventos de Auditoría Recientes Volumen de Eventos por Acción

2. The duplicate the stale translation was hiding. With the source string restored, the board carried the same label twice: widget_events_by_type (a pie) and widget_recent_events (a table) both declared Audit Events by Action, over the same dataset and the same dimension. They looked distinct in a running instance only because one of them was serving a stale translation — so the duplicate was invisible in the UI and visible only in the source.

The pair now splits on what each one adds: the pie keeps Audit Events by Action (the share picture), the table becomes Event Volume by Action (the exact per-action count, which is what its values: ['event_count'] produces and what its description already said). The pie is left untouched deliberately, so this PR does not re-translate three bundles' worth of strings that were never stale. All nine widget titles on the board are now distinct, in all four locales.

Widget ids are unchanged, so no translation key, persisted widget state or dataset binding moves.

3. The gate that would have caught it. Every pre-existing claim over this half is a key-set claim — app-nav-translation-parity.test.ts asserts a translation exists and does not outlive its declaration, check:i18n-coverage ratchets untranslated labels, check:app-nav-i18n judges the merged nav tree. A key whose value is stale satisfies all of them.

That test now also asserts the default locale's content: every statically declared app label, description and nav label, plus the dashboard's label, description and every widget title/description, must appear in en.ts verbatim. The claim is available for en alone because en is a copy of the source rather than a translation of it — the same invariant the generated half of this package's i18n already enforces by rewriting its en bundle on every extract.

Positive control — the assertion is shown to fail

An assertion that cannot fail is worse than none, so it was broken three ways at the committed state and restored from the commit each time (never git stash):

mutation result
en.ts widget title dragged back to Recent Audit Events RED on dashboards.system_overview.widgets.widget_recent_events.title
the source moved instead (widget_events_by_user.description) RED on that path — the claim is symmetric, not one-sided
an en.ts app nav label suffixed with (stale) RED on apps.account.navigation.grp_account_inbox.label

Each run reported 1 failed, 23 passed: the 23 pre-existing key-set claims stayed green under every stale value, which is exactly the blindness this card was filed for, reproduced and then caught.

Verification

Gate union re-run after the final commit, at aefb22fe5 — all green:

platform-objects test (20 files, 380 tests) and typecheck; check:i18n, check:i18n-coverage, check:app-nav-i18n; check:changeset-gate-self-tests, check:objectui-changeset, check-adr-0087-registration, check-changeset-no-major, check-empty-changeset; check:query-options-erasure; check:nul-bytes; check:type-check-coverage and the check:type-check-debt ratchet over the built closure — this package's tsconfig.json excludes **/*.test.ts, so the new test code's types are verified by that re-measure (it lifts the exclusion) rather than by pnpm typecheck, and its exact TEST_DEBT of 3 is unmoved.

Deliberately not done here

Stale-marking for translated locales when a source string changes — a product decision on what a stale translation should do, excluded by this card's triage fence. Filed as #8765 rather than designed here, with the observation that pinning en sharpens the asymmetry rather than reducing it: the drift stops being uniform across four bundles and becomes locale-specific, invisible to any reviewer reading the product in English.

Also filed: #8764 — the pages.* third of these bundles mirrors page metadata authored in other packages, so it is outside this walk in every locale including en. Nothing is stale there today; the two deliberate gaps are now cross-referenced from the test's own comments instead of being argued and tracked nowhere.

Neither is addressed in this PR.


Generated by Claude Code

claude added 3 commits August 14, 2026 19:46
…iew by-action table and pin the default-locale bundle to the source (#8721)

`widget_recent_events` became an ADR-0021 dataset-bound breakdown of audit
events by action, but all four hand-authored locale bundles kept the
pre-conversion title (`Recent Audit Events` and its three translations). The
translation is what renders, so the declared string reached nobody in any
locale; the widget's `description` had drifted the same way.

Restoring the source string exposed the duplicate it was masking: the Row 3 pie
(`widget_events_by_type`) and this table both declared `Audit Events by Action`
over the same dataset and dimension. The pie keeps the broad name (the share
picture); the table becomes `Event Volume by Action` — the exact per-action
count its `values: ['event_count']` produces, which is what its description
already said. Widget ids are untouched, so no translation key or persisted
widget state moves.

- correct `widget_recent_events` title + description in en / zh-CN / ja-JP /
  es-ES (leaf values only — this half is hand-authored and regenerating it
  would delete the runtime-contributed nav translations)
- add the default-locale content-parity assertion to
  `app-nav-translation-parity.test.ts`: every declared app label/description,
  statically declared nav label, dashboard label/description and widget
  title/description must appear in `en.ts` verbatim. Every pre-existing claim
  in that file is a key-set claim, which a stale value satisfies.
- stale-marking for TRANSLATED locales when a source string changes is
  deliberately not designed here — it needs a product decision on what a stale
  translation should do.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XeQRiAa7vYRVX5Fog7Zby8
… tracking issues (#8721)

The default-locale content check documents two gaps it does not close: the
`pages.*` section (sources live in @objectstack/cloud-connection and
@objectstack/mcp, which this package must not import) and the translated
locales (what a stale translation should do is a product decision). Both were
argued in the comments and tracked nowhere.

- `pages.*` gap -> #8764, with the note that it is unguarded in EVERY locale
  including `en`, and that `check:app-nav-i18n` is the gate that can see it
- translated-locale gap -> #8765, with the consequence pinning `en` has on it:
  the drift stops being uniform across four bundles and becomes locale-specific

Comment-only; no assertion changes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XeQRiAa7vYRVX5Fog7Zby8
@vercel

vercel Bot commented Aug 14, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 14, 2026 9:28pm

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/platform-objects.

2 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/plugins/packages.mdx (via @objectstack/platform-objects)
  • content/docs/ui/setup-app.mdx (via @objectstack/platform-objects)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

2 participants