Uh oh!
There was an error while loading. Please reload this page.
docs(skills): objectstack-ui factual sweep — 8 false behavioral claims corrected (flight ⑤) - #13777
Conversation
…s corrected Flight ⑤ of the published-skills factual sweep. Every correction is settled against the implementation (spec Zod schemas in this repo; @object-ui renderer sources probed read-only in objectui), never against another document. Three of the seven are one class: "silently dropped" claims that outlived the protocol-17 strict-unknown-keys cutover, where the schema now REJECTS by name. Net -12 tokens / -2 lines; no ratchet ceiling touched. Part of #13658 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EnE7G31tqbxN1rqpQmzurT
huangyiirene
commented
Aug 31, 2026
Contract review — PASS at head |
Uh oh!
There was an error while loading. Please reload this page.
Fixes#13772
Part of #13658
Flight ⑤ of the published-skills factual sweep:
skills/objectstack-ui/**. Everybehavioral claim was settled against the implementation — the Zod schemas in
packages/spec/src/ui/**andpackages/lint/src/**in this repo, and the@object-ui/*renderer sources probed read-only in a detached objectui worktree —never against another document.
8 distinct false facts / 8 landing sites, all in
SKILL.md.Net -12 tokens / -2 lines; no ratchet ceiling touched.
The dominant class: three retired "silently dropped" claims
Three of the eight are one defect: the doc teaches that a bad key is silently
dropped, when the protocol-17 strict-unknown-keys cutover closed those schemas and
they now reject by name. This is the most expensive direction for an AI author —
"silently dropped" says your build succeeds and the key is inert, so the author goes
hunting for a rendering bug; the truth is a loud
os validatefailure with aprescription attached.
Per-item: 落点 | before | after
userFilterstabselement is untypable at author time and dropped at parse"datasetfailsos validate"datasetfailsos validate"positionpitfallpositionkey on a widget, so apositionobject is silently dropped"positionis not a widget key and the closed schema REJECTS it by name (it was silently dropped before protocol 17)"pageabsentpagerow (pageName; no rows of its own)ChartTypeSchemamembers;comboabsentMixedrow forcombo_startonly) — table enumerated 32 while the heading says 36next_*_start/_end×4, matching the sibling rows; table now enumerates all 36Nis any positive integer"Nis any non-negative integer"opacity: 0.5claimed "for line/area/scatter";opacity: 0.4for bars'4 4'on line/area only; reduced opacity on all)"Items 4–6 are the hidden-shipped-capability direction flight ② named as the
majority: the surface is live and authorable, and the skill's own table says it is not
there. Item 6 is self-contradicting in place — the heading counts 36, the table lists
32.
Item 8 in detail:
packages/plugin-charts/src/AdvancedChartImpl.tsxcomparisonStyle()gives the dash to line/area only (scatter gets none), and the muted opacity differs
per family (line/scatter stroke 0.5, area fill 0.2, bar fill 0.4). The doc had the two
families crossed. The replacement is true and shorter, so this correction helps pay
for the others.
Payment for the additions (SKILL.md headroom was 0)
The ratchet requires new text to be paid for by genuine deletion in the same file.
Two redundant passages in the
timeSegmentsblock paid for items 4–7; no fact wasdropped — both were restatements of rows already in the field table directly above them:
showMidnighttable rowbands[].colorrowtimeSegmentsand the gantt renders unsegmented."Evidence — executed probes
Non-vacuity control satisfied several times over; each probe carries positive and
negative controls.
DATE_MACRO_TOKENS.length === 36;isDateMacroTokenreturnstruefor all fournext_*_end,falsefor the controlnext_fortnight_end,truefor the controltoday.{0_days_ago}is accepted, settling item 7.type: 'page'—ListViewSchema.safeParseACCEPTStype:'page'+pageName;the control
type:'carousel'is REJECTED and its own message enumerates all tenmembers including
page.combo—ChartTypeSchemaenumerates 20 members includingcombo; thegenerated
contracts/react-blocks.contract.jsonalready carries it, so the SKILL.mdtable contradicted its own package.
tabsrejected, not dropped —ObjectListViewSchemaREJECTSuserFilters:{element:'tabs'}("expected one of dropdown|toggle"); controls:dropdownACCEPTED, and page-listListViewSchemastill ACCEPTStabs. The spec'sown pin (
packages/spec/src/ui/object-list-view.test.ts) says "rejected at parse"and records the flip from "drops".
position/ inline keys rejected —DashboardSchemareturnsunrecognized_keysnamingposition, and separatelyobject,categoryField,valueField,aggregate; controls: a cleandataset+valueswidget ACCEPTED, awidget missing
datasetREJECTED for that reason alone.A vacuity trap caught by a control (worth recording)
GanttConfigSchema.safeParseACCEPTStimeSegments— but it also accepts a bogus__zz__key identically, because that schema is passthrough. The acceptancemeasured nothing. Settled instead on the declaration:
GanttConfigSchemahas 19declared members and
timeSegmentsis not one (zero hits inpackages/spec/src/),which confirms the doc's existing claim that
timeSegmentsis an ObjectUI displayextension and not upstream spec. VERIFIED, no change.
Gates — union run at
ec46764f, this PR's head commitAll 14 families derived from the REAL diff via
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack(exit 0; changeset derived by the script from the merge base, not hand-supplied):
node scripts/check-ci-filter-parity.mjsnode scripts/check-cross-package-test-inputs.mjsnode scripts/check-shard-attestation.mjsnode scripts/check-skills-token-ratchet.mjsnode scripts/check-test-completeness.mjsturbo run testlog it cannot produce; "not a red, nothing here to fix")pnpm --filter @objectstack/lint run check:doc-formula-expressionspnpm check:agent-test-spellingpnpm check:corpus-claim-driftpnpm check:cross-package-test-inputspnpm check:doc-authoringpnpm check:pm-governed-mergespnpm check:role-wordpnpm check:skill-compatibilitypnpm check:skill-frame-syncPlus, as the diff implicates them:
pnpm --filter @objectstack/spec check:skill-examples— exit 0, fully measuredafter building
@objectstack/client-reactwith declarations. Verdict line: "260prose examples type-check across 3 surface(s) — every marked block parsed, so tsc ran
the SEMANTIC pass on all of them". Population check: NON-empty —
objectstack-uicarries 11
os:checkmarkers (contrast flight ③'sobjectstack-query, which had 0and recorded an empty population). Marker count is 11 before and after this diff, and
a line-level check shows 0 of the 22 changed lines falls inside any fence — the
marked-example population is byte-identical across this change.
pnpm --filter @objectstack/spec check:skill-refs— exit 0, "9 generated files insync with packages/spec".
pnpm --filter @objectstack/spec check:react-blocks— exit 0, "2 generated files insync with packages/spec".
node scripts/check-nul-bytes.mjs— exit 0, 7578 files scanned. Plus a directcontrol-byte scan of the edited file: clean.
Ratchet, before and after:
Generated files: measured, not touched
contracts/react-blocks.contract.jsonandreferences/react-blocks.mdare bothemitted by
packages/spec/scripts/build-react-blocks-contract.ts(gen:react-blocks),and
references/_index.mdbybuild-skill-references.ts— all three aregenerator-owned and excluded from the ratchet by name. Both sync gates report them
already in sync with
packages/spec, so no regeneration was due and nothing washand-edited. Their content is a function of the spec source, so a correction there
would have to land in
packages/spec/src/ui/**— outside this flight's fence, andreported rather than made.
PR #13372 (the
pageview-type member) is the reason item 4 exists: its diff on thispackage regenerated only those two generated files and never touched
SKILL.md, sothe authored table went stale while the generated contract moved. Read before flagging,
as instructed.
Scope
skills/objectstack-ui/SKILL.md. objectui was probe-read onlyfrom a detached worktree; no branch pushed there, worktree torn down.
skills/**), whichis the documented
skip-changesetexemption inpr-automation.yml— "this PRdeclares no release of its own". Label applied at creation.
needs:contract-reviewattached tothis PR and to card skills-sweep ⑤: objectstack-ui (2,298 md lines + 616 contract/eval JSON lines, 6 files) — behavioral-claim verification, cross-repo probes into objectui #13772 in the same stroke, per the clause ② CONTENT limb; this
seat never self-clears it.
Generated by Claude Code
Generated by Claude Code