Part of #12183 (parent). Filed by the domain:spec seat executing the ruled contract-first decomposition; grading/type stays with triage (domain:spec is the expected route — the enum, the retirement channel, and the parse-time rejection all live in packages/spec).
The ruling this implements
Maintainer, 2026-08-26 (comment 5419723931 on #12183), verbatim: 「其他接受你的建议」 accepting:
Phase 2: global:search / global:notifications — read platform data-source readiness FIRST; a member with no data-source plan inside the horizon is retired per B (ADR-0087 channel, author-time loud rejection) rather than left as a declared-unrendered trap.
Rides with the ruling: PageComponentSchema.type's union accepts arbitrary strings at parse time, which is why an unimplemented type reaches the renderer as a plain string; the author-time rejection half gets handled alongside whichever phase touches the enum.
Work items
- Readiness read (evidence, not verdict): for
global:search and global:notifications, measure what platform data source each would need (search backend, notification stream), what exists today in packages/**, and whether any recorded plan covers the horizon. Report the evidence face per member. - Per the ruling, retire any member the readiness read shows unplanned — ADR-0087 channel, spec-property-retirement route (enum-value narrowing + ComponentPropsMap row + registries + generated docs). The B-retirement for unplanned members is pre-authorized by the ruling; a member WITH a credible plan stays declared and is reported back instead.
- Author-time rejection: close the arbitrary-string acceptance on
PageComponentSchema.type (union narrowing or a validate rule — whichever the tree supports without breaking the declared extension story, measured not assumed) so an unknown type fails at author time instead of rendering scaffold.
Clause-②: expected YES (enum narrowing / retirement / parse-behaviour change) — CONTRACT_REVIEW_TIER at dispatch, per the spec lane's standing rules.
Sequencing: independent of the Phase-1 renderer card (objectstack-ai/objectui#6661); the two never share files. The hotCRM repro pages stay untouched until a renderer lands (they are the only evidence — recorded on #12183).
Refs: #12183 (parent + ruling) · objectstack-ai/objectui#6661 (Phase 1) · objectstack-ai/hotcrm#734 (downstream evidence archive).
Part of #12183 (parent). Filed by the
domain:specseat executing the ruled contract-first decomposition; grading/type stays with triage (domain:specis the expected route — the enum, the retirement channel, and the parse-time rejection all live inpackages/spec).The ruling this implements
Maintainer, 2026-08-26 (comment 5419723931 on #12183), verbatim: 「其他接受你的建议」 accepting:
Work items
global:searchandglobal:notifications, measure what platform data source each would need (search backend, notification stream), what exists today inpackages/**, and whether any recorded plan covers the horizon. Report the evidence face per member.PageComponentSchema.type(union narrowing or a validate rule — whichever the tree supports without breaking the declared extension story, measured not assumed) so an unknown type fails at author time instead of rendering scaffold.Clause-②: expected YES (enum narrowing / retirement / parse-behaviour change) — CONTRACT_REVIEW_TIER at dispatch, per the spec lane's standing rules.
Sequencing: independent of the Phase-1 renderer card (objectstack-ai/objectui#6661); the two never share files. The hotCRM repro pages stay untouched until a renderer lands (they are the only evidence — recorded on #12183).
Refs: #12183 (parent + ruling) · objectstack-ai/objectui#6661 (Phase 1) · objectstack-ai/hotcrm#734 (downstream evidence archive).