docs(skills): the upgrade skill's v17-canonical Lead declares its select options - #21402
Conversation
…ect options `FieldSchema` now refuses a `select` / `radio` with neither a non-empty `options` list nor a `picklist` reference, so the "v17-canonical shapes, compiled" block in the objectstack-upgrade skill was teaching a shape the spec rejects at parse while `check:skill-examples` (a type check) stayed green. The `status` field gains a two-entry `options` list; the section's lead sentence is narrowed to what the gate actually checks, which pays for the addition under the file's token ceiling (1188 -> 1195 of 1197). Claude-Session: https://claude.ai/code/session_01FNKm1SmPpuJASnbjxWGtsJ Co-authored-by: Claude <noreply@anthropic.com>
维护者速读(终稿)席位(skills 席 1, 改了什么。 对外发布的 为什么改。 PR #21390(#20827 裁决 A)今天 10:55 合入后, 风险与代价(含回滚)。 纯文档,一个示例块加两项选项、一句引导句收窄;24 条派生门禁全绿, 席位意见。 建议批准,且建议尽快 —— 发布目录现在在教一个 spec 拒收的形状。席内达档契约复核 PASS(见本 PR 评论)。给 你要做的(一个动作)。 在本 PR 上留一条 APPROVED review( |
Contract reviewServed-tier: Face: governed skill text ( ① Derived judgments
② Semver levelDocs-only in a governed surface no package ships ( ③ Boundary flags
Implemented-by: VERDICT: PASS (text); landing blocked on the approval and the |
Fixes #21392
Clause-②: no
What changed
skills/objectstack-upgrade/references/examples-upgrade.md, § The v17-canonical shapes, compiled — two edits, nothing else in the file:statusfield in the block carrying theos:checkmarker gains a two-entryoptionslist (New/Qualified, CRM-lead vocabulary), in the shapeskills/objectstack-data/references/examples-objects.md:73already teaches. Every other line of the block is unchanged.check:skill-examplesactually does — a type check. The clause claiming the block "cannot rot into teaching a shape that no longer compiles" is removed: PR feat(spec)!: FieldSchema refuses a select / radio with neither options nor picklist #21390 is the counter-example (the block type-checked green and parsed red at the same time), and the deletion is what pays for theoptionslist under the file's token ceiling.The section title is untouched (
SKILL.md:461references it by text). No parse limb is added tocheck:skill-examples— triage 5950866103: not this card, new gates default to no.Why
PR #21390 (ruling A on #20827, record 5910124148) is on
mainatc52c49d9:FieldSchemarefuses at parse aselect/radiowith neither a non-emptyoptionslist nor apicklistreference. The published block was teaching exactly that shape to every AI author who reads the skill, while the gate watching the block (tsc --noEmit) stayed green —optionsis optional in the type, and the refusal is a Zod refine.ObjectSchema.create()runs that same parse, so the block as published would also throw at module evaluation.Measured
Tree:
05733de0(this PR's head, the branch's only commit). Base:ecb6ca02.Parse probe (one-shot script in the scratchpad, not committed, no gate added) — the
Leadliteral extracted from the block and handed toObjectSchema.safeParsefrompackages/spec/distbuilt at this head:ecb6ca02):success=false, one issue,code=custom path=fields.status.options, message begins "Aselectfield needs its choices: declare a non-emptyoptionslist …"success=trueToken ratchet (
node scripts/check-skills-token-ratchet.mjs, unit = ceil(utf8 bytes / 4)):Net +29 bytes / +7 tokens / 0 lines: the
optionslist costs +94 bytes, the lead-sentence narrowing pays −65. The ceiling is not moved, and no re-wrap is used as currency.Gates — the 24 families
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commandsderives at05733de0(set-equal to the dispatch's list), each exit captured before any pipe, then--ranreconciled: 0 unrun, every family exit 0. Two refused on first run with a printed prerequisite (exit 3 — not a verdict):check:skill-examplesuntilpackages/client-react/distexisted,check:doc-formula-expressionsuntil@objectstack/formulaand@objectstack/lintwere built. Afterturbo run build --filter=@objectstack/client-react --filter=@objectstack/lint(34 tasks, under the shared verify lock) both ran green:check:skill-examples— "259 prose examples type-check across 3 surface(s) — every marked block parsed, so tsc ran the SEMANTIC pass on all of them";check:doc-formula-expressions— 22 record-scoped examples and 14 field-level*Whenpredicates judged clean.Not run locally, declared to CI: repo-wide
pnpm lint; package test suites (the diff touches no package, andskills/**is in no package'sfiles[], henceskip-changeset).Risk and rollback
A two-line example-and-prose change in a published skill reference; no runtime, package or gate code moves. Rollback is a revert of
05733de0. Governed surface (skills/**, Tier H): this PR stays draft until an authorized APPROVED review; no seat readies, queues or arms it.Acceptance notes
check:skill-examples) is a new gate and explicitly not this card. Noted, not filed; carrier: none.check:skill-examplesandcheck:doc-formula-expressionseach exit 3 with a printed remedy on an unbuilt tree — a prerequisite refusal by design, not a finding.ObjectSchema.create()runs the full parse at module evaluation, so the block before this PR would have thrown when executed, not only underos validate. Observation only; the gate that reads the block never executes it.维护者速读(草稿)
改了什么:升级技能(
skills/objectstack-upgrade)参考文件里「v17 规范形状」示例中的status单选字段补上两项options(New / Qualified);该节引导句从「经类型检查所以不会腐烂」收窄为「经类型检查」。文件其余部分、节标题、门禁脚本均未动。为什么改:PR #21390 已合入,spec 现在在 parse 时拒收没有选项的
select字段;这段示例正是在教 AI 写一个会被拒收的形状,而守着它的门禁只做类型检查,看不见这一点。写给 AI 的技能说错一句等于产品缺陷(NORTH-STAR 优先规则 4)。风险与代价(含回滚):纯文档示例,两处改动,不影响任何运行时与发布包;token 账本余量从 9 降到 2,未抬上限。回滚即 revert 本 PR 的单个 commit。
席位意见:(留空)
你要做的:审阅通过即在本 PR 上 APPROVE,席位随后落地;本 PR 应与 #21390 同随下一个 Version Packages 发布。
Generated by Claude Code