Skip to content

Commit e6e8aa0

Browse files
committed
chore(changeset): platform-objects patch for the permission_change tile removal
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeQRiAa7vYRVX5Fog7Zby8
1 parent 783f714 commit e6e8aa0

1 file changed

Lines changed: 61 additions & 0 deletions

File tree

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
---
2+
"@objectstack/platform-objects": patch
3+
---
4+
5+
fix(platform-objects): remove the System Overview board's permanently-empty "Permission Changes" tile (#8148, #7675)
6+
7+
<!-- adr-0087: not-required (no-migration-prescription) A widget is removed from
8+
a platform-shipped dashboard, and four hand-authored locale bundles drop the
9+
matching `dashboards.system_overview.widgets.widget_permission_changes` subtree.
10+
No authorable KEY changes: `DashboardWidgetSchema` is untouched, nothing is
11+
renamed or tombstoned, and the retirement of the `sys_audit_log.action` VALUE
12+
this tile filtered was registered by #8147 as a SEMANTIC entry
13+
(`17.audit-log-action-enum-retired`). This change is the UI half of that already
14+
registered retirement, so it prescribes no migration of its own. -->
15+
16+
The System Overview dashboard shipped a "Permission Changes" metric tile
17+
filtering `sys_audit_log.action = 'permission_change'`. **The tile could never
18+
report anything but `0`, on any deployment that has ever existed** — the value
19+
had no writer anywhere in the repo. There are exactly two `sys_audit_log`
20+
writers: `plugin-audit`'s generic hook writer, whose `actionFor` maps
21+
afterInsert/afterUpdate/afterDelete to `create`/`update`/`delete` and nothing
22+
else, and `plugin-auth`'s admin user-import. Neither has ever emitted
23+
`permission_change`. #8147 then retired the value from the action enum outright,
24+
so the tile's filter now names a value the platform does not even declare.
25+
26+
**An empty tile on a compliance surface is worse than a missing one.** A
27+
permanently-`0` "Permission Changes" count does not read as "this platform does
28+
not track permission changes" — it reads as a *negative finding*: an auditor
29+
concludes the platform watched for permission changes over the selected window
30+
and found none. The number was live and the query was real; the question it
31+
answered was one no row could ever be an answer to. 审计面宁窄勿谎 — a narrow
32+
audit surface beats a lying one.
33+
34+
**Removed rather than refiltered onto a live action.** Permission and role edits
35+
*are* captured today, as ordinary `create` / `update` rows written by the generic
36+
hook against the permission objects — so the honest lens on them is `object_name`
37+
on the audit list view, a row-level question rather than a single-number KPI.
38+
Approximating one as a tile would have put a second not-quite-true number on the
39+
same board. The two surviving Row 2 tiles ("Login Events", "Config Changes")
40+
split the 12-column row in half instead of leaving a gap where the removed tile
41+
sat.
42+
43+
The by-action tile's description stops naming `permission` among its example
44+
actions, in the source **and in all four locale bundles** — the translations are
45+
the strings actually served, so correcting only the source would not have reached
46+
a single user.
47+
48+
⚠️ **`import` is deliberately untouched.** It was named in the same ruling as
49+
`permission_change`, but its retirement premise was falsified during #8147: it
50+
has a live writer (`plugin-auth`'s admin user-import writes a run-level row) and
51+
a shipped list view that filters it. Removing it from the dashboard while the
52+
platform still emits it would produce the exact inverse defect — an audit action
53+
that can be written but cannot be found.
54+
55+
Both directions are pinned. A tombstone refuses any board widget filtering a
56+
retired action value, with a live-action control so it cannot pass on a board
57+
that has no widgets or whose predicates moved. The app/dashboard translation
58+
parity test gains the **reverse direction it was missing** for dashboard widgets
59+
— it asserted every declared widget has a translation, but nothing stopped a
60+
translation outliving its widget, which is precisely what these four locale
61+
entries would have done.

0 commit comments

Comments
 (0)