Found while executing the 2026-08-24 ruling on #11507 (declaration half, domain:services lane). Filed unassigned — not touched there, because the fix is a packages/spec change and that is another seat's call (fences on that card: no packages/spec/**, no objectui).
What was measured
packages/spec/src/ui/component.zod.ts:1088 — RecordActivityProps:
types: z.array(FeedItemType).optional().describe('Feed item types to show (default: all)'),FeedItemType (packages/spec/src/data/feed.zod.ts:20) is a closed z.enum of 13 UI kinds (comment, field_change, task, event, email, call, note, file, record_create, record_delete, approval, sharing, system). It is the vocabulary the renderer maps sys_activity.typeonto: objectui's packages/plugin-detail/src/renderers/recordActivityFeed.ts keys its feed-kind map on the activity type and emits a FeedItemType.
The maintainer ruled on 2026-08-24 (#11507, direction 4) that sys_activity.type is an open, author-extensible vocabulary — the declared options are the platform built-in set, ADR-0052 §5b.2 stays a sanctioned author write path — and, verbatim: "every closed map over this vocabulary is now the bug".
This is that closed map one level removed, and it is authorable surface, not just renderer internals: an author who contributes an activity type (say scheduled, which hotcrm writes today) cannot name it in types: [...]. The best the renderer can do is fold it into some built-in kind, at which point the filter cannot separate it from the rows that genuinely are that kind.
Why it is filed separately rather than fixed in the #11507 PR
Options, unranked — this needs the spec seat's judgement, not mine
- Leave
types closed and document it as "built-in kinds only" — cheapest, and honest only if authors genuinely never need to filter on their own kinds. - Widen the element type to
z.union([FeedItemType, z.string()]) (or a branded open string) so an author-contributed kind is nameable — the shape the ruling's logic points at, at the cost of losing the named rejection on a typo'd built-in. - Keep the closed enum but declare a documented
other/fallback member so unknown source types have a nameable bucket.
Not measured
Refs: #11507 (the ruling) · ADR-0052 §5b.2 (the author write path) · objectstack-ai/objectui#5840
Found while executing the 2026-08-24 ruling on #11507 (declaration half,
domain:serviceslane). Filed unassigned — not touched there, because the fix is apackages/specchange and that is another seat's call (fences on that card: nopackages/spec/**, no objectui).What was measured
packages/spec/src/ui/component.zod.ts:1088—RecordActivityProps:FeedItemType(packages/spec/src/data/feed.zod.ts:20) is a closedz.enumof 13 UI kinds (comment,field_change,task,event,email,call,note,file,record_create,record_delete,approval,sharing,system). It is the vocabulary the renderer mapssys_activity.typeonto: objectui'spackages/plugin-detail/src/renderers/recordActivityFeed.tskeys its feed-kind map on the activity type and emits aFeedItemType.The maintainer ruled on 2026-08-24 (#11507, direction 4) that
sys_activity.typeis an open, author-extensible vocabulary — the declared options are the platform built-in set, ADR-0052 §5b.2 stays a sanctioned author write path — and, verbatim: "every closed map over this vocabulary is now the bug".This is that closed map one level removed, and it is authorable surface, not just renderer internals: an author who contributes an activity type (say
scheduled, which hotcrm writes today) cannot name it intypes: [...]. The best the renderer can do is fold it into some built-in kind, at which point the filter cannot separate it from the rows that genuinely are that kind.Why it is filed separately rather than fixed in the #11507 PR
sys_activity.typea closed platform vocabulary or an author-extensible one? Both readings are true of the code today #11507) lives in@objectstack/plugin-auditand is deliberately fenced out ofpackages/spec— split precedent/api/v1/analytics/querystill drops per-measure and dataset-levelfilteron the ObjectQL path —engine.aggregatereceives no filter at all #10413 → engine.aggregate: add per-aggregation filter to the contract — ruled half of #10413 (measure-level filters on the ObjectQL analytics path) #10576, Should a definition-level input-schema refusal be non-retryable? #9889's parity floor makes a flow burn its whole retry budget on a verdict that cannot change #10025 → spec: widen AutomationResult.code + register a never-dispatched ADR-0112 code for the definition-level input-schema refusal — the contract half of #10025's ruled Option B #11504.sys_activity.type: "scheduled"row, and 10 of FeedItemType's 13 kinds have no producer at all objectui#5840 un-pinned) is already a card in the objectui lane per the ruling.Options, unranked — this needs the spec seat's judgement, not mine
typesclosed and document it as "built-in kinds only" — cheapest, and honest only if authors genuinely never need to filter on their own kinds.z.union([FeedItemType, z.string()])(or a branded open string) so an author-contributed kind is nameable — the shape the ruling's logic points at, at the cost of losing the named rejection on a typo'd built-in.other/fallback member so unknown source types have a nameable bucket.Not measured
record:activitytypesat all (this repo's examples were not swept for it).sys_activity.typea closed platform vocabulary or an author-extensible one? Both readings are true of the code today #11507 card and objectui#5840, not measured here; this repo cannot import objectui.Refs: #11507 (the ruling) · ADR-0052 §5b.2 (the author write path) · objectstack-ai/objectui#5840