Repository navigation
docs(skills): cite the platform-tool registry instead of restating it - #17259
Merged
Merged
Conversation
The resolution-ladder passage in `skills/objectstack-ai/SKILL.md` carried three tool counts and two source line ranges. Counts and ranges are copies of the registry, so every registry change owed this passage a correction that nobody made: the `validate-ai-tool-references.ts` range was already wrong before the registry grew, and the counts went stale on the merge that added tools. Cite by symbol instead. `collectToolUniverse` names the resolver and `PLATFORM_TOOLS_BY_PACKAGE` names the registry, both without ranges; the per-package character of each group stays (structure, not counts) and the passage keeps telling the reader to open the file for the exact set. Nothing in the tree read the removed numbers, so no gate or generator follows. Claude-Session: https://claude.ai/code/session_01MoTv7pn338AZ71owsp19gQ Co-authored-by: Claude <noreply@anthropic.com>
Collaborator
Author
维护者速读改了什么 — 只改一段已发布的 skill 散文: 为什么改 — 这些数字没有任何程序在读,却要求注册表每变一次就手工同步一次,而事实是没人同步:行号区间在 PR #16844 之前就已经错了,三个数量在 #16844 合并当天全部作废。这段文字会整份装进客户的 AI 上下文,写错就是在每个客户项目里被执行一次的错误指令。分诊席的判断是「改数字只买一个版本,改成引用才终结这一类」,本 PR 取后者。 风险与代价(含回滚) — 纯散文、零运行时影响、不发布任何包(dev 三种方法实测不欠 changeset)。代价是读者少了六个工具名的即看即得,换来这段话不会再过期。四个被引用的符号在树上都在,skills 门禁与 CI 全绿。回滚 = revert 这一个提交。 席位意见 — 本席以契约复审档复核通过:改法与裁决一致、段内无残留数字、引用符号全部在树、合并无冲突。建议合并。同文件另有四处按行号引用的段落今天仍准确,同类隐患,不在本卡范围,若你想整文件一次清掉,说一声我立一张卡。 你要做的 — 受管面走人工合并:看一眼改后的那段,认可即批准并合并本 PR。是否合并? Generated by Claude Code |
os-zhuang
approved these changes
Sep 10, 2026
os-zhuang
marked this pull request as ready for review
September 10, 2026 02:56
os-zhuang
enabled auto-merge
September 10, 2026 02:56
This was referenced Sep 17, 2026
akarma-synetal
pushed a commit
to akarma-synetal/framework
that referenced
this pull request
Sep 28, 2026
…its count in objectstack-platform (objectstack-ai#18839) Fixes objectstack-ai#18705 Clause-②: no The `requires:` section of the published `skills/objectstack-platform/SKILL.md` copied two numbers out of the platform capability vocabulary into prose — 「The other eight tokens in the vocabulary …」 and 「The authoritative list of all 28 is `PLATFORM_CAPABILITY_TOKENS`」 — and no gate reads either number against `packages/spec/src/kernel/platform-capabilities.ts`. PR objectstack-ai#18694 (objectstack-ai#18053) took the vocabulary 28 → 29 when it landed at 2026-09-17T16:10Z, so on `origin/main` both sentences were already false when this branch was cut. This PR is the card's option A in the shape of the objectstack-ai#16853 precedent (`a256f18962`, PR objectstack-ai#17259 「cite the platform-tool registry instead of restating it」): the two counts become citations, and nothing is left in those two sentences that a registry change can falsify. No other sentence in the file moves. The `package-registry` runtime half is objectstack-ai#17676's and is not addressed here; objectstack-ai#16767 (the example block's TypeScript range, same file) remains open and is not folded. ## 维护者速读(草稿) **改了什么** — 发布给客户项目的 `skills/objectstack-platform/SKILL.md` 里,`requires:` 一节原来写死了两个数字(「the other eight tokens」「the authoritative list of all 28」)。本 PR 把这两句改成引用常量 `PLATFORM_CAPABILITY_TOKENS`,不再写数字;其余 1221 行一字未动(diff 是 3 行增 / 3 行删)。 **为什么改** — 这两个数字是从 `packages/spec` 的能力词汇表抄来的,没有任何门禁核对它们。objectstack-ai#18694 落地后词汇表已是 29 个 token(新增 `package-registry`),这两句在 `main` 上已经是假话,而客户项目里的 AI 每次加载这份 skill 都会读到。同一类缺陷在 `skills/objectstack-ai/SKILL.md` 上已由 objectstack-ai#16853 / PR objectstack-ai#17259 用同样的办法修过一次:引用注册表,不复述它。 **风险与代价(含回滚)** — 纯文档改动,不发布代码,不改任何运行时行为;skill 的 token 计数 12980 → 12975,上限 12984 不动。回滚就是 revert 这一个提交。留下一处未动:同一节 :440 的「all 20 of its entries」仍是一个抄写的计数(今天为真,objectstack-ai#17676 引擎侧落地时会变假),按派发令本卡不动其它句子——要不要顺手折进来由席位定,见下方 Acceptance notes。 **席位意见** — **你要做的** — 这是受管面(`skills/**`),按 Prime Directive objectstack-ai#14 需要你亲自确认并合并;PR 保持 draft。读一眼 diff 里那两句(6 行),没有别的。 ## Re-derived readings All on `origin/main` `5941246b70` (the branch point); none copied from the card. | reading | value | how | |:--|:--|:--| | `PLATFORM_CAPABILITY_TOKENS` size | **29** | parsed the frozen array literal in `packages/spec/src/kernel/platform-capabilities.ts`; `PLATFORM_CAPABILITY_PROVIDERS` has the same 29 keys | | `Serve.CAPABILITY_PROVIDERS` size (the map the section describes) | **20** | top-level keys of the static at `packages/cli/src/commands/serve.ts` :1863–:2009; the skill's :442 table names the same 20 as a set | | vocabulary tokens NOT in that map | **9** | `ai` `ai-studio` `i18n` `ui` `auth` `hierarchy-security` `ai-seat` `governance` — the eight the section lists — plus `package-registry` | | 「all 28」 on the tip | **false** (29) | | | 「the other eight」 on the tip | **false** (nine) | | | 「all 20 of its entries」 at :440 (same section; not named by the card) | **true** today (20 = 20) | | **Gate reading — which gate surfaces read the constant name — with controls (`git grep -l` at `5941246b70`):** - `scripts/` · `packages/*/scripts/` · `.github/` for `PLATFORM_CAPABILITY_TOKENS`: **0 files** (exit 1) - lit control, the same grep across the whole tree: **18 files** (exit 0; the card read 17 before objectstack-ai#18694 landed — `.changeset/18053-package-registry-capability.md` and `content/docs/releases/v16.mdx` are the new hits) - dark control, a forged constant name across the whole tree: **0 files** (exit 1) ## The two sentences, before / after :452–:453 before: ``` The other eight tokens in the vocabulary are **not** in that map and do not resolve through it: ``` after: ``` The tokens in `PLATFORM_CAPABILITY_TOKENS` not in that map do not resolve through it: ``` :463 before: ``` The authoritative list of all 28 is `PLATFORM_CAPABILITY_TOKENS` ``` after: ``` The authoritative list is `PLATFORM_CAPABILITY_TOKENS` ``` The diff is 3 insertions / 3 deletions in one file. ## The enumeration under :452, re-read against the constant at the tip Every name the two bullets carry — tier-gated `ai`, `ai-studio`, `i18n`, `ui`, `auth` (= the five keys of `Serve.CAPABILITY_TO_TIER` at :1577–:1585, verbatim); enterprise / cloud `hierarchy-security`, `ai-seat`, `governance` — is in `PLATFORM_CAPABILITY_TOKENS` at the tip, and none of the eight is a `Serve.CAPABILITY_PROVIDERS` key. So the list is kept as the list it is: no name dropped, no name added. The ninth not-in-map token, `package-registry`, is in the vocabulary and in `PLATFORM_CAPABILITY_PROVIDERS` (`@objectstack/service-package`, open edition) but has no `Serve.CAPABILITY_PROVIDERS` row yet — the constant's own comment says it is inert under `objectstack serve` until objectstack-ai#17676's runtime half lands. Per the card this PR documents no new token; the Acceptance notes say who holds that. The `marketplace` provider line (:444, `@objectstack/service-package`) was read against `Serve.CAPABILITY_PROVIDERS.marketplace.pkg` at :1958 (`@objectstack/service-package`): it matches the tip and is not touched — repointing it is objectstack-ai#17676's engine lane. ## Token ratchet `node scripts/check-skills-token-ratchet.mjs`, convention ceil(utf8 bytes / 4): | | bytes | tokens | ceiling | headroom | exit | |:--|--:|--:|--:|--:|--:| | before (`5941246b70`) | 51918 | 12980 | 12984 | 4 | 0 | | after (`bef0dc6dfa`) | 51898 | 12975 | 12984 | 9 | 0 | No ceiling moves. The published-skill readings the os-dev definition asks for: this file 1223 → 1223 lines and 12980 → 12975 tokens; the package (all ten `skills/*/SKILL.md`) 6145 → 6145 lines and 70695 → 70690 tokens; the whole priced bundle 139987 → 139982 tokens. Lowering this file's ceiling to 12975 is the script's stated option, but it edits `scripts/check-skills-token-ratchet.mjs`, outside this card's one-file surface — left to the seat. ## Gates Derived with `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` from the worktree (no hand-fed paths; change set read from the merge base `5941246b70`); every exit code captured redirect-then-`$?`; all runs at `bef0dc6dfa`. 23 derived commands, every one exit 0: `node scripts/check-ci-filter-parity.mjs` · `node scripts/check-closing-keyword-parity.mjs` · `node scripts/check-closing-keyword-parity.mjs --self-test` · `node scripts/check-comment-mask-corpus.mjs` · `node scripts/check-doc-route-spelling.mjs --advisory` · `node scripts/check-doc-route-spelling.mjs --self-test` · `node scripts/check-skills-token-ratchet.mjs` · `node scripts/check-skills-token-ratchet.mjs --self-test` · `pnpm --filter @objectstack/spec run check:skill-docs` · `pnpm check:agent-test-spelling` · `pnpm check:corpus-claim-drift` · `pnpm check:cross-package-test-inputs` · `pnpm check:doc-authoring` · `pnpm check:driver-memory-census` · `pnpm check:nul-bytes` · `pnpm check:pm-governed-merges` · `pnpm check:refd-timer-probe` · `pnpm check:role-word` · `pnpm check:skill-compatibility` · `pnpm check:skill-frame-sync` · `pnpm check:skill-identifier-liveness` · `pnpm check:watch-hint-literal` · `pnpm --filter @objectstack/lint run check:doc-formula-expressions` - `check:doc-formula-expressions` answered exit **3** (PREREQUISITE NOT MET) on its first run, before any build; then `pnpm --workspace-concurrency=2 --filter '@objectstack/lint...' build` under `scripts/pm/os-verify-lock.sh` (VERDICT command-exit 0, held 169s, waited 0s); the second run answered exit **0** — the 0 above is the second run. - Reconciliation: `node scripts/pm/dispatch-gates.mjs --ran ran.list` → `✓ dispatch-gates --ran: 23 derived famil(ies) accounted for — 23 run, 0 NOT-MEASURED (a DERIVED zero — all 23 recorded an exit code and none of them is 3)`, exit 0. - Named by the dispatch and run in addition (not in the derivation): `pnpm check:pm-skill-id-lint` exit 0. - Repo-wide `pnpm lint` (`eslint . --no-inline-config`) under the verify lock: VERDICT command-exit 0 (held 88s, waited 65s — shared-box seconds), at `bef0dc6dfa`. - Control-byte self-scan of the edited file (`grep -naP` over the C0/DEL range): 0 hits. Not owed locally, because the diff touches no package: no dependency-closure build, no package `test` / `typecheck`. What stays CI's, as the derivation's stderr names it: 51 artifact-roster families, 11 wide-population families, 14 pending-changeset families, and the path-scheduled `Test Core` job. ## Acceptance notes - noted, not filed — :440 「all 20 of its entries」 is a third copied count in the same section, true on the tip (map = 20, table = the same 20 names) and the same class as this card; it turns false the moment objectstack-ai#17676's runtime half keys `package-registry` in `Serve.CAPABILITY_PROVIDERS`. Kept out by the dispatch's 「no other sentence moves」. 承接者: the seat (a patch round on this PR — 「— all 20 of its entries:」 → 「— its entries:」 — pays for itself in tokens) or objectstack-ai#17676's runtime-half PR, which must edit the :442 table anyway. - noted, not filed — `package-registry` (in the vocabulary since objectstack-ai#18694, no CLI provider row yet) is not documented in this section, so the enumeration of not-in-map tokens is one name short on the tip. Incompleteness, not a wrong instruction: an author never writes the token, it is always-on. It closes by itself when objectstack-ai#17676's runtime half adds the row (the enumeration is complete again and the :442 table gains a line). 承接者: objectstack-ai#17676 (open, `domain:engine`); the card's 「objectstack-ai#18694 / objectstack-ai#18053's own text」 has no live holder — objectstack-ai#18053 is done and objectstack-ai#18694 landed without touching the skill. - option B, one sentence for the seat, no code: the gate that already walks `skills/**` for exactly this shape is `scripts/check-skill-identifier-liveness.mjs` Leg 2 (its header: 「the missing row — a doc enumeration presented as exhaustive stopped growing when the schema did」); registering this section's enumeration (the :442 table plus the two bullets) against `PLATFORM_CAPABILITY_TOKENS` there would flag `package-registry` today, while a prose COUNT such as 「all 20」 is outside both of its legs (existence, not arithmetic) and `check-skills-token-ratchet.mjs` prices bytes, not claims. - objectstack-ai#16767 remains open — the example block's TypeScript range in this file is a different number and is not folded. --- _Generated by [Claude Code](https://claude.ai/code/session_01Gqi43smmqjJ5sUrhfoPeKu)_ Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #16853
The 〈Naming the tools: the resolution ladder〉 passage in
skills/objectstack-ai/SKILL.mdrestated the platform-tool registry — three tool counts and two source line ranges — instead of citing it. Triage's ruling on the card is taken over the card's own minimum:So no number and no range is replaced with a fresher one. They are removed, and the passage cites the registry and the resolver by symbol. There is nothing left in the passage that a registry change can falsify.
Before / after
Before (the two spots this PR touches):
After:
Items 1 and 3 of the ladder, and every other line of the file, are untouched. The diff is 7 insertions / 8 deletions in one file.
Measurements — every fact the passage keeps, and where it was read
All read on
origin/main5a95b0e9(the branch point), never copied from the card.collectToolUniverseis the resolverpackages/lint/src/validate-ai-tool-references.ts:144, body ends:163grep -n; this is why the removed:148-171was already wrong, independently of PR #16844PLATFORM_TOOLS_BY_PACKAGEis the registrypackages/spec/src/system/constants/platform-tool-names.ts,:38to:87grep -nPLATFORM_PROVIDED_TOOL_NAMESis flattened from itObject.values(PLATFORM_TOOLS_BY_PACKAGE).flat()at:93-94service-aiandservice-ai-studioObject.keysreturns exactly those two, in that ordertsximport of the modulePLATFORM_TOOL_FAMILY_PREFIXES(kept from the old text, untouched):107grep -nMeasured and then deliberately not written into the file:
service-aiholds 6 names,service-ai-studio29, flattened total 35, and the registry object ends at:87. Those confirm the card's predictions (30 → 35,24 → 29,38-82 → 38-87) exactly — and they are precisely the values this PR deletes rather than refreshes.The six
service-ainames — the ruling's conditional, answeredThe card's shape allowed keeping the six inline names only if they are still exactly that group and the passage's own reason for listing them survives. Both halves were measured:
PLATFORM_TOOLS_BY_PACKAGE['service-ai']today (aggregate_data,get_record,query_data,query_records,search_knowledge,visualize_data).service-ai, and it is exactly Leg 2 ofcheck-skill-identifier-liveness's own measured defect class — "a doc enumeration presented as exhaustive stopped growing when the schema did". The passage already tells the reader to open the file for the exact set.So they are dropped into the citation. What is kept is each group's character — data / knowledge from
service-ai, schema / metadata / package fromservice-ai-studio— which is structure rather than a count, and tells a reader which group to look in without naming a member.Gates
Derived with
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackfrom the real change set (1 path, committed), then reconciled with--ran:All 24 exit 0. The verdict lines that carry this card's specific content:
One gate refused before measuring anything on the first pass and is reported honestly:
pnpm --filter @objectstack/lint run check:doc-formula-expressionsexited 3 withPREREQUISITE NOT MET — the workspace package @objectstack/formula is not built. That is not a finding. Afterpnpm exec turbo run build --concurrency=2 --filter=@objectstack/formula --filter=@objectstack/lint(under the shared verify lock,VERDICT command-exit 0), it re-ran at exit 0.pnpm --filter @objectstack/spec run check:skill-refswas run in addition to the 24 — AGENTS.md's regeneration table names it for anySKILL.mdbody change, while the path derivation does not. It is green (9 generated files in sync with packages/spec), andcheck:skill-docsis green too: that generator reads only the YAML frontmatter, which this PR does not touch, so neitherskills/README.mdnorcontent/docs/ai/skills-reference.mdxmoves.Repo-wide
pnpm lintis CI's run, not this PR's; no package source is touched, so no build closure beyond the one a gate demanded above.Size — the published catalog is priced in tokens, and this PR pays in
skills/objectstack-ai/SKILL.mdlinesskills/objectstack-ai/SKILL.mdtokensSKILL.md— linesSKILL.md— tokensNet decrease on both units, so nothing is bought on credit and no ceiling moves. The ceiling was not lowered even though the gate invites it ("A ceiling may be LOWERED by any PR that shrinks its file"): that edit lands in
scripts/check-skills-token-ratchet.mjs, outside this card's declared one-file surface. It is left for a maintainer or a follow-up.Changeset — measured, not assumed
No changeset is added, because nothing published moves:
package.jsonin the workspace was read; not onefiles[]array namesskillsat any depth.@objectstack/specshipsdist,json-schema,liveness,prompts,llms.txt,README.md,src/**/*.zod.ts,CHANGELOG.md,api-surface,spec-changes.json;@objectstack/clishipsdist,README.md,CHANGELOG.md.dist/,packages/spec/prompts/,packages/spec/llms.txtand every packageREADME.mdfor the passage's text (resolution ladder) returns 0 hits. The positive control — a string known to be published,Machine name (snake_case)— returns hits in 3 files underpackages/spec/dist/. So the search reaches published bytes and this passage is not among them.build-skill-docs.tsregeneratesskills/README.mdandcontent/docs/ai/skills-reference.mdxfrom the frontmatter only, andcheck:skill-docsis green with no drift.node scripts/check-changeset-no-major.mjs --base origin/main— exit 0:⇒
skip-changesetis the correct disposition, and the label is applied on this PR.维护者速读(草稿)
改了什么 — 只改一段已发布的 skill 散文:
skills/objectstack-ai/SKILL.md里讲「一个 skill 的工具名去哪里解析」的那段。原文把平台工具注册表的内容抄了一份进来(30 个工具、6 个 / 24 个的分组、两处源码行号区间),现在改成指过去:点名PLATFORM_TOOLS_BY_PACKAGE这个注册表和collectToolUniverse这个解析函数,不写数量、不写行号。一个文件、7 增 8 删,无代码改动。为什么改 — 这些数字没有任何程序在读,却要求每次注册表变化都手工同步一次,而事实是没人同步:
validate-ai-tool-references.ts的行号区间在 PR #16844 之前就已经错了,三个数量则在 #16844 合并当天全部作废。这段文字会被整份装进客户的 AI 上下文,写错就是每个客户项目里被执行一次的错误指令。定级席位的原话是「Correcting three numbers buys one release; making the passage citeplatform-tool-names.tsas the authority ends the class」——改数字只买一个版本,改成引用才终结这一类问题。本 PR 取后者。风险与代价(含回滚) — 风险极低:纯散文,零运行时影响,零 API 变化,不发布任何包(已实测,见上)。代价是读者少了六个工具名的「即看即得」——换来的是这段话不会再过期,而且它原本就已经写着「Read that file for the exact set」。回滚就是
git revert这一个提交,不牵连任何其它文件、不需要重新生成任何产物。24 个门禁族全绿。席位意见 —
你要做的 — ① 这是受管面(
skills/**),必须人工合并,任何 AI 席位都不会点 ready、不会入队、不会开 auto-merge;请确认后手动合并。② 如果你更希望保留那六个工具名(理由:给读者一个具体的手感),请直接说,我改回去——但那样就需要一个会在数量漂移时变红的检查,否则第四次手工订正还会漏。③ token 上限(6806)这次没有下调,虽然文件已经降到 5444;下调要动scripts/下的门禁脚本,超出本卡声明的文件面,留给你或后续 PR 决定。Acceptance notes
skills/objectstack-ai/SKILL.md; nopackages/**, noscripts/**, no other skill file, and no rider. A single governed path makes the whole diff human-merge-only, so a mixed diff would have changed this PR's landing route.packages/spec/src/ai/skill.zod.ts:37-51, 139-202,packages/spec/src/stack.zod.ts:595-602,packages/spec/src/ai/agent.zod.ts:36-40, andpackages/spec/src/ai/agent.zod.ts:234, :251. All four were spot-checked and are accurate today (:37and:51land on the two trigger-operator constants;:139and:202bracket the refinement and the schema that calls it), so none is a defect now — but they carry the same drift liability this card is about. Left alone deliberately: this card is fenced to one passage, and a governed-surface PR that quietly widened its own file surface would be the wrong precedent. Successor: whoever next edits one of those passages, or a dedicated follow-up card if a maintainer wants the class closed file-wide.collectToolUniverse,PLATFORM_TOOLS_BY_PACKAGE,PLATFORM_PROVIDED_TOOL_NAMESandPLATFORM_TOOL_FAMILY_PREFIXESare all live symbols in the tree, verified before naming any of them;check:skill-identifier-livenessis green.Generated by Claude Code