Uh oh!
There was an error while loading. Please reload this page.
docs(skills): state the label contract spec 17 actually enforces (#5081) - #5464
Merged
os-support-ai merged 1 commit intoAug 21, 2026
Merged
Conversation
`skills/objectui/guides/i18n.md` backed its label rule with `@objectstack/spec`
v4 on lines 117 and 162 while every manifest here declares `^17.0.0`. Measured
against the installed 17.0.0 dist, the rule was wrong too: `I18nLabelSchema` is
a union of a plain string AND an inline locale map keyed by BCP-47 tags or
`default`, so neither renumbering the qualifier nor deleting it was writable —
both keep a false sentence. Maintainer ruling 2026-08-20, option A: restate the
rule per the installed spec, with no version qualifier.
The `{key, defaultValue}` advice stays and gains its real reason: that
key-reference vocabulary was retired (objectstack#5055), the spec rejects the
object with its own message, and `pickLocalized` would paint the raw key.
Same commit, as the ratchet requires: the `KNOWN_CLAIMS` `stale` entry that
inventoried the fossil is deleted, and the ledger header prose that restated
the now-falsified two-branch fork is corrected.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RV6yuVCxymHYE16PL9vQkEos-support-ai
marked this pull request as ready for review
August 21, 2026 00:54
Uh oh!
There was an error while loading. Please reload this page.
os-support-ai
deleted the
claude/issue-5081-i18n-spec-version-fossil-v2
branch
August 21, 2026 00:54
This was referenced Aug 21, 2026
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 freeto 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#5081
⛔ Draft, and
skills/is maintainer-merge-only. Do not enable auto-merge; do not merge. This queues for the maintainer.What was wrong — twice over
skills/objectui/guides/i18n.mdbacked its label rule with@objectstack/specv4 on lines 117 and 162 while every manifest here declares^17.0.0(33 declarations,node_modulescarrying17.0.0) — thirteen majors, on the surface an agent reads before it writes a user's project.The version number was the reported defect. The rule it was backing was wrong too, which is why the card's original fork had no writable arm: renumbering to v17 and deleting the qualifier both keep the sentence, and the sentence is false.
Maintainer ruling, 2026-08-20 — quoted verbatim
My own measurement of what spec 17 admits
Re-verified from scratch this round against the INSTALLED package —
node_modules/.pnpm/@objectstack+spec@17.0.0_ai@7.0.65_zod@4.4.3_/node_modules/@objectstack/spec,package.jsonversion17.0.0— not from the thread, not from source, not from memory.Declaration (
dist/ui/index.d.ts:614, angle brackets spaced so GitHub's sanitizer keeps them):Runtime (
dist/ui/index.mjs:1932-1943) — this is the load-bearing half, because the.d.tstype saysz.ZodRecordof plain strings while the runtime constrains the KEY:Executed probes against
dist/ui/index.mjs(safeParse, this worktree, spec17.0.0):'Save'''{ en: 'Save', 'zh-CN': '保存' }{ default: 'Save' }{ key: 'common.save', defaultValue: 'Save' }{ notALocale: 'Save' }{ en: 42 }/42/nullThe rejection carries the bespoke message, nested one level under
invalid_unionatpath: ["defaultValue"],code: "invalid_key":Per-key admission, probed one key at a time:
en,zh-CN,zh-Hans-CN,default,ENACCEPTED;defaultValue,notALocale,x-private,eREJECTED.So the ruling's description matches the installed package exactly, and 回翻条款 did not fire this round. Two authorized forms; the key-reference form rejected with its own error.
Two measured details that changed the wording
ComponentRegistry.register('card', PageCardRenderer, …)(packages/components/src/renderers/layout/containers.tsx:775) resolvesschema.titlethroughpickLocalizedat:739;ElementButtonRendererresolvesprops.labelatpackages/components/src/renderers/basic/elements.tsx:230. The new example puts an inline map on exactly those two keys and nowhere else.{key, defaultValue}bullet keeps its conclusion and gains a true reason. Executed:pickLocalized({ key: 'common.save', defaultValue: 'Save' }, 'en')returns'common.save'— the last-resort "first string value" limb — so a map-shaped key-reference object that reaches a renderer paints the raw translation key on screen. That, plus the spec's parse-time rejection, replaces the old false reason ("uses plain strings only").The pairing, and reverse-verification of both halves
The ledger's downward ratchet says no entry may outlive the claim it excuses, so the fix and the
KNOWN_CLAIMSdeletion are one commit. Predictions were written before each run.Leg A — revert the ledger half only (stale entry restored, guide fixed). Predicted: downward ratchet red, upward green.
Leg B — revert the guide half only (
v4back on :117/:162, entry stays deleted). Predicted: upward ratchet red, downward green.Both legs landed in the predicted direction, each naming the other ratchet's test as still green — so the pairing is load-bearing in both directions, not incidental. No rebuild sits between the ablation and the thing under test: this gate reads the markdown and the manifests straight off disk with
fs.readFileSyncfromrepoRoot, and the test file is the ledger, so there is nodistin the resolution path for a stale artifact to hide in.Restored with
git checkout HEAD -- ...after each leg;git status --porcelainis empty andgit diff HEADis empty — a byte-identical restore, not an approximate one.Gates run locally, all at
600807f8a(final commit, clean tree)pnpm exec vitest run scripts/__tests__/doc-version-claims.test.tsTest Files 1 passed (1)/Tests 18 passed (18)pnpm check:control-bytespnpm check:skills-pathspnpm check:doc-typesnode scripts/check-changeset-presence.mjssrc/, 1 changeset addedcheck-changeset-no-major.mjs/check-changeset-fixed.mjspnpm type-check:scriptseslint scripts/__tests__/doc-version-claims.test.tsHeavy runs were serialized under
/tmp/os-heavy-verify.lock.One gate deliberately not claimed green, because a green from it would have been false.
pnpm check:doc-snippetsexits 0 here with "The snippet program was NOT run: the packages it resolves against are not built" — a silent no-op locally. It would not have covered this change anyway: that gate's scan surface is stated in its own header ascontent/docspluspackages/(name)/README.md, andskills/is not in it, so the new snippet is compiled by no typechecker on any machine. It was hand-checked against the schema instead (detail 1 above). Filed as a finding — see the linked issue on #5081.Counter-probe of the zero
Before claiming no other
@objectstack/specv4 attribution survives, the same search was run with a version string known to be present:@objectstack/spec+ a v4-style qualifier acrossskills/,content/docs/,packages/*/README.md: two hits remain, both oncontent/docs/guide/release-notes.md(:16,:55). They sit under the## v3.3.0 — 2026-04-17heading, are historically accurate (that release did align with^4.0.4), and are structurally exempt from the ratchet by the version-heading rule. Not fossils, and not this card's surface.17: hitsskills/objectui/guides/schema-expressions.md:262andpackages/app-shell/README.md:319. The pattern finds live claims.v4on the same surfaces: hits Tailwind v4 lines instyling.md,project-setup.md,theming.mdand theactions/checkout@v4block inci-cd-pipeline.md. The corpus is being read.So the accurate statement is not "no
v4remains" but "the only surviving@objectstack/specv4 attributions are historical release notes, exempt by design".Scope
Two files plus a changeset.
skills/objectui/guides/page-builder.md(sibling #5352) was not touched — verified in the diff.Side effect worth naming for the reviewer: two passages in the ledger's header say "NO
staleentry remains" (:291) and "NONE remains today" (:632). Those were written at the census and were falsified when #4981 inventoried a tenthstaleentry. Deleting that entry makes both sentences true again, so they are left untouched rather than edited.Generated by Claude Code
Generated by Claude Code