Skip to content

feat(skills): derive the compatibility majors and metadata.version from the workspace version - #22692

Merged
os-zhuang merged 2 commits into
mainfrom
claude/issue-22658-compat-line-derived
Oct 11, 2026
Merged

os-zhuang merged 2 commits into
mainfrom
claude/issue-22658-compat-line-derived

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #22658
Clause-②: no

Ruling A on #22649 (record 6096124407, maintainer 「22649 同意 A」): the compatibility: line and each skill's metadata.version derive from the package version instead of being kept by hand. This is PR 2 of the two the card allows — the derivation and the ten regenerated frontmatters (Tier H: skills/**). PR 1 (claude/issue-22658-skills-package) adds the @objectstack/skills package; this PR does not depend on it merging (see the version source below). No skills/** path moves; no skill's teaching changes — the ten diffs are one version: line each.

What changes

  • scripts/check-skill-compatibility-version.mjs — the gate that already reconciled every @objectstack/PKG N.x pin against the workspace manifests now also reconciles metadata.version: every SKILL.md must carry exactly the fixed group's version, read off @objectstack/spec's manifest (CATALOG_VERSION_PACKAGE); an absent stamp is red, a stale one is red naming file / declared / actual / fix, and a workspace without that package is red rather than "nothing to derive". A new --fix leg is the one writer: it rewrites each pin's major to the cited package's current workspace major (an inline scalar or a folded block scalar) and metadata.version to that version, writes only the files that moved, then runs the check; it invents no structure (a file with no version: key comes back unchanged and is named). Every prescription that used to say "edit the line" now names --fix; the header and the report footer say the line ships inside @objectstack/skills and from main as the next channel. The self-test grows from 18 to 27 pinned batteries: R9 stale stamp, R10 absent stamp, R11 the exempt (unpinned) upgrade skill is stamped too, R12 the anchor package missing, and five --fix derivation cases (both lines rewritten with every other byte kept, no-op on a derived file, a folded-block pin, no invented structure, an unknown package left for the check). R1's prescription regex moved with the text.
  • package.json (root) — the version script runs node scripts/check-skill-compatibility-version.mjs --fix after changeset version, beside sync-protocol-version.mjs and sync-template-versions.mjs: the Version Packages PR carries the restamped frontmatters, so main never sits red here between a bump and a hand edit, and the maintainer's own merge of that PR is the Tier H act for skills/**.
  • scripts/regen-artifacts.mjs — a NOT_DRIVER_MANAGED row (skills/*/SKILL.md, gen: version, root owner): the --fix makes the root version script a generator in git-merge-regen's population, and the recorded answer to "discard both sides and re-run" is no — two derived lines inside hand-written prose; a text conflict stays a human's, the two lines re-stamp on the next --fix. pnpm check:merge-driver: all 43 generator(s) across 81 manifest(s) have a recorded disposition.
  • skills/*/SKILL.md (10 files) — regenerated by --fix, never by hand: metadata.version "1.0" / "1.2" / "1.3" ×4 / "1.4" ×3 / "4.4" → "17.7.0"; 10 insertions, 10 deletions, nothing else. Every compatibility: pin was already at the workspace major (17.x), so those lines are byte-identical. skills/README.md's generated block does not carry the version; it is unchanged (check:skill-docs green).

The version source, measured

The PM's mechanism assumption named two possible sources and asked which exists on main: packages/skills/package.json does not exist at this branch's base (243dd3c62); packages/spec/package.json does. The derivation reads @objectstack/spec — the fixed group's anchor, the package every published skill's compatibility: line cites — and @objectstack/skills carries the identical version by the fixed group (check-changeset-fixed holds the membership). So this PR is green on its own and stays correct whichever of the two PRs lands first; the alternative (read packages/skills/package.json) would red check:skill-compatibility on this branch until PR 1 is on main, and red main if this PR landed first. The constant is one line to change if the maintainer prefers the literal package.

The gate had no hand-maintained version constant to replace: it already reconciled pins against the workspace manifests. What was hand-kept was the frontmatter itself; that is what --fix and the version script now own.

Reverse verification on the live tree (restored, proven)

On skills/objectstack-query/SKILL.md (HEAD blob 5e7ca000…), with a trap restoring through git checkout HEAD -- PATH:

  • leg 1, the version: line deleted → check-skill-compatibility-version exit 1: cannot read metadata.version: frontmatter metadata: map has no version: key, naming the file and --fix;
  • leg 2, the stamp set to "4.4" → exit 1: declared: metadata.version "4.4" / actual: @objectstack/spec 17.7.0 (packages/spec/package.json) / fix: run … --fix;
  • leg 3, --fix → 1 of 10 SKILL.md file(s) rewritten, exit 0;
  • restored: blob equal to HEAD, git diff HEAD empty, git status clean; the gate green again (10 metadata.version stamp(s) all equal @objectstack/spec 17.7.0).

Gates run (exit codes captured before any pipe)

Derived on the changed set and reconciled with --ran: 51 derived, 51 run, 0 UNRUN; every family exit 0. Named by the card and all green: check:skill-compatibility (self-test 22 check cases + 5 derivation cases + 6 declaration cases; run: 10 files, 11 pins, 10 stamps), check-skills-token-ratchet (+ self-test), check:skill-docs, check:skill-refs, check:skill-examples (262 prose examples type-check, on the built tree), check:skill-identifier-liveness, check:skill-frame-sync, check:skill-frame-freshness, check:skill-top-level-keys, check:pm-governed-merges (+ pm-governed-prose), check:merge-driver, check:doc-authoring, check:nul-bytes, check:corpus-claim-drift, check:role-word, check:self-test-wired, check:ratchet-remedy-authority, check:dts-closure / check:dual-build-cjs-loads / check:sourcemap-no-sources-content / check:lean-entry-closure on a full build under the verify lock (72 tasks, VERDICT command-exit 0, held 463s), check:pm-dispatch-gates (fast tier; its reading is in the report comment). Lint at 5567d606c: eslint --format json over the two JavaScript files touched — 2 files, 0 errors, 0 warnings; the config enables no type-aware linting, so no untouched file's verdict moves.

Token ratchet reading, before → after (check-skills-token-ratchet, all within ceilings, exit 0): objectstack-data/SKILL.md 6127 → 6128 of 6128 (headroom 1 → 0), objectstack-automation 5783 → 5783 (headroom 2), objectstack-platform 5830 → 5831 (headroom 2), objectstack-ui 3847 → 3848 (headroom 8), objectstack-upgrade 6184 → 6185 (headroom 8); the other five gain one token with wide headroom. No ceiling was touched. A future bump that lengthens the version string (17.10.0) may cost one more token on objectstack-data; that would be the version script's run, and the ceiling is the maintainer's to move.

Acceptance notes

  • The maintainer named no new standalone gate and none is added: the derivation lives inside the existing gate as its --fix leg, and the self-test rides the existing check:skill-compatibility alias.
  • skip-changeset: nothing publishes from this PR (skills/** reaches npm only through @objectstack/skills's build, whose changeset is PR 1's; the gate and the ledger are repo tooling; the root manifest is private).
  • Landing order is free, but the stamps are the ones a consumer reads: the first release after both PRs publishes metadata.version: "17.x.y" inside @objectstack/skills.

维护者速读(草稿)

  • 改了什么:十个 SKILL.md 里的 metadata.version 不再手写,由 check-skill-compatibility-version.mjs --fix 从工作区版本派生(本次全部变成 "17.7.0";compatibility: 的 17.x 已与工作区一致,一字未动);门禁同时校验这一行,发版时 pnpm run version 自动重打。
  • 为什么改:裁决 A 要求技能目录随版本发运,版本号就不能靠人记——以前每个技能各写一个 "1.3"、"4.4",与任何真实版本无关。
  • 风险与代价(含回滚):十个受管文件各改一行;每次发版的 Version Packages PR 会多出这十行(由你手合)。回滚 = 还原这三个脚本改动,十行自动回到旧值。
  • 席位意见:(留空)
  • 你要做的:在这张 PR 上给一个 APPROVED review(Tier H:skills/**);之后由席位落地。

Claim

This branch, claude/issue-22658-compat-line-derived, is named on the Branch: line of the claim extension 6098607178 on #22658 (the round-2 claim 6096391379 names PR 1's branch); contract review 6098612738 on this PR.


Generated by Claude Code

…om the workspace version

check-skill-compatibility-version.mjs gains the derivation the catalog's
version binding asks for: every SKILL.md metadata.version must equal the
fixed group's version (read off @objectstack/spec's manifest, the package
every compatibility line cites and the version @objectstack/skills ships
at), and --fix writes both that stamp and each pin's major from the
workspace manifests. The root `version` script runs --fix after
`changeset version`, so a Version Packages PR carries the restamped
frontmatters. The ten SKILL.md files are regenerated by --fix: only their
version: line moves (1.x/4.4 -> 17.7.0); every compatibility pin was
already at the workspace major.

Claude-Session: https://claude.ai/code/session_01RdnZdPZH9ByduzPRWuH9tN
Co-authored-by: Claude <noreply@anthropic.com>
…derived SKILL.md lines

The --fix leg in the root `version` script makes it a generator in
git-merge-regen's population; the NOT_DRIVER_MANAGED row says why the ten
SKILL.md files stay a human's to merge: two derived lines inside
hand-written prose.

Claude-Session: https://claude.ai/code/session_01RdnZdPZH9ByduzPRWuH9tN
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 5567d606c5d457e87aff477524060b99bad38b99
Local-runs: none

Skills seat 1 (seat post #7623), session_01RdnZdPZH9ByduzPRWuH9tN, read at 2026-10-10T14:36Z; Tier H (skills/**, the maintainer's word) — the record of the four-piece set (ACCEPT on #22658, this record, needs-user-decision + 维护者速读(终稿) on the PR, review requested from the authorized approvers). Inputs: git diff 243dd3c62 5567d606c (13 files, +340/−27, read in full), the PR body, the card #22658 (ruling 6096124407 on #22649 letter A; claim 6096391379 and its extension 6098607178; report 6098502739), the sibling cards #22659 and #22668, and this head's check-runs at write time (Lint & Repo Gates and Type Check · workspace pending; one red — the closing-target claim guard — whose cause and remedy are in ③). The served model was re-read from get_session before this write and equals the constant's value.

① Derived judgments

  1. The ten governed files move exactly one derived line each. skills/*/SKILL.md: metadata.version from the hand-typed 1.0 / 1.2 / 1.3 ×4 / 1.4 ×3 / 4.4 to "17.7.0"; no compatibility: pin moved (every pin already 17.x); no body byte moved; skills/README.md unchanged. Written by the gate's --fix, never by hand. Right.
  2. The derivation is pure and invents nothing. deriveFrontmatter rewrites each @objectstack/PKG MAJOR.x pin to that package's workspace major (inline or folded block), and metadata.version to CATALOG_VERSION_PACKAGE's workspace version, double-quoted; a file without the stamp or the line comes back unchanged and the check names it; a pin naming a package the workspace lacks is left for the check to refuse. Right.
  3. The version source is the fixed group's anchor, @objectstack/spec, which every published skill's compatibility: cites and which every checkout has; @objectstack/skills carries the identical version by the changeset fixed group (PR feat(skills): publish the skills catalog as @objectstack/skills in the fixed group #22691). So this PR is green on its own and lands in either order relative to PR 1; reading the literal catalog manifest instead would be a one-constant change the maintainer may ask for. Right, and said in the PR body.
  4. The check is loud. metadata.version is required (R10), must equal the anchor (R9), the exempt file is stamped too (R11), an absent anchor is RED never "nothing to derive" (R12); the default mode reads and never writes; every prescription names --fix instead of "edit the line". Right.
  5. The stamp stays current without a hand. The root version script runs check-skill-compatibility-version.mjs --fix after changeset version, the sync-protocol-version.mjs / sync-template-versions.mjs precedent; cut-rc.yml runs pnpm run version, so the Version Packages PR carries the ten re-stamped lines and main never sits red between a bump and a hand edit. Right.
  6. The merge driver's question is answered. scripts/regen-artifacts.mjs gains a NOT_DRIVER_MANAGED row for skills/*/SKILL.md (gen version): "discard both sides and re-run" is NO — a regeneration would restore the two lines and lose the prose around them; a text conflict stays a human's, the two lines re-stamp on the next --fix. Right.
  7. Evidence pinned to the head. Self-test 22 check + 5 derivation + 6 declaration cases (floor 18 → 27); reverse verification on the live tree (the version line deleted → red naming the missing key; the stamp set to 4.4 → red naming declared/actual/fix; --fix rewrites 1 of 10; restored blob equal to HEAD); 51 derived gate families exit 0, among them check:skill-compatibility, the token ratchet, check:skill-docs, check:skill-refs, check:merge-driver (0 after the row). Right.
  8. What a skill teaches is unchanged (the claim's ⛔): zero body bytes moved; check-skills-token-ratchet within every ceiling. Right.
  9. Declaration. Clause-②: no on the claim, its extension, and the PR body: no accept set, no public API; the frontmatter's producer changes, not its meaning. skip-changeset is right for this PR: the stamp is derived mechanically and PR feat(skills): publish the skills catalog as @objectstack/skills in the fixed group #22691's changeset already states that the catalog ships at the version of the packages it teaches. Right.
  10. Closing keyword. Fixes #22658 on line 1 and nowhere else; PR 1 is Part of. The card closes when this PR merges. Right.

② Semver level

None owed from this PR (skip-changeset); the catalog package's minor is PR #22691's changeset.

③ Boundary flags

  • The red claim guard ("The card this PR closes must claim this branch") is the seat's, not the dev's: the round-2 claim named PR 1's branch on its Branch: line and PR 2's only in prose; the seat posted the claim extension 6098607178 naming this branch, and this body edit is the edited event that re-judges it (the guard's own header names edited as the remedy path). Not a code finding.
  • packages/spec/scripts/build-skill-docs.ts untouched — the dispatch's assumption that it writes the frontmatter was false (it reads frontmatter and writes the listings); the real writer is the gate's --fix. Accepted as the dev's measured correction.
  • Surface beyond the claim, each gate-driven and named in the body: the root package.json version script and the regen-artifacts.mjs row (the merge-driver gate was red until it landed). Accepted.
  • skills/objectstack-data/SKILL.md sits at its token ceiling after this PR (6128/6128, headroom 0): the next edit to that skill pays with a deletion. Carried on the seat post.
  • Out of scope, noted, no card: metadata.version is read by no tool today (skills@1.7.2's lock records the npm package's own version; no gate read the stamp before this PR) — the ruling still derives it; it is prose for a human reader of the installed SKILL.md.
  • NOT MEASURED until the next release: the first Version Packages PR carrying the ten re-stamped lines through the version script's --fix leg.
  • Landing: Tier H — an authorized APPROVED review (GOVERNED_APPROVERS), then the seat lands through the queue (every check green on the head, check-expected-skips exit 0). PR feat(skills): publish the skills catalog as @objectstack/skills in the fixed group #22691 lands separately through the queue once its patch round (README truth + the scaffold smoke) is in.

Implemented-by: claude/issue-22658-compat-line-derived
Reviewed-by: session_01RdnZdPZH9ByduzPRWuH9tN

VERDICT: PASS


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

维护者速读(终稿)— PR #22692(#22658 的 PR 2,Tier H)

Skills seat 1 · session_01RdnZdPZH9ByduzPRWuH9tN · 2026-10-10T14:37Z · 契约复审 6098612738(PASS,head 5567d606c)。

  • 改了什么:十个对外 skills 的版本号不再手填。SKILL.md 里的 metadata.version 由工作区版本派生(本次 1.x/4.4 → 17.7.0),compatibility: 的大版本号同一机制;发版脚本在每次 changeset version 之后自动重打这两行;门禁从「只核大版本」改为「版本号不等于工作区版本即红,修法只有 --fix」。十个受管文件各改一行,正文零字节改动。
  • 为什么改:决策 [Decision] bind the published skills catalog to the ObjectStack version it teaches: ship skills/** as a versioned package beside @objectstack/spec (A), pin a git ref per release (B), warn on mismatch (C), or keep serving main #22649 你裁了 A——skills 目录跟 objectstack 版本绑定。手填的「1.3」「4.4」与实际的 17.x 脱节,安装了 skills 的人无从判断它对应哪个版本;派生后版本号就是发布版本号,不会再漂。
  • 风险与代价(含回滚):风险低——只动十行派生值与三个脚本;合并后每次发版的 Version Packages PR 会多这十行(仍由你手合)。首次真正跑到发版脚本的 --fix 是下一次发版,那是实测点,此前自测与反向验证(删行/改值即红、--fix 修回)已钉死。回滚 = revert 三个脚本改动,十行随之回旧值。
  • 席位意见:PASS。版本源读 @objectstack/spec(fixed 组锚点),与 PR 1(feat(skills): publish the skills catalog as @objectstack/skills in the fixed group #22691,@objectstack/skills 包本身)落地顺序无关;PR 1 由席位经队列落地,不需要你批。
  • 你要做的:一个动作——在本 PR 上给 APPROVED review;之后席位落地。

Generated by Claude Code

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

Labels

dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

3 participants