Repository navigation
fix(plugin-audit): the generic activity entry for an update names the fields that changed - #25958
Conversation
…hanged An update that moves no `trackHistory` field and fires no milestone wrote `Updated <object> "<label>"` and nothing else, so a record a rollup or flow bumps repeatedly showed a wall of identical feed entries. The fallback now names the changed fields by label (never their values) — at most five, the rest counted — and names fewer when the text would exceed the `sys_activity.summary` bound. Every field it names or counts is declared as a summary source, so the read-side field redaction still applies. Claude-Session: https://claude.ai/code/session_0166WnEHW3hURHjBf9cLK32f Co-authored-by: Claude <noreply@anthropic.com>
The untracked-change fallback names the fields that changed, in declaration order, never their values; at most five are named and the rest counted; the text stays inside the declared `sys_activity.summary` bound; every named or counted field is declared as a summary source; zh-CN localizes the list. Claude-Session: https://claude.ai/code/session_0166WnEHW3hURHjBf9cLK32f Co-authored-by: Claude <noreply@anthropic.com>
…ps it An app-shipped locale bundle that defines `messages.activityUpdated` but not the new `messages.activityUpdatedFields` would have been handed an English named-field sentence; it keeps its own localized field-less one. Adds the patch changeset. Claude-Session: https://claude.ai/code/session_0166WnEHW3hURHjBf9cLK32f Co-authored-by: Claude <noreply@anthropic.com>
… lib Claude-Session: https://claude.ai/code/session_0166WnEHW3hURHjBf9cLK32f Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 1 package(s): 5 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 4 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 10 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin bbf5d5ab0f5a15125f66b8c57a5ff4c84a4b2227 && git checkout bbf5d5ab0f5a15125f66b8c57a5ff4c84a4b2227
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin d65cbb61bdea303f4f414e76fdf747b448f3a9af cebc2d010b94c16dcc4e11e1ad2047e46a9f6869 && git checkout -B drift-repro d65cbb61bdea303f4f414e76fdf747b448f3a9af && git merge --no-ff cebc2d010b94c16dcc4e11e1ad2047e46a9f6869
node scripts/docs-audit/affected-docs.mjs --json d65cbb61bdea303f4f414e76fdf747b448f3a9af
|
席位核对ACCEPT ·
Generated by Claude Code |
Requested by Elon · project thread
Fixes #25787
Clause-②: no
Metadata-protocol: none
What changed
The activity mirror in
plugin-audit(audit-writers.ts, ADR-0052 §5b) writes an update entry in one of three shapes: a fired milestone's sentence, atrackHistorydiff (Stage: Proposal → Closed Won), or a generic fallback. The fallback saidUpdated OBJECT "LABEL"and nothing else. On HotCRM 18.1.0 the campaign roll-up counters (num_sent,num_responses, … — plainnumberfields, none tracked, bumped once per enrolled member bycampaign_member.hook.ts) produced thirteen identical entries in a row.The fallback now names the changed fields by label, in declaration order:
Updated Campaign "CPG-0001": Number Sent, Responses, and LeadstrackHistorystill decides whether old → new VALUES are rendered; an untracked field's value (or a credential's) never reaches the text. The ADR-0052 §5b.1 opt-in is unchanged.…, Field 5, and 3 more). Whensys_activity.summarydeclaresmaxLength(500 today; the SQL driver sizes the columnvarchar(500)from it, so an over-long text fails the whole activity insert), fewer fields are named until the text fits; if not even one name fits, the field-less frame is written as before.text_sources.summary), soactivity-field-redaction.tsdrops the summary for a reader not served one of them, exactly as for a tracked-change summary.translations/messages.ts):messages.activityUpdatedFields(frame with{{fields}}) andmessages.activityMoreFields({{count}} more). The list is joined withIntl.ListFormatin the frame's locale (zh-CN:F1、F2、F3、F4、F5和另外 2 个字段). A locale bundle that has only the oldermessages.activityUpdated(an app-shipped locale) keeps its own field-less sentence rather than an English one.metadata.old/new,changed_fields.Folding consecutive same-actor entries is the renderer's half (objectui) and is not in this PR; #25787's triage routes it to its own card.
Evidence
audit-writers.test.tsrun againstorigin/main2a728ba2'saudit-writers.ts+messages.ts(restored into the tree, thengit checkout HEAD --back;git diff HEAD0 bytes after):Tests 8 failed | 108 passed (116). With the fix: all pass.pnpm --filter @objectstack/plugin-audit test:Test Files 60 passed (60),Tests 993 passed (993)(before the last two commits;audit-writers.test.tsre-run at head: 117 passed).pnpm --filter @objectstack/plugin-audit typecheck: exit 0.secret) in the text; source declaration; five-name cap with count; 40 long labels under a declared 500 bound (length at most 500, count still present); field-less frame when nothing fits; zh-CN list; an app locale with onlyactivityUpdatedkeeps its sentence.audit-milestone-summary.test.tsandaudit-option-label-summary.test.tspass unchanged.Gates (local subset, at head
cebc2d01)pnpm --filter @objectstack/plugin-audit testatcebc2d01:Test Files 60 passed (60),Tests 993 passed (993);pnpm --filter @objectstack/plugin-audit typecheck: exit 0.node scripts/pm/dispatch-gates.mjs --commands(72 families, merge base2a728ba2a), reconciled with--ran: 71 run, all exit 0; 1 NOT MEASURED:pnpm check:dual-build-cjs-loads(exit 3, needs a whole-tree build; CI's lint lane owns it).check:i18nwas run after its declared CLI closure build (10 packages in sync,plugins/plugin-audit7 bundles);check-plugin-teardown-shape --self-testafter fetching its pinned fixture commit.check:commit-card-trailers --range origin/main..HEAD: 4 commits clean.check:nul-bytes: exit 0.origin/mainmoved 5 commits since the base; none touchespackages/plugins/plugin-audit, so no merge was taken.Acceptance notes
formula,summary,rollup,autonumber) writes no activity row at all:diff()drops those types and the writer returns on an empty diff. Unchanged here, noted by the seat on the claim.trackHistorydiff of long values is unbounded too; both predate this PR. Not measured against a SQL driver here.Generated by Claude Code