Repository navigation
Commit 46ca793
docs(skills): pages.md says what a page type, template and region name run (#23758)
Fixes #23610
Clause-②: no
Executes ruling `6190536588` item 4 under claim `6204703954`:
`skills/objectstack-ui/rules/pages.md` says what PR #23708 makes the
page contract. This PR is the card's last piece and carries its closing
keyword (#23708 is `Part of #23610`). **It turns ready only after #23708
has merged** — the seat marks it; the dev does not — and, as a
`skills/**` diff (governed, Tier H), it lands only after a human
approval, by the seat.
## What changes
One skill file, `skills/objectstack-ui/rules/pages.md`, plus a
`@objectstack/skills` patch changeset. Every sentence follows the spec
text #23708 lands — `PageTypeSchema`'s docblock and enum comments,
`PageTemplateSchema`, `PAGE_TEMPLATE_SLOTS`, `checkPageRegionPlacement`,
`misplacedDefaultPageRefusal`, the `utility` print refusal — and
`content/docs/ui/pages.mdx`'s new wording. Nothing the spec does not
declare enters the skill.
| Where (line on `main`) | Was | Now |
| :--- | :--- | :--- |
| Page Types table, `home` (24) | App home / landing page | Widest
region page; not a landing (`isDefault` refused): an app opens on its
first navigation item |
| Page Types table, `app` (25) | App-level page with navigation context
| Region page at app width |
| Page Types table, `utility` (26) | Floating utility panel (e.g. notes,
phone dialer) | Narrow inline region page for a tool (notes, a dialer);
no floating or docked shell slot exists |
| Disambiguation paragraph (29–34) | "…a utility panel is `type:
'utility'`…" plus a restatement of the table's three `type` values | The
no-such-type list and the visualizations-are-not-page-types sentence
stay; the restated `type` values go (the table carries them) |
| Templates & Regions (38–41) | `three-column` / `two-column` /
`single-column`; regions `header`, `left_sidebar`, `main`,
`right_sidebar`, `footer` | `default` (header, sidebar, main, aside,
footer), `header-sidebar-main` (header, sidebar, main), `three-column`
(the same five), `dashboard` (header, footer; other regions are grid
cells); `full-width` retired; on a `kind: 'full'` page a region the
template does not place, or a second region for a filled slot, is
refused at its `name`; left column `sidebar`, right `aside` |
| Print pages (71–72) | "a `utility` panel" | "a `utility` page" |
| Source tiers (137–138) | "The legacy value `kind:'jsx'` is a
deprecated alias for `kind:'html'`" | "`kind:'jsx'` is retired: the
parse refuses it and names `kind:'html'`" (#23543 F5-jsx, PR #23638) |
The `home` row's landing sentence is the one
`misplacedDefaultPageRefusal` prints (an app's landing is its first
navigation item); the `utility` row's is `PageTypeSchema`'s ("no
floating or docked shell slot"); the template sentence is
`PAGE_TEMPLATE_SLOTS` plus `checkPageRegionPlacement`'s two refusals
(unplaced region; second region for a filled slot). The file mentioned
no page default or landing anywhere else, so nothing else moved.
## Token ratchet — paid in the same file
`check:skills-token-ratchet` holds `rules/pages.md` at ceiling 5692 with
6 tokens of headroom on `main`. The new sentences cost about 135 tokens,
so they are paid by deleting content from the same file, never by
re-wrapping:
- the disambiguation clause that restated the table's three `type`
values;
- the renderer clause of the five-values line (its ADR-0049 citation
stays);
- the `responsive.zod.ts` source pointer under the Styling rules (the
field name `responsiveStyles` and every rule stay).
Readings, `ceil(utf8 bytes / 4)` as the gate counts, at `a869ea6` → this
head:
| Reading | Before | After |
| :--- | ---: | ---: |
| `rules/pages.md` lines | 433 | 428 |
| `rules/pages.md` bytes / tokens | 22,741 / 5,686 | 22,727 / 5,682
(ceiling 5,692) |
| `skills/**/*.md` lines | 12,697 | 12,692 |
| `skills/**/*.md` bytes / tokens | 576,525 / 144,132 | 576,511 /
144,128 |
| sum of the eleven `SKILL.md` lines | 4,408 | 4,408 |
## Changeset
`@objectstack/skills: patch`
(`.changeset/23610-skills-pages-contract.md`): `packages/skills` ships
the `skills/**` tree (`sync-catalog.mjs` → `dist`), so this text
publishes; a docs fix in a released package takes `patch`. `Clause-②:
no` — the accept set and the public surface are unchanged.
## Eval fixtures and generated references
- `skills/objectstack-ui/evals/views-apps-actions-pages.json:37` names
`template: 'three-column'` — a member of the closed set, so it stands.
No fixture under `skills/objectstack-ui/evals/` and no sibling
`rules/*.md` or `SKILL.md` names `utility`, `left_sidebar`,
`right_sidebar`, `two-column`, `single-column`, `full-width` or
`kind:'jsx'` (grep on this head).
- `skills/objectstack-ui/references/_index.md` is generator-owned and
unchanged (#23708 keeps it byte-identical). No other `skills/**` path
enters this PR.
## Verification (head `e97d4c0`)
- `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack`: 41 families; each run once, exit captured
before any pipe; `--ran` reconciliation: "41 derived famil(ies)
accounted for — 41 run, 0 NOT-MEASURED (a DERIVED zero)"; every family
exit 0. The skills families all pass: `check-skills-token-ratchet` (+
`--self-test`), `check:skill-compatibility`, `check:skill-frame-sync`,
`check:skill-identifier-liveness`, `check:pm-skill-id-lint`,
`check:doc-authoring`, `check:role-word`, `check:nul-bytes`, the
changeset gates (`check-adr-0087-registration`,
`check-changeset-no-major`, `check-empty-changeset`,
`check:changeset-gate-self-tests`, `check:published-files`,
`check:pm-changeset-deadline-census`).
- Five families first refused with exit 3 `PREREQUISITE NOT MET` on the
fresh worktree (they sweep the built closure):
`check:doc-formula-expressions` (lint), `check:dts-closure`,
`check:dual-build-cjs-loads`, `check:lean-entry-closure`,
`check:sourcemap-no-sources-content`. After `pnpm build` under the
verify lock (75 tasks, 6m54s) each was re-run once and exited 0; the
working tree stayed clean (no generated artifact moved).
- Local-only: `check:skill-frame-freshness` exit 0 (frame byte-identical
to `origin/main`).
- Stale-term check on the file: zero hits for `left_sidebar`,
`two-column`, `Floating`, `deprecated alias`, `landing page`, `utility …
panel`.
## 维护者速读(草稿)
**改了什么** 只改一个对外发布的技能文件 `skills/objectstack-ui/rules/pages.md`(加一条
`@objectstack/skills` patch changeset)。页面类型表里 `home`
不再写成「应用落地页」,改为「最宽的区域页;不是落地声明(`isDefault` 被拒),应用打开的是第一个导航项」;`utility`
不再写成「浮动工具面板」,改为「窄的内联区域页,没有浮动或停靠的外壳槽位」;「模板与区域」一段从 `three-column /
two-column / single-column` 与 `left_sidebar / right_sidebar` 改为 #23708
落地的封闭模板集(`default`、`header-sidebar-main`、`three-column`、`dashboard`)和各自放置的区域名(左栏
`sidebar`、右栏 `aside`;`full-width` 退役;模板不放置的区域、重复占槽的区域被拒);`kind:'jsx'`
从「`html` 的别名」改为「已退役,解析时被拒并指向 `html`」。
**为什么改** 这份技能是 AI 写页面元数据时读的规则。它教的 `two-column`、`left_sidebar`、「home
是落地页」在 #23708 之后会被 `os validate` 和保存门直接拒收(在此之前则是静默错排或无效声明),也就是技能本身在教 AI
写出会被拒的元数据。裁决 `6190536588` 第 4 项把这份文件的更新单列为一个 Tier H PR。
**风险与代价(含回滚)** 零运行时影响:只有技能文本与 changeset,不碰 `packages/**`。文本描述的是 #23708
合入之后的契约,所以本 PR 在 #23708 合入前保持 draft,不会先于契约发布。token
棘轮零余量,新增内容靠删同文件的三处重复/指针付账(净 −14 字节),没有抬上限。回滚 = revert 这一个 commit
对,无状态可清理。
**席位意见** 同意合入。#23708 已于 10-16 02:31Z 落地(`a69a40a572`),`main` 上的 spec
现在就拒收这份技能旧的教法(`two-column`、`left_sidebar`、home 上的 `isDefault`);不合入,技能就在教
AI 写一定会被拒的页面元数据。改动只有一份技能文本加一条 patch changeset,零运行时影响,不碰契约(`Clause-②:
no`),CI 全绿,与 `main` 无冲突。为满足 token 上限删掉的三处都是重复说明或源码指针,没有删任何规则;其中删
`responsive.zod.ts` 源码指针一处,席位已确认可接受。
**你要做的** 一个动作:在本 PR 上点 Approve。席位随后开 auto-merge 落地,#23610 随之关闭。
## Acceptance notes
- The text states the contract that #23708 landed on `main` as
`a69a40a572` (2026-10-16T02:31Z). The seat marked this PR ready after
that merge, and the skill and the parse now agree.
- Content deleted to pay the ratchet (listed above) is restatement or a
source pointer; no rule left the file.
- No out-of-scope findings.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01H9YpvyoScsRAsjBc2pCUgn)_
---------
Co-authored-by: objectstack-fleet[bot] <noreply@anthropic.com>1 parent e5136ff commit 46ca793
2 files changed
Lines changed: 25 additions & 21 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
18 | | - | |
19 | | - | |
| 18 | + | |
20 | 19 | | |
21 | 20 | | |
22 | 21 | | |
23 | 22 | | |
24 | | - | |
25 | | - | |
26 | | - | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
27 | 26 | | |
28 | 27 | | |
29 | | - | |
30 | | - | |
31 | | - | |
32 | | - | |
33 | | - | |
34 | | - | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
35 | 31 | | |
36 | 32 | | |
37 | 33 | | |
38 | | - | |
39 | | - | |
40 | | - | |
41 | | - | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
42 | 40 | | |
43 | 41 | | |
44 | 42 | | |
| |||
69 | 67 | | |
70 | 68 | | |
71 | 69 | | |
72 | | - | |
| 70 | + | |
73 | 71 | | |
74 | 72 | | |
75 | 73 | | |
| |||
134 | 132 | | |
135 | 133 | | |
136 | 134 | | |
137 | | - | |
138 | | - | |
| 135 | + | |
| 136 | + | |
139 | 137 | | |
140 | 138 | | |
141 | 139 | | |
| |||
284 | 282 | | |
285 | 283 | | |
286 | 284 | | |
287 | | - | |
288 | | - | |
289 | | - | |
290 | 285 | | |
291 | 286 | | |
292 | 287 | | |
| |||
0 commit comments