Skip to content

Commit 713f231

Browse files
skills(objectstack-upgrade, catalog READMEs): the upgrade preflight re-installs the catalog from @objectstack/skills on a 17.x to 18 move; both READMEs give the scaffolder's pinned --copy sync (#23366)
Fixes #23276 Clause-②: no Ruling A on #22649 (record 6096124407), the upgrade-playbook half: the skills catalog ships as the versioned npm package `@objectstack/skills`, installed and upgraded with the other `@objectstack/*` packages, and the GitHub path is the `next` channel only. `skills/objectstack-upgrade/SKILL.md` §0 Preflight gains one step that re-installs the catalog from the package when a 17.x project moves to 18, and the two READMEs the package ships (`skills/README.md`, published as `dist/skills/README.md`, and `packages/skills/README.md`, the npm page) replace the unpinned linked sync with the scaffolder's pinned `--copy` spelling. One `patch` changeset for `@objectstack/skills`. Four files; nothing under `content/docs/**` or `packages/create-objectstack/**` is touched (the first is the devx lane's landed sibling, the second is read as the source of the spelling). ## The step (`skills/objectstack-upgrade/SKILL.md`, §0 Preflight, after the upgrade branch and `.upgrade/` exist) Placed after "Make the work reviewable", so the re-install lands on the `upgrade/protocol-17` branch beside the rest of the upgrade. The one "why" sentence: a 17.x project's skills came from `skills add`; their `skills-lock.json` entries read `sourceType: github`, so the sync skips them (exit 0) and the agent keeps reading 17.x skill text. The three commands: ```bash npx skills remove objectstack-ai objectstack-api objectstack-automation \ objectstack-data objectstack-formula objectstack-i18n objectstack-platform \ objectstack-pm-dispatch objectstack-query objectstack-ui objectstack-upgrade -y npm install --save-dev "@objectstack/skills@$(node -p "require('@objectstack/spec/package.json').version")" npx skills@1.7.2 experimental_sync --agent claude-code --copy -y ``` - **The remove list is the devx seat's eleven names** (pointer comment 6148721272: `objectstack-pm-dispatch` was in the catalog through the `@objectstack/spec` 17.0.0–17.4.0 trees; a ten-name remove on a 17.4.0 project printed `Found 11 / removed 10`), copied byte for byte from `content/docs/upgrading.mdx` lines 108–110 at this tree, so the skill and the site read the same. The prose names the two facts the site states beside it: a missing name is skipped (exit 0), and `--all` does the same when these are the project's only skills. - **The sync spelling is the scaffolder's**, read from `packages/create-objectstack/src/skills-install.ts` at `441106662a` (unchanged since the dispatch tree `228357ab69`): line 102 `export const SKILLS_CLI = 'skills@1.7.2';`, line 119 `` return `${SKILLS_CLI} experimental_sync --agent ${agent} --copy -y`; ``, line 127 `` export const SKILLS_INSTALL_COMMAND = `npx -y ${skillsSyncArgs(DEFAULT_SKILLS_AGENT)}`; `` — so what the scaffolder RUNS is `npx -y skills@1.7.2 experimental_sync --agent claude-code --copy -y`, and what it PRINTS for a user to run later (line 131, `skillsInstallHint`) is `npx skills@1.7.2 experimental_sync --agent AGENT --copy -y`. The skill and both READMEs carry the printed form, as `content/docs/upgrading.mdx:97,112` and `skills-reference.mdx:24` do; the `-y` after `npx` only suppresses npx's own install prompt for the pinned CLI, and the trailing `-y` is the CLI's. ## Paying for it under the token ratchet (`ceil(utf8 bytes / 4)`, the release-stamp line excluded) The step costs 815 bytes (about 204 tokens, 16 lines) — more than the card's 60–100 estimate, because the eleven-name list alone is 234 bytes. It is paid by six deletions in the same file, each a sentence the file states elsewhere; no re-wrap and no ceiling move. Every deleted sentence and its home: | # | deleted (section) | home in the same file | |:--|:--|:--| | 1 | "Everything below is the long form of those four steps." (under Quickstart) | the Quickstart's four `# N ·` comments and the four `## N ·` section headings | | 2 | "Below the floor, upgrade to it by the older route first, then run the chain." (§0, FROM major) | Failure modes row `MigrationFloorError`: "Upgrade to the floor by an older route first; the floor is a release-policy boundary, not an oversight." | | 3 | "Porting the edits left unwritten is yours, one `conversionId` at a time; use `--out` as the oracle you diff against, never as the file you ship." (§1) | Failure modes row 1 ("Pass `--write`, or port the printed edits by hand; then replay from the target major to confirm 0 changes"), row 2 ("Diff against `--out`"), and the boundary section's "One `conversionId` per commit" | | 4 | the first R2 trap bullet, "A renamed context field keeps compiling. … assert the value observed under the canonical key." (§2.5) | §2.2's R2 definition ("or worse, keeps compiling while reading `undefined`") and Failure modes row 3 ("An R2 residue item: code reading a renamed key now reads `undefined`. Exercise the path for real."). The intro "Two traps…" becomes "One trap…" with the surviving bullet folded into the sentence. | | 5 | "Fixing the project's standing lint debt may be a welcome side-effect, but it is not this upgrade, and it must not be reported as part of it." (§3.3) | the same paragraph ("a **pre-existing** project-quality issue, not upgrade residue") and Failure modes row 5 ("Pre-existing findings are not this upgrade's scope") | | 6 | "Run both. A report that cites only `validate` cannot see this class at all." (§3.3 call-out) | the call-out's own "`validate` green is necessary and not sufficient, and the criterion that closes the gap is the replay", the Quickstart's "# 3 · acceptance — all four, not three", and the §3.5 outcome table's third row | No eval or reference file names any deleted sentence (`grep` over `skills/objectstack-upgrade/evals/` and `references/` for the deleted phrases: 0 hits), and `git grep` repo-wide outside the file: 0 hits. ## Readings — before (`origin/main` `e790cfc503` = the branch base) and after (this head `441106662a`) | surface | before | after | net | |:--|:--|:--|:--| | `skills/objectstack-upgrade/SKILL.md` | 24746 bytes / 485 lines / **6180 tokens** (ceiling 6188, headroom 8) | 24715 bytes / 484 lines / **6172 tokens** (ceiling 6188, headroom 16) | −31 bytes, −1 line, −8 tokens | | `skills/README.md` (outside the ratchet's population; ships as `dist/skills/README.md`) | 8322 bytes / 128 lines / 2081 tokens | 8506 bytes / 130 lines / 2127 tokens | +184 bytes, +2 lines | | `packages/skills/README.md` (not under `skills/**`; the npm page) | 4024 bytes / 74 lines / 1006 tokens | 4224 bytes / 76 lines / 1056 tokens | +200 bytes, +2 lines | | whole package — `check-skills-token-ratchet`'s "ratcheted (authored)" sum, 54 files | 144089 / 154888 | 144081 / 154888 | −8 tokens | | whole package — "bundle total (whole shipped tree)", 64 files | 155052 | 155044 | −8 tokens | | every `skills/*/SKILL.md`, 10 files | 210600 bytes / 4409 lines | 210569 bytes / 4408 lines | −31 bytes, −1 line | Line budget from the claim: SKILL.md net lines ≤ +6 (actual −1); each README ≤ +2 (actual +2 and +2). The generated index block of `skills/README.md` is byte-identical (`check:skill-docs` ✓ `skills/README.md`, and the diff touches lines 5–21 only). ## The READMEs - `skills/README.md`: "sync it" → "copy it"; the command line becomes `npx skills@1.7.2 experimental_sync --agent claude-code --copy -y`; the paragraph below opens with why `--copy` (real files in `.claude/skills/`, to commit with the project; without it, links into `node_modules`, which a clone does not have) and points the move from a `skills add` install at the Skills reference, whose `#installing-skills` section carries it. The linked form is dropped, not kept: the one-sentence explanation of what it does is the whole mention. The `next` channel paragraph is unchanged. - `packages/skills/README.md`: step 2 becomes "copy it …" with the same command; the paragraph below says the sync copies real files and records the source in `skills-lock.json`, why to keep `--copy`, and that the CLI is pinned to the version `create-objectstack` runs. The "Projects scaffolded by `create-objectstack`" paragraph (remove first — `npx skills remove --all`, or name the `objectstack-*` skills — then steps 1 and 2) already matches the pointer's `--all` alternative and is unchanged; "Through `18.0.0-next.0`" is still true of every published `create-objectstack` (the package is at `18.0.0-next.0` on this tree). ## Verification (every exit captured before any pipe: `cmd > log 2>&1; EXIT=$?`; logs under the session scratchpad `issue-23276/gates/`) - `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` (no paths: the change set from the merge base) derived **68** commands from the tree at `441106662a` (the same 68 on `f88e80d981`; `origin/main` had moved 3 commits, so `origin/main` was merged first and the list re-derived). Each ran in the foreground, sequentially; `--ran` reconciliation: `✓ dispatch-gates --ran: 68 derived famil(ies) accounted for — 66 run, 2 NOT-MEASURED (2 DERIVED from a recorded exit 3).` 0 UNRUN. All 66 exit 0. - **NOT MEASURED locally (exit 3, PREREQUISITE NOT MET), declared to CI:** `pnpm check:dts-closure` and `pnpm check:dual-build-cjs-loads` read every package's built `dist/`; a turbo dry run on this tree reads 82 of 83 build tasks as cache MISS, and the full build does not fit a foreground call on the shared box. This diff changes three markdown files and a changeset — no source, `exports` or type entry — so their population is unreachable by it. `Lint & Repo Gates` runs both on the PR. The two other exit-3 refusals of the first pass (`check:doc-formula-expressions`, `check:lean-entry-closure`) were re-run to exit 0 after `pnpm turbo run build --filter='@objectstack/lint...' --filter='@objectstack/objectql...' --concurrency=2` under the verify lock (14 tasks, 2m18s, `VERDICT command-exit 0`). - **The card's named gates:** `check:skill-compatibility` 0 (`11 pinned major(s) all match the workspace`), `pnpm --filter @objectstack/spec run check:skill-docs` 0 (`✓ skills/README.md`, `✅ Skill docs in sync`), `check:skill-refs` 0 (`9 generated files in sync`), `check:skills-token-ratchet` 0 (the readings above, from the sweep on this head), `check:published-readme-links` 0 (`226 outbound link(s) across 104 published markdown file(s) … 2 anchor(s) verified`), `check:published-readme-exports` **3 — NOT MEASURED**: `48 package(s) whose built type entry this run would read are not built` (same prerequisite as above; neither README carries an import, their fenced blocks are `sh`/`bash` commands). `git status` clean after the two spec checks. - **Changeset gates:** `check-empty-changeset --base origin/main` 0 (`1 declaring changeset(s) added`, no base changeset modified), `check-changeset-no-major --base origin/main` 0, `check-adr-0087-registration --base origin/main` 0 (`this PR adds no declared-breaking changeset`), `check:changeset-gate-self-tests` 0, `check:pm-changeset-deadline-census` 0, `check:published-files` 0. ⛔ No `skip-changeset`: both READMEs and the skill text ship in the `@objectstack/skills` tarball (`files`: `dist`, `README.md`, `CHANGELOG.md`). - **The package itself:** `@objectstack/skills` has no workspace dependencies (step ① closure empty) and declares `build` and `prepublishOnly` only (no `test`/`typecheck` to run; a zero-match `--filter` run would exit 0 having run nothing, so none is cited). `pnpm --filter @objectstack/skills build` under the verify lock: `VERDICT command-exit 0`, `65 file(s) across 10 skill(s) copied from skills/** into dist/skills and read back byte-identical`; `cmp skills/README.md packages/skills/dist/skills/README.md` and `cmp` of the SKILL.md against its dist copy both identical. - **`pnpm lint`, narrowed and measured:** `eslint --no-inline-config --format json` over the four files answers 4 results, 0 errors, one warning each — `File ignored because no matching configuration was supplied` (eslint's own config, not a guess); `eslint.config.mjs:328` states no type-aware linting is enabled, so no untouched file's verdict can move. Population reachable by this diff: 0 files. - **Bytes:** control-character grep (`[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]`, `-naP`) over the four files: exit 1, 0 hits; `check:nul-bytes` 0; no HTML comment added (0 added lines carry one); `check:pm-governed-merges` 0. - No reverse verification or ablation applies: the diff is prose and a changeset, with no gate, test or runtime path whose verdict it could move. ## Acceptance notes - Tier H (`skills/**`): this PR stays a draft until an authorized APPROVED review; no seat readies it or arms auto-merge. The seat requests the review. - The Quickstart block (`# 0 · preflight`) does not name the skills step; the long-form §0 does. Adding a comment line there costs about 15 tokens and was not spent — a reviewer who wants it there can ask and the seat pays it with one more same-file deletion. - Eleven names versus `--all`: the step carries the eleven-name list as its primary spelling (the card's and the site's), with `--all` as the stated alternative. Swapping to `--all` as primary would return about 150 bytes to the ratchet; the maintainer's preference decides, not this PR. - Observation, noted, not filed (no class a/b/c evidence): §0 of the skill still says "down to the chain's support floor, 16 today", a pinned number the same skill tells its reader never to carry (§2.1), while `spec-changes.json` carries `supportFloor` and the §2.1 snippet already prints it. Carrier: the next PR that edits this file; this one did not spend the ratchet on it. - Observation, noted, not filed: `packages/skills/README.md`'s "Through `18.0.0-next.0` the scaffolder installs the skills from the `next` channel" and `skills-reference.mdx:31`'s matching sentence go stale when `create-objectstack` publishes a version above `18.0.0-next.0` with the package-based scaffolder (PR #23248, on `main`, unreleased). Carrier: the Version Packages release that bumps it; the sentence is true of every published scaffolder today. - The two NOT MEASURED families above are the only narrowing; it is declared here and in the report, and CI measures them. - #23275 is not addressed here (the devx lane's docs pass, landed as PR #23295); `content/docs/**` is untouched. - Commit trailers are the model-free pair AGENTS.md requires; no card relation rides a commit — this body is the one carrier. ## 维护者速读(草稿) **改了什么。** 对外发布的升级技能 `objectstack-upgrade` 的「0 · 预检」多了一步:17.x 项目的 AI 技能是用 `skills add` 从仓库 `main` 装的,`skills-lock.json` 里记为 `sourceType: github`,新的同步命令会静默跳过它们(退出码 0),于是只升包不升技能的项目,`.claude/skills/` 里仍是 17.x 的技能文本。这一步先删掉 17.x 目录曾含的十一个 `objectstack-*` 技能(与官网升级页同一份名单;名单里没装的会被跳过;只装了这些技能的项目可用 `--all`),再按已装 `@objectstack/spec` 的版本安装 `@objectstack/skills`,最后用脚手架同一条钉版本、带 `--copy` 的命令复制进代理目录。同时,随 `@objectstack/skills` 发布的两份 README(目录首页与 npm 页面)把未钉版本、生成软链接的同步命令换成脚手架这条拼写,并说明为何要 `--copy`(软链接指向 `node_modules`,克隆后是悬空链接)。附一个 `@objectstack/skills` 的 patch changeset。`content/docs/**` 与脚手架源码一字未动。 **为什么改。** #22649 裁决 A:技能目录随 `@objectstack/*` 一起装、一起升,GitHub 路径只是 `next` 渠道。升级手册此前对技能只字未提(实测 `grep` 为 0 行),升级者按手册走完,技能文本停在 17.x 且同步静默跳过——这是 devx 席位在 17.4.0 项目上实测到的(十个名字删了十个、找到十一个,`objectstack-pm-dispatch` 留在原地),所以名单是十一个。 **风险与代价(含回滚)。** 纯文本改动,无行为变化。代价全在技能文件的 token 棘轮:该文件此前只剩 8 个 token 余量,这一步要 815 字节(约 204 token),比卡上估的 60–100 多,因为十一个名字本身就 234 字节;用同文件六处「别处已有原话」的句子抵掉(每句与其落点见上表),未折行、未抬上限,落地后余量 16。两份 README 各净增 2 行,恰在认领给的预算上。回滚即 revert 本 PR 的单个 squash 提交;changeset 未被消费前删除即无痕。本地未测到的两族门禁(`dts-closure`、`dual-build-cjs-loads`)要全仓构建,本次改动触不到它们的判定面,交 CI 测。 **席位意见。** (留空,席位定稿成评论。) **你要做的。** 本 PR 含 `skills/**`,属 Tier H:只需您在 PR 上给一个 APPROVED review(任一提交上、不撤回即可),席位随后负责排队落地;不需要您合并。两处可一句话定的措辞:① 删除名单以十一个名字为主、`--all` 为备(与官网一致),若您更想以 `--all` 为主,席位代改并把省下的约 150 字节退还棘轮;② Quickstart 的 `# 0 · preflight` 块未点名技能这一步(长文 §0 有),要加约 15 个 token,席位可再删一句同文件复述来付。 --- _Generated by [Claude Code](https://claude.ai/code/session_013zGKMG1cRedVzWtqGGGZW9)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent f24574a commit 713f231

4 files changed

Lines changed: 50 additions & 36 deletions

File tree

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
"@objectstack/skills": patch
3+
---
4+
5+
docs(skills): the upgrade skill's preflight re-installs the catalog from `@objectstack/skills` when a 17.x project moves to 18, and both READMEs give the scaffolder's pinned `--copy` sync (#23276)
6+
7+
Clause-②: no
8+
9+
`objectstack-upgrade`'s §0 Preflight gains one step for the skills themselves. A 17.x project's skills were installed with `skills add` from the repository's `main`; their `skills-lock.json` entries read `sourceType: github`, and `experimental_sync` skips them (it prints `Skipped … installed with skills add` and exits 0), so a project that only bumps its packages keeps its 17.x-era skill text. The step removes the eleven `objectstack-*` skills the catalog carried during 17.x (a name not installed is skipped; `--all` when they are the project's only skills), installs `@objectstack/skills` at the installed `@objectstack/spec`'s version, and copies it with `npx skills@1.7.2 experimental_sync --agent claude-code --copy -y` — the command `create-objectstack` runs. The step is paid under the token ratchet by deleting text the same file restates elsewhere; the ceiling is unchanged.
10+
11+
`README.md` (the npm page) and `dist/skills/README.md` (the catalog's front page, copied from the repository's `skills/README.md`) replace the unpinned linked sync (`npx skills experimental_sync --agent claude-code -y`) with that pinned `--copy` spelling and say why: without `--copy` the sync writes links into `node_modules`, which a clone of a project that commits its skills does not have.

‎packages/skills/README.md‎

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,18 @@ agent's own skills directory (`.claude/skills/` for Claude Code, and so on):
2727
# 1 · the catalog, at the version of your installed @objectstack/spec
2828
npm install --save-dev "@objectstack/skills@$(node -p "require('@objectstack/spec/package.json').version")"
2929

30-
# 2 · link it from node_modules into your agent's skills directory
31-
npx skills experimental_sync --agent claude-code -y
30+
# 2 · copy it from node_modules into your agent's skills directory
31+
npx skills@1.7.2 experimental_sync --agent claude-code --copy -y
3232
```
3333

3434
`experimental_sync` discovers the skills at `dist/skills/<skill>/SKILL.md` of
35-
every dependency and links each one into the named agent's skills directory
36-
(`--agent <name>` names the runtime — `codex`, `cursor`, …; `--copy` writes real
37-
files instead of links). Keep the version in step 1: a bare
38-
`npm install --save-dev @objectstack/skills` installs whichever version the
39-
registry tags `latest`, not your spec's.
35+
every dependency and copies each one into the named agent's skills directory
36+
as real files, recording the source in `skills-lock.json` (`--agent <name>`
37+
names the runtime — `codex`, `cursor`, …). Keep `--copy`: without it the sync
38+
writes links into `node_modules`, which a clone of the project does not have;
39+
the CLI is pinned to the version `create-objectstack` runs. Keep the version
40+
in step 1: a bare `npm install --save-dev @objectstack/skills` installs
41+
whichever version the registry tags `latest`, not your spec's.
4042

4143
**Updating.** The catalog moves only with your ObjectStack version: bump
4244
`@objectstack/skills` with the other `@objectstack/*` packages, then re-run the

‎skills/README.md‎

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,20 @@ working in **any ObjectStack app** — this monorepo *and* third-party projects.
55
They ship as the npm package `@objectstack/skills`, released with the other
66
`@objectstack/*` packages at one shared version. Install it at your installed
77
`@objectstack/spec`'s version — the catalog's version is then your spec's — and
8-
sync it from `node_modules` into your agent's directory:
8+
copy it from `node_modules` into your agent's directory:
99

1010
```bash
1111
npm install --save-dev "@objectstack/skills@$(node -p "require('@objectstack/spec/package.json').version")"
12-
npx skills experimental_sync --agent claude-code -y
12+
npx skills@1.7.2 experimental_sync --agent claude-code --copy -y
1313
```
1414

15-
Name your own runtime after `--agent` (`codex`, `cursor`, …). To update, bump
16-
`@objectstack/skills` with the other `@objectstack/*` packages, then re-run the
17-
sync. The package is published from `18.0.0-next.0` on (there is no 17.x release);
18-
`--copy`, projects scaffolded by `npm create objectstack` and the rest are in the
19-
[Skills reference](https://objectstack.ai/docs/ai/skills-reference#installing-skills).
15+
Keep `--copy`: the skills land as real files in `.claude/skills/`, to commit with
16+
the project; without it they are links into `node_modules`, which a clone does
17+
not have. Name your own runtime after `--agent` (`codex`, `cursor`, …). To update,
18+
bump `@objectstack/skills` with the other `@objectstack/*` packages, then re-run
19+
the sync. The package is published from `18.0.0-next.0` on (there is no 17.x
20+
release); scaffolded projects, the move from a `skills add` install and the rest
21+
are in the [Skills reference](https://objectstack.ai/docs/ai/skills-reference#installing-skills).
2022

2123
**The `next` channel.** `npx skills add objectstack-ai/objectstack/skills --skill '*' --agent claude-code -y`
2224
reads the catalog straight from the repository's unreleased `main` — for trying

‎skills/objectstack-upgrade/SKILL.md‎

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,6 @@ os migrate meta --from 17 --json # `applied` must be [] (see §3.3)
7575
# → write .upgrade/REPORT.md (template in §3.4)
7676
```
7777

78-
Everything below is the long form of those four steps.
79-
8078
---
8179

8280
## 0 · Preflight
@@ -102,8 +100,7 @@ one installed. Three sources, in order of authority:
102100

103101
Arriving several majors late is the designed-for case: `os migrate meta --from 16`
104102
replays every step in order, with no requirement to upgrade one major at a time —
105-
down to the chain's support floor, 16 today. Below the floor, upgrade to it by
106-
the older route first, then run the chain.
103+
down to the chain's support floor, 16 today.
107104

108105
### Make the work reviewable before you change anything
109106

@@ -117,6 +114,22 @@ The `.upgrade/` directory is the deliverable's workspace: the machine outputs
117114
and the human output (`REPORT.md`). Keeping them in the repo for the review, and
118115
deleting them on merge, is the usual arrangement — decide it with the owner.
119116

117+
### Re-install the skills from the moved catalog
118+
119+
A 17.x project's skills came from `skills add`; their `skills-lock.json` entries
120+
read `sourceType: github`, so the sync skips them (exit 0) and the agent keeps
121+
reading 17.x skill text. Remove them (a missing name is skipped; `--all` when
122+
they are the project's only skills), add `@objectstack/skills` at the installed
123+
spec's version, copy it:
124+
125+
```bash
126+
npx skills remove objectstack-ai objectstack-api objectstack-automation \
127+
objectstack-data objectstack-formula objectstack-i18n objectstack-platform \
128+
objectstack-pm-dispatch objectstack-query objectstack-ui objectstack-upgrade -y
129+
npm install --save-dev "@objectstack/skills@$(node -p "require('@objectstack/spec/package.json').version")"
130+
npx skills@1.7.2 experimental_sync --agent claude-code --copy -y
131+
```
132+
120133
---
121134

122135
## 1 · Mechanical layer — invoke the chain
@@ -157,9 +170,6 @@ other with the reason it was not written, never writes a semantic change, and
157170
if re-running the chain over the written files disagrees, restores every file
158171
and exits 1.
159172

160-
Porting the edits left unwritten is yours, one `conversionId` at a time; use
161-
`--out` as the oracle you diff against, never as the file you ship.
162-
163173
### Stored rows: rehydration replays the same conversions
164174

165175
A deployment's `sys_metadata` rows are the other subject. They are handled for
@@ -318,16 +328,9 @@ os migrate meta --from 16 --json | node -e "
318328
grep -rn "<surface-token>" src/ app/ --include='*.ts' --include='*.tsx'
319329
```
320330

321-
Two traps that have cost real upgrades a lap:
322-
323-
- **A renamed context field keeps compiling.** When a read moves from one key to
324-
another and the old key is simply absent afterwards, the code reads
325-
`undefined` and every branch quietly takes its false path. Verify against a
326-
real dispatch, not a fixture — invoke the path and assert the value observed
327-
under the canonical key.
328-
- **A rename is not always the fix.** If the old read was itself wrong, renaming
329-
it migrates the defect rather than the code. Read the semantic entry's
330-
`reason` before applying its `replacement`.
331+
One trap that has cost real upgrades a lap: **a rename is not always the fix.**
332+
If the old read was itself wrong, renaming it migrates the defect rather than
333+
the code. Read the semantic entry's `reason` before applying its `replacement`.
331334

332335
### 2.6 Working an R3 — the prose sweep
333336

@@ -383,9 +386,7 @@ the author-time rule set. Read the two separately — a rule finding about a
383386
missing sharing model or an options-less choice field is a **pre-existing**
384387
project-quality issue, not upgrade residue. Establish which is which by running
385388
`os validate` **once before you start**, on the un-upgraded source, and keeping
386-
that output as the control. Fixing the project's standing lint debt may be a
387-
welcome side-effect, but it is not this upgrade, and it must not be reported as
388-
part of it.
389+
that output as the control.
389390

390391
> ### ⚠ A green `validate` does NOT mean the chain has nothing left to do
391392
>
@@ -408,8 +409,6 @@ part of it.
408409
> build carries a step for, which is one PAST the installed major for most of a
409410
> release line, so `todos` carries the next major's semantic residue — real, but
410411
> not this upgrade's business.
411-
>
412-
> Run both. A report that cites only `validate` cannot see this class at all.
413412
414413
→ Moved verbatim to [references/examples-upgrade.md](./references/examples-upgrade.md) § 3.4 The report — the human half.
415414

0 commit comments

Comments
 (0)