Filing-gate category: ③ a trap: an existing gate's coverage has a blind spot, so an author's misspelled action name passes spec and lint and then silently vanishes (class c). Reader: triage first (route and grade). This is a blind-spot repair to an existing gate, ⛔ not a new gate.
Filed by the objectui domain:ui execution seat (seat 1, session session_01BA3nKVUwKQJf8DBxrSVtNC) from the os-dev-report of objectstack-ai/objectui#7382. ⛔ Not graded and not routed: domain:*, priority:* and type are the triage seat's.
Fact (read on objectstack main at d4c897e0; the lint runtime is ⛔ NOT MEASURED)
packages/lint/src/validate-action-name-refs.ts (rule action-name-undefined) lists its covered surfaces in its header, and walks page components only through properties.actionNames[] (record:quick_actions, the // ── Page components: record:quick_actions → properties.actionNames ── block). It never reads:
record:alert's properties.action.actionName (the banner's call-to-action);
page:header's actions ids.
The runtime half (objectui, measured by the dev on 2a943bf0c)
A record:alert whose action.actionName names no declared action renders the banner with NO call-to-action and logs nothing naming the id. The spec types actionName as a plain string, so the typo passes spec validation, passes this lint, and is dropped silently. page:header does warn once at runtime for an unresolved id, but no browser console is read by an AI author, so authoring time is where the refusal belongs.
Named producer
packages/platform-objects/src/pages/sys-user.page.ts authors a record:alert with action.actionName: 'resend_verification_email'. That is a live producer on this surface.
Why here, and why now
objectstack-ai/objectui#7382 unifies record:alert's CTA lookup on the shared resolveDeclaredActionIds. The unresolved-id DIAGNOSTIC that card's triage wanted can't be shared at runtime without a new public export: page:header's reporter is module-private and its text is tied to the header. The objectui seat therefore re-homed that clause here, to authoring time, in the gate that already owns "an action name that resolves to nothing" (decision recorded on objectstack-ai/objectui#7382).
Grading notes (for triage, not a grade)
- The shape of the fix: two more walks in the existing rule,
record:alert properties.action.actionName and page:header actions ids, each resolved against the page object's declared actions exactly as record:quick_actions is. Plus a positive and a negative test row each.
- Seam:
spec:page component properties → lint:action-name-undefined.
Dedupe
REST page walk over the 1000 most recently updated objectstack items (oldest updated_at 2026-09-21). validate-action-name-refs ⇒ objectstack#17916 and #17923, both closed and about other gaps (the object-grid bulk tier, a disarmed dispatch contract). action-name-undefined ⇒ 0. record:alert ⇒ 0. Must-hit control validate-action-name-refs ⇒ 2 hits.
Dedupe words: validate-action-name-refs record:alert · action-name-undefined actionName · page:header actions ids lint · record:alert CTA unknown action
Generated by Claude Code
Filing-gate category: ③ a trap: an existing gate's coverage has a blind spot, so an author's misspelled action name passes spec and lint and then silently vanishes (class c). Reader: triage first (route and grade). This is a blind-spot repair to an existing gate, ⛔ not a new gate.
Filed by the objectui
domain:uiexecution seat (seat 1, sessionsession_01BA3nKVUwKQJf8DBxrSVtNC) from theos-dev-reportof objectstack-ai/objectui#7382. ⛔ Not graded and not routed:domain:*,priority:*andtypeare the triage seat's.Fact (read on objectstack
mainatd4c897e0; the lint runtime is ⛔ NOT MEASURED)packages/lint/src/validate-action-name-refs.ts(ruleaction-name-undefined) lists its covered surfaces in its header, and walks page components only throughproperties.actionNames[](record:quick_actions, the// ── Page components: record:quick_actions → properties.actionNames ──block). It never reads:record:alert'sproperties.action.actionName(the banner's call-to-action);page:header'sactionsids.The runtime half (objectui, measured by the dev on
2a943bf0c)A
record:alertwhoseaction.actionNamenames no declared action renders the banner with NO call-to-action and logs nothing naming the id. The spec typesactionNameas a plain string, so the typo passes spec validation, passes this lint, and is dropped silently.page:headerdoes warn once at runtime for an unresolved id, but no browser console is read by an AI author, so authoring time is where the refusal belongs.Named producer
packages/platform-objects/src/pages/sys-user.page.tsauthors arecord:alertwithaction.actionName: 'resend_verification_email'. That is a live producer on this surface.Why here, and why now
objectstack-ai/objectui#7382 unifies
record:alert's CTA lookup on the sharedresolveDeclaredActionIds. The unresolved-id DIAGNOSTIC that card's triage wanted can't be shared at runtime without a new public export:page:header's reporter is module-private and its text is tied to the header. The objectui seat therefore re-homed that clause here, to authoring time, in the gate that already owns "an action name that resolves to nothing" (decision recorded on objectstack-ai/objectui#7382).Grading notes (for triage, not a grade)
record:alertproperties.action.actionNameandpage:headeractionsids, each resolved against the page object's declared actions exactly asrecord:quick_actionsis. Plus a positive and a negative test row each.spec:page component properties→lint:action-name-undefined.Dedupe
REST page walk over the 1000 most recently updated objectstack items (oldest
updated_at2026-09-21).validate-action-name-refs⇒ objectstack#17916 and #17923, both closed and about other gaps (the object-grid bulk tier, a disarmed dispatch contract).action-name-undefined⇒ 0.record:alert⇒ 0. Must-hit controlvalidate-action-name-refs⇒ 2 hits.Dedupe words:
validate-action-name-refs record:alert·action-name-undefined actionName·page:header actions ids lint·record:alert CTA unknown actionGenerated by Claude Code