Context
Screenplay's ui profile declares an ordered package chain (core +
vendor + internal extensions). Scene needs the runtime/design-time
resolution logic that turns a bare or qualified widget name
(button, Internal.Widgets.TrendChart) into a concrete component,
respecting override priority and surfacing collisions.
Proposal
- Resolve bare names by walking the profile's
packages list in
declaration order; a name declared in a later package shadows the same
name in an earlier one (override-by-priority, so extension packages
only need to define what they override).
core is always present as the final fallback — guarantees a minimum
vocabulary (button, table, form, title, ...) resolves regardless
of profile.
- Qualified names (
Internal.Widgets.TrendChart) bypass ambiguity
resolution entirely and resolve directly against the named package.
- Ambiguity detection: if a bare name matches components in two active
packages at the same effective priority, produce the same class of
diagnostic as ambiguous query names — named candidates, not a silent
pick.
- This resolution needs to run both at design time (Studio's component
picker/property inspector needs to know what's resolvable) and at build
time (Stage needs the same resolution when generating the shipped app
per profile).
Open questions
- Should resolution results (and warnings) be cacheable/inspectable via
the CLI, similar to how Chronicle's CLI exposes projection/observer
state — useful for diagnosing "why did my button render as PrimeReact's
and not core's" without opening Studio.
Dependencies
Depends on
Blocks
Part of the screen work — build order and full dependency map: #7
Implementation notes
Runs on both sides, and that is the point of the issue's "design time and build time" requirement:
Keep one algorithm specified once and implemented on each side against a shared spec corpus — the same profile/package fixtures asserted in both languages — so the two cannot drift. See the dual-stack decision in #1.
Context
Screenplay's
ui profiledeclares an ordered package chain (core+vendor + internal extensions). Scene needs the runtime/design-time
resolution logic that turns a bare or qualified widget name
(
button,Internal.Widgets.TrendChart) into a concrete component,respecting override priority and surfacing collisions.
Proposal
packageslist indeclaration order; a name declared in a later package shadows the same
name in an earlier one (override-by-priority, so extension packages
only need to define what they override).
coreis always present as the final fallback — guarantees a minimumvocabulary (
button,table,form,title, ...) resolves regardlessof profile.
Internal.Widgets.TrendChart) bypass ambiguityresolution entirely and resolve directly against the named package.
packages at the same effective priority, produce the same class of
diagnostic as ambiguous query names — named candidates, not a silent
pick.
picker/property inspector needs to know what's resolvable) and at build
time (Stage needs the same resolution when generating the shipped app
per profile).
Open questions
the CLI, similar to how Chronicle's CLI exposes projection/observer
state — useful for diagnosing "why did my button render as PrimeReact's
and not core's" without opening Studio.
Dependencies
Depends on
ui profile— platform/size targeting and component packages Screenplay#94 — thepackageslist and qualification syntax this resolvesBlocks
ui profileat build/run time) Stage#39 — build-time resolution per deployment targetui profileand theme configuration UI StudioIssues#160 — component picker and collision surfacingPart of the screen work — build order and full dependency map: #7
Implementation notes
Runs on both sides, and that is the point of the issue's "design time and build time" requirement:
Scene.Model, is what Stage drives at build time (Runtime rendering per deployment target (ui profileat build/run time) Stage#39) and what Studio's design-time tooling queries.Scene.Enginewhen a profile is applied.Keep one algorithm specified once and implemented on each side against a shared spec corpus — the same profile/package fixtures asserted in both languages — so the two cannot drift. See the dual-stack decision in #1.