Filed by the domain:skills execution seat (session session_01P58euzUXCVJNwmhuPC9DXY, hotlong, 2026-09-08T04:20Z) out of #16655's flight. Routing and grading are triage's: the fix lands in scripts/sync-scaffold-emission-policy.mjs (gen: / check:scaffold-emission-policy in the root package.json), a gate whose SUBJECT is the scaffold emission policy and its published restatements — the seat's reading is domain:devx by the gate-subject split, with domain:cli the other candidate since the policy constant lives in packages/cli. ⛔ Not claimed, not dispatched.
Measured
Class and why it is a card
declared ≠ enforced ⇒ the enforce-or-remove channel: the policy is declared once (SCAFFOLD_TYPESCRIPT_RANGE, #16485) and enforced on one of its two hand-written restatements. A pin costs zero bundle tokens; a sentence costs 17 the bundle does not have.
Suggested handling (⛔ not a prescription)
Extend the --check leg to locate the skill's package.json fence (the "Complete Working Example" block), parse it, and compare its typescript value with the policy constant — red on mismatch exactly as for the template. If the gate already knows the @objectstack/* release range, the same fence's four @objectstack/* values are a second candidate row; if not, leave them. Alternatively gen: could rewrite the fence from the policy, but a generator writing into a governed published file needs its own ruling — the check leg does not.
⚠️ Serial: land after PR #16763 (#16655) is on main, or the new pin is red on arrival; the fence's line number moves (608 today, 613 on the card), so locate by the fence, not by line.
Refs: #16655 · PR #16763 · #16485 · #15818 · #16756 (the content/docs/** carrier, same shape, domain:devx).
Filed by the
domain:skillsexecution seat (sessionsession_01P58euzUXCVJNwmhuPC9DXY, hotlong, 2026-09-08T04:20Z) out of #16655's flight. Routing and grading are triage's: the fix lands inscripts/sync-scaffold-emission-policy.mjs(gen:/check:scaffold-emission-policyin the rootpackage.json), a gate whose SUBJECT is the scaffold emission policy and its published restatements — the seat's reading isdomain:devxby the gate-subject split, withdomain:clithe other candidate since the policy constant lives inpackages/cli. ⛔ Not claimed, not dispatched.Measured
objectstack-platformskill still teachestypescript: ^6.0.0— the one carrier of the retired scaffold range left after #16485 #16655):✓ check:scaffold-emission-policy: 1 bundled template(s) emit the shared policy (SCAFFOLD_PNPM_RANGE=>=10.15, SCAFFOLD_TYPESCRIPT_RANGE=^5.3.0).— one carrier is pinned:packages/create-objectstack/src/templates/blank/package.json.skills/objectstack-platform/SKILL.mdline 608 (the "Complete Working Example" package.json fence) restated the range by hand and drifted to the retired^6.0.0— the fourth carrier Extract the restated scaffold emission policy — three scaffolders declare three different TypeScript ranges (^5.3.0/^5.8.0/^6.0.0), and restating is what drifted for 102 days #15818 did not enumerate — until PR docs(skills): platform skill's Complete Working Example prints the scaffolder's TypeScript range #16763 ([finding] the publishedobjectstack-platformskill still teachestypescript: ^6.0.0— the one carrier of the retired scaffold range left after #16485 #16655) moved the value. No gate reads that fence; the value can drift again the day after it lands.SCAFFOLD_TYPESCRIPT_RANGEas the authority beside the block) cannot land: the file sits at 12980 tokens against a ceiling of 12984 incheck-skills-token-ratchet, and the shortest conforming sentence is 85 bytes ⇒ 17 tokens over (measured on PR docs(skills): platform skill's Complete Working Example prints the scaffolder's TypeScript range #16763). A prose pointer would also be read by every customer agent that loads the skill while its only reader is the skill's maintainer.Class and why it is a card
declared ≠ enforced ⇒ the enforce-or-remove channel: the policy is declared once (
SCAFFOLD_TYPESCRIPT_RANGE, #16485) and enforced on one of its two hand-written restatements. A pin costs zero bundle tokens; a sentence costs 17 the bundle does not have.Suggested handling (⛔ not a prescription)
Extend the
--checkleg to locate the skill's package.json fence (the "Complete Working Example" block), parse it, and compare itstypescriptvalue with the policy constant — red on mismatch exactly as for the template. If the gate already knows the@objectstack/*release range, the same fence's four@objectstack/*values are a second candidate row; if not, leave them. Alternativelygen:could rewrite the fence from the policy, but a generator writing into a governed published file needs its own ruling — the check leg does not.main, or the new pin is red on arrival; the fence's line number moves (608 today, 613 on the card), so locate by the fence, not by line.Refs: #16655 · PR #16763 · #16485 · #15818 · #16756 (the
content/docs/**carrier, same shape,domain:devx).