Repository navigation
Commit 4941c40
feat(scripts): skills link/anchor gate and three liveness-exhaustive sections (#31432)
<!-- claude-projects-attribution: {"github_login":"zhuangjianguo"} -->
_Requested by **Steedos** · [project
thread](https://claude.ai/code/project/chan_018ETKaNwMZCNRYD7D8Q9Ubb?thread=cmsg_018ETKaNwMZCNRYD7D8Q9UbbPjpDtuAfMiZPGY3g5SZw34)_
Part of #31115 (items 1 and 2). Item 3 follows in a separate PR.
Clause-②: no
Metadata-protocol: none
## 维护者速读
- **改了什么:** 新增 skills 链接/锚点检查 `check:skill-links`(按 GitHub 的标题锚点规则核对
`skills/**` 里每个相对链接),并让现有的标识符存活检查多守三张表:`requires:` 能力表、`os generate`
那一行、过滤运算符表;`os generate` 行顺手补全为 10 种类型。
- **为什么改:** 11 月 2 日的技能复审手工找到了 3 个失效锚点和这几张表的缺漏,而当时所有门禁都是绿的;这两项让同类问题以后在
PR 上直接变红(维护者已对新增门禁回复「同意」)。
- **风险与回滚:** 只加检查脚本和一行技能文字,不改任何运行时代码;main 上新检查全绿(248 个链接 0 失效)。回滚即
revert 本 PR。
- **先看:** `scripts/check-skill-links.mjs`(锚点规则
`githubSlug`,误报风险所在);`scripts/check-skill-identifier-liveness.mjs`(新的
`literalMembersOf` 读取器与三条绑定);`.github/workflows/lint.yml`(新增的一个步骤)。
- **两分钟验证:** 运行 `pnpm check:skill-links`,应看到自测 22 条全过,以及「248 relative
link(s) … resolve」。
- **需要你做的:** 这是受管面 PR(`skills/**` 与
`.github/workflows/**`),需要一位受管审批人批准(APPROVED review)。
## What changes
- **`scripts/check-skill-links.mjs` (new) + `check:skill-links`.** Walks
every `*.md` under `skills/**` and resolves each relative link: the file
must exist, and a `#fragment` on a markdown target must match a heading
slug under GitHub's own rule (rendered text, lower-case, punctuation and
em-dashes deleted, spaces to hyphens with no collapsing, `-N` for
repeats) or an HTML `id`/`name`. Fenced code, inline code spans, HTML
comments, absolute URLs and fragments on non-markdown targets are not
judged. Exit 0 / 1 (dead link) / 2 (prerequisite, including a lit
control on the live link count). Battery-floored `--self-test` with the
verdict handshake, copied from `check-skill-top-level-keys.mjs`; it
reproduces the three moved-verbatim links from the review and pins each
slug case (em-dash, code span, emoji, intra-word underscore,
duplicates).
- **Wiring.** `package.json` `check:skill-links` (`--self-test &&
scan`); one step in `lint.yml` `typecheck-source-gates`, beside
`check:skill-top-level-keys`, `continue-on-error` with an `id:` so the
lane verdict carries it. No new job.
- **`scripts/check-skill-identifier-liveness.mjs`: three Leg 2
bindings.**
- `requires-capability-tokens`: platform SKILL.md `### requires:`
section against `PLATFORM_CAPABILITY_TOKENS` ∩ `CAPABILITY_PROVIDERS`.
- `generate-kinds`: operations.md `## Build & runtime`, row `os generate
<kind>`, against `GENERATORS` minus `RETIRED_GENERATORS`; a retired kind
listed in the row is its own red (`[leg2-retired-row]`).
- `filter-operators`: filters.md `## Operator Reference` against
`FILTER_OPERATORS` (`$empty` is a member, confirmed on main).
- To read these, the gate gains `literalMembersOf` (a string array or an
object literal's top-level keys, read by name with a character scanner
that refuses spreads and computed keys), `intersect` / `minus` set
algebra and an optional `row` scope on a binding. `extractSymbols` is
unchanged, so `--suggest` is unchanged.
- **`skills/objectstack-platform/references/operations.md`.** The `os
generate <kind>` row listed four kinds in prose; it now lists all ten.
Two restating clauses in the same file's port table pay for the bytes
(line count 180 → 180; tokens 3375 → 3370).
- **`.changeset/31115-skills-link-and-liveness-gates.md`**:
`@objectstack/skills` patch.
## Why
All the mechanical skill gates were green while the 2026-11-02 review
found these defects by hand. The maintainer approved the new gate
(ruling 6708443569, 「同意」 to letter A). Items 2 and 3 widen existing
gates onto their measured blind spots.
## Tests
<details><summary>Self-tests and scans at the final head</summary>
- `pnpm check:skill-links`: self-test 22 cases pass; scan "248 relative
link(s) in 71 published skill file(s) resolve; 119 fragment(s) name a
real heading".
- `pnpm check:skill-identifier-liveness`: self-test OK (new battery "LEG
2: string arrays, object keys, set algebra and row scope", 15 cases;
roster floor 10 → 11); scan OK, "Leg 2: 11 registered exhaustive
section(s), 0 ledgered gap(s)".
- Live mutation (restored, `git diff HEAD` empty afterwards): `agent`
added to the generate row reds `[leg2-retired-row]`; the `mailbox` row
deleted from the requires table reds `[leg2-missing-row]`.
- `node scripts/check-skills-token-ratchet.mjs`: exit 0 (operations.md
3370 / 3375).
- `pnpm exec eslint --no-inline-config` on the touched scripts: exit 0.
</details>
## Acceptance notes
- **Re-measure of the card on main.** Item 1: the three named anchors
already resolve on main (the text-fix cards #31130 and #31131 landed
first); the new gate is green there. Item 2: `package-registry` and
`mailbox` are already in the requires table, `$empty` already in the
operator table, and the generate row no longer names `agent`; but the
row listed only four of the ten kinds, so it was red as an exhaustive
row and is fixed here.
- **Item 3 is not in this PR.** Where its `--fix` writes land (the
release post-version guard reads `stampedSkillPaths()`, and the token
ratchet prices body pins) is open with the maintainer; it follows in its
own PR.
- **Not judged by the link gate:** whether a link that leaves `skills/`
reaches a file that also ships in the published package.
- **`skills/**` readings:** operations.md 180 → 180 lines; the bundle
(all SKILL.md) 4524 → 4524 lines.
## Verification
- Head `11be7732` (merge base `cd6618e88`). Full workspace `pnpm build`:
119 of 119 tasks.
- `node scripts/pm/dispatch-gates.mjs --ran`: 89 derived, 89 run, 0
NOT-MEASURED, 0 UNRUN. All 89 exit 0, rerun at this head after the
item-3 revert, including `check:doc-formula-expressions`,
`check:dts-closure`, `check:dual-build-cjs-loads`,
`check:lean-entry-closure` and `check:sourcemap-no-sources-content` on
the built tree.
- Left to this PR's check-runs: the artifact-roster and wide-population
families, the path-scheduled CI jobs, the type-check lanes and the
always-runs tail that dispatch-gates prints outside the derived total.
- Deviations: `dispatch-gates --tier` names claude-fable-5-1 for
`skills/**` (clause 1); this was built on the default tier. The two
port-table clauses in operations.md were deleted to pay the token
ratchet for the longer generate row. Item 3 was committed and then
reverted on this branch with `git revert` (no history rewrite), so
`scripts/check-skill-compatibility-version.mjs` is byte-identical to
main.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01QsR2jU4PLtyyimMz72z285)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent bc3d8c6 commit 4941c40
6 files changed
Lines changed: 783 additions & 20 deletions
File tree
- .changeset
- .github/workflows
- scripts
- skills/objectstack-platform/references
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5385 | 5385 | | |
5386 | 5386 | | |
5387 | 5387 | | |
| 5388 | + | |
| 5389 | + | |
| 5390 | + | |
| 5391 | + | |
| 5392 | + | |
| 5393 | + | |
| 5394 | + | |
| 5395 | + | |
5388 | 5396 | | |
5389 | 5397 | | |
5390 | 5398 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
68 | 68 | | |
69 | 69 | | |
70 | 70 | | |
| 71 | + | |
71 | 72 | | |
72 | 73 | | |
73 | 74 | | |
| |||
0 commit comments