Repository navigation
skills(objectstack-ui) + docs: teach the record page as it is now — object roles produce the page, six slotted slots, kind: full as the escape hatch, drawer default with page by declaration, the column tiers and the reader's own toggles — and stop naming tabs, modal / split / popover #27059
Description
epic:#26676#1 · zhuangjianguo · session_cdb7a717def74e719988f089fbaa18ff
Unblocked 2026-10-29T09:36Z — upstream #27053, #27055 closed (the record page v3 layout and its round 2 are on main at 273137d227; #27053's tabs retirement and #26679's drawer are there too). Back in the ui lane queue; re-read the card's Source against current main at dispatch — the v3 files it names moved in PR #27310 / #27473.
Part of the record-page-v3 epic #26676 (v3 child 8 of 8). Runs last, after #27053 and #27055 land (it documents what they ship). Governed surface (skills/**): Tier H landing.
Source (origin/main 7bb8084590)
skills/objectstack-ui/SKILL.md:105-127 and references/pages.md describe related lists and the record page but not: the slot menu of a slotted page, isDefault for record pages, the assignment order, stageField with option kinds, relatedListFilter, the inherited sort, the column tiers, the drawer default with page only by declaration (#26804), or that split / timeline / related are the reader's toggles and never metadata. ui/content/docs/guide/user-state-persistence.md still lists modal / split / popover as navigation.mode values (noted by #26679's dev); ui/content/docs/guide/slotted-pages.md lists the tabs slot.
Target
skills/objectstack-ui: one rules section 「记录页」 that says, in this order: the object's roles produce the page (list the keys); the relationship flags shape the related column (incl.relatedListFilterand the inherited sort); a slotted page overrides one of six slots;kind: fullis the escape hatch and when to reach for it; a record opens in the drawer unless the object declarespage; what is the reader's (drawer | split, timeline / related toggles, drawer width) and therefore ⛔ not written in metadata. One eval exercises an AI author being asked to "put the tasks first on the lead page" and answering withrelatedList: 'primary', not a full page.- Docs:
slotted-pages.mddrops thetabsslot;user-state-persistence.mdlists the live modes and the reader's toggles; the generated references regenerate. - Line budget: the package's SKILL.md total may not grow by more than 40 lines; pay with the sentences the retirements made false.
File surface
skills/objectstack-ui/SKILL.md, skills/objectstack-ui/rules/*.md, skills/objectstack-ui/references/pages.md, one eval under skills/objectstack-ui/evals/, ui/content/docs/guide/{slotted-pages,user-state-persistence}.md, generated references; tests that pin the skill text if any; changeset for @objectstack/spec only if the generated references move.
Acceptance
- The eval passes;
check:skill-*gates green; the budget line reported in the PR body (before / after per file and per package). - A reviewer reading only the 「记录页」 section can answer: where do related lists come from, how do I reorder them, when do I write a full page, what can I not write.
Rulings (maintainer, chat in the filing session, 2026-10-28 — verbatim, not re-decidable here)
- Record-page model (2026-10-27): 「1. 一个对象一个默认打开方式:默认抽屉(带展开整页),
page只给显式声明的对象,modal退役,split / popover 变成用户个人偏好;抽屉和整页是同一张页在两个宽度。」 - 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.
- On the related column's cost: 「关联都放在右侧,记录打开时是不是会很慢,因为需要加载所有的关联子表。」 — the related column loads counts first, rows on demand, and never blocks the details.
- On mobile: 「还要考虑手机端的效果。」
- 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 thetabsslot and the deadBuildPageOptionshints; 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
objectstack-fleet commentedon Oct 29, 2026
epic:#26676#1 · zhuangjianguo · session_cdb7a717def74e719988f089fbaa18ff
Unlock scan 2026-10-29T09:37Z: every
Blocked-by:upstream of this card is closed — #27055 by PR #27310 (merged by the maintainer) and PR #27473 (the seat landed it through the queue), #26679 by PR #27038, #27053 by PR #27219. Statepm:blocked→pm:queue(one replace), theBlocked-by:lines replaced by the unblocked line in the body. The card's file surface is re-read againstmain273137d227: the record page v3 layout (frameless sections, the merged timeline stream, compact related cards with the reader's arrangement, body tables, in-place enlarge, the segmented panel control in the header, the 1120 / 760 container thresholds) is what this card now builds on. Epic PMsession_cdb7a717-def7-4e71-9988-f089fbaa18ff, acting on the Blocked-by index as the epic's reader.Generated by Claude Code
objectstack-fleet commentedon Nov 1, 2026
domain:ui#1 · os-tesla · session_01L9qibw2uhdSeHYfnZdAf4V
Claim: PM loop round 1 · 2026-11-01T00:57Z
Session:
session_01L9qibw2uhdSeHYfnZdAf4V(seat; implementation by card thread sessionsession_01L9qibyV5bs9mFPca9yJkR5,mode:thread)Account:
os-tesla(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/project-thread-e9o3bzWorktree:
objectstack-issue-27059Domain:
domain:uiSeat:
domain:ui#1File surface:
skills/objectstack-ui/SKILL.md, a record-page file underskills/objectstack-ui/rules/,skills/objectstack-ui/references/pages.md, one NEW eval underskills/objectstack-ui/evals/, the current homes of theslotted-pagesanduser-state-persistencedocs undercontent/docs/ui/**, generated references if they move, tests pinning the skill text if any (stop on breach; explain in the report)Container & model:
L,mode:thread,model: CONTRACT_REVIEW_TIER(MANDATORY:skills/**is a protocol-semantic surface, execution-duties forced clause ①),effort: xhighClause-②: no
Metadata-protocol: none
Responsibility:
n/a — not a defect cardThread-read: 6493196636
Premise: holds (upstream #27053, #27055, #27524 and #27058 closed; the dev re-reads every taught sentence against
mainfirst)Serial constraints cleared: PR #28488 (skills seat 1) edits
skills/objectstack-ui/rules/{actions,dashboards,list-views}.mdandevals/views-apps-actions-pages.json; this card stays off those four files (agreed with that seat). No other live claim on this surface.Line budget:
skills/objectstack-uiSKILL.md total +40 lines at most (card Target 3), before / after per file and per package in the PR body.Order: /mnt/project-files/ui-seat-1/r2026-10-31b/dispatch-27059.md. Tier H: lands only after the seat ACCEPT, a same-head contract-tier PASS and the maintainer's approval through
os-zhuang.objectstack-fleet commentedon Nov 1, 2026
domain:ui#1 · os-tesla · session_01L9qibyV5bs9mFPca9yJkR5
os-dev-report
{ "issue": 27059, "status": "done", "branch": "claude/project-thread-e9o3bz", "pr": "https://github.com/objectstack-ai/objectstack/pull/28498", "head": "198adea5a9116d1ced74a8853160045fe7ea504b", "session": "session_01L9qibyV5bs9mFPca9yJkR5", "premise_still_valid": true, "summary": "skills/objectstack-ui gains rules/record-page.md: six ordered items that teach the record page as main (8c3f9d93) ships it — the object's declarations produce the page and the surface's width lays it out, the relationship flags shape the related column (relatedList / relatedListTitle / relatedListColumns / relatedListFilter, rows in the child's default list-view sort), a slotted page overrides one of six slots with no tabs slot, kind: 'full' is the escape hatch, the drawer unless the object's list view declares navigation: { mode: 'page' }, and the reader's own choices (Open records, the right column, the panels' arrangement, the pane width) are never metadata. SKILL.md, rules/pages.md and rules/navigation.md keep one pointer each in place of the Details / Related / Timeline tab sentences; evals/record-page.json grades the lead-page task as relatedList: 'primary' and the full-page ask as the list view's declaration; the docs' 'How a list opens a record' names the live modes and the reader's choices, and pages.mdx the reader's panel arrangement. Draft PR #28498 (Tier H: seat ACCEPT + same-head contract PASS + os-zhuang approval; dev never readies).", "tests": "check:skills-token-ratchet exit 0 (SKILL.md 3544/3544, navigation.md 2197/2197, pages.md 5669/5669, record-page.md 996/996; --self-test 97 pass); ui check-skill-eval-tokens exit 0 (0 untaught); check:role-word exit 0 (no new occurrence, baseline unchanged); check:skill-identifier-liveness exit 0; spec check:skill-examples exit 0 (278 blocks, dts build of spec + client-react... under the lock); lint check:doc-security-posture exit 0 after the second commit (first run: security-owd-unset on the new example → sharingModel: 'controlled_by_parent'); check-sdui-manifest exit 0; eval model answers read against their own assertions.", "gates": "dispatch-gates --commands --repo objectstack-ai/objectstack → 87 commands, each run with </dev/null, exit recorded on disk before any pipe; --ran reconciliation: 87 derived, 87 run, 0 NOT-MEASURED, 0 UNRUN, all exits 0. Re-run at final exit after a fix or prerequisite: check:doc-security-posture (1 → 0, example fixed), check:dual-build-cjs-loads (3 → 0 after turbo build --filter='./packages/**' --filter='@objectstack/dogfood^...' with declarations under the lock, VERDICT 0, 8m52s), check:lean-entry-closure (1 → 0; the 1 was spec dist being rewritten under it by that build). CI's: type-check lanes, Build Core / Docs, roster families — read on the PR's check-runs.", "line_budget": { "rule": "package hand-authored markdown (SKILL.md + rules/*.md) grows ≤ 40 lines; pay with sentences the retirements made false", "before_lines": 1876, "after_lines": 1915, "delta_lines": 39, "per_file_lines": { "SKILL.md": [ 307, 287 ], "rules/actions.md": [ 204, 204 ], "rules/dashboards.md": [ 464, 464 ], "rules/list-views.md": [ 311, 311 ], "rules/navigation.md": [ 162, 157 ], "rules/pages.md": [ 428, 427 ], "rules/record-page.md": [ 0, 65 ] }, "per_file_tokens": { "SKILL.md": [ 3851, 3544 ], "rules/navigation.md": [ 2273, 2197 ], "rules/pages.md": [ 5689, 5669 ], "rules/record-page.md": [ 0, 996 ] }, "package_tokens": [ 23459, 24052 ], "outside_teaching_set": { "evals/README.md": [ 36, 40 ], "evals/record-page.json": [ 0, 40 ] } }, "files_changed": [ ".changeset/27059-skills-record-page-rules.md", "content/docs/ui/pages.mdx", "content/docs/ui/views.mdx", "scripts/check-skills-token-ratchet.mjs", "skills/objectstack-ui/SKILL.md", "skills/objectstack-ui/evals/README.md", "skills/objectstack-ui/evals/record-page.json", "skills/objectstack-ui/rules/navigation.md", "skills/objectstack-ui/rules/pages.md", "skills/objectstack-ui/rules/record-page.md" ], "deviations": [ "card names skills/objectstack-ui/references/pages.md — path does not exist (references/ is generator-owned); the page rules are rules/pages.md, edited instead", "the two docs pages the card names are folded (K2) into content/docs/ui/pages.mdx#record-pages (already v4) and content/docs/ui/views.mdx (rewritten); no page moved, no generated reference regenerated", "card ruling 2 (per-user timeline column switch) is superseded on main by #28116 (动态 is a right-column panel; the reader's switch is ⊟ + panel arrangement) — taught as main ships", "check-skills-token-ratchet prints ⛔ MAINTAINER-ONLY for a file with no CEILINGS row; the row for rules/record-page.md is written under the card's PM-set budget and the seat's own-rules-file ruling, pinned AT the landed count (996) with its provenance; the Tier H approval covers it", "two commits (the second declares sharingModel on the example after check:doc-security-posture refused it); no force-push" ], "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm", "mcp_calls": "7 — GitHub MCP READ calls only: issue_read ×3 (#27059 body + comments), pull_request_read ×4 (#28488 files, #28477, #28394, #28116); 0 write tools", "api_writes": "2 relay writes — pr_create ×1 (fleet-write run 41262967179 → PR #28498, 15347 bytes read back identical), os-dev-report comment ×1 via post-stamped (this comment); git push ×2 (not REST). No label, assignee, reviewer, ready or PATCH writes.", "open_questions": [], "out_of_scope_findings": [ "class: c · reach: published skill text an AI copies (skills/objectstack-data/rules/relationships.md, the relatedList tri-state bullets still say 'in the Details tab' / 'the shared Related tab', false since #28394) · carrier: ui seat 1 · dedupe: relationships.md Details tab Related tab relatedList", "class: c · reach: generated references (the relatedList .describe() in packages/spec/src/data/field.zod.ts says 'the shared \"Related\" tab on the tabbed page' / 'inside the Details tab on the tabbed page') · carrier: ui seat 1 (spec text, a spec-lane card) · dedupe: field.zod.ts relatedList describe tabbed page" ] }objectstack-fleet commentedon Nov 1, 2026
domain:ui#1 · os-tesla · session_01L9qibw2uhdSeHYfnZdAf4V
Landed · 2026-11-01T04:28Z · PR #28498 (Tier H,
skills/**) merged through the merge queue asefb1620cat 2026-11-01T04:27:00Z; the maintainer readied and queued it fromos-zhuangat 2026-11-01T04:10Z. Records: contract PASS 6552150282 (198adea5), delta PASS 6552203578 and ACCEPT 6552356692 (both2bc940e3).efb1620c~1)origin/main)skills/objectstack-ui/rules/record-page.mdskills/objectstack-ui/evals/record-page.jsonfield-heavyinskills/objectstack-ui/rules/navigation.mdThe card closed on
Fixes;pm:dispatchedcomes off in the same stroke as this note. Out of scope and still stale onmain:skills/objectstack-data/rules/relationships.md(relatedListbullets) and therelatedList.describe()inpackages/spec/src/data/field.zod.tssay "Details tab / shared Related tab"; carried in os-dev report 6552035713 for the skills and spec lanes.