Skip to content

Commit 595621d

Browse files
huangyiireneclaude
andauthored
docs(skills): split the four over-500-line SKILL.md into routing + references, TOC the seven long reference files, trim data's description (#19738)
Fixes #19715 Clause-②: no ## 维护者速读(草稿) **改了什么** — 四个超过 500 行的已发布 `SKILL.md`(platform 1223 → 487 · automation 961 → 448 · data 854 → 469 · upgrade 600 → 488)按标题边界切分:每个被移走的段落与代码块**逐字节**落到该技能自己的 `references/` 下(新增 9 个参考文件),原位只留一行指针;七个超过 300 行的参考文件顶部各加 5 行目录(锚到已有标题);`objectstack-data` 的 `description` 压到 689 字符,触发短语与排除句原样保留、只删括号枚举。零删内容:20 个移动块中 17 个字节相同,3 个仅改了 10 处相对链接路径(逐条列在下文)。 **为什么改** — 决策批次 #213 第 1 项,维护者裁决「1 2 4 同意」:超长 SKILL.md 会被 `head` 预读截断,示例与运维尾段读起来像第二个技能;切成「路由 + 规则」后入口文件只装规则、决策表与指针,长示例按需跟指针再读。 **风险与代价(含回滚)** — ① 直接读 `SKILL.md` 单文件时,105 个 eval 断言词里有 18 个(从 103 降到 85)现在只经指针可达;整棵技能树(SKILL.md + rules + references)的读数 105/105 前后不变,方法与局限见下文。② 为了到 500 行,platform 的第二部分(插件开发)与 automation 的「状态机与审批」整段下沉,其中含少量决策表——它们仍在树里,入口页保留指向 `rules/*.md` 的路由行。③ 三个门禁脚本的数据行跟着文本走(token 天花板行、role-word 基线两行搬家、scaffold 政策的载体路径),没有新增门禁。④ 令牌总量 +2058(指针行 + 目录行),四个入口行已按落地值下锁,七个目录文件中 4 行按裁决上调、3 行有余量按落地值下锁。回滚:整个 PR 一次 revert 即可,没有生成物或状态迁移。 **席位意见** — **建议批准并合并,但先看一眼「Sections that left SKILL.md」。** 裁决的八条形状逐条核过:零删内容(20 个移动块 17 个字节相同、3 个只改了 8 处相对链接;席位另做了四个技能的整行多重集比对,除链接与 description 外没有任何一行离开树)、四个入口文件全部 ≤ 500、data 的 description 689 字且触发短语与排除句原文保留、七个长参考文件各 5 行目录且锚点全部可达、净 +77 ≤ +80、无新门禁、changeset 按 #19721 惯例。evals 读数按机械法前后树列 105 / 105 不变;入口页单读 103 → 85,离开的 18 个词都在指针可达处 —— 这是切分的代价,不是丢失。token 棘轮四行入口下锁、九个新文件零余量钉住、四行目录文件按裁决引文上调。第 0 轮 CI 红是本 PR 的:`packages/rest` 的仓级测试钉住 automation 入口页必须写出状态内省路由,切分把唯一拼写搬走了;第 1 轮把拼写放回指针行(净 0 行,不改测试),席位在补丁头上重跑该测试 8 / 8 绿。留给你的一个判断:为了到 500 行,platform 的插件开发与运维两大部分、automation 的状态机与审批、data 的 seeds / 字段组 / lint 整段下沉,其中含少量决策表 —— 它们仍在树里、入口页留有路由行;如认为某段必须留在入口页,点名即可,dev 按行预算换一段下沉。复核记录:PR 评论 5786766593(PASS,在席按服务档渲染);ACCEPT 在卡 #19715。CI 读数:32 latest-per-name check runs — 25 success, 7 skipped, 0 in progress, 0 other。 **你要做的** — 这是 Tier H(`skills/**`)受管面:确认「哪些规则段可以离开入口页」符合你的意图(见「Sections that left SKILL.md」),然后手工合并;如认为某段必须留在入口页,请点名,我按行预算再换一段下沉。 --- ## What this does The four published `SKILL.md` files over 500 lines are split at heading boundaries into routing + rules. Every moved paragraph and code block lands **verbatim** under that skill's `references/` (nine new files) with a one-line pointer left where it was; the seven reference files over 300 lines gain a 5-line table of contents anchored to their existing headings; `objectstack-data`'s `description` shrinks to 689 characters with the same trigger phrases and exclusion sentence. The token ratchet re-locks the four entry rows at their landed counts, pins the nine new files at theirs, and raises the four TOC'd rows that carried no headroom by exactly the added tokens under the ruling. `skills/README.md` and `content/docs/ai/skills-reference.mdx` are regenerated from the trimmed frontmatter by `gen:skill-docs`. Premise re-measured on `origin/main` `106d4c8dd` before editing: the four line counts (1223 · 961 · 854 · 600) hold; the seven files carried no TOC; data's `description` measured **1003** characters by a YAML folded-scalar parse (the card's 1,023 was a different counting; either way it sat against the 1,024 cap). `premise_still_valid: true`. ## Readings after (head `011dfd603`) | File | Before | After | |:--|--:|--:| | `skills/objectstack-platform/SKILL.md` | 1223 | **487** | | `skills/objectstack-automation/SKILL.md` | 961 | **448** | | `skills/objectstack-data/SKILL.md` | 854 | **469** | | `skills/objectstack-upgrade/SKILL.md` | 600 | **488** | | data `description` (YAML folded, trailing newline excluded) | 1003 chars | **689 chars** | | net lines across `skills/**` (tracked +77 / −1781, new files +1781) | — | **+77** (budget ≤ +80) | ## Diff proof — every moved block (source lines at `106d4c8dd` → destination), verified byte-for-byte against the base blob | # | Source (lines, count) | Heading(s) | Destination (lines) | Bytes | |:-:|:--|:--|:--|:--| | 1 | platform `SKILL.md` 39–68 (30) | `### Minimal Example` | `references/bootstrap.md` 3–32 | verbatim | | 2 | platform 116–157 (42) | `### Map Format (Key → Name)` · `### Barrel Import Pattern` | `references/bootstrap.md` 34–75 | verbatim | | 3 | platform 272–280 (9) | `### Scaffolding Command` | `references/bootstrap.md` 77–85 | verbatim | | 4 | platform 498–527 (30) | `### Plugin Loading Order Matters` · `### Programmatic Bootstrap (Without CLI)` | `references/bootstrap.md` 87–116 | verbatim | | 5 | platform 531–542 (12) | `## Multi-App Composition` | `references/bootstrap.md` 118–129 | verbatim | | 6 | platform 585–644 (60) | `## Complete Working Example` | `references/bootstrap.md` 131–190 | verbatim | | 7 | platform 649–1007 (359) | `# Part 2 — Plugin Development & Kernel Extension` (whole) | `references/plugin-development.md` 1–359 | 6 link paths re-pathed, else verbatim | | 8 | platform 1012–1213 (202) | `# Part 3 — Operations: CLI, Testing, Deployment` (whole) | `references/operations.md` 1–202 | verbatim | | 9 | automation 143–209 (67) | `### Flow Example — Auto-Escalate Overdue Cases` | `references/examples-flows.md` 3–69 | verbatim | | 10 | automation 378–760 (383) | `## State Machines & Approvals` (whole) | `references/state-machines-and-approvals.md` 1–383 | verbatim | | 11 | automation 851–916 (66) | `### Time-relative triggers — scheduled per-record date sweep` | `references/examples-flows.md` 71–136 | verbatim | | 12 | data 184–230 (47) | `## Field Groups (MVP)` | `references/examples-objects.md` 3–49 | verbatim | | 13 | data 300–359 (60) | `## Quick-Start Template` | `references/examples-objects.md` 51–110 | 1 link path re-pathed | | 14 | data 499–525 (27) | `### Lifecycle Hooks` | `references/examples-objects.md` 112–138 | 1 link path re-pathed | | 15 | data 565–622 (58) | `## Metadata Protection (\`protection\`)` | `references/examples-objects.md` 140–197 | verbatim | | 16 | data 626–767 (142) | `## Seed Data & Fixtures (\`defineSeed()\`)` (whole) | `references/seeds.md` 1–142 | verbatim | | 17 | data 771–823 (53) | `## Linting & Generation Quality` | `references/lint-rules.md` 1–53 | verbatim | | 18 | upgrade 269–301 (33) | `### 2.3 A worked R1 — the retired field-mapping \`transform\`` | `references/examples-upgrade.md` 3–35 | verbatim | | 19 | upgrade 449–496 (48) | `### 3.4 The report — the human half` | `references/examples-upgrade.md` 37–84 | verbatim | | 20 | upgrade 540–573 (34) | `## The v17-canonical shapes, compiled` | `references/examples-upgrade.md` 86–119 | verbatim | Method: for each row the base bytes (`git show 106d4c8:path`, the listed lines) were hashed against the destination's listed lines — 17 rows identical, 3 rows differ only on the link-path lines below. The upgrade `a`-tag anchors (`decide-alone-or-ask`, `reverse-check`) stayed in `SKILL.md` because they sit just outside the moved ranges. The four new multi-block files carry a one-line H1; the five single-block files begin with the moved heading itself. **The only non-verbatim bytes — 10 link-path retargets** (a relative link crossing a move boundary would otherwise dangle): - platform `SKILL.md` (staying text): `#verify-your-work`, `#ports--networking`, `#part-3--operations-cli-testing-deployment` → `./references/operations.md#…` (3) - `references/plugin-development.md` (moved text, lines 656/657/658/738/760/791 at base): `./rules/plugin-lifecycle.md` → `../rules/…` (2), `./rules/service-registry.md` → `../rules/…` (2), `./references/plugin-hooks.md` → `./plugin-hooks.md` (2), `../objectstack-data/SKILL.md` → `../../objectstack-data/SKILL.md` (1) - data `SKILL.md` (staying text): `#field-groups-mvp` → `./references/examples-objects.md#field-groups-mvp` (1) - `references/examples-objects.md` (moved text, base lines 359 and 523): `./rules/indexing.md` → `../rules/indexing.md` (1), `./references/data-hooks.md` → `./data-hooks.md` (1) Every intra-file anchor in the 15 touched markdown files resolves (github-slugger, the repo's slug authority; 100 anchors, 0 unresolved) and all 104 relative links under `skills/**` resolve to existing files (the two `./crm_index.md` / `./crm_user_guide.md` spellings in `objectstack-ui/rules/pages.md` are illustrative example text on the base, untouched). ## Sections that left SKILL.md, and why the route had to widen The card's route (platform's ops tail + the two 60-line complete examples) reaches 894 lines on platform — the fenced code in the four files totals 462 / 310 / 223 / 162 lines against the 723 / 461 / 354 / 100 that had to go, so examples alone cannot reach 500 on three of the four. The cut therefore also moves whole self-contained parts: platform Part 2 (plugin development, which already has its own `rules/*.md` and `references/plugin-hooks.md` — the entry keeps a routing line to them), automation's State Machines & Approvals, data's Seed Data & Fixtures, Field Groups and Linting. Decision tables that now live behind a pointer: platform's ObjectKernel vs LiteKernel, Plugin Loading Order, Well-Known Plugin Names, MetadataPlugin boundary, Feature Flags, the ops tables; automation's Approver Types, Node Config, Branching, Best Practices and the state-machine rule; data's seed tables and the lint-rule table. Every pointer names the destination and the moved headings (heading names only — no paraphrase). If the maintainer wants a named section back in the entry, it costs its line count against the 500 ceiling; say which and I swap. ## Evals reading (card item 5) — method, before / after, limit There is no executable runner in this repo: the fixtures `skills/*/evals/*.json` are read by `scripts/check-skills-token-ratchet.mjs` for pricing only (no script consumes `must_contain`). The reading is therefore the mechanical one the dispatch names: for every eval of the four skills, each `must_contain` term's presence (substring, case as written) in that skill's `SKILL.md` alone and in the skill tree (`SKILL.md` + `rules/**` + `references/**`), on `106d4c8dd` and on this head. Script: `eval-reading.mjs` (in the scratchpad, not committed). | Skill | SKILL.md alone, before | SKILL.md alone, after | Tree, before | Tree, after | |:--|--:|--:|--:|--:| | objectstack-platform | 24/24 | 18/24 | 24/24 | 24/24 | | objectstack-automation | 26/26 | 20/26 | 26/26 | 26/26 | | objectstack-data | 35/37 | 31/37 | 37/37 | 37/37 | | objectstack-upgrade | 18/18 | 16/18 | 18/18 | 18/18 | | **total** | **103/105** | **85/105** | **105/105** | **105/105** | The tree column — the reading of record for a skill whose entry routes to references — is unchanged for all 105 terms. The 18 terms that left `SKILL.md` alone, each with the pointer on the eval prompt's path (the two data terms already absent on the base, `schemaMode` and `type: 'secret'`, live in `rules/datasources.md` and `rules/security.md` and are untouched): | Eval | Term | Now in | Pointer in SKILL.md | |:--|:--|:--|:--| | platform #2 (audit plugin) | `registerService`, `ctx.hook(`, `metadata:reloaded`, `init(`, `destroy` | `references/plugin-development.md` (+ `rules/plugin-lifecycle.md`, `references/plugin-hooks.md`) | the Part 2 pointer, which also names `rules/plugin-lifecycle.md` · `rules/service-registry.md` · `references/plugin-hooks.md` | | platform #6 (production deploy) | `OS_TRUSTED_ORIGINS` | `references/operations.md` | the Part 3 pointer (names Ports & networking · Deployment targets) | | automation #1 (nightly sweep) | `defineFlow`, `type: 'schedule'` | `references/examples-flows.md` | the Flow Example pointer; the Flow Types table row `schedule` stays in the entry | | automation #3 (approval + revise) | `type: 'approval'`, `type: 'back'`, `maxRevisions` | `references/state-machines-and-approvals.md` | the State Machines & Approvals pointer (names Send-back for revision · Node Config); `approval_revise` and `revise` stay in the entry | | automation #5 (function step) | `timeoutMs` | `references/examples-flows.md` | the Flow Example pointer | | data #4 (seeds) | `env:`, `daysFromNow` | `references/seeds.md` | the Seed Data pointer (names Dynamic values (CEL)); `defineSeed`, `externalId`, `upsert` stay in the entry | | data #2 (invoice lines) | `deleteBehavior`, `inlineEdit` | `rules/relationships.md`, `rules/field-types.md`, `references/lint-rules.md` | the Relationship Patterns table's link to `rules/relationships.md` (unchanged) | | upgrade #2 (conditionalRequired) | `requiredWhen` | `references/examples-upgrade.md` | the v17-canonical shapes pointer | | upgrade #3 (transform residue) | `never executed` | `references/examples-upgrade.md` | the worked R1 pointer | Limit of the method: substring presence is not a graded run — it cannot say whether an agent given the prompt would follow the pointer. It is the reading the card can have today; no runner was built (item 6). No assertion was tuned. ## Token ratchet (`scripts/check-skills-token-ratchet.mjs`, convention ceil(utf8 bytes / 4)) Bundle total 152,338 → **154,396** (+2,058: the 20 pointer lines, seven 5-line TOCs, four new-file titles, minus the description trim); ratcheted ceiling sum 157,621 → 154,915 (the four entry re-locks bank their shrink). Gate and `--self-test` green on this head (54 authored files within ceilings, 65 self-test cases). | Row | Ceiling before → after | Kind | |:--|:--|:--| | `objectstack-platform/SKILL.md` | 12984 → 5833 | re-lock at landed count | | `objectstack-automation/SKILL.md` | 12768 → 5762 | re-lock | | `objectstack-data/SKILL.md` | 10009 → 6128 | re-lock | | `objectstack-upgrade/SKILL.md` | 8333 → 6193 | re-lock | | `objectstack-data/rules/field-types.md` | 3032 → 3158 | **raise** +126 (TOC; zero headroom) — ruling cited in the row | | `objectstack-ui/rules/dashboards.md` | 6090 → 6252 | **raise** +162 (TOC; zero headroom) | | `objectstack-ui/rules/list-views.md` | 3011 → 3141 | **raise** +130 (TOC +132, 2 absorbed) | | `objectstack-ui/rules/pages.md` | 5501 → 5692 | **raise** +191 (TOC; zero headroom) | | `objectstack-data/references/data-hooks.md` | 12611 → 10066 | re-lock (TOC +182 landed inside 2,727 headroom) | | `objectstack-data/rules/relationships.md` | 3778 → 3676 | re-lock (TOC +154 inside 256 headroom) | | `objectstack-data/rules/validation.md` | 3109 → 2756 | re-lock (TOC +155 inside 508 headroom) | | 9 new rows | `examples-flows` 1436 · `state-machines-and-approvals` 5569 · `examples-objects` 1779 · `lint-rules` 970 · `seeds` 1299 · `bootstrap` 1351 · `operations` 3125 · `plugin-development` 3137 · `examples-upgrade` 1197 | pinned AT landed count, zero headroom | The dispatch's assumption that all seven TOC'd rows sat at zero headroom was false for four of them; those four are re-locked (a lowering, always legitimate) rather than raised. ## Other gate data that followed the moved text (no new gate, ratchet or check script) - `scripts/role-word-baseline.json`: the automation entry's one `role` occurrence (the Approver Types row) and the upgrade entry's one (`role:` in the v17 agent shape) moved with their sections; the two ledger rows moved with them. 44 files / 123 occurrences before and after — a relocation, not an expansion; `check:role-word` green. - `scripts/sync-scaffold-emission-policy.mjs`: the published-restatement row that locates the Complete Working Example's `package.json` fence by heading now points at `references/bootstrap.md`, where the fence lives; `check:scaffold-emission-policy` green (2 carriers). - Generator-owned files: `check:skill-refs` stays green without regeneration — `build-skill-references.ts` owns only `_index.md`, `*.zod.ts` and subfolders under `references/`, so the new top-level hand-written files are inputs it tolerates; `_index.md` lists Zod schemas only. `gen:skill-docs` regenerated `skills/README.md` and `content/docs/ai/skills-reference.mdx` (the one file outside `skills/**` and the gate scripts). - `check-skill-identifier-liveness` leg-2 bindings (`## Seed Data` on platform, `### Access depth …` on data) stayed in their entries. ## Gates (captured exit before any pipe; union derived by `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands` on `011dfd603`, 70 families, `--ran` reconciles 70/70 with exit codes) All 70 derived families exit 0 on `011dfd603`, plus `pnpm --filter @objectstack/spec check:generated` (15 artifacts up to date after the `origin/main` merge). The ones that read a build were run after `pnpm --filter '@objectstack/lint...' build` and `pnpm --filter '@objectstack/client-react...' build` under the shared verify lock: `check:skill-examples` — "258 prose examples type-check across 3 surface(s)" (the moved os:check blocks included); `check:docs`; `check:docs-transcript-drift`; the two `@objectstack/lint` doc checks. Highlights: `check:skills-token-ratchet` + self-test ✓ · `check:skill-docs` ✓ · `check:skill-refs` ✓ · `check:skill-identifier-liveness` ✓ · `check:skill-top-level-keys` ✓ · `check:skill-compatibility` ✓ · `check:skill-frame-sync` ✓ · `check:doc-authoring` ✓ · `check:role-word` ✓ · `check:scaffold-emission-policy` ✓ · `check:nul-bytes` ✓ · `check:pm-dispatch-gates` (1905 cases) ✓ · `bare-root-worklist --self-test` ✓ (the `skills/*/references/**` liveness/precision pin holds over the enlarged population). `pnpm lint` (repo-wide eslint) is CI's run: the diff touches no `.ts`/`.js` source, only markdown, one JSON ledger and two `.mjs` gate scripts whose own self-tests ran green. Branch merged `origin/main` `170fd836a` (three spec commits, no overlap with this diff) before opening; `packages/spec` was rebuilt after the merge. ## Changeset `skip-changeset`, per the last merged `skills/**` PR (#19721: `documentation` · `skip-changeset`, Clause-②: no) and measured: no workspace package's `files[]` ships `skills/` (positive control: `packages/cli` ships `bin`). `Clause-②: no`. Tier H — draft, the maintainer merges by hand. ## Acceptance notes - Two data eval terms were already reachable only through `rules/` on the base (`schemaMode`, `type: 'secret'`) — noted, not a card. - `objectstack-ui/rules/pages.md` lines 356/448 carry `./crm_index.md`-style example links that resolve to nothing; they are illustrative package-docs text inside the Docs section, untouched here — noted, not a card. --- _Generated by [Claude Code](https://claude.ai/code/session_01Wnstp2kTth7sGXfr8fXypc)_ --- _Generated by [Claude Code](https://claude.ai/code)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 70a2e75 commit 595621d

25 files changed

Lines changed: 1962 additions & 1799 deletions

‎content/docs/ai/skills-reference.mdx‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ ObjectStack ships **10 skills** — one per authoring domain, plus process skill
4646
| # | Skill | Domain | Path | What it covers |
4747
| :--- | :--- | :--- | :--- | :--- |
4848
| 1 | [Platform](#platform) | `platform` | `skills/objectstack-platform/` | Bootstrap, configure, extend, and operate ObjectStack runtimes. Covers project setup (`defineStack`, drivers, scaffolding), declaring platform capabilities (`requires:` — which service plugins boot), plugin and service development (PluginContext, DI, kernel hooks like `kernel:ready`), and operations (CLI commands, migrations, deployment, test harnesses via LiteKernel). |
49-
| 2 | [Data](#data) | `data` | `skills/objectstack-data/` | Design ObjectStack data schemas — objects, fields, field conditional rules, relationships, validations, indexes, lifecycle hooks, permissions, row-level security, data `lifecycle` retention/TTL/rotation, metadata `protection` locks, and external / federated datasources (`defineDatasource`) — and the seeds (`defineSeed()`) that load fixtures and reference data alongside them. |
49+
| 2 | [Data](#data) | `data` | `skills/objectstack-data/` | Design ObjectStack data schemas — objects, fields, relationships, validations, indexes, hooks, security, seeds and datasources. |
5050
| 3 | [Query](#query) | `query` | `skills/objectstack-query/` | Construct ObjectQL queries — filters, sorting, pagination, aggregation, relation expansion, and full-text search. |
5151
| 4 | [UI](#ui) | `ui` | `skills/objectstack-ui/` | Author ObjectStack UI metadata — Views (list/form/kanban/calendar/gantt), Apps (navigation), Pages (structured plus the HTML and React source-authoring tiers, ADR-0080/0081), Dashboards, Reports, Charts, Actions, and package Docs (`src/docs/*.md`). |
5252
| 5 | [Automation](#automation) | `automation` | `skills/objectstack-automation/` | Design ObjectStack automation — Flows (visual logic), Triggers, Approvals, state machines, and the `jobs` (`defineJob`) / `webhooks` (`defineWebhook`) stack collections. |
@@ -76,11 +76,11 @@ Do not use for data schema design (see objectstack-data) or query patterns (see
7676

7777
**Domain** `data` · **Path** `skills/objectstack-data/`
7878

79-
Design ObjectStack data schemas — objects, fields, field conditional rules, relationships, validations, indexes, lifecycle hooks, permissions, row-level security, data `lifecycle` retention/TTL/rotation, metadata `protection` locks, and external / federated datasources (`defineDatasource`) — and the seeds (`defineSeed()`) that load fixtures and reference data alongside them.
79+
Design ObjectStack data schemas — objects, fields, relationships, validations, indexes, hooks, security, seeds and datasources.
8080

8181
Use when the user is creating or modifying `*.object.ts` files or `src/data/*.ts` seed modules, picking field types, modelling relationships, writing `beforeInsert`/`afterUpdate` hooks, configuring per-object access control, pointing an object at an existing external database, or authoring bootstrap / demo data. Use for `visibleWhen` / `readonlyWhen` / `requiredWhen` rules that belong on fields.
8282

83-
Do not use for querying data (see objectstack-query) or for plugin / kernel hooks (see objectstack-platform). CEL expressions in formulas / validations / sharing rules / dynamic seed values: load objectstack-formula alongside.
83+
Do not use for querying data (see objectstack-query) or for plugin / kernel hooks (see objectstack-platform). CEL expressions: load objectstack-formula alongside.
8484

8585
**Tags:** `object`, `field`, `validation`, `index`, `relationship`, `hook`, `schema`, `permission`, `rls`, `security`, `seed`, `fixture`
8686

‎scripts/check-skills-token-ratchet.mjs‎

Lines changed: 93 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,21 @@ export const CEILINGS = new Map([
306306
// trigger user to narrow it, so one with no organization predicate reads and
307307
// writes across every tenant. +150 tokens, of which the row's 25 tokens of
308308
// headroom absorb 25; the CEILING moves 125.
309-
['skills/objectstack-automation/SKILL.md', 12768],
309+
// 12768 -> 5762: RE-LOCK at the landed count after the #19715 split (decision
310+
// batch #213 item 1, maintainer 「1 2 4 同意」): the Flow Example, the whole State
311+
// Machines & Approvals block and the Time-relative triggers section moved
312+
// VERBATIM into `references/examples-flows.md` and
313+
// `references/state-machines-and-approvals.md` (rows below), one pointer line
314+
// each left in place. The moved text is priced in its own rows, so the split
315+
// banks the entry's shrink instead of leaving 7,006 tokens of headroom behind.
316+
// 5762 -> 5785: the pointer line for that block also carries the one route
317+
// spelling a repo test pins to THIS entry file —
318+
// `packages/rest/src/meta-state-route-doc-spelling.test.ts` asserts the
319+
// automation entry teaches `/api/v1/meta/object/:name/state/:field`, and the
320+
// only spelling had moved with the section. +23 tokens, re-locked at the
321+
// landed count of the same split (no ruling needed: the raise is against a
322+
// row this PR itself lowered by 7,006, and the entry stays 448 lines).
323+
['skills/objectstack-automation/SKILL.md', 5785],
310324
// 13783 -> 13892 (2026-08-31 app-repo-principles raise, see the block above).
311325
// The invariant-vs-transition-gate choice, placed in the field-conditional-rule
312326
// bullet list where the tool is actually picked. Both wrong picks are silent:
@@ -317,7 +331,14 @@ export const CEILINGS = new Map([
317331
// split (#14296 item 1 = A, condition (b)). The raise recorded above is spent
318332
// and its headroom leaves with it; the moved text is priced in its own row
319333
// below, so the package total is unchanged by the re-lock itself.
320-
['skills/objectstack-data/SKILL.md', 10009],
334+
// 10009 -> 6128: RE-LOCK at the landed count after the #19715 split (decision
335+
// batch #213 item 1, maintainer 「1 2 4 同意」): Field Groups, the Quick-Start
336+
// Template, Lifecycle Hooks, Metadata Protection, the whole Seed Data &
337+
// Fixtures block and Linting & Generation Quality moved VERBATIM into
338+
// `references/examples-objects.md`, `references/seeds.md` and
339+
// `references/lint-rules.md` (rows below); the frontmatter `description`
340+
// shrank to 689 characters (card item 3). One pointer line per moved block.
341+
['skills/objectstack-data/SKILL.md', 6128],
321342
['skills/objectstack-formula/SKILL.md', 6002], // -53 (was 6055)
322343
['skills/objectstack-i18n/SKILL.md', 6338], // -11 (was 6349)
323344
// 12705 -> 12984 (2026-08-31 app-repo-principles raise, see the block above).
@@ -328,7 +349,14 @@ export const CEILINGS = new Map([
328349
// fix; no defensive coding, no shape tolerance, no hand-written predicate
329350
// re-implementing a platform rule, and no landing of the half that fits.
330351
// Nothing in this file said any of it. +280 tokens, 1 absorbed, ceiling +279.
331-
['skills/objectstack-platform/SKILL.md', 12984],
352+
// 12984 -> 5833: RE-LOCK at the landed count after the #19715 split (decision
353+
// batch #213 item 1, maintainer 「1 2 4 同意」): Part 2 (plugin development) and
354+
// Part 3 (the operations tail) moved VERBATIM into
355+
// `references/plugin-development.md` and `references/operations.md`, and six
356+
// Part 1 example / composition sections into `references/bootstrap.md` (rows
357+
// below). One pointer line per moved block; the entry keeps its rules and
358+
// decision tables at 487 lines.
359+
['skills/objectstack-platform/SKILL.md', 5833],
332360
// `skills/objectstack-pm-dispatch/SKILL.md` (9708) and its
333361
// `rules/dev-template.md` (1838) left this table on 2026-09-10 with the files:
334362
// the maintainer deleted the published PM skill whole (verbatim:
@@ -389,7 +417,11 @@ export const CEILINGS = new Map([
389417
// Independently reproducible without running this script:
390418
// ceil($(wc -c < skills/objectstack-ui/SKILL.md) / 4) == ceil(15424 / 4)
391419
['skills/objectstack-ui/SKILL.md', 3856],
392-
['skills/objectstack-upgrade/SKILL.md', 8333], // -2 (was 8335)
420+
// 8333 -> 6193: RE-LOCK at the landed count after the #19715 split (decision
421+
// batch #213 item 1, maintainer 「1 2 4 同意」): the worked R1, the report
422+
// template and the v17-canonical shapes block moved VERBATIM into
423+
// `references/examples-upgrade.md` (row below), one pointer line each.
424+
['skills/objectstack-upgrade/SKILL.md', 6193],
393425

394426
// ── the #12392 extension: the rest of the AUTHORED bundle ────────────────
395427
// Every row below is an INITIAL measurement, taken on
@@ -407,17 +439,30 @@ export const CEILINGS = new Map([
407439
// SKILL.md ceilings, which is the single fact that made #12392 a defect
408440
// rather than an observation.
409441
['skills/objectstack-data/evals/README.md', 143],
410-
['skills/objectstack-data/references/data-hooks.md', 12611],
442+
// 12611 -> 10066: RE-LOCK at the landed count (#19715, card item 4). The file
443+
// gained a 5-line table of contents (+182 tokens, anchors to its own
444+
// headings); the row carried 2,727 tokens of headroom left by an earlier
445+
// shrink that nobody re-locked, so the TOC needed no raise. Pinned AT the
446+
// measurement — zero headroom, the ratchet's steady state.
447+
['skills/objectstack-data/references/data-hooks.md', 10066],
411448
['skills/objectstack-data/rules/datasources.md', 911],
412449
// -552 (was 3584): re-locked at the landed count (#16374) after PR #16187
413450
// (the two `tree` rows) and PR #16369 (the ASCII decision tree deleted)
414451
// both merged. Lowering to the landed count is the ratchet's ordinary
415452
// direction — a seat's re-lock, not a maintainer ruling.
416-
['skills/objectstack-data/rules/field-types.md', 3032],
453+
// 3032 -> 3158 (#19715, card item 4): a 5-line table of contents at the top,
454+
// anchors to the file's existing headings, nothing else changed. +126 tokens,
455+
// zero headroom to absorb any of it, ceiling +126. Maintainer ruling
456+
// 2026-09-22 on decision batch #213 (item 1 carries the TOCs: 「四个超长 SKILL.md 按 500 行切,整段示例与 platform 的运维尾段下沉 references/,零删内容;同卡顺手:data 的 description 压到约 700 字符、长参考文件加目录」),
457+
// verbatim and untranslated: 「1 2 4 同意」.
458+
['skills/objectstack-data/rules/field-types.md', 3158],
417459
['skills/objectstack-data/rules/indexing.md', 3241],
418460
['skills/objectstack-data/rules/lifecycle.md', 1590],
419461
['skills/objectstack-data/rules/naming.md', 773],
420-
['skills/objectstack-data/rules/relationships.md', 3778],
462+
// 3778 -> 3676: RE-LOCK at the landed count (#19715, card item 4). A 5-line
463+
// table of contents (+154 tokens) landed inside the row's 256 tokens of
464+
// headroom, so no raise; pinned AT the measurement — zero headroom.
465+
['skills/objectstack-data/rules/relationships.md', 3676],
421466
// NEW FILE (#14296 item 1 = A, condition (b)): the entry's Security & Access
422467
// Control block moved here whole. Pinned at its landed count — no headroom,
423468
// because a split that arrives with budget is a raise wearing a new path.
@@ -437,7 +482,10 @@ export const CEILINGS = new Map([
437482
// score, a duplicate guess — warns and never errors, and an override flag
438483
// added to soften a block is evidence the block should have been a warning.
439484
// +85 tokens, no headroom to absorb any of it, ceiling +85.
440-
['skills/objectstack-data/rules/validation.md', 3109],
485+
// 3109 -> 2756: RE-LOCK at the landed count (#19715, card item 4). A 5-line
486+
// table of contents (+155 tokens) landed inside the row's 508 tokens of
487+
// headroom, so no raise; pinned AT the measurement — zero headroom.
488+
['skills/objectstack-data/rules/validation.md', 2756],
441489

442490
// objectstack-platform
443491
['skills/objectstack-platform/references/plugin-hooks.md', 2628],
@@ -467,10 +515,25 @@ export const CEILINGS = new Map([
467515
// added nothing but five titles and five pointers,
468516
// so the package nets -58 (33,957 -> 33,899).
469517
['skills/objectstack-ui/rules/actions.md', 2108],
470-
['skills/objectstack-ui/rules/dashboards.md', 6090],
471-
['skills/objectstack-ui/rules/list-views.md', 3011],
518+
// 6090 -> 6252 (#19715, card item 4): a 5-line table of contents at the top,
519+
// anchors to the file's existing headings, nothing else changed. +162 tokens,
520+
// zero headroom to absorb any of it, ceiling +162. Maintainer ruling
521+
// 2026-09-22 on decision batch #213 item 1, verbatim and untranslated:
522+
// 「1 2 4 同意」.
523+
['skills/objectstack-ui/rules/dashboards.md', 6252],
524+
// 3011 -> 3141 (#19715, card item 4): a 5-line table of contents at the top,
525+
// anchors to the file's existing headings, nothing else changed. +132 tokens,
526+
// of which the row's 2 tokens of headroom absorb 2; the CEILING moves 130.
527+
// Maintainer ruling 2026-09-22 on decision batch #213 item 1, verbatim and
528+
// untranslated: 「1 2 4 同意」.
529+
['skills/objectstack-ui/rules/list-views.md', 3141],
472530
['skills/objectstack-ui/rules/navigation.md', 2273],
473-
['skills/objectstack-ui/rules/pages.md', 5501],
531+
// 5501 -> 5692 (#19715, card item 4): a 5-line table of contents at the top,
532+
// anchors to the file's existing headings, nothing else changed. +191 tokens,
533+
// zero headroom to absorb any of it, ceiling +191. Maintainer ruling
534+
// 2026-09-22 on decision batch #213 item 1, verbatim and untranslated:
535+
// 「1 2 4 同意」.
536+
['skills/objectstack-ui/rules/pages.md', 5692],
474537

475538
// ── 2026-09-22 evals fixtures — decision batch #213 item 2, PR #19721 ────
476539
// Every published skill gained `evals/*.json` in the objectui fixture shape.
@@ -500,6 +563,25 @@ export const CEILINGS = new Map([
500563
['skills/objectstack-upgrade/evals/protocol-major-upgrade.json', 1033],
501564

502565
// the remaining skills' eval notes
566+
567+
// ── 2026-09-22 the #19715 split — decision batch #213 item 1 ─────────────
568+
// The maintainer ruled the four over-500-line published SKILL.md files split
569+
// into routing + rules, every moved paragraph and code block landing
570+
// VERBATIM under that skill's `references/` with a one-line pointer left in
571+
// place; verbatim and untranslated: 「1 2 4 同意」 on item 1 「四个超长 SKILL.md 按 500 行切,整段示例与 platform 的运维尾段下沉 references/,零删内容;同卡顺手:data 的 description 压到约 700 字符、长参考文件加目录」.
572+
// Each row below is a NEW FILE holding text that moved out of its SKILL.md
573+
// (whose row is RE-LOCKED above), pinned AT its landed count — no headroom,
574+
// because a split that arrives with budget is a raise wearing a new path.
575+
// The package deltas are the pointer lines and the four new file titles only.
576+
['skills/objectstack-automation/references/examples-flows.md', 1436],
577+
['skills/objectstack-automation/references/state-machines-and-approvals.md', 5569],
578+
['skills/objectstack-data/references/examples-objects.md', 1779],
579+
['skills/objectstack-data/references/lint-rules.md', 970],
580+
['skills/objectstack-data/references/seeds.md', 1299],
581+
['skills/objectstack-platform/references/bootstrap.md', 1351],
582+
['skills/objectstack-platform/references/operations.md', 3125],
583+
['skills/objectstack-platform/references/plugin-development.md', 3137],
584+
['skills/objectstack-upgrade/references/examples-upgrade.md', 1197],
503585
]);
504586

505587
/**

‎scripts/role-word-baseline.json‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,13 @@
3434
"content/docs/releases/v17/17-0.mdx": 2,
3535
"content/docs/ui/forms.mdx": 3,
3636
"skills/objectstack-ai/SKILL.md": 1,
37-
"skills/objectstack-automation/SKILL.md": 1,
37+
"skills/objectstack-automation/references/state-machines-and-approvals.md": 1,
3838
"skills/objectstack-data/SKILL.md": 1,
3939
"skills/objectstack-data/references/data-hooks.md": 3,
4040
"skills/objectstack-data/rules/relationships.md": 1,
4141
"skills/objectstack-platform/SKILL.md": 2,
4242
"skills/objectstack-query/rules/filters.md": 8,
4343
"skills/objectstack-ui/rules/list-views.md": 1,
4444
"skills/objectstack-ui/rules/navigation.md": 1,
45-
"skills/objectstack-upgrade/SKILL.md": 1
45+
"skills/objectstack-upgrade/references/examples-upgrade.md": 1
4646
}

‎scripts/sync-scaffold-emission-policy.mjs‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@
7171
//
7272
// The bundled template was never the only hand-written restatement of this
7373
// policy. The other one is the "Complete Working Example" `package.json` fence
74-
// in `skills/objectstack-platform/SKILL.md` — the copy-paste manifest every
74+
// in `skills/objectstack-platform/references/bootstrap.md` (moved there VERBATIM
75+
// out of the entry SKILL.md by the #19715 split) — the copy-paste manifest every
7576
// agent that loads that skill reads — and no gate read it (#16767). It sat at
7677
// the retired `^6.0.0` longer than the bundled template did, for the ordinary
7778
// reason: the carrier with no reader is where the next drift lands.
@@ -160,7 +161,10 @@ export const POLICY_STAMPS = [
160161
*/
161162
export const PUBLISHED_RESTATEMENTS = [
162163
{
163-
path: 'skills/objectstack-platform/SKILL.md',
164+
// The section moved verbatim out of `skills/objectstack-platform/SKILL.md`
165+
// into this reference file (#19715, decision batch #213 item 1); the row
166+
// follows the text, and a renamed heading still reds below.
167+
path: 'skills/objectstack-platform/references/bootstrap.md',
164168
heading: '## Complete Working Example',
165169
label: '**`package.json`**:',
166170
fence: 'json',

‎skills/README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ apps too).
3838
| Skill | Domain | What it covers |
3939
|:------|:-------|:---------------|
4040
| [Platform](./objectstack-platform/SKILL.md) | `platform` | Bootstrap, configure, extend, and operate ObjectStack runtimes. Covers project setup (`defineStack`, drivers, scaffolding), declaring platform capabilities (`requires:` — which service plugins boot), plugin and service development (PluginContext, DI, kernel hooks like `kernel:ready`), and operations (CLI commands, migrations, deployment, test harnesses via LiteKernel). |
41-
| [Data](./objectstack-data/SKILL.md) | `data` | Design ObjectStack data schemas — objects, fields, field conditional rules, relationships, validations, indexes, lifecycle hooks, permissions, row-level security, data `lifecycle` retention/TTL/rotation, metadata `protection` locks, and external / federated datasources (`defineDatasource`) — and the seeds (`defineSeed()`) that load fixtures and reference data alongside them. |
41+
| [Data](./objectstack-data/SKILL.md) | `data` | Design ObjectStack data schemas — objects, fields, relationships, validations, indexes, hooks, security, seeds and datasources. |
4242
| [Query](./objectstack-query/SKILL.md) | `query` | Construct ObjectQL queries — filters, sorting, pagination, aggregation, relation expansion, and full-text search. |
4343
| [UI](./objectstack-ui/SKILL.md) | `ui` | Author ObjectStack UI metadata — Views (list/form/kanban/calendar/gantt), Apps (navigation), Pages (structured plus the HTML and React source-authoring tiers, ADR-0080/0081), Dashboards, Reports, Charts, Actions, and package Docs (`src/docs/*.md`). |
4444
| [Automation](./objectstack-automation/SKILL.md) | `automation` | Design ObjectStack automation — Flows (visual logic), Triggers, Approvals, state machines, and the `jobs` (`defineJob`) / `webhooks` (`defineWebhook`) stack collections. |

0 commit comments

Comments
 (0)