Repository navigation
docs(skills): objectstack-upgrade's late-arrival example starts at the support floor - #22145
Conversation
…e support floor The "several majors late" paragraph examples `os migrate meta --from 10`, which the chain refuses below MIGRATION_SUPPORT_FLOOR = 16 with MigrationFloorError. Reword it: the example is now `--from 16`, the floor is stated in the same breath (16 today), and a project below the floor is told to upgrade to it by the older route first, then run the chain. Token ratchet (ceil(utf8 bytes / 4), ceiling 6193): 6187 -> 6184. The reword is paid by deleting two clauses the same file already states beside them — the `mkdir -p .upgrade` trailing comment (the paragraph under the block says it) and "which is exactly what the table above points at" (the table above is those two sources). No re-wrap. Claude-Session: https://claude.ai/code/session_01CXydFDyiQwNbGFkmwrcRQq Co-authored-by: Claude <noreply@anthropic.com>
Contract reviewServed-tier: Reviewed in-seat by the skills seat 1 (dispatching seat; this session is served at the contract-review tier, read off ① Derived judgments
② Semver levelNone. Prose-only edit to a published skill file; no package ③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
维护者速读(终稿)席位:skills 席 1, 改了什么:只改对外发布的技能文件 为什么改:这份技能随 风险与代价(含回滚):纯文本改动,无代码、无 changeset( 席位意见:同意合入,席内契约复核 PASS。两点留给维护者,均未下令、不阻塞:① 同文件 你要做的:用授权账号( Generated by Claude Code |
…does: lists the edits, `--write` applies the proven sites (objectstack-ai#22199) Fixes objectstack-ai#22144 Clause-②: no Two published lines in the objectstack-data skill said `os migrate meta --from 16` strips the retired index keys `type` and `partial` ("to strip them automatically" at `rules/indexing.md:31`, "strips them" at `SKILL.md:377`). Neither was true of the tool: the default run writes no authored source file, and `--write` rewrites only the sites it can prove. Both lines now carry the house sentence. The closing enumeration of every `os migrate meta` sentence in `skills/**` is below; every other hit reads true and is left byte-for-byte alone. Family: objectstack-ai#22120 is landed (PR objectstack-ai#22122, the upgrade skill) and objectstack-ai#22123 is landed (PR objectstack-ai#22145, the `--from 10` example); this PR is the family's closing card. objectstack-ai#9591 (PR objectstack-ai#22142, spec lane) is referenced only: it moves the spec tombstones to the same sentence and holds the class pin. ## The tool, re-taken on this tree (`0aa5205228`, cut from `origin/main` at `1e5d322c1e`) - `packages/cli/src/commands/migrate/meta.ts:762-769`, the flag declaration, verbatim: ```ts write: Flags.boolean({ description: 'Rewrite the authored source files in place for each mechanical change traced to one literal in one ' + 'project file; every other change is listed with the reason it was not written. Never writes the ' + 'manual (semantic) changes.', default: false, exclusive: ['stored'], }), ``` - `packages/cli/src/utils/authored-source-codemod.ts` (module header): `--write` writes a diff change only when its path leads, through the authored modules' syntax, to ONE object or array literal in ONE project file and the loaded value agrees with that literal; anything else is refused by a named reason and stays on the list for the author. - `packages/spec/src/migrations/registry.ts:79`: `export const MIGRATION_SUPPORT_FLOOR = 16;` — `applyMetaMigrations` throws `MigrationFloorError` for any `--from` under it (`meta.ts:713-716`). - `packages/spec/src/conversions/registry.ts:3906`: `id: 'object-index-type-partial-removed'` — the 16 → 17 step carries the conversion, so "lists the mechanical edits" is true of these two keys specifically, not only in general. - House sentence (`packages/spec/src/shared/retired-key.ts`: "It must be TRUE of the tool"). The tombstones on `main` close with "Run `os migrate meta --from 16` to list the mechanical edits for existing sources; apply them by hand." (`packages/spec/src/data/object.zod.ts:558,567`); PR objectstack-ai#22142 moves that to "… `--write` applies the ones it can prove, and you apply the rest by hand."; the upgrade skill says "By default `os migrate meta` rewrites no source file" (`skills/objectstack-upgrade/SKILL.md:153`) and "`--write` … rewrite the proven sites in place" (`:132`). No third vocabulary is introduced here. ## The two edits `skills/objectstack-data/rules/indexing.md:31-33` (headroom 1058 tokens before): - before: "… run `os migrate meta --from 16` to strip them automatically. What to do instead is the subject of "Access methods and partial indexes" below." - after: "… run `os migrate meta --from 16` to list the mechanical edits; `--write` applies the ones it can prove, and you apply the rest by hand. What to do instead is the subject of "Access methods and partial indexes" below." `skills/objectstack-data/SKILL.md:377-378` (ceiling 6128, headroom 0 before — the shortest form that stays true): - before: "Both are now a `tsc` error and a parse error; `os migrate meta --from 16` strips them. Access methods and partial predicates are database-layer migrations." - after: "Both are now a `tsc` error and a parse error; `os migrate meta --from 16` lists the edits; `--write` applies the ones it can prove, the rest by hand." ### Token ratchet payment (`node scripts/check-skills-token-ratchet.mjs`, `ceil(utf8 bytes / 4)` per file) The new sentence in `SKILL.md` costs 63 bytes over the old one. It is paid by deleting one clause the same section restates — never by re-wrapping, never by touching the ceiling: - deleted (`SKILL.md:377-378`): "Access methods and partial predicates are database-layer migrations." (70 bytes with its leading space); - where its content survives, same file: `SKILL.md:387-388` "See rules/indexing.md for composite indexes, unique scope, and how to build partial / gin / gist indexes at the database layer." and `SKILL.md:44` "Index Strategy (rules/indexing.md) — btree/gin/gist/fulltext, composite indexes, partial indexes"; and in `rules/indexing.md` § "Access methods and partial indexes", the section the retirement callout points at; - net: 24512 → 24506 bytes, 6128 → 6127 tokens, headroom 0 → 1. The ceiling row in `scripts/check-skills-token-ratchet.mjs` is not touched (see Acceptance notes). ## `skills/**` readings — lines, and tokens as the ratchet counts them | File | Before | After | |:--|:--|:--| | `skills/objectstack-data/SKILL.md` | 469 lines · 24512 bytes · 6128 tokens (ceiling 6128, headroom 0) | 469 lines · 24506 bytes · 6127 tokens (headroom 1) | | `skills/objectstack-data/rules/indexing.md` | 229 lines · 8729 bytes · 2183 tokens (ceiling 3241) | 230 lines · 8805 bytes · 2202 tokens | | Whole package — every `skills/**/SKILL.md` summed | 4408 lines · 210279 bytes | 4408 lines · 210273 bytes | | Whole shipped bundle — the ratchet's own "bundle total" line | 154833 tokens (the gate run in a detached worktree at `1e5d322c1e`) | 154851 tokens (+18: −1 and +19) | No eval under `skills/objectstack-data/evals/` quotes either sentence (`grep -rn strip skills/objectstack-data/evals/` — 0 hits). Frontmatter untouched; `check:skill-docs` and `check:skill-refs` both report in sync. ## Closing enumeration — every `os migrate meta` sentence in `skills/**` `git grep -n "os migrate meta" -- skills/` on `0aa5205228`: 30 hits in 5 files (`objectstack-data/SKILL.md` 1, `objectstack-data/rules/indexing.md` 1, `objectstack-upgrade/SKILL.md` 21, `objectstack-upgrade/evals/protocol-major-upgrade.json` 5, `objectstack-upgrade/references/examples-upgrade.md` 2) — the same lines as on `origin/main`, since only the two data-skill lines moved. A widened `git grep -n "migrate meta" -- skills/` adds one bare hit (`objectstack-upgrade/SKILL.md:466`), judged too. Three tests per hit: (a) the default run lists and writes no source; (b) `--write` rewrites only the provable sites; (c) `--from N` is at or above `MIGRATION_SUPPORT_FLOOR` (16). A line is changed only when it is false. | File:line | Sentence (abridged) | Reading | Changed? | |:--|:--|:--|:--| | `objectstack-data/SKILL.md:377` | "`os migrate meta --from 16` strips them." | FALSE on (a) and (b): the default run strips nothing; `--write` strips only the proven sites | yes | | `objectstack-data/rules/indexing.md:31` | "run `os migrate meta --from 16` to strip them automatically." | FALSE on (a) and (b) | yes | | `objectstack-upgrade/SKILL.md:64-66` | Quickstart: `--from 16 --step`, `--from 16 --json`, `--from 16 --out …`, under the comment "replay the chain (writes only --out; --write also rewrites the sites it can prove)" | true: (a) listing runs, `--out` is a snapshot and not a source; (b) stated; (c) 16 | no | | `objectstack-upgrade/SKILL.md:74` | "`os migrate meta --from 17 --json` — `applied` must be []" | true: the replay from the target major; (c) 17 ≥ 16 | no | | `objectstack-upgrade/SKILL.md:103` | "`os migrate meta --from 16` replays every step in order … down to the chain's support floor, 16 today" | true: (c) the floor constant is 16 | no | | `objectstack-upgrade/SKILL.md:124-133` | "What `os migrate meta` actually does" and its command block (`--out` "write the canonicalized stack", `--write` "rewrite the proven sites in place") | true on (a), (b), (c) | no | | `objectstack-upgrade/SKILL.md:153` | "By default `os migrate meta` rewrites no source file … `--write` rewrites in place each edit it can trace to one literal in one project file, lists every other with the reason …" | true: matches the flag description | no | | `objectstack-upgrade/SKILL.md:177-179` | `--stored` preview, `--stored --type …` narrowing, `--stored --apply --yes` | true of the stored pass (`write` is `exclusive: ['stored']`; `--apply` is the only writer there) | no | | `objectstack-upgrade/SKILL.md:215` | "`os migrate meta --from N --json` → `.specChanges`" | true: the JSON face carries `specChanges` (`meta.ts:881,928`); N is bounded by the floor sentence at `:103` | no | | `objectstack-upgrade/SKILL.md:313` | "`os migrate meta --from 16 --json`" piped into `node -e`, reading `.todos` | true: (a) a listing run; `todos` is the key (`meta.ts:459`) | no | | `objectstack-upgrade/SKILL.md:404` | "`os migrate meta --from TARGET_MAJOR --json` — `applied` must be []" (the placeholder is spelled out here) | true: (a); (c) by construction | no | | `objectstack-upgrade/SKILL.md:449` | "`os migrate meta --stored --json` — 0 = every row canonical, 1 = work left" | true of the stored pass: read-only, exit 1 while rows are pending (`storedMigrationClean`) | no | | `objectstack-upgrade/SKILL.md:466` | "`migrate meta` reports changes, but the files are unchanged — working as designed, the default run only lists — pass `--write`, or port the printed edits by hand" | true on (a) and (b) | no | | `objectstack-upgrade/evals/protocol-major-upgrade.json:7` | "`--step`, `--json`, and `--out …` — the command rewrites nothing on disk, so port the printed edits into the sources" | true of the invoked forms (none carries `--write`; `--out` writes a new snapshot and rewrites no source) | no | | `objectstack-upgrade/evals/protocol-major-upgrade.json:10,20` | `must_contain` token lists | not behaviour claims | no | | `objectstack-upgrade/evals/protocol-major-upgrade.json:17` | "runs `os migrate meta --from AUTHORED_MAJOR` to attribute the site to its `conversionId`, ports `requiredWhen` …" (placeholder spelled out) | true: (a) the listing attributes; the port is by hand | no | | `objectstack-upgrade/evals/protocol-major-upgrade.json:37` | "Replays `os migrate meta --from 17 --json` and reads `applied` … runs `os migrate meta --stored` (read-only) then `--stored --apply --yes`" | true on (a), (c), and of the stored pass | no | | `objectstack-upgrade/references/examples-upgrade.md:57` | "Ported into sources from `os migrate meta --out`." | true: hand-ported from the snapshot | no | | `objectstack-upgrade/references/examples-upgrade.md:79` | "`os migrate meta --stored --apply` — rows rehydrate correctly today; this makes it durable." | true of the stored pass | no | ## Local verification (tree `0aa5205228`; every exit code captured before any pipe) Derived with `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` (no paths; the tool took the changeset from the merge-base itself): 24 commands. Run after the final commit as one union with the tool's own loop idiom, recorded as `cmd :: exit N`, and reconciled: `dispatch-gates --ran` — "24 derived, 24 run, 0 NOT-MEASURED, 0 UNRUN". All 24 exit 0: `check-ci-filter-parity` · `check-closing-keyword-parity` (+ `--self-test`) · `check-comment-mask-corpus` · `check-doc-route-spelling --advisory` (+ `--self-test`) · `check-skills-token-ratchet` (+ `--self-test`) · `@objectstack/lint check:doc-formula-expressions` · `@objectstack/spec check:skill-docs` · `check:agent-test-spelling` · `check:corpus-claim-drift` · `check:cross-package-test-inputs` · `check:doc-authoring` · `check:driver-memory-census` · `check:gitlink-declared` · `check:nul-bytes` · `check:pm-governed-merges` · `check:refd-timer-probe` · `check:role-word` · `check:skill-compatibility` · `check:skill-frame-sync` · `check:skill-identifier-liveness` · `check:watch-hint-literal`. - `check:doc-formula-expressions` first answered exit 3 (PREREQUISITE NOT MET — `@objectstack/formula` and `@objectstack/lint` were unbuilt; nothing measured). After `pnpm exec turbo run build --filter=@objectstack/formula --filter=@objectstack/lint --concurrency=2` behind `scripts/pm/os-verify-lock.sh` (VERDICT command-exit 0; held 92 s, waited 0 s) it exits 0. - Also run, outside the derivation: `pnpm --filter @objectstack/spec run check:skill-refs` exit 0 ("9 generated files in sync"); `pnpm check:skill-top-level-keys` exit 0. - NOT MEASURED locally, by design: the type-check lanes, the Test Core shards, the 11 wide-population families and the 51 roster families the derivation names are CI's; the 15 pending-changeset families do not apply (no changeset — this diff publishes nothing from any released package; label `skip-changeset`). ### Reverse verification of the ratchet payment (one-off; committed first; `scripts/ablation-replace.mjs`) - Attempt 1 was a no-op by the tool's own count check (the anchor was a substring of its replacement, anchor count 1 → 1): refused and restored, nothing measured. - Attempt 2, re-anchored on "prove, the rest by hand." with the deleted clause re-added: mutation landed on disk (blob `7220a34363d3` → `efe8f6825326`); `node scripts/check-skills-token-ratchet.mjs` exit 1 — "`skills/objectstack-data/SKILL.md` is 6144 tokens; the ratchet ceiling is 6128 (over by 16)". Restore proven: blob == HEAD `7220a34363d3`, `git diff HEAD` empty, `git status --porcelain` empty. ## Acceptance notes - The class pin `packages/spec/src/shared/retired-key-migrate-sentence.test.ts` (`WITHDRAWN_CLAIM`) matches only "to rewrite … automatically" and the "rewrites (it for you / existing sources / authored sources / your sources / your source files)" spellings — no "strip" — so it never saw these two lines, and nothing in this PR is implied to be covered by it. Widening it is spec-lane work and the file is held by PR objectstack-ai#22142; it is not touched here. Carrier: the `domain:spec` seat, via the skills seat's relay. - `skills/objectstack-data/SKILL.md` now sits 1 token under its unchanged 6128 ceiling. Lowering the ceiling to 6127 is legitimate per the gate's own header and outside this card's file surface. Carrier: the next PR that touches `scripts/check-skills-token-ratchet.mjs`, or the skills seat. - Tier H (`skills/**`): this PR stays draft and lands on an authorized APPROVED review or the maintainer's hand; no seat flips it ready. ## 维护者速读(草稿) **改了什么**:objectstack-data 技能里两句话(`rules/indexing.md:31`、`SKILL.md:377`)原本说 `os migrate meta --from 16` 会"自动剥掉"/"剥掉"已退役的索引键 `type` 和 `partial`。改成工具的真实行为:默认只列出机械修改;`--write` 只落它能证明的那些站点;其余由作者手工完成。顺带把 `skills/**` 里所有 `os migrate meta` 句子逐条核对了一遍(上表),其余均属实,一字未动。 **为什么改**:这是对外发布的技能包(`npx skills add` 原样装进客户项目),读到这句的 AI 作者会以为源码已被清理,把退役键留在原地,直到 `tsc` 或解析报错才发现。`docs/NORTH-STAR.md` 优先级第 4 条:发布面上的错句就是产品缺陷;`retired-key.ts` 的内部裁决是"这句话必须对工具为真"。 **风险与代价(含回滚)**:纯文本改动,不碰代码、不碰 spec、不发包、无 changeset。`SKILL.md` 已顶在 token 上限,新句子靠删掉同一段里被下文重述的一句付账(内容仍在 `SKILL.md:387-388` 与 `rules/indexing.md`)。回滚 = revert 这一个提交。 **席位意见**: **你要做的**:确认两句新措辞与 PR objectstack-ai#22142 正在采用的 house sentence 一致;同意则 APPROVE,由席位落地。 --- _Generated by [Claude Code](https://claude.ai/code/session_01CXydFDyiQwNbGFkmwrcRQq)_ Co-authored-by: Claude <noreply@anthropic.com>
Fixes #22123
Clause-②: no
The published upgrade skill's "several majors late" paragraph examples
os migrate meta --from 10. The chain refuses every--frombelowMIGRATION_SUPPORT_FLOOR = 16(packages/spec/src/migrations/registry.ts:79) withMigrationFloorError— exit 1,--jsonerror: unsupported_from_major— and the same file's failure-mode row already says so. This PR rewords the paragraph so its point (lateness is the designed-for case) is stated with an example the chain accepts and with the floor in the same breath, within the file's token ceiling. #22120 is landed (PR #22122, same file); this branch cuts fromorigin/mainafter it.What changed (one file:
skills/objectstack-upgrade/SKILL.md)The paragraph under §0 "Establish the FROM major", before:
after:
The example is now the floor itself (the chain's lowest accepted
--from, and the spelling every other example in the file already uses); the floor's value is stated where the reader decides--from; the below-floor case carries the same remedy the failure-mode row and the CLI's own refusal text give ("Upgrade to protocol 16 by another path first, then re-run"). "There is no penalty for lateness" is dropped as restating "the designed-for case". Nothing else in the file states a--frombelow 16:grep -rn -F -- '--from 10' skills/objectstack-upgrade/is now 0 hits (control:--from 1612 hits inSKILL.md), andreferences/examples-upgrade.mdandevals/protocol-major-upgrade.jsonnever carried the example.Token ratchet — paid in content, not wrapping
node scripts/check-skills-token-ratchet.mjs(tokens = ceil(utf8 bytes / 4); ceiling for this file 6193):ef1fcb26a2, the file as #22122 left it)3e842f9fd8)Whole package (the ten
skills/*/SKILL.md): 4407 → 4408 lines, 52575 → 52572 tokens; the ratchet's authored-bundle total 144050 → 144047 (shipped tree 154836 → 154833). Diff: +6 / −5 lines. Gate line at3e842f9fd8:✓ check-skills-token-ratchet: skills/objectstack-upgrade/SKILL.md is 6184 tokens (ceiling 6193; headroom 9).The paragraph grew by +94 bytes (197 → 291). That is paid by deleting two clauses the same file states beside them — no rule, failure-mode row or command among them, and no line re-wrapped:
mkdir -p .upgradein §0's "Make the work reviewable" block ("every artifact this skill produces lands here", −57 bytes) — the paragraph directly under the block opens "The.upgrade/directory is the deliverable's workspace" and lists the artifacts;spec-changes.jsonand the chain's--jsonoutput, which are two rows of that table.Net −12 bytes.
Scope held
packages/spec/**, nopackages/cli/**, nocontent/docs/**;references/examples-upgrade.mdandevals/protocol-major-upgrade.jsonuntouched (neither carries the example; the eval'smust_containisos migrate meta --from 16, which still holds). Frontmatter unchanged:check:skill-docsandcheck:skill-refsgreen ("Skill docs in sync", "9 generated files in sync").--from 16,^17and "The 16 → 17 crossing"; the frontmatter'scompatibilityline keeps the general statement ("the chain replays from the spec'sMIGRATION_SUPPORT_FLOOR"), and §2.1's reading printssupportFloorfrom the installed spec. When the floor moves, this sentence is one of the file's dated numbers, not the only one.Gates
Derived with
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackon this tree (24 families atef1fcb26a2and again at3e842f9fd8; identical to the PM's path-derived list). All 24 run, exit 0 each, recorded beside the printed command and reconciled with--ran("24 derived, 24 run, 0 NOT-MEASURED, 0 UNRUN", a derived zero).check:doc-formula-expressionsfirst exited 3 (prerequisite:@objectstack/formulaand@objectstack/lintnot built) and was re-run green after the prescribed build under the verify lock. Beyond the derived list, also green:check:skill-top-level-keys,check:skill-frame-freshness,check:skill-refs. NOT MEASURED:check:skill-examples(prerequisite: the client SDK dist is not built; outside the derived list, and this diff touches no SDK example).Acceptance notes
维护者速读(草稿)
改了什么:只改一份对外发布的技能文件
skills/objectstack-upgrade/SKILL.md的一个段落。原文以os migrate meta --from 10作为"晚几个大版本再升级也没关系"的示例,但迁移链的支持下限是 16(MIGRATION_SUPPORT_FLOOR = 16),--from 10会被 CLI 直接拒绝(MigrationFloorError,退出码 1)。现在示例改为链接受的--from 16,同一句话里说明下限(今天是 16),并告诉低于下限的项目先用旧路线升到 16 再跑链——与同一文件故障表里已有的那一行一致。为什么改:这份技能随每次
npx skills add整包进入客户项目的 agent 上下文;一句教人运行会被拒绝的命令的话,是发布面上的错误句子(NORTH-STAR「优先级」第 4 条)。CLI 的拒绝挡住了实际伤害,但文字不改就一直是错的。风险与代价(含回滚):纯文本改动,无代码、无 changeset、无生成物变化。token 棘轮:6187 → 6184(上限 6193),净减 12 字节,靠删除两处紧邻处已有陈述的重复子句支付(一处代码块尾注,一处收尾从句),未删任何规则、故障行或命令,未折行。回滚即 revert 本 PR 的一个提交。注意:下限值"16"写成了具体数字,与文件里其它写死的
--from 16、^17同样随下限移动而需要更新;frontmatter 与 §2.1 的读数保留了通用表述。席位意见:(留空,席位定稿)
你要做的:
skills/**为 Tier H 受管面:请以授权账号 APPROVE 一次,或亲手合入;本 PR 保持 draft,不由 agent 翻 ready。Generated by Claude Code