Skip to content

spec: a slotted record page keeps six slots — header, actions, alerts, highlights, details, discussion — and the tabs slot is retired; a page that needs its own tab strip is a kind: full page #27053

Closed

Description

@objectstack-fleet

Part of the record-page-v3 epic #26676 (v3 child 4 of 8). Contract card (spec lane); claimed from the epic session on the maintainer's instruction in the footer.

Source (origin/main 7bb8084590)

packages/spec/src/ui/page.zod.ts slots (strict object, ~:2121) admits header, actions, alerts, highlights, details, tabs, discussion (aliases activity / chatter → discussion, related / relatedLists → tabs, fields / body → details); checkPageSlotPair (:1262, #22568) refuses details + tabs together. buildDefaultPageSchema.ts:~1130-1215 composes: a tabs slot replaces the whole synthesized strip (related / approvals / attachments / history included — the author must re-add them). With the column tiers (#26758) a tabs slot bypasses the tiers (RecordDetailView.tsx:825 pageColumnsEligible): the page is tabbed at every width. HotCRM uses slotted once (account: header + discussion), never tabs.

Target

  1. slots.tabs is retired under the spec-property-retirement kit: tombstone via retiredKey() with the prescription 「the record page composes its tabs / columns from the object's roles and relationship flags; to change which related lists appear or their order, set relatedList / relatedList: 'primary' on the child's reference field; a page that needs its own strip is kind: 'full'」; the related / relatedLists aliases go with it; checkPageSlotPair and its test retire with the pair; ADR-0087 disposition (D2 conversion that drops the slot and, when it was the only slot, leaves an empty slotted page = the synthesized default; D3 entry for the judgement the edit cannot make — whether that page should become kind: full).
  2. The synthesizer composes the strip / columns from the six remaining slots only; RecordDetailView's pageColumnsEligible no longer needs the tabs branch.
  3. Docs: ui/content/docs/guide/slotted-pages.md slot menu, the generated references, the skill bullet (skills/objectstack-ui/** — governed, Tier H).

File surface

packages/spec/src/ui/page.zod.ts + the retirement kit files, spec tests; ui/packages/plugin-detail/src/synth/buildDefaultPageSchema.ts, ui/packages/app-shell/src/views/RecordDetailView.tsx (one gate line), ui/content/docs/guide/slotted-pages.md, skills/objectstack-ui/rules/*.md (one bullet), changesets (narrowed, BREAKING with migration). Clause-②: no (narrowing); Metadata-protocol: narrowed.

Acceptance

  1. safeParse of slots: { tabs: … }, related, relatedLists fails with the prescription (code + status + first sentence); the six live slots parse; a stored slotted page with tabs replays through the conversion.
  2. HotCRM account's slotted page still renders header + discussion overrides with the column tiers on.
  3. Tree-scoped absence pin: nothing in the repo authors a tabs slot.

Rulings (maintainer, chat in the filing session, 2026-10-28 — verbatim, not re-decidable here)

  1. Record-page model (2026-10-27): 「1. 一个对象一个默认打开方式:默认抽屉(带展开整页),page 只给显式声明的对象,modal 退役,split / popover 变成用户个人偏好;抽屉和整页是同一张页在两个宽度。」
  2. On the resident timeline column: 「时间线是不是太突出了,这个只适合部分对象吧?适合做所有业务对象的默认布局吗」 and then 「时间线是否显示,是否可以切换,比如当前版本的 Claude code,顶部有很多切换图标」 — the column's presence is a per-user toggle with an object-derived default, never metadata.
  3. On the related column's cost: 「关联都放在右侧,记录打开时是不是会很慢,因为需要加载所有的关联子表。」 — the related column loads counts first, rows on demand, and never blocks the details.
  4. On mobile: 「还要考虑手机端的效果。」
  5. On the definition surfaces: the PM's keep / narrow / retire table was put to the maintainer (keep object roles, relationship flags, six slotted slots and kind: full; retire the tabs slot and the dead BuildPageOptions hints; fold the quick-look path into the one record page) and approved with the instruction in the footer.

Filed by the epic PM session session_cdb7a717-def7-4e71-9988-f089fbaa18ff on 2026-10-28 under epic #26676 (record page v2 → v3), from the record-page definition-surface inventory on objectstack main 7bb8084590 and the maintainer's rulings in that session. The maintainer's instruction to file and dispatch, verbatim: 「同意,以上界面相关的需要我确认的你负责立卡派发,如果有可能可以启动云会话,开发完你来确认。」 Design evidence: the design canvas boards 「记录页 v3」 row (RecordPageV3, RecordPageV3NoTimeline, RecordPageRef, RecordDrawerV3, RecordMobile) — exported to the never-merged branch named in the epic parent once this batch is filed.

Activity

  1. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 2 · 2026-10-28T09:09Z
    Session: session_01WGufzfhobWEgUUrjz4rrbh
    Account: os-support-ai
    Branch: claude/project-thread-tc4fe5 (card thread session_01WGufzff3QiP6kmtajVnKnq. The platform assigns the thread's branch and the thread can push only that one, so the branch is written as measured instead of claude/issue-27053-<slug>.)
    Worktree: objectstack-issue-27053
    Domain: domain:spec
    Seat: domain:spec#1
    File surface:

  2. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 27053,
      "status": "done",
      "branch": "claude/project-thread-tc4fe5",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/27219",
      "session": "session_01WGufzff3QiP6kmtajVnKnq",
      "premise_still_valid": false,
      "summary": "Head ca5556e06, main merged at b322b5da. Re-measured on main 0f1045bc: the card's premise that no producer authors slots.tabs was wrong. Four in-repo pages did (sys_user_detail, sys_organization_detail, sys_approval_request_detail, showcase_project_detail). Seat 1 confirmed moving all four to kind: 'full' as faithful rebuilds, plus the ADR-0133 one-line amendment (comment 6465037594 claim). Done per the card Target: slots.tabs is a retiredKey tombstone with the card's prescription and the house migrate sentence; related / relatedLists aliases became strictObject guidance refusals; checkPageSlotPair and page-slot-pair.test.ts are removed, with its ui export and both objectui superRefine attachments. D2 page-slots-tabs-removed (order 78, retiredAfter 18.2.0) drops the slot and leaves an empty slotted page when it was the only slot. D3 page-slots-tabs-retired absorbs page-slots-details-beside-tabs-refused; its STEP18 fragment is at order 112; the retired-key entry is ui/Page:slots.tabs. The JOIN row, the liveness note and the regenerated api-surface/export-origins/references go with it. buildDefaultPageSchema loses the tabs branch, RecordDetailView pageColumnsEligible is one line, PageSlotMap.tabs is typed never, and the Studio SLOT_ORDER has six slots. slotted-pages.md, content/docs/ui/pages.mdx (merged from main) and one skills bullet in skills/objectstack-ui/rules/pages.md, paid by a deletion in the same file (5669/5692). ADR-0133 inline Amended line; identity-auth.json rev 6 and studio-authoring.json rev 4 pins moved. Changeset: Clause-② no (narrowing), Metadata-protocol narrowed, adr-0087 registered for both ids, BREAKING with FROM → TO, minor for spec, platform-objects, plugin-approvals, @object-ui/types, plugin-detail, app-shell and skills. PR body: /mnt/project-files/issue-27053/pr-body.md.",
      "tests": "Under the lock: spec local 22219 passed, and its 3 first-run reds fixed and re-run green (166). spec test:repo 82 files / 1343 passed. platform-objects 1377, plugin-approvals 1331, lint 7522, cli touched files 59, plugin-auth org-page 3. ui: plugin-detail 2941; 19 slot-map and served-approvals-page files 319; RecordDetailView tiers and named page 13; PagePreview 8. Typecheck 104/104 turbo tasks over the touched packages, including test-layer ledgers. New: page-slots-tabs-retirement.test.ts with 19 cases, including the tree-scoped absence pin. Moved fixtures and tests are listed in the PR body's acceptance notes.",
      "gates": "dispatch-gates --commands: 126 commands, 121 exit 0. check:role-word (the word 'roles' in the docs prose) and check:cross-package-test-inputs (the absence pin was not yet in vitest.repo-tests.json) were found and fixed, now exit 0. check-plugin-teardown-shape --self-test exit 3 on the shallow clone, then 48 cases pass after fetching its pinned commit. check:skill-examples and check:dual-build-cjs-loads exit 3: they need a full repo build, so nothing was measured. CI on the PR: not yet read at report time.",
      "dogfood_battery": "not run: no runtime path changed beyond the record page synthesizer's slot read; the four producer pages are covered by their package suites",
      "mcp_calls": "subscribe_pr_activity x1; issue_read earlier for #27053; 0 writes via MCP",
      "api_writes": "3 via the relay: pr_create (#27219, 12231 bytes read back identical, assignee os-support-ai), pr_request_reviewers (os-support-ai), and this os-dev-report comment",
      "open_questions": [
        "HotCRM's account slotted page was not measured: the hotcrm repo is outside this session's scope. If it authors tabs, the D2 conversion converts its stored row on read and os migrate meta --from 17 lists the source edit."
      ],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

  3. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Seat ruling · domain:spec seat 1 (#6017) · session session_01WGufzfhobWEgUUrjz4rrbh · 2026-10-28T11:20Z

    This records on the card a ruling the seat gave the dev thread while #27053 was in flight. The contract review on PR #27219 (6467641976, should-fix ③) asked for it.

    Premise correction. The card says no producer authors slots.tabs. The dev re-measured on origin/main 0f1045bc and found four in-repo pages that do:

    • sys_organization_detail and sys_user_detail, in @objectstack/platform-objects
    • sys_approval_request_detail, in @objectstack/plugin-approvals
    • showcase_project_detail, in examples/app-showcase (private)

    Ruling. All four move to kind: 'full' in the same PR, with behaviour identical to what the synthesizer drew for them on main:

    • the same nodes in the synthesizer's order;
    • header actions are the object's record_header / record_more ids, in declaration order;
    • the strip is byte-identical;
    • record:discussion is present exactly when the slotted page did not author discussion: [].

    Nothing is redesigned. ADR-0133 gets a dated inline amendment saying the slotted page no longer has a tabs slot and that a page needing its own strip is kind: 'full'. This follows the card's own prescription. There is no new decision for the maintainer, because the maintainer's keep/narrow/retire ruling already retires the slot and names kind: 'full' as the route.

    Measured. Contract review 6467641976 judged the four rebuilds faithful node by node against buildDefaultPageSchema on main.

  4. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:spec seat 1 (#6017) · session session_01WGufzfhobWEgUUrjz4rrbh · 2026-10-28T15:16Z

    PR #27219 merged through the queue at 6dbff8e2, which is an ancestor of origin/main. On 65 of the 72 paths the PR touched, the merge tree matches the accepted head 95738710 byte for byte. On the other 7 paths, the PR's net hunks from the merge-base cdec7473 are identical to 6dbff8e2^1..6dbff8e2; the bytes differ only because other work landed on main in between. In registry.ts.template a moved unchanged text: context line pairs out to nothing.

    The page tabs slot is retired. D2 page-slots-tabs-removed (idempotent, copy-on-write, retiredAfter 18.2.0) converts a stored page, and the D3 entry 18.page-slots-tabs-retired names that conversion. The four built-in record pages are rebuilt as kind: 'full' pages that author their own page:tabs. A drift pin holds their page:header actions equal to the object's record_header ∪ record_more. It landed with os-zhuang's governed approval (5684520620). The evals for the skills bullet live on #27059.

    The card closed through Fixes #27053, and this seat removes pm:dispatched.

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

Metadata

Metadata

Assignees

Labels

area:recordsBusiness objects, records, the views that show data, usable forms, searchdomain:specenhancementNew feature or requestpriority:p1High: required for production / M2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions