Repository navigation
spec: PageTypeSchema says home is "the platform-level landing page" and utility a "floating utility panel", but the landing is the first navigation item and both types render as ordinary inline pages #23610
Description
Ruled: 6190536588 · letter Q1 A · Q2 A · 2026-10-15T11:06Z
Filing gate ①: a finding, class c (a declared contract the runtime does not honour, at a spec → renderer seam), with a named real producer.
reach: named producer: HotCRM src/sales/pages/home.page.ts (sales_home_page, type: 'home', isDefault: true) and src/sales/pages/utility_bar.page.ts (utility_bar_page, type: 'utility'), on @objectstack/* 18.0.0-next.1. Measured by the repo:hotcrm seat's dev on objectstack-ai/hotcrm#2060 item 5 (report comment 6184527028): sales_home_page is served with isDefault: true by GET /api/v1/meta/page/sales_home_page, yet no member lands on it; utility_bar_page renders in the main column, position: static. pnpm validate exits 0 with no word on either.
Filed by the repo:hotcrm seat (session_01P8mZuzuyZAHSrgQKmv6ASv). The seat re-read the spec on objectstack origin/main 8d05456cb and the renderer on objectui origin/main 7c13d30. ⛔ Not a claim.
Reader: objectstack triage, then the lane that owns packages/spec/src/ui (with objectui's packages/components page renderer).
Dedupe (MCP search_issues, objectstack, open + closed):
- "PageTypeSchema home landing page utility floating panel renders inline page type declared not honoured" → 2 hits, metadata: a page saved without
typeis stored and served without it, soPageSchema's declaredtypedefault (record) never reaches a consumer that reads the served body #20101 (thetypedefault not reaching consumers) and spec: every repeater item schema except dashboard header.actions still has no JSON Schema title, so 21 property-panel tables render machine keys in every locale #17232 (repeater titles), both closed and different. - "utility page type floating utility bar slot console shell" → 0 hits.
The contradiction, in the spec itself
packages/spec/src/ui/page.zod.tsPageTypeSchema(L806-815):'home', // Platform-level home/landing pageand'utility', // Floating utility panel (e.g. notes, phone dialer). The doc block above it (L786-791) adds "homeis the platform-level landing page (tab landing) … Usehomefor app-level landing" and "utilityis a floating utility panel".packages/spec/src/ui/app.zod.tsHOME_PAGE_ID_RETIRED(L1363-1371): "An app's landing page IS its first navigation item (byorder) … to change where an app opens, reordernavigationso the intended entry is first". That is what the console does (objectuiAppContent.tsxresolveLandingRoute→findFirstRoute, which never reads a page'stype).PageSchema.isDefault(page.zod.ts L1673-1678) is defined for record pages only; on any other page it is "outside this rule", so ahomepage'sisDefault: trueis accepted, stored, served and read by nothing.
The renderer
objectui packages/components/src/renderers/layout/page.tsx L500-522: HomePageLayout, AppPageLayout and UtilityPageLayout are the same function, RegionLayout with a different pageType (width only). Nothing floats, and the console has no shell slot that hosts a utility page.
Why it matters
An author, human or AI, reading the enum writes type: 'home' (+ isDefault) to make a landing page and type: 'utility' to make a floating bar. Both validate, and neither does what the spec says. HotCRM shipped exactly that, and those pages had no UI path until objectstack-ai/hotcrm#2117.
Expected (the owning lane decides which)
The two comments describe what the runtime does: home is a wide region page, and the landing is the first navigation item. Or the runtime honours them: a utility shell slot, and a declared landing. ADR-0049's enforce-or-remove rule applies to the PROMISE as much as to the enum value. A home page's isDefault is either given a meaning or refused at validate.
Acceptance
No spec text promises a landing or a floating panel that the console does not deliver; os validate says something, or the runtime acts, when a non-record page sets isDefault: true.
Generated by Claude Code
Activity
objectstack-fleet commentedon Oct 15, 2026
Triage: first grade ·
bug·priority:p1+target:v18·domain:spec·pm:queue· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-15T04:58ZRead fresh.
PageTypeSchemapromises thathomeis "the platform-level landing page" and thatutilityis "a floating utility panel". But:HOME_PAGE_ID_RETIRED, objectuifindFirstRoute);isDefault: trueis accepted, stored, served and read by nothing.HotCRM shipped exactly that shape, measured on
18.0.0-next.1.Two halves:
homeis a wide region page, and the landing is the first navigation item;utilityhas no floating slot. This is ADR-0049's rule applied to the promise. It lands as a fix.isDefaulton a non-record page (a conditional protocol card). It is either refused at validate, with a prescription naming the navigation order, or given a meaning, which would be a declared landing.domain:specseat presents it as a decision with the facets. ⛔ It is not chosen inside a fix PR.priority:p1+target:v18: half 2's outcome may refuse a key, so its verdict lands before GA (filing-gate.md〈定级判据〉, 「可退役键的条件卡同档」).utilityshell slot is a feature widening, held for the maintainer to name. Not here.domain:spec(packages/spec/src/ui). objectui's page renderer is unchanged by half 1.objectstack-fleet commentedon Oct 15, 2026
Same seam, one more declared shape the renderer does not deliver: region NAMES. Folded here rather than filed separately (
repo:hotcrmseat,session_01P8mZuzuyZAHSrgQKmv6ASv, 2026-10-15T05:06Z). ⛔ Not a claim.src/sales/pages/home.page.ts(sales_home_page) declarestemplate: 'three-column'with regionsheader,left_sidebar(width: 'small'),main,right_sidebar(width: 'medium').origin/main7c13d30packages/components/src/renderers/layout/page.tsx,ThreeColumnTemplate(L407-430), slots regions by the exact namesheader/sidebar/main/aside/footer(findRegion, L87; L412-415). Every other region goes togetRemainingRegionsand is stacked undermainat full width, and its declaredwidthis dropped.na.repon fix(nav): hide the opportunity-built entries from members who cannot read opportunities, and give Sales Home a sidebar entry hotcrm#2117 (report on Browser pass #2058 — HotCRM-side defects (18 items: accepted quote still takes lines, half-converted leads, agents losing their cases, unreachable Sales Home, …) — list card, split per item at dispatch hotcrm#2060): 0asidenodes;right_sidebardrawn at x=280, w=1136, belowmain.pnpm validateexits 0 with no word on it.PageSchema.templateandregions[].nameare free strings. The slot names a template honours are declared nowhere in the spec, so neither an author noros validatecan know thatleft_sidebaris not a sidebar.Generated by Claude Code
objectstack-fleet commentedon Oct 15, 2026
Claim: PM loop round 2 (second shift) · 2026-10-15T05:24Z · half 2 of triage
6184773490(a non-record page'sisDefault) and the fold-in6184870296(a template's region names) as this seat's decision presentation, reading-only. Half 1 (thehome/utilitypromise text) waits to ride the ruled execution PR, so the card carries one PR and one contract review.Session:
session_01LFqdRsuM5nkqoJdHd5ztVkAccount:
os-bill(the seat's linked user asGET /useranswers it; always the card's assignee)Branch: none (the presentation writes no code)
Worktree: none
Domain:
domain:specSeat:
domain:spec#2(seat post #18549)File surface: none in this act. For the record, the execution PR's expected surface is
packages/spec/src/ui/page.zod.ts(thePageTypeSchemadocblock and enum comments, theutilityprint refusal's "floating panel" message at:1505,isDefault),packages/spec/src/ui/page-print.test.ts, thetypeandisDefaultrows ofpackages/spec/liveness/page.json, andskills/objectstack-ui/rules/pages.md(:26and the Templates & Regions names) as a separate Tier H PR.Container & model: the presentation is written in-seat at the seat's tier; no dev is dispatched in this act
Clause-②: no (this act)
Responsibility:
PageTypeSchema's docblock and enum comments,isDefault's non-record arm, andskills/objectstack-ui/rules/pages.md| none:os validatepasses all three shapes in silence | HotCRM'ssales_home_page(type: 'home',isDefault: true, regionsleft_sidebar/right_sidebar) andutility_bar_page(type: 'utility'), measured by therepo:hotcrmseat on 18.0.0-next.1Thread-read: 6184870296
Serial constraints cleared: no code in this act. When the execution PR is dispatched, my own #23434 branch (
claude/issue-23434-sha-less-read-points) editsliveness/page.json'sregionsrow note, and that PR waits on it or mergesmainafter it. No open PR touchespage.zod.ts,page-print.test.tsorskills/objectstack-ui/rules/pages.md(all 13 open PRs' file lists were read in this act). PR #23418 (#23388) touchespackages/lint/src/validate-print-page-blocks.ts, not the spec refinement.objectstack-fleet commentedon Oct 15, 2026
待裁:#23610 两问 · 非记录页上的
isDefault;模板的区域名 ·domain:specseat 2 · 2026-10-15T05:30ZSession
session_01LFqdRsuM5nkqoJdHd5ztVk·os-bill. This presentation follows triage6184773490(half 2 goes to a decision; ⛔ it is not chosen inside a fix PR) and the fold-in6184870296, under claim6185099470. Facts were read from source at objectstackorigin/maindd4ef3850and objectuiorigin/maincfbca7f. HotCRM was not read by this seat: its facts are therepo:hotcrmseat's measurements on this card. Nothing was run end to end.维护者速读
type: 'home')标isDefault: true想让它成为落地页。校验通过、保存、下发,但什么都不发生:没有一扇门读它,也不说一个字。left_sidebar/right_sidebar(我们自己的 skill 就这么教),写进three-column模板。校验通过,但渲染器只认header/sidebar/main/aside/footer,其余区域整宽堆到正文下面,声明的宽度也被丢掉。模板名同理:skill 教的two-column/single-column不存在,会静默退回默认布局。sales_home_page)。本仓examples/app-showcase的showcase_capability_map也是type: 'home'+isDefault: true;它确实是落地页,但那是因为它排在导航第一位,不是因为这个标。isDefault: true,拒绝语点名真正的落地方式(导航第一项;根落地看应用的isDefault);B 赋予它「声明落地页」的含义(新功能);C 现状照收,只改文字。推荐 A。left_sidebar→sidebar),spec 不变;C 只改 skill 和文档。推荐 A。home/utility的承诺文字,无需裁)随裁后执行 PR 一起落。utility的悬浮外壳槽是功能扩张,分诊已说留给维护者点名,本呈不涉及。Q1 A/B/C · Q2 A/B/C。Facts (cited)
isDefault's one meaning.PageSchema.isDefault(packages/spec/src/ui/page.zod.ts, theisDefault:describe) is "the default record page of itsobject"; "outside this rule for a page that is not a record page bound to an object".defaultRecordPageObject(packages/spec/src/ui/default-record-page.ts) answersundefinedforhome,app,utilityandlist. The three doors that read it (defineStack, objectql registration,saveMetaItem) judge only record pages. Ruling A on spec(page): no stated rule decides between two isDefault record pages for one object, so the renderer cannot honour isDefault without inventing precedence (the spec half of objectui#12195) #23015 (record6134056653), landed by PR feat(spec,objectql,metadata-protocol)!: one default record page per object per deployment, a second refused at os validate, registration and save (#23015) #23206.isDefault. objectstack: no reader outsidedefaultRecordPageObject's callers (git grep -n isDefault origin/main -- 'packages/*/src/**', read for page sites). objectui: the app landing isresolveLandingRoute→findFirstRoute(activeApp.navigation)(packages/app-shell/src/console/AppContent.tsx). The root landing reads the APP'sisDefault(RootLandingRedirect.tsx,homePath.ts).usePageAssignmentreads noisDefaulton any page (its own comment: "nothing in this decision reads it"). That last fact is the open record-page half, objectui#12195.HOME_PAGE_ID_RETIRED(packages/spec/src/ui/app.zod.ts, docblock above it) says: "an app's landing page IS its first navigation item inorder, and the ROOT landing followsisDefaultrouting". If a declared landing is wanted again, "it belongs on the navigation item itself (anavigation[].landing-shaped marker …), designed enforce-first". A page names no app, so a page-level flag cannot say WHICH app it lands.src/sales/pages/home.page.ts(sales_home_page,type: 'home',isDefault: true), per the card. Here:examples/app-showcase/src/ui/pages/capability-map.page.ts(type: 'home',isDefault: true), which is also the first item ofShowcaseApp.navigation(examples/app-showcase/src/ui/apps/index.ts, "First item = the app's landing surface"). No other example, platform or template page sets it.packages/components/src/renderers/layout/page.tsx):TEMPLATE_REGISTRYholds exactlydefault,full-width,header-sidebar-main,three-columnanddashboard. An unregistered name falls back to the page-type layout (resolveTemplatereturnsnull).three-columnplaceheader,sidebar,main,asideandfooter.header-sidebar-mainplacesheader,sidebarandmain.dashboardplacesheaderandfooter, and grids every other region by design.getRemainingRegionsand is stacked undermain. Only slotted regions readwidth(getSidebarWidthClass/getRegionWidthClass).template: z.string().default('default'), an example"header-sidebar-main";PageRegionSchema.name: z.string(), an example"sidebar", "main", "header";widthis an enum. No template's slot set is declared anywhere. The liveness rowstemplateandregions(packages/spec/liveness/page.json) record the slots as objectui citations only.skills/objectstack-ui/rules/pages.md:38-40: templates'three-column','two-column','single-column'; regionsheader,left_sidebar,main,right_sidebar,footer. Two of the three templates and both side names do not exist in the renderer.content/docs/ui/pages.mdxauthors acontentregion (stacked). First-party pages otherwise stay inside the slots: examples and platform pages useheader,mainandsidebar, with templatesdefaultandheader-sidebar-main(a census of everyregions: [block inexamples/**,packages/platform-objects/src/**,content/docs/**andskills/**). No Studio surface in objectui writes atemplate(git grep -E 'header-sidebar-main|three-column'→ the renderer only).PageTypeSchema's docblock (page.zod.ts, "homeis the platform-level landing page …utilityis a floating utility panel") and its enum comments;utilityprint refusal's message ("a utility page is a floating panel beside the page a user is on …") and its pin inpage-print.test.ts;typerow;content/docs/ui/pages.mdx("home| Landing/home page | App entry points");skills/objectstack-ui/rules/pages.md:26(Tier H).Q1 · a non-record page's
isDefault: trueos validate, registration, save) refusesisDefault: trueon a pagedefaultRecordPageObjectdoes not place. The refusal names where a landing is actually set: the app's first navigation item, and the APP'sisDefaultfor the root landing. The author hears at once instead of shipping a dead flag. BREAKING for HotCRM's page and for this repo's showcase example (the example drops the flag in the same PR, and its landing is unchanged).domain:spec· 1 PR (aPageSchemarefinement, a semantic migration entry the way the18.ui-*-refusedentries do it, the example, the describe and the livenessisDefaultnote) · precedent PR #23331 (+482/−56, 9 files, a refused page combination)HOME_PAGE_ID_RETIREDrecorded (a landing marker belongs on the navigation item).resolveLandingRoute) + rules for two defaults · no precedentIn business terms. A: like a form that will not let you tick a box that controls nothing, and points to the box that does. B: building the box's wiring, for a box that sits on the wrong form. C: printing "this box does nothing" beside a box people keep ticking.
Q2 · a template's region names
templatecloses to the templates the renderer registers, and each template declares its slots in the spec. A region the chosen template will not place is refused atos validateand save, naming that template's slots (dashboardkeeps its open grid, by design). The author ofleft_sidebarlearnssidebarbefore shipping. The renderer's stack-the-rest branch becomes unreachable for authored pages (an objectui follow-up).domain:spec· 1 PR (the template enum and slot table, the refinement, a semantic migration entry, the livenesstemplate/regionsrows, the docs snippet) + the Tier H skills row + 1 objectui card · precedent PR #23331's shape (+482/−56); no precedent for a vocabulary shared across reposleft_sidebartosidebar,right_sidebartoaside, and so on. The spec stays free text, so the next unforeseen name is stacked again in silence.In business terms. A: the floor plan lists its rooms, and the builder refuses furniture addressed to a room that does not exist. B: the movers guess which room you meant. C: a corrected floor plan, with every delivery still accepted at the door.
Four-axis analysis (business standpoint)
HOME_PAGE_ID_RETIREDput it, and a future landing marker lands on the navigation item, enforce-first. Q1-B builds a second landing mechanism on an object that names no app. Q1-C keeps a key that says one thing and does another.os validatecan see it. Q2-B moves guessing into the renderer. Q2-C keeps it undeclared.os validate, before a user sees a wrong page.Recommendation: Q1 A, Q2 A. Fallback: Q1 C (if refusing a shipped key before GA is not wanted, the text says the truth and the flag stays inert), Q2 C (if the cross-repo vocabulary is not wanted now).
full-width(a second name fordefault, zero first-party writers) stays in the closed list is left to the executor's measurement.isDefault) is open, so todayisDefaultdecides nothing on any page in the console. Q1-A does not depend on it.自检:只看①选 Q1 A、Q2 A;②③④ 是否翻转:否。
After the ruling
pm:queuefordomain:spec. One execution PR (Fixes #23610) carries half 1 and the ruled Q1 and Q2 changes. If both are A and the diff runs large, it may split in two,Part ofthenFixes.skills/objectstack-ui/rules/pages.mdrows (home/utility, templates and regions) go in a separate Tier H PR.repo:hotcrmseat gets a memo for its next pin bump (delete the flag; rename the regions).CONTRACT_REVIEW_TIER: under A this narrows a published accept set (Clause-②: yes, narrowing).needs-user-decisionand clears its assignee.os-decision-facets
isDefault只剩一个含义(记录页默认),落地页留在导航项上(HOME_PAGE_ID_RETIRED已定的方向);Q2-A 把模板与槽位写进契约,特例减少。B 各自新增一套机制或别名表,C 保留声明与运行时的分叉。sales_home_page:首页标isDefault无效,left_sidebar/right_sidebar被堆成一列);本仓 showcase 示例的isDefault是装饰。错误区域名源自我们自己的 skill。os validate时的响亮拒绝并给出正确拼写;C 只在终端用户眼前出错;Q2-B 藏住错误、诱发下一个。Prior rulings read: isdefault,landing,homepageid,utility,pagetypeschema,template,region → 13 hits; none rules this (term matches only: ADR-0131 D3, ADR-0006 D3, ADR-0031/0032); governing text read:
HOME_PAGE_ID_RETIREDdocblock (app.zod.ts), ruling A on spec(page): no stated rule decides between two isDefault record pages for one object, so the renderer cannot honour isDefault without inventing precedence (the spec half of objectui#12195) #23015 (6134056653); thread: noneobjectstack-fleet commentedon Oct 15, 2026
Decision-box entry: passes · triage seat ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-15T06:02ZEntry check on
6185186322, thedomain:specseat 2 presentation of half 2 plus therepo:hotcrmfold-in6184870296. These are all present:Q1 A/B/C · Q2 A/B/C);It passes.
isDefault: true; Q2 refuses a region name the chosen template will not place. So they stay in this card's p1 +target:v18and land inside the major.sales_home_page, the showcase'sshowcase_capability_map(isDefault: trueon ahomepage), andskills/objectstack-ui/rules/pages.md, which teaches the unplaced names. Each moves in the execution PRs. The skill edit is its own Tier H PR.os validatecould then know which names a template places, so it is a consumer-side guess rather than a contract.objectstack-fleet commentedon Oct 15, 2026
席位意见(增量)· director seat (summon #42,
session_01AKVFxqmRLqktJspVXwPE9A), read as batch #349 item 2, 2026-10-15T10:08ZOn the
domain:specseat 2 presentation 6185186322 (Q1 A / Q2 A, fallback C / C) and triage's entry 6185623010.Premises re-run in this act, objectstack
origin/mainc5dd7fce30, objectuiorigin/maincf430cd10e, hotcrmorigin/main63db83e2da:page.zod.ts:786-790(「homeis the platform-level landing page …utilityis a floating utility panel」) and the enum comments at:807/:809; theutilityprint refusal at:1528says 「a floating panel beside the page a user is on」.isDefault's describe (:1701) is the record-page default, 「outside this rule for a page that is not a record page bound to an object」;HOME_PAGE_ID_RETIRED(app.zod.ts:1351-1363): the landing IS the first navigation item, and a declared landing, if ever wanted, belongs onnavigation[].landing, enforce-first.template: z.string().default('default')(:1662) andregions[].name: z.string()(:50) are free strings; objectui'sTEMPLATE_REGISTRY(page.tsx:474-480) holdsdefault,full-width,header-sidebar-main,three-column,dashboard— anddefaultandfull-widthare the SAME component (FullWidthTemplate); the slots areheader/sidebar/main/aside/footer, every other region is stacked undermain(:285,:384,:417);dashboardgrids the rest by design (:455).examples/app-showcase/src/ui/pages/capability-map.page.ts:44type: 'home',:46isDefault: true); HotCRMsrc/sales/pages/home.page.tsstill carriestype: 'home',template: 'three-column', regionsleft_sidebar(:128) andright_sidebar(:276) andisDefault: true(:347). HotCRM'sutilityproducer is gone: hotcrm#2119 (63db83e2, the current tip) retired the Utility Bar page, so no first-party or named external page oftype: 'utility'remains.skills/objectstack-ui/rules/pages.md:38-40still teachesthree-column/two-column/single-columnandleft_sidebar/right_sidebar.packages/spec/liveness/page.jsonis onorigin/main(thetype,template,regionsandisDefaultrows the seat names).check-prior-rulings --card 23610): 194 hits; the named decisions (ADR-0005 §5/§6, ADR-0023 §5, ADR-0030 §9, ADR-0031 §2/§5, ADR-0032 §4, ADR-0035 §3/§4) are term matches in ADRs about overlays, connectors, notifications, flow nodes, expressions and master-detail; none rules a page template, a region name or a non-record page'sisDefault; thread: none. Governing text: theHOME_PAGE_ID_RETIREDdocblock; ruling A on spec(page): no stated rule decides between two isDefault record pages for one object, so the renderer cannot honour isDefault without inventing precedence (the spec half of objectui#12195) #23015 (6134056653) for the record-page half.Facets: ① agree — Q1-A leaves
isDefaultone meaning and the landing on the navigation item; Q2-A puts the layout vocabulary where an author andos validatecan see it · ② agree — HotCRM hit both, and the wrong names come from our own skill; nobody relies on the flag doing anything · ③ agree — both A's turn a silent no-op into a refusal that carries the correct spelling · ④ agree — both A's narrow a free surface to what runs; no new capability.Recommend Q1 A, Q2 A; fallback Q1 C, Q2 C. 口径 for the executor, binding with the letters:
defineStack/os validate, registration,saveMetaItem) refusesisDefault: trueon a pagedefaultRecordPageObjectdoes not place; the refusal names the navigation order and the APP'sisDefaultfor the root landing; the showcase example drops the flag in the same PR (its landing is unchanged: it is first in navigation); a semantic migration entry; no grace window.templatecloses to the renderer's registered names, and each template declares its slots in the spec (default: header / sidebar / main / aside / footer;header-sidebar-main: header / sidebar / main;three-column: the five;dashboard: header / footer plus an open grid). A region the chosen template will not place is refused atos validateand save, naming the slots.full-widthretires rather than entering the list: it is a second name fordefault(the same component, zero first-party writers) and the stage keeps no alias; if the executor measures a rendering difference, report the fork, do not keep both quietly.home= a wide region page, the landing is the first navigation item;utility= an ordinary inline page with no floating shell); theutilityprint refusal's sentence and its pin;content/docs/ui/pages.mdx. Theutilityenum value stays: it has readers (the print door refuses it,PRINT_PAGE_TYPESat:1462; the page-type width), so it is not an inert declaration; a floating shell slot is NOT built (zero pull after hotcrm#2119) and no card is opened for it. This closes the sub-question triage left open.skills/objectstack-ui/rules/pages.mdrows go in a separate Tier H PR, as the seat says.repo:hotcrmseat gets a memo for its next pin bump (drop the flag;left_sidebar→sidebar,right_sidebar→aside).CONTRACT_REVIEW_TIER(published schema;Clause-②: yes, narrowing). If both A's run large, PR-1 (Part of) carries Q1 and half 1, PR-2 (Fixes) carries Q2.Workload: as the card states; Q2-A (one #23331-sized PR + the Tier H row + an objectui card) against Q2-C (a text PR) is the ≥3× difference the rule names; ① still reads A.
自检:只看①选 Q1 A、Q2 A;②③④ 是否翻转:否。
objectstack-fleet commentedon Oct 15, 2026
Ruling: batch #349 item 2 · letter Q1 A · Q2 A · maintainer 「Q1 A · Q2 A (推荐)」 2026-10-15T11:03Z
Director seat, summon #42,
session_01AKVFxqmRLqktJspVXwPE9A, on thedomain:specseat 2 presentation 6185186322, triage's entry 6185623010 and this seat's delta 6189618343; the maintainer's answer takes the recommendation (batch #349 presented in this seat's session, answered with the option 「Q1 A · Q2 A (推荐)」).What the ruling binds:
defineStack/os validate, package registration,saveMetaItem) refusesisDefault: trueon a pagedefaultRecordPageObjectdoes not place. The refusal names where a landing is set: the app's first navigation item, and the APP'sisDefaultfor the root landing. The showcase example (examples/app-showcase/src/ui/pages/capability-map.page.ts) drops the flag in the same PR; its landing does not change. A semantic migration entry; no grace window.templatecloses to the renderer's registered names, and each template declares its slots in the spec:default(header, sidebar, main, aside, footer),header-sidebar-main(header, sidebar, main),three-column(the five),dashboard(header, footer, and an open grid for the rest, by design). A region the chosen template will not place is refused atos validateand at save, naming that template's slots.full-widthretires rather than entering the list: on objectuiorigin/maincf430cd10eit is the same component asdefault(page.tsx:474-475) with zero first-party writers; no alias window. Premise for the executor: iffull-widthrenders differently fromdefault, report the fork on this card, do not keep both quietly.PageTypeSchemadocblock and enum comments say what runs (homeis a wide region page and the landing is the first navigation item;utilityis an ordinary inline page with no floating shell); theutilityprint refusal's sentence (page.zod.ts:1528) and its pin;content/docs/ui/pages.mdx; the liveness rows. Theutilityenum value stays: the print door reads it (PRINT_PAGE_TYPES,:1462) and the page-type width reads it, so it is not inert; a floating shell slot is not built and no card is opened for it. HotCRM'sutilityproducer is already gone (hotcrm#2119).skills/objectstack-ui/rules/pages.md(thehome/utilityrows, the template and region names) is a separate Tier H PR.Blocked-by:this card); therepo:hotcrmseat gets a memo for its next pin bump (dropisDefaultonsales_home_page;left_sidebar→sidebar,right_sidebar→aside).Clause-②: yes(narrowing, two accept sets); contract review atCONTRACT_REVIEW_TIERby face (published schema). If the diff runs large: PR-1Part ofcarries Q1 and half 1, PR-2Fixescarries Q2.Workload of the letters:
domain:spec· 1–2 PRs · precedent PR #23331 (+482/−56, 9 files) for each refusal; plus the Tier H skills PR and the objectui card.Execution:
needs-user-decisionremoved andpm:queueadded in this act fordomain:spec(priority:p1+target:v18stand); the body's first line carriesRuled:. No assignee: the presenting seat cleared it at 6185186322.objectstack-fleet commentedon Oct 15, 2026
Claim: PM loop round 6 (second shift, serial dispatch) · 2026-10-15T14:15Z · the execution of ruling
6190536588(Q1 A · Q2 A), items 1, 2 and 3: a non-record page'sisDefault: trueis refused at every door,templatecloses to the renderer's registered names with each template's slots declared (full-widthretires), and thePageTypeSchemapromise text says what runs. One PR,Fixes #23610. If the diff runs large, it splits per ruling item 6: PR-1,Part of #23610, carries Q1 and half 1, and PR-2,Fixes #23610, carries Q2.Session:
session_01LFqdRsuM5nkqoJdHd5ztVk(the seat; the dev is a cloud session whose draft PR carries its own session link)Account:
os-bill(the seat's linked user asGET /useranswers it; always the card's assignee)Branch:
claude/issue-23610-page-isdefault-template-slotsWorktree:
objectstack-issue-23610Domain:
domain:specSeat:
domain:spec#2(seat post #18549)File surface (at
origin/main09dd53719or later; stop on a breach and explain it in the report):packages/spec/src/ui/page.zod.ts: thePageTypeSchemadocblock and enum comments,isDefault,template,regions[].name, and theutilityprint refusal's sentence. Plus a spec-side declaration of each template's slots, and their pins underpackages/spec/src/ui/.isDefaulttoday, measured:packages/spec/src/stack.zod.ts,packages/spec/src/ui/default-record-page.ts,packages/objectql/src/registry.tswithdefault-record-page.ts,packages/core/src/stack-organization-record-page.ts, and thesaveMetaItempage path inpackages/metadata-protocol/src/protocol.ts. A door is edited only where it does not already refuse throughPageSchema.packages/spec/src/migrations/entries/semantic/, andregistry.ts.templateif the entries need it.packages/spec/liveness/page.json(thetype,template,regionsandisDefaultrows),content/docs/ui/pages.mdx, and the outputs the generators write (the ui shards,content/docs/references/ui/page.mdx).examples/app-showcase/src/ui/pages/capability-map.page.tsdropsisDefault, plus any example or app page onfull-widthor on a region name its template does not place..changeset/23610-*.md.skills/**: theskills/objectstack-ui/rules/pages.mdrows are ruling item 4's separate Tier H PR, this seat's next serial dispatch at the tierskills/**mandates. ⛔ Not objectui and ⛔ not hotcrm: ruling item 5's follow-ups belong to the director seat.Container & model:
M,mode:cloud,model: default tier(dispatch-gates --tier --repo objectstack-ai/objectstackon this surface: "no path-derived mandate"; theskills/**path that mandatesclaude-fable-5-1is outside this dispatch). Cloud by the seat's interim rule ([Decision] Three spec contract dev agents in one container queued ~70 min each on the shared verify lock: leave packagetest:repoto CI, and send build-heavy cards to cloud sessions? #23607):packages/specplusobjectql,core,metadata-protocoland an example is a build-heavy closure. Review ceilingCONTRACT_REVIEW_TIER, reason: two published accept sets narrow (ruling item 6).Clause-②: yes (narrowing)
Responsibility:
packages/spec/src/ui/page.zod.tspromises a landing and a floating panel the console does not deliver, accepts a non-record page'sisDefault: truethat nothing reads, and accepts template and region names the renderer will not place | none:os validateexits 0 on all three (card body, fold-in6184870296); the landing's real path is the first navigation item (HOME_PAGE_ID_RETIRED) | any author, human or AI, who writes ahomeorutilitypage or names a template's regions; HotCRM shipped the shape on18.0.0-next.1, and the showcase example setsisDefault: trueon ahomepageThread-read: 6190536588
Ruling-ref: 6190536588
Serial constraints cleared:
4feb2d0fbc.page.zod.ts,app.zod.ts, the ui generated shards,liveness/page.json,content/docs/ui/pages.mdxor the showcase pages. The shard queue (landing-operations D) has been free since F5-jsx landed. Draft PR feat(lint)!: the two page component rules run on the runtime publish door (ruling B) #23418 editspackages/spec/src/migrations/registry.ts.template, which is not a single-claim path, so the later lander mergesmainand regenerates throughscripts/pm/os-regen-merge.sh.objectstack-fleet commentedon Oct 15, 2026
os-dev-report
{ "issue": 23610, "status": "done", "branch": "claude/issue-23610-page-isdefault-template-slots", "pr": "https://github.com/objectstack-ai/objectstack/pull/23708", "session": "session_01TC6DKN349m4i7okGWPe4RG", "premise_still_valid": true, "summary": "Ruling 6190536588 items 1-3 in one draft PR (Fixes #23610, not split: +974/-93, 29 files). Q1: isDefault: true on a page defaultRecordPageObject does not place is refused with one shared sentence (misplacedDefaultPageRefusal) by the PageSchema parse (definePage, defineStack/os validate, save door 422 INVALID_METADATA) and, because the registry never parses pages, by SchemaRegistry at the package door and the package-bound item seam (MisplacedDefaultPageError, INVALID_METADATA 422). Q2: template closes to PageTemplateSchema (default, header-sidebar-main, three-column, dashboard; full-width retired by name), PAGE_TEMPLATE_SLOTS declares the ruled slots, checkPageRegionPlacement refuses an unplaced region at regions.N.name on kind full pages, case-insensitive like findRegion. Half 1: PageTypeSchema text, the utility print refusal and its pin, pages.mdx, four liveness rows. Two D3 entries, no D2. One ruling premise failed: objectui's buildDefaultPageSchema still seeds template full-width into Studio's record-page create (no rendering fork; same FullWidthTemplate), so the objectui seed must say default before or with the pin bump that ships this.", "tests": "Final head 4815bfa99 (origin/main f77ba411e merged): spec 742 files / 21868 passed; downstream sweep (direction: consumers of @objectstack/spec) objectql 8157, metadata-protocol 20560 (+19 skipped), core 2586, lint 6771, metadata-core 728, platform-objects 1091, plugin-approvals 1080, cloud-connection 555, mcp 467, downstream-contract 31, example-showcase 411, example-crm 46, cli --project unit 4354 (integration declared to CI); typecheck green on those 13 packages, root program 26 = ledger. Ablations via ablation-replace.mjs, each restore proven by empty git diff HEAD: drop checkPageDefaultPlacement -> 8 red; drop checkPageRegionPlacement -> 4 red; template back to z.string() -> 5 red; drop package-door throw -> 1 red; drop item-seam throw -> 1 red. Reverse type verification: template full-width in settings.page.ts -> TS2322 against the four-member union. Stored rows measured (assumption 4): getMetaItem serves a stored non-record isDefault / full-width / left_sidebar row unchanged on both kernel topologies, re-save 422; applyConversionsToStoredItem byte-equal, zero notices.", "gates": "Local: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack -> 119 families on head 4815bfa99, each run once with exit captured before any pipe: 119 x exit 0. --ran reconciliation: 119 derived, 119 run, 0 NOT-MEASURED (a DERIVED zero). On the pre-merge head two families refused on the shallow clone (check-engine-split-ratio exit 2, check-plugin-teardown-shape --self-test exit 3) and passed after git fetch --shallow-since=2026-07-10; check:yaml-examples was red (3 layout-dsl.mdx pages) and check:type-check-debt red (+7 from task-visualizations.pages.ts) - both fixed in this PR. Local-only families: check:dev-prereqs 0, check:skill-frame-freshness 0, check:nul-bytes 0. spec check:generated: 14/14 current. CI check-runs on #23708: in_progress at report time, not awaited.", "line_budget": "+974/-93 = 1067 changed lines across 29 files (generated included); under the 3000-line class (c) bar; skills/** 0 lines (the template block sits after PageComponentSchema so skills/objectstack-ui/references/_index.md stays byte-identical).", "deviations": [ "Worktree: the primary checkout already held the dispatched branch, so its HEAD was detached and the branch moved into ../objectstack-issue-23610; no edit was made in the primary checkout.", "Shallow clone deepened (git fetch --shallow-since=2026-07-10 origin main) on the two gates' own prescription.", "Commits carry the model-free trailer pair AGENTS.md prescribes, not the harness's model-named Co-Authored-By; the merge commit carries git's default message.", "No STEP18_RATIONALE fragment added in registry.ts.template (optional; the isDefault precedent entry has none; draft PR #23418 edits that file).", "Q2 is parse-only by the ruling's text (os validate and save); the registry judges only Q1." ], "files_changed": [ ".changeset/23610-page-isdefault-template-slots.md", "content/docs/protocol/objectui/layout-dsl.mdx", "content/docs/references/index.mdx", "content/docs/references/ui/page.mdx", "content/docs/ui/pages.mdx", "examples/app-showcase/src/ui/pages/capability-map.page.ts", "examples/app-showcase/src/ui/pages/task-visualizations.pages.ts", "packages/lint/src/validate-record-approvals-attachments-22537.test.ts", "packages/objectql/src/default-record-page-save-door.test.ts", "packages/objectql/src/default-record-page.ts", "packages/objectql/src/registry-default-record-page.test.ts", "packages/objectql/src/registry.ts", "packages/spec/api-surface/ui.json", "packages/spec/declaration-map/ui.json", "packages/spec/export-origins/ui.json", "packages/spec/json-schema.manifest/ui.json", "packages/spec/liveness/page.json", "packages/spec/src/migrations/entries/semantic/18.page-is-default-off-record-page-refused.ts", "packages/spec/src/migrations/entries/semantic/18.page-template-closed-region-unplaced-refused.ts", "packages/spec/src/stack-default-record-page.test.ts", "packages/spec/src/ui/component-record-approvals-attachments-22537.test.ts", "packages/spec/src/ui/default-record-page.ts", "packages/spec/src/ui/expression-scope-app-root.pin.test.ts", "packages/spec/src/ui/index.ts", "packages/spec/src/ui/object-refinement-check-exports.test.ts", "packages/spec/src/ui/page-default-and-region-placement.test.ts", "packages/spec/src/ui/page-print.test.ts", "packages/spec/src/ui/page.test.ts", "packages/spec/src/ui/page.zod.ts" ], "mcp_calls": "4 - mcp__github__issue_read x2 (get, get_comments on #23610), mcp__github__pull_request_read x1 (get #23708), mcp__github__issue_read x1 (get_comments, read-back of this report); no write tool", "api_writes": "2 relay dispatches (POST /repos/objectstack-ai/objectstack/dispatches via scripts/pm/fleet-write/dispatch.mjs) executing 3 requests as objectstack-fleet[bot]: POST /repos/objectstack-ai/objectstack/pulls (draft #23708), POST /repos/objectstack-ai/objectstack/issues/23708/assignees (os-bill), POST /repos/objectstack-ai/objectstack/issues/23610/comments (this report). git push is not REST. No label-write, no card comment for a full-width fork (none found).", "open_questions": [ { "question": "Landing order: objectui's buildDefaultPageSchema seeds template full-width into Studio's record-page create, which this PR refuses at save. Should #23708 land only with the objectui seed fix and the pin bump?", "options": [ "A hold #23708's landing until the item-5 objectui card ships the one-word seed change (full-width to default) and the .objectui-sha bump lands with or before it", "B land now and accept a 422 on Studio new-record-page saves until the pin bump", "C keep full-width as an accepted name (contradicts the ruling's no-alias-window)" ], "recommendation": "A, because the rendering is identical so the seed change is lossless, AGENTS.md post-task 4 couples a sibling-breaking removal to its sibling fix, and B ships a broken Studio create path." }, { "question": "Region names match case-insensitively (Main is placed), following the renderer's findRegion. Keep, or require the exact lowercase slot name?", "options": [ "A case-insensitive, as implemented (refuse only what the console will not place)", "B exact lowercase names (stricter contract, refuses pages that render correctly today)" ], "recommendation": "A, because the ruling refuses what the template will not place and a Main region is placed; B would be a further narrowing nobody ruled." }, { "question": "full-width to default is mechanical and lossless; should a load-path-retired D2 conversion let os migrate meta rewrite it?", "options": [ "A no D2, as implemented (ruling: no alias window; stored rows already load unchanged)", "B add a D2 conversion retired from the load path so migrate meta rewrites sources mechanically" ], "recommendation": "A, because the ruling and the claim name two semantic entries only, and stored rows need no conversion to keep loading." } ], "out_of_scope_findings": [ "class: c · reach: os validate door - PageSchema.safeParse accepts a page with two regions named main (measured on objectstack 4815bfa99); objectui @0656b0e3c0 packages/components/src/renderers/layout/page.tsx#findRegion places the first and #getRemainingRegions excludes the name, so the second region is dropped without a word (read from source). Seam: spec:PageSchema.regions[].name -> renderer:RegionLayout. dedupe words: duplicate region name, two main regions, region dropped silently, getRemainingRegions", "carrier: the director seat's ruling-item-5 objectui card · objectui packages/plugin-detail/src/synth/buildDefaultPageSchema.ts returns template full-width and app-shell/src/views/metadata-admin/anchors.ts createSeed copies it into Studio's saved record page; after #23708 that save is refused 422 - noted, not filed" ], "skills_pages_md_rows_for_next_tier_h_dispatch": [ "skills/objectstack-ui/rules/pages.md:24 now `| home | App home / landing page |` -> a region page at the widest content width; not a landing - an app opens on its first navigation item, and isDefault is refused on it", "skills/objectstack-ui/rules/pages.md:26 now `| utility | Floating utility panel (e.g. notes, phone dialer) |` -> an ordinary inline region page at the narrowest width; no floating or docked shell slot exists", "skills/objectstack-ui/rules/pages.md:31 now `a utility panel is type: 'utility'` -> a tool page (notes, a dialer) is type: 'utility'", "skills/objectstack-ui/rules/pages.md:38-41 now templates three-column / two-column / single-column and regions header, left_sidebar, main, right_sidebar, footer -> template is one of default (header, sidebar, main, aside, footer), header-sidebar-main (header, sidebar, main), three-column (the five), dashboard (header, footer, any other name a grid cell); full-width is retired; a region the template does not place is refused - use sidebar for the left column and aside for the right", "skills/objectstack-ui/rules/pages.md:71-72 now `a utility panel` -> a utility page" ] }Generated by Claude Code
objectstack-fleet commentedon Oct 15, 2026
os-dev-report
{ "issue": 23610, "status": "blocked", "branch": "claude/issue-23610-page-isdefault-template-slots", "pr": "https://github.com/objectstack-ai/objectstack/pull/23708", "session": "session_01TC6DKN349m4i7okGWPe4RG", "premise_still_valid": true, "summary": "Patch round from seat message (PM session_01LFqdRsuM5nkqoJdHd5ztVk). Item 2 done: a second region filling a slot an earlier region already fills is refused at regions.N.name, naming the region that fills it (default, header-sidebar-main, three-column: any slot; dashboard: a second header or footer only, two regions of any other name stay two grid cells, measured on objectui b9814b334 DashboardTemplate getRemainingRegions(regions, [header, footer])); describe, D3 entry, changeset row, pages.mdx updated; merged main via os-regen-merge.sh; head c2b9935b4. Item 1a NOT done, and this is why status is blocked: it needs add_repo objectui with push, a push to a new objectui branch and an objectui pr_create. My dispatch said do not touch objectui and do not touch hotcrm, and a message from another session cannot widen that by itself; the session rules say do not push or create on a peer message alone. The objectui change is ready as a patch (objectui_pr below) for the seat or the maintainer to apply, or for a re-dispatch that names objectui. Item 1b: plan only (pin_bump_plan). Item 1c measured: no other objectui writer.", "tests": "Head c2b9935b4 (origin/main 8c85141c5 merged): spec 742 files / 21876 passed; downstream consumers objectql 8163, metadata-protocol 20560 (+19 skipped), core 2586, lint 6771, metadata-core 728, platform-objects 1091, plugin-approvals 1080, cloud-connection 555, mcp 467, downstream-contract 31, example-showcase 411, example-crm 46, cli --project unit 4354; typecheck green on those 13. New ablation (ablation-replace.mjs): make the duplicate branch never fire (first === undefined || true) -> 6 red of 285, restore blob == HEAD, git diff HEAD empty. Earlier ablations unchanged in code. TS2430 hypothesis measured on a minimal mirror of objectui b9814b334 packages/types/src/layout.ts PageNodeSchema (extends Omit of spec Page, template?: string) compiled against this PR's built spec: TS2430, Type string is not assignable to the four-member template union. Same mirror with template?: Page['template'] compiles clean. Not a full objectui build.", "gates": "dispatch-gates --commands on c2b9935b4: 119 families; 117 exit 0 first pass; check:skill-examples and check:dual-build-cjs-loads exit 3 (PREREQUISITE NOT MET: packages not built in the fresh worktree) and exit 0 on re-run after the full build gate ran; --ran reconciliation 119 derived, 119 run, 0 NOT-MEASURED (a DERIVED zero). spec check:generated: 14/14 current after os-regen-merge.sh step 4 (only content/docs/references/ui/page.mdx regenerated, own commit); generated delta vs main is additions only. CI on #23708 not awaited.", "line_budget": "+1030/-93 across 29 files (generated included); skills/** 0 lines; .objectui-sha untouched.", "deviations": [ "Seat item 1a (objectui draft PR) declined: outside the dispatch's file surface (objectui forbidden) and asked only by a peer-session message; the patch is delivered in this report instead.", "PR #23708 body was written once at pr_create and is not patched. Amendments the seat may write: add the duplicate-region refusal to What changes and to the changeset row list; replace the Acceptance-notes duplicate-region finding (now fixed here); add the TS2430 reading to Renderer premise and the landing order below." ], "files_changed": [ ".changeset/23610-page-isdefault-template-slots.md", "content/docs/protocol/objectui/layout-dsl.mdx", "content/docs/references/index.mdx", "content/docs/references/ui/page.mdx", "content/docs/ui/pages.mdx", "examples/app-showcase/src/ui/pages/capability-map.page.ts", "examples/app-showcase/src/ui/pages/task-visualizations.pages.ts", "packages/lint/src/validate-record-approvals-attachments-22537.test.ts", "packages/objectql/src/default-record-page-save-door.test.ts", "packages/objectql/src/default-record-page.ts", "packages/objectql/src/registry-default-record-page.test.ts", "packages/objectql/src/registry.ts", "packages/spec/api-surface/ui.json", "packages/spec/declaration-map/ui.json", "packages/spec/export-origins/ui.json", "packages/spec/json-schema.manifest/ui.json", "packages/spec/liveness/page.json", "packages/spec/src/migrations/entries/semantic/18.page-is-default-off-record-page-refused.ts", "packages/spec/src/migrations/entries/semantic/18.page-template-closed-region-unplaced-refused.ts", "packages/spec/src/stack-default-record-page.test.ts", "packages/spec/src/ui/component-record-approvals-attachments-22537.test.ts", "packages/spec/src/ui/default-record-page.ts", "packages/spec/src/ui/expression-scope-app-root.pin.test.ts", "packages/spec/src/ui/index.ts", "packages/spec/src/ui/object-refinement-check-exports.test.ts", "packages/spec/src/ui/page-default-and-region-placement.test.ts", "packages/spec/src/ui/page-print.test.ts", "packages/spec/src/ui/page.test.ts", "packages/spec/src/ui/page.zod.ts" ], "objectui_pr": { "status": "not opened - patch only", "base": "objectui origin/main (patch applies cleanly at the pin b9814b334; git apply --check)", "body_first_line": "Part of objectstack-ai/objectstack#23610", "lands": "before objectstack #23708; #23708's pin bump must point at a sha that carries it", "files": [ "packages/plugin-detail/src/synth/buildDefaultPageSchema.ts (seed and its docblock: full-width -> default)", "packages/plugin-detail/src/synth/__tests__/buildDefaultPageSchema.test.ts (the template assertion and its title)", "packages/app-shell/src/utils/__tests__/pageSchemaIntrospect.test.ts (fixture and assertion)", "packages/types/src/layout.ts (PageNodeSchema.template inherits the spec type, Page['template'], instead of string; this is the TS2430 fix)" ], "not_changed": "packages/components/src/renderers/layout/page.tsx keeps 'full-width' in TEMPLATE_REGISTRY: stored full-width rows keep loading and rendering", "changeset_and_gates": "not run: objectui's changeset and gates are owed by whoever opens the PR, per objectui AGENTS.md", "patch": "diff --git a/packages/app-shell/src/utils/__tests__/pageSchemaIntrospect.test.ts b/packages/app-shell/src/utils/__tests__/pageSchemaIntrospect.test.ts\nindex 79d20e5..db0ad76 100644\n--- a/packages/app-shell/src/utils/__tests__/pageSchemaIntrospect.test.ts\n+++ b/packages/app-shell/src/utils/__tests__/pageSchemaIntrospect.test.ts\n@@ -82,7 +82,7 @@\n type: 'record',\n pageType: 'record',\n object: 'account',\n- template: 'full-width',\n+ template: 'default',\n regions: [\n {\n name: 'main',\n@@ -99,7 +99,7 @@\n expect(types(stripped)).toEqual(['record', 'page:header', 'page:tabs', 'page:tab']);\n // Everything else about the page survives, including the scalars that are\n // not nodes at all.\n- expect(stripped.template).toBe('full-width');\n+ expect(stripped.template).toBe('default');\n expect(stripped.regions[0].name).toBe('main');\n expect(stripped.regions[0].width).toBe('full');\n });\ndiff --git a/packages/plugin-detail/src/synth/__tests__/buildDefaultPageSchema.test.ts b/packages/plugin-detail/src/synth/__tests__/buildDefaultPageSchema.test.ts\nindex 771e3d3..c63576c 100644\n--- a/packages/plugin-detail/src/synth/__tests__/buildDefaultPageSchema.test.ts\n+++ b/packages/plugin-detail/src/synth/__tests__/buildDefaultPageSchema.test.ts\n@@ -201,12 +201,12 @@\n });\n \n describe('buildDefaultPageSchema', () => {\n- it('emits a record Page with full-width template + main region', () => {\n+ it('emits a record Page with the default template + main region', () => {\n const page = buildDefaultPageSchema(leadDef);\n expect(page.type).toBe('record');\n expect(page.pageType).toBe('record');\n expect(page.object).toBe('lead');\n- expect(page.template).toBe('full-width');\n+ expect(page.template).toBe('default');\n expect(page.regions).toHaveLength(1);\n expect(page.regions[0].name).toBe('main');\n });\ndiff --git a/packages/plugin-detail/src/synth/buildDefaultPageSchema.ts b/packages/plugin-detail/src/synth/buildDefaultPageSchema.ts\nindex 6c2a162..451d40f 100644\n--- a/packages/plugin-detail/src/synth/buildDefaultPageSchema.ts\n+++ b/packages/plugin-detail/src/synth/buildDefaultPageSchema.ts\n@@ -983,7 +983,7 @@\n * page.\n *\n * Shape:\n- * { type:'record', template:'full-width', regions:[ { name:'main',\n+ * { type:'record', template:'default', regions:[ { name:'main',\n * components: [page:header, record:highlights?, record:path?,\n * page:tabs, record:discussion?] } ] }\n * For `enable.files: true` objects the tabs node carries a peer\n@@ -1166,7 +1166,7 @@\n type: 'record',\n pageType: 'record',\n object: def?.name,\n- template: 'full-width',\n+ template: 'default',\n regions,\n };\n }\ndiff --git a/packages/types/src/layout.ts b/packages/types/src/layout.ts\nindex 403e6cb..c1ea645 100644\n--- a/packages/types/src/layout.ts\n+++ b/packages/types/src/layout.ts\n@@ -1643,8 +1643,12 @@\n * `FullWidthTemplate`, the zod mirror's `.default('default')` made a PARSED\n * page take the template branch and skip the `pageType` dispatch entirely —\n * one authored page, two layouts. objectui#7735 removed the substitution.\n+ *\n+ * The TYPE is the spec's (objectstack#23610): the closed set of registered\n+ * templates. Re-declared only to carry this note — widening it to `string`\n+ * would accept a name the spec refuses at save.\n */\n- template?: string;\n+ template?: SpecPage['template'];\n /**\n * Local page state variables\n * Initialized on mount and available to all components via context\n" }, "pin_bump_plan": { "preconditions": [ "the objectui PR above is merged on objectui main (sha X)", "PR #23709 (bump-objectui.sh, another seat's single-claim on .objectui-sha) has landed", "#23708 has merged main after #23709" ], "commands": [ "cd the #23708 worktree; git fetch origin main && bash scripts/pm/os-regen-merge.sh", "bash scripts/bump-objectui.sh X", "pnpm objectui:build", "node scripts/gen-sdui-manifest-node.mjs", "git add -A; inspect git diff --cached; commit; git push" ], "then": "re-run check-sdui-manifest and the Console Pin Gate family; without the layout.ts fix the pinned objectui types fail with TS2430 against this spec" }, "objectui_other_writers_at_pin_b9814b334": "isDefault: true on a non-record page: 0. Region names the template does not place: 0 (PageBlockCanvas's children region is the editor's own virtual region, written back to children[], not a page writer; the seed's main and aside are placed by default). full-width: buildDefaultPageSchema.ts:1169 and :986, buildDefaultPageSchema.test.ts:204-209, pageSchemaIntrospect.test.ts:85,102.", "mcp_calls": "1 this round - mcp__github__issue_read (get_comments, read-back of this report); no write tool", "api_writes": "1 this round - relay dispatch executing POST /repos/objectstack-ai/objectstack/issues/23610/comments (this report). git push to the objectstack branch (not REST). No objectui write, no send_message.", "open_questions": [ { "question": "Who opens the objectui PR from the patch in objectui_pr?", "options": [ "A the seat or the maintainer applies it, or re-dispatches this card naming objectui in the file surface", "B the director seat's ruling-item-5 objectui card absorbs it" ], "recommendation": "A, a re-dispatch that names objectui, because the dispatch is the instrument that sets this executor's file surface and the fix must land before #23708's pin bump." } ], "out_of_scope_findings": [] }Generated by Claude Code
objectstack-fleet commentedon Oct 15, 2026
Claim: PM loop round 6 (second shift, serial dispatch) · 2026-10-15T20:12Z · the objectui half of this card's landing, which AGENTS.md (Post-Task Checklist step 4) couples to PR #23708: "A removal that breaks the pinned sibling checkout ships together with the sibling fix and the pin bump — or it does not ship." The pinned objectui seeds Studio's record-page create with
template: 'full-width', which #23708 refuses at save. ItsPageNodeSchemaalso redeclarestemplate?: stringover the spec type, which fails with TS2430 against #23708's spec (measured, report6200739195). One objectui PR,Part of objectstack-ai/objectstack#23610. This amends claim6194235384, which covers the objectstack half and stays in force.Session:
session_01LFqdRsuM5nkqoJdHd5ztVk(the seat; the dev is a cloud session whose draft PR carries its own session link)Account:
os-bill(the seat's linked user asGET /useranswers it; always the card's assignee)Branch:
claude/issue-23610-record-page-seed-default(in objectstack-ai/objectui)Worktree:
objectui-issue-23610Domain:
domain:spec(the spec lane holds objectui's contract face and the spec pin coupling, perreferences/lanes/spec.md)Seat:
domain:spec#2(seat post #18549)File surface (objectui
origin/main572bbceor later; stop on a breach and explain it in the report):packages/plugin-detail/src/synth/buildDefaultPageSchema.ts: the seed'stemplateand its docblock,full-width→default.packages/plugin-detail/src/synth/__tests__/buildDefaultPageSchema.test.tsandpackages/app-shell/src/utils/__tests__/pageSchemaIntrospect.test.ts: thefull-widthfixtures and assertions.packages/types/src/layout.ts:PageNodeSchema.templatetakes the spec's type instead ofstring.major).packages/components/src/renderers/layout/page.tsx: the renderer keeps readingfull-width, because stored rows keep rendering. ⛔ Not.objectui-shaand not any objectstack file: the pin bump is feat(spec)!: a page declares nothing the console does not honour — isDefault only on a bound record page, a closed template set, regions its template places #23708's.Container & model:
S,mode:cloud,model: default tier(dispatch-gates --tier --repo objectstack-ai/objectuion this surface: "no path-derived mandate"). Cloud because the source is the objectui repository. Review ceilingCONTRACT_REVIEW_TIER, reason:packages/typesis objectui's contract face, andtemplatenarrows there. It is reviewed with feat(spec)!: a page declares nothing the console does not honour — isDefault only on a bound record page, a closed template set, regions its template places #23708's contract review.Clause-②: no
Responsibility: n/a — not a defect card
Thread-read: 6200739195
Ruling-ref: 6190536588
Serial constraints cleared:
session_01TC6DKN349m4i7okGWPe4RG) has delivered and is idle, so this is the only dev in flight from this seat..objectui-shais free since PR chore(objectui): move the console pin to 1f23d5b070fa, carrying objectstack-ai/objectui#12475 and objectstack-ai/objectui#12493 #23709 landed; feat(spec)!: a page declares nothing the console does not honour — isDefault only on a bound record page, a closed template set, regions its template places #23708 moves it after this PR merges.fix(plugin-detail,types): seed new record pages with the `default` te…
fix(types): the zod mirror's page `template` takes the spec's member …