docs(skills): the retirement kit becomes a playbook — plus the form.data correction the docs missed - #4080
Merged
Conversation
The #3896 enforce-or-remove line retired 20+ authorable keys across six metadata types, and every batch re-derived the same procedure from scratch — including the parts that only announce themselves as a red build. Sediment it as an internal skill so the next retirement executes instead of excavates. `.claude/skills/spec-property-retirement/SKILL.md` covers what nothing else documents: the disposition gate (enforce vs experimental vs remove, and the docs-shaped fields deliberately exempt), the three removal routes and how to pick one, the fourteen surfaces a removal touches, and the traps that each cost a red build. Two findings are load-bearing enough to have their own sections: - **The ledger discipline is OPPOSITE per route, and the failures are not symmetric.** `retiredKey()` leaves the key in the walked shape, so its liveness entry must STAY; a strict removal takes the key out, so its entry must GO. Deleting a tombstoned key's entry reports UNCLASSIFIED and fails CI (14 at once in the sweep). The reverse — a leftover entry after a strict removal — is never checked at all, because the gate walks the schema and never walks entries looking for absent keys. One direction fails loudly; the other rots silently, which is how the stale report `aria`/`performance` entries survived a release. - **The build is the referee, not the ledger.** A `dead` verdict is an input to removal, not a substitute for the build's own proof. `view.form.data` was on the worklist and the removal broke `gen:schema` — `defineForm` writes `data.provider='schema'` onto every metadata form. The correct response is to correct the ledger, not force the removal. That correction is also the bug this commit fixes. When `form.data` flipped back to `live`, the schema, ledger, conversion and tests were all corrected, but the v17 dead-cluster row and the liveness README's view row kept listing it as removed — telling authors to delete a key `defineForm` requires. Both now say it stays live, with the reason. The correction path is precisely what had no checklist, so the skill carries one. AGENTS.md gets the two pointers it was missing: the retirement note in the Post-Task Checklist said only `UNKNOWN_KEY_GUIDANCE` while `build-schemas.ts` has prescribed `retiredKey()` first since #3855, and the Skills section listed only the published catalog, leaving both internal playbooks undiscoverable from the file agents are told to read first. Verification: all ten spec gates pass (`check:liveness`, `check:empty-state`, `check:authorable-surface`, `check:docs`, `check:api-surface`, `check:spec-changes`, `check:upgrade-guide`, `check:skill-refs`, `check:skill-docs`, `check:skill-examples`), plus `check:i18n`, `check:doc-authoring`, `check:release-notes` and the skills-catalog boundary test that enforces `metadata.internal: true` on every SKILL.md outside `skills/`. The gate loop the skill ships was run as written — it is the same loop, exit codes captured explicitly rather than piped. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QuViRSR1j6GJjf9qGbnqFX
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 105 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
os-zhuang
marked this pull request as ready for review
July 30, 2026 09:10
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.
The #3896 enforce-or-remove line retired 20+ authorable keys across six metadata types, and every batch re-derived the same procedure from scratch — including the parts that only announce themselves as a red build. This sediments it as an internal skill, and fixes one docs defect the last batch left behind.
.claude/skills/spec-property-retirement/SKILL.mdCovers what nothing else in the repo documents: the disposition gate (enforce vs
experimentalvs remove, and the docs-shaped fields deliberately exempt), the three removal routes and how to pick one, the fourteen surfaces a removal touches, the gate loop, and the traps that each cost a red build. It deliberately does not repeatliveness/README.md(how a verdict is reached) or AGENTS.md (the eight generated artifacts) — it points at them.Two findings earned their own sections:
The ledger discipline is OPPOSITE per route, and the two failures are not symmetric.
retiredKey()leaves the key in the walked shape, so its liveness entry must stay (dead+verifiedAt+ a REMOVED note); a strict removal takes the key out of the shape, so its entry must go. Deleting a tombstoned key's entry reports it UNCLASSIFIED and fails CI — 14 at once during the sweep. The reverse is never checked at all: the gate walks the schema and looks entries up, and never walks entries looking for absent schema keys, so a leftover entry after a strict removal rots invisibly. That asymmetry is how the stale reportaria/performanceentries survived a release before a human deleted them as hygiene. One direction fails loudly; the other never fails.The build is the referee, not the ledger. A
deadverdict is an input to removal, not a substitute for the build's own proof.view.form.datawas on the worklist and the removal brokegen:schema—defineFormwritesdata: { provider: 'schema', schemaId }onto every metadata form andmetadata-protocolserves it. The correct response is to correct the ledger, not force the removal. One of fourteen keys was refuted this way; the skill says to budget for it.The bug this fixes
That correction is exactly what went wrong. When
form.dataflipped back tolivein #4054, the schema, ledger entry, conversion and tests were all corrected — but two prose surfaces were not:content/docs/releases/v17.mdx— the dead-cluster row still listed formdataas removedpackages/spec/liveness/README.md— the view row saidform.{data,defaultSort,aria} REMOVEDBoth told authors to delete a key
defineFormrequires. Both now state it stays live, with the reason. Note the ledger counts were right the whole time (4 dead = responsive/performance/defaultSort/aria) — only the prose drifted, which is why no gate caught it. The correction path is precisely the one nobody had a checklist for, so the skill now carries one.AGENTS.md
Two pointers it was missing:
UNKNOWN_KEY_GUIDANCE, whilebuild-schemas.tshas prescribedretiredKey()first since [P3] Retire the three deprecated aliases — via the ADR-0087 D2 conversion layer, not by deleting the keys #3855. Now names both routes and flags that they imply opposite ledger dispositions.skills/catalog, leaving both internal playbooks undiscoverable from the file agents are told to read first. Now namesdogfood-verificationandspec-property-retirement, with themetadata.internal: truerequirement.Verification
check:liveness,check:empty-state,check:authorable-surface,check:docs,check:api-surface,check:spec-changes,check:upgrade-guide,check:skill-refs,check:skill-docs,check:skill-examples.check:i18n,check:doc-authoring,check:release-notes,check:nul-bytesclean.packages/create-objectstack/src/template-consistency.test.ts, 18/18) enforcesmetadata.internal: trueon everySKILL.mdoutsideskills/— it readsgit ls-files, so the new file was staged before the run actually validated it.skills/+ anobjectstack-prefix, so an internal skill does not move those artifacts.| tail -1masks them, and the first draft of that loop leaned on an implicit$?.Generated by Claude Code