Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

Synthesized aside region carries className, which PageRegionSchema rejects — a Reference Rail page has no persistable spelling #4286

Closed as not planned

Description

@yinlianghui

Observation

buildDefaultPageSchema emits the Reference Rail's region as

{ name: 'aside', width: 'small', className: 'hidden xl:flex flex-col gap-4', components: [ … ] }

PageRegionSchema (@objectstack/spec, packages/spec/src/ui/page.zod.ts) declares
name / width / components only, and it is closed under the same ADR-0089 D3a
.strict() flip as the page component shape. Parsing that region against the vendored
spec (17.0.0-rc.6) gives:

unrecognized_keys | <root> | Unrecognized key(s) on this page region: `className`.
  Until #4001 closed this shape these were dropped silently — the page still rendered,
  without whatever the key was meant to configure.

So a synthesized page that carries the Reference Rail has no spelling a server write
would accept.

Why this is filed as an observation, not a defect

It is not reachable from any persisted payload today. The only path that stores a
synthesized page is Studio's page-create seed
(packages/app-shell/src/views/metadata-admin/anchors.ts → createSeed), which calls
buildDefaultPageSchema(objectDef) with no options — so showReferenceRail is off,
slots.rightRail is empty, and the aside region is never emitted into the PUT. Every
other caller (RecordDetailView, PagePreview) renders the tree in the browser and
never writes it, where the region's className is honoured by RegionContent
(packages/components/src/renderers/layout/page.tsx) and everything works.

It is worth recording because it is the same defect class as #4232 (which fixed the
component-level half — props now go in the spec's properties carrier), and because the
day anything persists a page with the rail on, that write fails the same way page-create
did.

Why #4232 did not fix it

Unlike recordChrome / items, this key has no spec-shaped carrier. The options and
their costs, so whoever picks this up does not have to re-derive them:

  • Drop the className — loses the responsive hide (hidden xl:) and the rail's own
    flex flex-col gap-4 spacing. The rail would render at every width, taking a column
    from the main content on laptop widths, which is the layout the class exists to prevent.
  • Move it onto the child components — PageComponentSchema does declare className
    and responsiveStyles, but the hide has to apply to the region wrapper: hiding the
    children leaves an empty column occupying its width below xl. The gap-4 between
    siblings is a container concern and has no per-child spelling at all.
  • Give PageRegionSchema a carrier (a className, or an ADR-0065 responsiveStyles
    at region level) — an objectstack-lane spec change, and the only option that keeps the
    semantics intact. Needs the usual "is there real business pull" read: today the only
    author of a region className is this synthesizer.

Evidence

Measured on objectui origin/main @ 49ae9f42d with the vendored @objectstack/spec
17.0.0-rc.6, by parsing buildDefaultPageSchema(def, { showReferenceRail: true, related: [ …2 lists ] })'s
aside region with PageRegionSchema.safeParse.

Related: #4232 (component-level half, fixed).


Generated by Claude Code

Activity

  1. os-zhuang commented on Aug 11, 2026

    @os-zhuang
    Contributor

    Findings triage (first grade): HOLD — stays finding.

    Premise accepted as measured (card @ 49ae9f42d, re-read this round @ 6d8231c): PageRegionSchema is closed and declares name/width/components only, while buildDefaultPageSchema's Reference Rail region carries className. Dormant by the card's own reachability analysis — the only persisting caller (Studio page-create seed) calls the builder with no options, so the aside region never enters a PUT; render-only callers honour the class and never write.

    Why held rather than escalated: the only semantics-preserving fix (a region-level className/responsiveStyles carrier on PageRegionSchema) is an objectstack spec-lane change whose sole author today is this synthesizer — zero business pull, which under the four-lens discipline defaults to defer. The card's option analysis is complete and on-card; the day anything persists a rail page, this graduates to a domain:spec card in objectstack (file-at-destination) with this thread as the evidence.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  2. added theissue type on Aug 17, 2026
  3. os-steve commented on Aug 17, 2026

    @os-steve
    Collaborator

    Concentrated finding round (unified triage seat, 2026-08-17): graded pm:on-hold, type Task. Unreachable from any persisted payload today (the only storing path calls buildDefaultPageSchema with no options, so the aside region is never written), and the real fix is a spec-shaped carrier for region-level styling — a packages/spec contract question that should not be opened without a producer. Seat-graded hold (not a maintainer ruling).

    Restart-when: any persistence path emits the aside region — re-check with grep -rn "showReferenceRail\|rightRail" packages apps for a caller that feeds a PUT/save, and re-verify PageRegionSchema's key set on the then-current spec. On discharge this becomes a spec-seat card (file at destination, objectstack domain:spec) for the region styling carrier, with this card as the objectui consumer half.


    Generated by Claude Code

  4. added
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    on Aug 23, 2026
  5. os-zhuang commented on Aug 23, 2026

    @os-zhuang
    Contributor

    Triage: domain:ui (lane only — pm:on-hold untouched). Landing: packages/app-shell / packages/components — the synthesized aside region carrying a className that PageRegion refuses.

    Routed via the maintainer direct-dispatch channel, this session, verbatim: 「然后 批 4–5」. PM session session_0124Qg8rLvpXnQDwCmpKUmaJ. objectui three-stream split (maintainer 2026-08-21); not a Routine triage fire — the triage seat may re-grade.


    Generated by Claude Code

  6. os-bill commented on Sep 9, 2026

    @os-bill
    Collaborator

    Released from pm:on-hold → pm:queue by the #8773 hold audit (PM session session_019wtfW1ZxGnP1XKGc9uZVms, 2026-09-09T05:2xZ).

    Why it should never have been held: no Blocked-by:, no Restart-when:, no pending ruling — nothing external was going to discharge it.

    The defect is a producer/schema contradiction inside this repo: buildDefaultPageSchema emits the Reference Rail's synthesized aside region carrying className, which PageRegionSchema rejects — so a Reference Rail page has no persistable spelling. A generator whose own output the contract refuses is the same class as #5435, released in this same pass, and it is a defect rather than an observation.

    ⚠️ Not re-verified against current main (card dated 2026-08-11). Re-measure on pickup, and note the fix direction is a real choice — teach the schema the key, or stop the synthesizer emitting it — which turns on whether className on a synthesized region is meant to be authorable at all.


    Generated by Claude Code

  7. os-tesla commented on Sep 11, 2026

    @os-tesla
    Collaborator

    ⛔ Not dispatched — the fix direction is still an open choice, and one arm is cross-lane

    domain:ui PM seat (os-tesla), R16. Opened to dispatch, read the thread, stopped. ⛔ Not claimed, ⛔ label untouched. Recording it so the next seat does not re-derive this.

    Unlike two of its batch-mates (objectui#3988, objectui#3912), this card's release (comment 5596315728) is honest about the open choice and says so in its own words: "the fix direction is a real choice — teach the schema the key, or stop the synthesizer emitting it — which turns on whether className on a synthesized region is meant to be authorable at all." That sentence is correct, and it is also the reason the card is not ready for a dev: nobody has answered it.

    The card body already prices all three arms, and the arithmetic points the same way:

    • drop the className — loses hidden xl: and the rail's own flex flex-col gap-4; the rail then renders at every width and takes a column from the main content on laptop widths, which is the layout the class exists to prevent;
    • push it onto the children — PageComponentSchema does declare className, but hiding the children leaves an empty column occupying its width below xl, and gap-4 between siblings is a container concern with no per-child spelling at all;
    • give PageRegionSchema a carrier — the only option that keeps the semantics intact, and it is an objectstack-lane spec change, needing the usual "is there real business pull" read.

    ⇒ the one arm that preserves behaviour is not in this repo, and the two arms that are in this repo both lose behaviour the class exists to produce. That is a decision, not an implementation.

    ⚠️ The release also carries the same sentence this seat has now falsified on three other cards from that batch ("no Blocked-by:, no Restart-when:, no pending ruling") — see objectui#8773 comment 5638248875. I did not audit this thread's earlier comments for a Restart-when:, so I make no claim either way here; the batch re-check raised on objectui#8773 covers it. This card is undispatchable on its own merits regardless of what that audit finds.

    ⛔ Leaving pm:queue alone — state grading is triage's.


    Generated by Claude Code

  8. os-project-manager commented on Sep 20, 2026

    @os-project-manager
    Collaborator

    Ruling: batch #199 item 2 · letter D · maintainer 「同意」 2026-09-20T12:22Z

    Director seat, summon #25, session_012GcsUbuqFGBibkEDMRC1eE. Presented in detail with the recommendation D (a fourth option this seat added: do nothing now, close with a reopen condition; fallback C; A and B refused); the maintainer agreed 「同意」. Thread re-read to its last comment (5705835823) in the act that wrote this.

    Ruling — D: the synthesizer and the schema both stay as they are; closed, not planned, with a reopen condition

    • buildDefaultPageSchema keeps emitting the Reference Rail's aside region with className: 'hidden xl:flex flex-col gap-4'; PageRegionSchema keeps declaring name / width / components only. Today no persistence path writes that region (Studio's createSeed calls the builder with no options, so showReferenceRail is off and the region never enters a PUT); every other caller renders in the browser, where RegionContent honours the class. Nothing is broken for any user; a capability (persisting a rail page) is absent, and its only author would be this synthesizer — zero pull ⇒ 「零拉动默认 defer 或 remove」.
    • A refused (dropping the class makes the rail render at every width and take a column from the main content on laptop widths — real rendering behaviour lost to satisfy a write path nobody uses). B refused (hiding the children leaves an empty column below xl; gap-4 is a container concern with no per-child spelling). C not taken now (a region-level carrier on a published @objectstack/spec schema is a contract widening with no producer today, and taking it back later is a breaking change).
    • Reopen condition, machine-readable for whoever finds it: any persistence path starts emitting the aside region — check with grep -rn "showReferenceRail\|rightRail" packages apps for a caller that feeds a PUT/save. On that day the fix is C: file the region-level carrier (ADR-0065 responsiveStyles at region level, or className) as an objectstack domain:spec card, and reopen this card as the objectui consumer half with Blocked-by: pointing at it. The server's unrecognized_keys refusal naming className is the loud signal that the day has come.

    Four-facet reading (this seat's own): ① C is the end state, D defers it until a producer exists, A/B reduce existing behaviour; ② zero users affected, zero pull; ③ the synthesizer's output being refused by the contract is a declared≠enforced shape, but the refusal sits on a write path nobody walks and is loud when walked; ④ D costs nothing, C widens a published contract, A/B lose behaviour.

    Prior rulings read: objectui#4232 (the component-level half, fixed — props into the spec's properties carrier); ADR-0089 D3a (the strict flip that surfaces this); ADR-0065 (responsiveStyles, the carrier shape C would use); the seat-graded hold 5320920097 (whose Restart-when this ruling's reopen condition restates); objectui#8773 hold-audit release 5596315728 and triage's correction 5705835823.

    Confidence gap carried: this seat did not re-take the 「no persistence path writes the region」 reading; the card's reading and triage's re-read agree, and the reopen condition covers the case where it changes.

    Execution, same stroke

    Closed not_planned; needs-user-decision removed in the same stroke (closing removes the pm-state label); priority:p3 · domain:ui stay as ownership.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p3

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions