Skip to content

docs(skills): navigation.md states the derived record surface per flow — viewing routes to a page, create/edit opens a modal bounded on desktop and full-screen on mobile, a light record uses a drawer - #23795

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-23753-navigation-record-surface
Oct 16, 2026
Merged

os-zhuang merged 1 commit into
mainfrom
claude/issue-23753-navigation-record-surface

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #23753
Clause-②: no

What

skills/objectstack-ui/rules/navigation.md L131–135 — the 「Surface (page vs drawer)」 bullet under Record Presentation — said a field-heavy object "opens create/edit/detail as a full page" and that "Mobile always pages". The platform derives otherwise. deriveRecordFlowSurface in packages/spec/src/data/record-surface.ts, read at the branch point 0b1179f33: deriveRecordSurface answers 'page' on a mobile viewport or at/above RECORD_SURFACE_PAGE_THRESHOLD (12) authorable fields, else 'drawer' (L88–93); the view flow routes when that says 'page' and overlays a drawer otherwise (L160–162); the task flows (create / edit / child-*) never route — a derived 'page' becomes a modal, size: 'full' on mobile and size: 'auto' (the renderer's bounded lg/xl) on desktop, and a light record stays a drawer (L163–169; objectui#12521 letter B, landed as PR #23747). So the sentence was wrong for create/edit on every viewport, and "mobile always pages" held only for view.

The bullet now reads (5 lines, as before):

- **Surface.** Derived from field count and viewport. A field-heavy record, or
  any on mobile, is viewed on a **page** and created/edited in a **modal**
  (bounded on desktop, full-screen on mobile); otherwise a **drawer**. To force
  it, set `navigation.mode` (`page` | `drawer` | `modal`) on the list view — or,
  for bespoke layout, assign a record `Page`.

Each clause against the derivation: "field-heavy record, or any on mobile" is deriveRecordSurface answering 'page' (L89, L91); "viewed on a page" is the view branch's 'route' (L161); "created/edited in a modal (bounded on desktop, full-screen on mobile)" is the task-flow branch (L166–168: surface: 'modal', size: opts.viewport === 'mobile' ? 'full' : 'auto'); "otherwise a drawer" is the light record on desktop, which every flow overlays as a drawer (L92, L169).

Keys named, each checked where the sentence puts it: navigation.mode is NavigationConfigSchema.mode (packages/spec/src/ui/view.zod.ts L2355; the enum at L2308–2316 carries page / drawer / modal among its seven values, unchanged hint), mounted on the list view at L2859 (ListViewSchema.navigation); a record Page is unchanged from the old text. The old "(or object)" is dropped: the object schema declares no navigation key (packages/spec/src/data/object.zod.ts — its edit-intent key is editMode, a different key; see Acceptance notes). navigation.size, FormView.type and modalSize, which the derivation's docblock (L150–152) also lists as overrides, are declared (L2376, L4313–4320, L4399) but not added here: size is already taught two bullets down under Overlay width, and the token budget below buys no new key.

Token payment at zero headroom, inside the file, by content deletion only (no re-wrap): the title parenthetical "(page vs drawer)" — the bullet now names three surfaces, so the two-way title was false as well as costly; "Don't set it." — the section's intro at L125–126 ("You do not author the surface…") and its closing rule of thumb at L160–162 both state it; the false "(or object)"; and "for a specific object" — the list view is the per-object placement. The bullet goes 364 → 363 bytes, the file 9091 → 9090.

Text only; no behaviour changes. One other file: .changeset/23753-navigation-record-surface.md (@objectstack/skills patch). The edited file ships: packages/skills/package.json files[] is dist, and sync-catalog copies skills/** into dist/skills/** byte for byte. Measured after pnpm --filter @objectstack/skills build under the shared verify lock (65 files across 10 skills copied, read back byte-identical): the new lead sentence is in dist/skills/objectstack-ui/rules/navigation.md (1 hit), the old title "Surface (page vs drawer)" is not (0 hits), the file's heading is (positive control, 1 hit), and cmp against the source answers identical.

Readings (skills/**)

reading before (0b1179f33) after (9fc1d4717)
navigation.md lines 162 162 (net 0; the bullet stays 5 lines)
skills/objectstack-ui/** lines (the skill, every file) 2214 2214
all ten skills/*/SKILL.md lines (the catalog) 4408 4408
check-skills-token-ratchet, navigation.md 2273 tokens (ceiling 2273; headroom 0) 2273 tokens (ceiling 2273; headroom 0)

Verdict lines verbatim — before: ✓ check-skills-token-ratchet: skills/objectstack-ui/rules/navigation.md is 2273 tokens (ceiling 2273; headroom 0). — after: ✓ check-skills-token-ratchet: skills/objectstack-ui/rules/navigation.md is 2273 tokens (ceiling 2273; headroom 0). No ceiling moves (the CEILINGS row is untouched). The new bullet's longest line is 80 characters (the old one's was 84; the file's longest line is 181, inside a code block); no other line in the file was touched.

Verification

Derived at 9fc1d4717 by node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths; change set from the merge base 0b1179f33: 2 files, +13/−4): 41 commands — the dispatch's 29 plus 12 the changeset adds. Each ran in the foreground after the final commit, its exit code captured before any pipe into a cmd :: exit N record, then --ran reconciled the record: ✓ dispatch-gates --ran: 41 derived famil(ies) accounted for — 39 run, 2 NOT-MEASURED (2 DERIVED from a recorded exit 3).

  • 39 run, every one exit 0 — among them check-skills-token-ratchet (and its --self-test), check:skill-compatibility, check:skill-frame-sync, check:skill-identifier-liveness, check:pm-skill-id-lint, check:doc-authoring, check:nul-bytes, check:role-word, check-adr-0087-registration --base origin/main, check-changeset-no-major --base origin/main, check-empty-changeset --base origin/main, check:changeset-gate-self-tests, check:published-files, check:pm-changeset-deadline-census, check:objectui-changeset, check:pm-governed-merges, check:dts-closure, check:sourcemap-no-sources-content. check:doc-formula-expressions first refused (exit 3, PREREQUISITE NOT MET — the workspace package @objectstack/formula is not built), then passed (exit 0) after pnpm exec turbo run build --filter=@objectstack/formula --filter=@objectstack/lint under the shared verify lock — the fix its refusal named.
  • 2 NOT MEASURED locally, declared: pnpm check:dual-build-cjs-loads and pnpm check:lean-entry-closure exit 3 (PREREQUISITE NOT MET: they load every package's built dist/, which only a whole-workspace build supplies; not built here for a markdown edit). CI's Lint & Repo Gates builds and runs them; its check-run is the reading.
  • Control characters: grep -naP over both changed files finds none; pnpm check:nul-bytes exit 0.
  • No tested behaviour changed, so no ablation. No code, no packages/* source, no generated artifact, no packages/spec build (so the local-only check:dev-prereqs / check:skill-frame-freshness are not owed).

CI runs the full farm; the os-dev-report comment on #23753 cites this PR's check-runs by name and conclusion.

Acceptance notes

  • Out-of-scope observations, noted and not filed (read-only inference, no public-door probe, no class a/b/c evidence): (1) the object schema declares editMode ('modal' | 'page', object.zod.ts L2805; its TSDoc says objectui's recordFormNavigation.ts branches on it) — a per-object edit-surface intent that the derivation's docblock does not list among its sanctioned overrides and that this skill does not name; whether the skill should teach it is a wording question for the skill's owner, outside this card's one paragraph and its zero-headroom budget. Dedupe words: editMode object edit intent; navigation.md override keys; record-surface sanctioned overrides. (2) The bullet's navigation.mode hint lists 3 of the 7 declared modes (split / popover / new_window / none omitted) — pre-existing, unchanged. (3) content/docs/releases/v12.mdx L71 says "mobile always pages" — a release page is release-owned history and is never edited in a code PR; it described v12 as shipped.
  • Nothing else under skills/ states the old mapping: git grep -n -i -E "full page|always pages|page vs drawer|field-heavy" over skills/ at 9fc1d4717 hits this bullet only.
  • Governed surface (skills/**), Tier H: this PR stays a draft until an authorized approval. No label written: the changeset is present, so skip-changeset does not apply, and the dispatch names no other label.
  • Disjoint from PR docs(skills): pages.md says what a page type, template and region name run #23758 (skills/objectstack-ui/rules/pages.md + its changeset) and the release PR chore: version packages (next) #23481 (skills/*/SKILL.md): no shared file.

维护者速读(草稿)

改了什么 — skills/objectstack-ui/rules/navigation.md 「Record Presentation」节的 Surface 要点(第 131–135 行,共 5 行)。原文说「字段多的对象,新建/编辑/详情都以整页打开;字段少的用抽屉;移动端一律整页」;现在改为「按字段数与视口推导:字段多的记录(或移动端的任何记录),查看走整页,新建/编辑走弹窗——桌面端有界、移动端全屏;其余用抽屉」。覆盖子句只保留 spec 真实声明的位置(navigation.mode 在列表视图上),删掉了「或对象上」这个并不存在的键位。文件行数不变(162 → 162),token 读数不变(2273/2273,余量 0,上限不动);另加一个 @objectstack/skills 的 patch changeset。

为什么改 — 这份技能包随 npx skills add 发到客户项目,读者是写元数据的 AI。平台的实际推导(deriveRecordFlowSurface)只有「查看」会走整页;新建/编辑一律是弹窗,PR #23747 落地后桌面端弹窗有界、移动端全屏。原句让 AI 以为新建/编辑会整页跳转,与运行时不符,属于「已发布句子失真」。

风险与代价(含回滚) — 纯文本改动,不改任何代码与行为。token 棘轮在零余量下靶内付清(删掉标题括注、与前后文重复的「Don't set it.」、错误的「(or object)」、「for a specific object」),上限不动。回滚:revert 本 PR 即可,无数据与迁移影响。

席位意见 — (留空)

你要做的 — Tier H 面(skills/**):审阅上面那 5 行英文是否准确(尤其「bounded on desktop, full-screen on mobile」与 #23747 的裁决一致);同意则给 APPROVED review,由席位落地。不需要其他动作。


Generated by Claude Code

…ecord surface per flow

The Surface bullet in skills/objectstack-ui/rules/navigation.md said a
field-heavy object opens create/edit/detail as a full page and that mobile
always pages. deriveRecordFlowSurface routes only the view flow to a page;
the create, edit and child task flows open a modal, bounded on desktop and
full-screen on mobile; a light record on desktop opens every flow in a
drawer. The bullet now states that mapping, drops the "(or object)"
placement (navigation is not an object key) and pays its tokens inside the
file: net 0 lines, 2273 tokens against ceiling 2273. An @objectstack/skills
patch changeset accompanies it.

Claude-Session: https://claude.ai/code/session_01VqGhCg9wdsBXPz54uAEWg7
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation tooling labels Oct 16, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

维护者速读

改了什么

  • 改的是 skills/objectstack-ui/rules/navigation.md「Record Presentation」下的 Surface 一条。原文说:重记录的新建/编辑/详情都开「整页」,移动端一律整页。现改为平台的实际推导:
    • 重记录(或移动端上的任何记录):查看走页面,新建/编辑走弹窗,桌面上有边界,移动端全屏;
    • 其余情况:抽屉。
  • 覆盖方式只保留 spec 真实声明的位置:列表视图上的 navigation.mode。删掉了「(or object)」,因为对象 schema 没有 navigation 键。
  • 另加一个 @objectstack/skills 的 patch changeset。行数不变(162 → 162),token 不变(2273 → 2273,上限不动)。

为什么改

风险与代价(含回滚)

  • 纯文本,不改任何行为、代码或数据。
  • token 余量为 0,靠删同文件内的重复或错误内容来付:
    • 标题括注「(page vs drawer)」;
    • 「Don't set it.」:同节开头和节末「only to override — never as the default」已经说过;
    • 「(or object)」和「for a specific object」。
  • 回滚:revert 本 PR 即可。

席位意见

  • 建议批准。席位对着 main 上的 deriveRecordFlowSurface(packages/spec/src/data/record-surface.ts)逐分支核过:
    • 查看流程在「重或移动端」时走路由;
    • 任务流程(新建/编辑/子记录)从不走路由,「重或移动端」时为弹窗,移动端 size: 'full',桌面 size: 'auto';
    • 轻记录在桌面一律抽屉。
  • 新段落与之逐一对应。隔离的达档契约复核本轮由席位发起,PASS 在案前席位不会落地。你的批准可以先给。

你要做的

席位核对

Seat domain:skills#2 · session_01VqGhCg9wdsBXPz54uAEWg7 (os-elon-musk) · read 2026-10-16T02:59Z · head 9fc1d47177d7a1e33bbed9fa68a679eb9c42e1d8 · verdict: ACCEPT (Tier H — stays draft for an authorized approval)

Implemented-by: claude/issue-23753-navigation-record-surface
Reviewed-by: session_01VqGhCg9wdsBXPz54uAEWg7

  1. Shape.
  2. The bullet against main, read by the seat (packages/spec/src/data/record-surface.ts):
    • deriveRecordSurface gives 'page' on mobile or at or above the field threshold, else 'drawer'.
    • deriveRecordFlowSurface:
      • view routes on 'page' → 「viewed on a page」;
      • task flows never route, and 'page' becomes a modal, size: 'full' on mobile and 'auto' on desktop → 「created/edited in a modal (bounded on desktop, full-screen on mobile)」;
      • otherwise an overlay drawer → 「otherwise a drawer」.
    • 「or any on mobile」 is right on both branches.
    • The override clause keeps navigation.mode on the list view, which view.zod.ts L2859 declares. 「(or object)」 is gone: object.zod.ts declares no navigation key, so it was false.
    • The token payment is lossless.
      • 「Don't set it.」 is said by L125–126 (「You do not author the surface …」) and L160–162 (「Reach for navigation.mode / size / a Page only to override — never as the default」).
      • The title parenthetical and 「for a specific object」 carry no rule.
    • Lines 162 → 162, the bullet 5 → 5, tokens 2273 → 2273 against ceiling 2273 (unmoved). No untouched line is re-wrapped.
  3. Gates — check-runs pinned to head 9fc1d4717.
    • 39 check-runs, all completed: 33 success and 6 skipped (path filter); none failed.
    • success includes Lint & Repo Gates, TypeScript Type Check, Test Core (aggregate and 1–6/6), Build Core, Check Changeset, Governed Surface Queue Guard, and every Lint and Type Check lane.
    • The dev's local union at 9fc1d4717: 41 derived families, 39 run at exit 0, 2 NOT MEASURED (check:dual-build-cjs-loads and check:lean-entry-closure, read by CI's Lint · repo & tooling gates), and --ran reconciled.
    • Ship-proof: the new text is in dist/skills/objectstack-ui/rules/navigation.md, and the old title is not.
  4. Changeset, read by the seat. An @objectstack/skills patch, with Clause-②: no and one sentence per change, each matching the diff and the derivation above. 「a light record on desktop opens every flow in a drawer」 matches the derivation.
  5. Out of scope (noted, not filed; the carrier is this seat's shift brief, skill-wording class):
    • object.zod.ts L2805 declares editMode ('modal' | 'page'), a per-object edit intent that the surface docblock does not list among the sanctioned overrides. Whether the skill should name it is a wording question; there is no defect.
    • The navigation.mode hint lists 3 of the 7 declared values. This is pre-existing and unchanged.
  6. Landing (Tier H).
    • In this act: needs-user-decision and needs:contract-review are added, and review is requested from os-zhuang and hotlong. The isolated CONTRACT_REVIEW_TIER reviewer is launched on this head.
    • Landing needs both an authorized APPROVED review and the at-tier PASS. Then come the pre-landing checks and pr_ready + automerge_enable.

Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 9fc1d47177d7a1e33bbed9fa68a679eb9c42e1d8
Local-runs: none
Scope: skills/objectstack-ui/rules/navigation.md + packages/spec/src/data/record-surface.ts, packages/spec/src/ui/view.zod.ts, packages/spec/src/data/object.zod.ts, docs/adr/0085-object-semantic-roles-over-surface-hint-blocks.md, packages/skills/package.json, packages/skills/scripts/sync-catalog.mjs, .changeset/23753-navigation-record-surface.md, and the renderer in objectui at origin/main 8415d9f1 (the pinned .objectui-sha f96f7711 is its ancestor): packages/plugin-view/src/recordSurface.ts, packages/plugin-view/src/ObjectView.tsx, packages/app-shell/src/console/AppContent.tsx, packages/app-shell/src/views/ObjectView.tsx, packages/app-shell/src/utils/recordFormNavigation.ts

Read 2026-10-16T03:15Z by the isolated at-tier reviewer under seat session session_01VqGhCg9wdsBXPz54uAEWg7. Inputs: card #23753 (body + 6 comments: 6205671387, 6206342342, 6206601975, 6206628224, 6206965250, 6207050136), PR #23795 (body, 2-file list, net diff +13/−4 against merge base 0b1179f33), and the head's check-runs. Read-only: nothing built, run or re-run; every cited file read with git show at the head, and at current origin/main 46ca793e to confirm drift.

① Derived judgments

Accept-set changes the diff implies — one, plus its changeset. The diff rewrites the Surface bullet (navigation.md L131–135, 4 lines replaced, L135 kept) and adds one changeset. No code, no schema, no gate, no generated artifact. Each sentence of the new bullet, judged against the derivation on main (packages/spec/src/data/record-surface.ts, byte-identical at 0b1179f33, 9fc1d4717 and 46ca793e):

  • 「Derived from field count and viewport.」 — right. deriveRecordSurface L88–93: 'page' on viewport: 'mobile' (L89) or at/above RECORD_SURFACE_PAGE_THRESHOLD = 12 authorable fields (L91), else 'drawer' (L92).
  • 「A field-heavy record, or any on mobile, is viewed on a page」 — right. deriveRecordFlowSurface L160–162: the view flow is container: 'route' exactly when the base says 'page'.
  • 「created/edited in a modal (bounded on desktop, full-screen on mobile)」 — right. L163–168: task flows never route; a derived 'page' becomes surface: 'modal' with size: 'full' on mobile and 'auto' on desktop, which the docblock L134–136 defines as the renderer's lg/xl bound (objectui#12521 letter B, landed as PR feat(spec)!: a field-heavy task flow on desktop derives a bounded modal; mobile keeps full-screen #23747, L146–148). This is the clause the card filed for, and it is now true.
  • 「otherwise a drawer」 — right of the derivation. L92 + L169: a light record on desktop is surface: 'drawer' for every flow.
  • 「To force it, set navigation.mode (page | drawer | modal) on the list view」 — right as to declaration. NavigationConfigSchema.mode (view.zod.ts L2355), the enum L2308–2316 carrying those three among seven; mounted at L2859 inside ListViewShapeSchema (L2715), which ListViewSchema (L3128) refines — so "on the list view" is where the spec puts it. The derivation docblock L150–152 names navigation.mode / navigation.size, FormView.type / modalSize and an assigned page as the sanctioned overrides.
  • 「assign a record Page」 — unchanged; ADR-0085 §2's sanctioned per-page path.
  • Dropping 「(or object)」 — right. object.zod.ts declares no navigation key (a strictObject, so a write there is refused); its edit-intent key is editMode (L2805), a different key.
  • Dropping 「full page」 for create/edit and 「Mobile always pages」 — right. Both were false of the derivation (the first since Design: record create/edit/subtable surface + return-flow model (follow-up to #2578) #2604 D1, the second for every task flow).

The renderer, read as the second half of "derive". objectui's plugin-view/src/recordSurface.ts re-exports deriveRecordSurface / deriveRecordFlowSurface from @objectstack/spec/data (one source, L24–29). The card's target clause holds in the shipped console too: AppContent.tsx opens every create/edit in ModalForm (formType: 'modal', L1209), spreads modalSize: 'full' only when the derivation answers 'full' (L1231–1238), and interimBoundedTaskFlowSurface (L131–132) maps 'full' → 'auto' on desktop until objectui installs a spec carrying #23734 (its pin test names the deletion; objectui pins ^18.0.0-next.1), so desktop is ModalForm's bounded lg/xl default and a phone is its full-screen sheet below sm (L118–121). The heavy view flow routes (app-shell/src/views/ObjectView.tsx L2657–2658 → onNavigate(id, 'view') L3693+ → the record route).

Two residual divergences, renderer against derivation, both pre-existing — the old text made the same two claims — and neither introduced nor widened by this diff:

  • (i) a light record's create/edit: the derivation says drawer; the console reads only .size from the derivation, never .surface, and opens ModalForm for every weight (AppContent L1223–1229 says so in its own comment). 「otherwise a drawer」 is true of the contract, not of the console's task flows.
  • (ii) a light record on a phone, view flow: the derivation says page; the console's detailNavigation calls deriveRecordSurface(objectDef) with no viewport (app-shell ObjectView L2657; its comment claims "Mobile always pages (in deriveRecordSurface)" but hands it none), lands on mode: 'drawer', and plugin-view draws a bottom sheet on isMobile (L2855). 「any on mobile is viewed on a page」 is true of the contract, not of the console for light records.

Judgment: the skill states the derivation, which is the contract (ADR-0085 §5 "one shared derivation, every surface"; Prime Directive #12: spec → implementation → docs). Rewording the paragraph to the console's lag would advertise an implementation gap as platform behaviour and contradict the spec's own docblock. The cure sits in objectui; both are escalated in ③ for filing. They are not defects of this diff.

Override reach (reader's seat). navigation.mode on the list view governs the console's row-click (view) flow (plugin-view/src/ObjectView.tsx handleRowClick L1807–1838: 'page' routes, 'drawer' / 'modal' open the in-view form). The console's create/edit override is the object's editMode: 'page' (recordFormNavigation.ts L116; AppContent.handleEdit L703–712), which neither the derivation docblock's sanctioned list nor the skill names. The old clause had the same reach plus an undeclared placement; the new clause is narrower and names only declared keys — right under the dispatch's rule, with the gap escalated in ③.

Token payment — lossless, verified at the head. 「Don't set it.」 is carried by L125–126 (「You do not author the surface…」) and L160–162 (「Reach for navigation.mode / size / a Page only to override — never as the default」). The title parenthetical 「(page vs drawer)」 named two surfaces where the bullet now names three, so it was false as well as costly. 「for a specific object」 adds nothing: the list view is the per-object placement. No untouched line is re-wrapped (the hunk is 4/4 inside L131–134). The ratchet's CEILINGS row (scripts/check-skills-token-ratchet.mjs L599, 2273) is not in the diff; CI Lint · repo & tooling gates (success) carries the ratchet and its self-test.

Whole-package value density. Five lines, net 0 tokens, that tell an authoring AI (a) not to author the surface, (b) the derived mapping per flow and viewport, (c) the one declared knob and the sanctioned page path. Nothing else under skills/ states the old mapping: git grep -n -i -E "full page|always pages|page vs drawer|field-heavy" -- skills/ at the head hits this bullet only; skills/objectstack-ui/SKILL.md L66–67's 「(modal, drawer, full-page)」 enumerates reachable presentations (full-page via editMode: 'page'), not a default. Right.

Main drift since the merge base. 0b1179f33 → 46ca793e moved skills/objectstack-ui/SKILL.md (version line → 18.0.0-next.2), skills/objectstack-ui/rules/pages.md (PR #23758), packages/skills/package.json + CHANGELOG.md (a release). None of the cited spec files, not navigation.md, not the ratchet script; the PR's two files diff identically (+13/−4) against current main. No joint-wrong surface.

Check-runs on 9fc1d4717 — the gate verdicts. 48 check-runs, all completed, none failed: Lint & Repo Gates, TypeScript Type Check, Test Core (aggregate and 1–6/6), Build Core, Governed Surface Queue Guard (two runs; the re-run after labelling completed success at 2026-10-16T03:02Z), Check Changeset (three runs), every Lint · and Type Check · lane, Dogfood Regression Gate, Check Documentation Links, Check PR Size, the three card/branch/path claim checks — success; Build Docs, Console Pin Gate, Dogfood Verify CLI, Temporal Conformance, the dogfood matrix shard and Packed-tarball smoke — skipped by path filter or opt-in.

② Semver level

  • Changeset: .changeset/23753-navigation-record-surface.md — '@objectstack/skills': patch; body carries Clause-②: no with no arm; the PR body's second line is Clause-②: no at line start, no arm. Matched and well-formed.
  • Right level: @objectstack/skills is public (publishConfig.access: public, in the changeset fixed group); files[] is dist, which packages/skills/scripts/sync-catalog.mjs builds by copying skills/** byte for byte and reading it back — so the edited file ships, a changeset is owed and skip-changeset does not apply. Text only: no authorable key, export, schema or behaviour changes → patch is the level and Clause-②: no is the clause. Check Changeset is success on the head; the 18.0.0-next.2 CHANGELOG entries on main carry the same shape (summary with the card number, Clause-②: no, one paragraph).
  • The changeset's 「a light record on desktop opens every flow in a drawer」 is the derivation's sentence; ① (i) applies to it exactly as to the skill — it states the contract.
  • No model identifier in the PR body (session-URL footer), the commit (Claude-Session: + Co-authored-by: Claude pair), the changeset or any comment read.

③ Boundary flags

Dev report 6206965250: open_questions: []; eight deviations, three out_of_scope_findings — each answered or escalated.

  • D1 base moved 0a168a33e → 0b1179f33: readings re-measured there and holding. Answered, and extended: every cited file is identical at 46ca793e (①, main drift).
  • D2 / OOS-1 「(or object)」 dropped; editMode not named: dropping an undeclared placement is right. Escalated — for the seat to file (skills lane, with the spec docblock): the skill's only named override does not reach create/edit in the shipped console; the object's declared editMode ('modal' | 'page', object.zod.ts L2805; honoured at recordFormNavigation.ts L116) does, and the derivation docblock's sanctioned list (record-surface.ts L150–152) omits it while ADR-0085 §2 rejects presentation toggles on the object — a spec/ADR tension and a metadata-authoring trap (an AI writing navigation.mode: 'page' on a list view to force a page-mode create still gets a modal). Alongside: objectui app-shell ObjectView L2640 reads objectDef.navigation as a fallback — a key the object schema refuses, a dead read in spec-valid metadata and the likely origin of the old 「(or object)」. Dedupe words: editMode object edit intent; navigation.md override keys; record-surface sanctioned overrides; objectDef.navigation fallback.
  • D3 payment at zero headroom: verified lossless (①).
  • D4 / D5 41 derived families, 2 not measured locally: CI carries all of them; Lint & Repo Gates and Lint · repo & tooling gates are success. Answered.
  • D6 trailer pair: the commit carries the model-free pair; no model identifier anywhere. Answered.
  • D7 labels: documentation / size/s / tooling by Auto Label; needs-user-decision and needs:contract-review by the seat. A reading for the seat, not a verdict factor: at this read the PR's draft flag is false, while comment 6207033367 (read 2026-10-16T02:59Z) says it stays draft; mergeable_state is blocked; one requested reviewer (hotlong). Tier H is whole-PR: landing needs an authorized APPROVED review and this record, and no AI seat readies, queues or arms. State another actor set — read the timeline actor, ask, never correct.
  • D8 shallow checkout: no windowed history question was asked. n/a.
  • OOS-2 the navigation.mode hint lists 3 of 7 values: the three named are the three record surfaces the bullet is about; split / popover / new_window / none are navigation behaviours. No action.
  • OOS-3 content/docs/releases/v12.mdx L71: release-owned history. Right not to edit.

Reviewer's own flags, none in the dev report:

  • F1 — escalated, objectui lane: console task flows ignore the derivation's surface (AppContent L1209 formType: 'modal'; L1231–1238 reads .size only) — a light record's create/edit opens a modal where ADR-0085 §5's shared derivation says drawer. Dedupe words: AppContent formType modal light drawer; deriveRecordFlowSurface surface ignored.
  • F2 — escalated, objectui lane: the console's view flow derives without the viewport (app-shell ObjectView L2657) — a light record on a phone opens a bottom-sheet drawer, not the derivation's page, under a comment that says mobile always pages. Dedupe words: detailNavigation viewport mobile page deriveRecordSurface.
  • F3 — noted, spec lane (wording): record-surface.ts's header docblock L4–6 and L13 (「create / edit / detail … a full page」; 「field-heavy → full page」) predate the flow derivation the file now hosts — the same drift this card fixed in the skill, inside the spec's own docblock. Dedupe words: record-surface docblock full page create edit.
  • F4 — context, no action: 「bounded on desktop」 is true today through objectui's interimBoundedTaskFlowSurface; once objectui installs a spec carrying spec(record-surface): a field-heavy create/edit flow on desktop derives a bounded modal, not full-screen; mobile keeps full (objectui#12521 letter B) #23734 the derivation itself answers 'auto' and the shim is deleted (its pin test names it).

Implemented-by: claude/issue-23753-navigation-record-surface
Reviewed-by: session_01VqGhCg9wdsBXPz54uAEWg7

VERDICT: PASS

The diff replaces a published sentence that was false of the derivation with one that is true of it clause by clause, pays its tokens by lossless deletion inside the file, names only declared keys, carries the owed @objectstack/skills patch with a matched Clause-②: no, and is green on every gate-carrying check-run at the head. The residual renderer-versus-derivation gaps are pre-existing, belong to objectui, and are escalated above rather than written into the skill.


Generated by Claude Code

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

Labels

documentation Improvements or additions to documentation needs-user-decision size/s tooling

Projects

None yet

3 participants