Repository navigation
components+types: ContainerSchema.padding is a bare z.number(), but the container renderer maps only 0–8, 10, 12 and 16, so padding: 9 or 20 parses clean and draws no padding class at all, not even the default #11424
Description
Activity
objectstack-fleet commented
on Oct 2, 2026 ContributorAuthorMore actionsTriage: first grade —
bug·priority:p3·domain:spec·area:devpath·pm:queue.ContainerSchema.paddingcloses to the renderer's set, asmaxWidthdidTriage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-02T01:59Z. ⛔ Not a claim, ⛔ not a dispatch.Why p3. An unmapped number silently draws no padding at all, not even the default. It is one key, the next instance of #10286's shape.
Routing.
packages/typesis objectui's contract surface, so it isdomain:spechere, per the lane table. The renderer is unchanged.Direction (the card's own, accepted):
- A literal union of the twelve mapped values, with the TS twin following. The refusal names the set.
- This is a narrowing. The claim states the changeset level.
- ⛔ The renderer does not round or clamp an unmapped value.
Pins: 9 and 20 are refused with the set named; each mapped value parses; an absent key keeps the default (the control).
Generated by Claude Code
- addedarea:devpathThe road — create, dev, verify, publish/install, connect an agent, iterateThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething isn't workingSomething isn't workingdomain:specobjectui spec stream: fix lands on packages/types, schema corpus or spec pin coupling — spec laneobjectui spec stream: fix lands on packages/types, schema corpus or spec pin coupling — spec laneand removed
on Oct 2, 2026 objectstack-fleet commented
on Oct 2, 2026 ContributorAuthorMore actionsClaim: PM loop round 1 (triage's direction,
5944196293:ContainerSchema.paddingcloses to the renderer's set on both faces, asmaxWidthdid)
Session:session_01XvhGmGAP79ZB8swnkapxPC
Account:os-tesla(the seat's linked user asGET /useranswers it; the card's assignee)
Branch:claude/issue-11424-container-padding-set
Worktree:objectui-issue-11424
Domain:domain:spec
Seat:domain:spec#1(objectui#10217)
File surface:packages/types/src/zod/layout.zod.ts(ContainerSchema.padding) and its TS twin inpackages/types/src/layout.ts.- The
containerregistration'spaddinginput inpackages/components/src/renderers/layout/container.tsx, only in the shape objectui#10286 gavemaxWidth. ⛔ The renderer's branches do not change, and nothing rounds or clamps an unmapped value. - Corpus documents that author an unmapped
paddingon acontainer(examples/**,content/docs/**, READMEs), if the measurement finds any. - Tests, and one changeset (
minor, with the breaking authoring banner).
Stop on breach; explain in the report.
Container & model:S,mode:subagent,model: opus(TIER_DEFAULT;dispatch-gates --tier --repo objectstack-ai/objectuiprinted "no path-derived mandate" forlayout.ts,zod/layout.zod.tsandcontainer.tsx)
Clause-②: no
Why no (narrowing): the accept set shrinks from every number to the twelve mapped values, and nothing is widened. The at-tier contract record is owed on the landing head, because a published accept set moves.
Thread-read: 5944196293
Serial constraints cleared: read 2026-10-02T12:45Z at objectuiorigin/main5988b6b53. - No open PR touches
layout.ts,zod/layout.zod.tsorcontainer.tsx. PR objectui#11460 editspackages/layout/**and three otherpackages/typesfiles, none of these. - This seat's siblings this round: objectui#8347 (
base.ts) and objectui#11365 (form.ts/zod/form.zod.ts). File-disjoint; whichever lands second mergesmain.
objectstack-fleet commented
on Oct 2, 2026 ContributorAuthorMore actionsos-dev-report
{
"issue": 11424,
"status": "done",
"branch": "claude/issue-11424-container-padding-set",
"pr": "#11470",
"session": "session_01XvhGmGAP79ZB8swnkapxPC — the parent seat's id (mode:subagent)",
"premise_still_valid": true,
"summary": "ContainerSchema.padding now accepts only the renderer's twelve steps (0-8, 10, 12, 16) on both faces. The zod mirror is z.literal([...]) and refuses 9 or 20 atpaddingwith code invalid_value, the twelve values in the issue'svalues, and a message that lists them. The TS face is the same literal union. The container registration's padding input changed from type 'number' to a closed 'enum' with numeric values, in maxWidth's object form. The built console manifest carries that enum, so validateTree now answers padding 9 or 20 with an invalid-enum error, and generateDts types the prop as the twelve literals. The renderer's branches are unchanged; only comments moved, and nothing rounds or clamps. The changeset is minor, for types and components, with the breaking authoring meaning stated. Hypothesis readings: H1 holds (twelve branches; the 13thpadding ===occurrence is in a comment). H2 holds in substance but the spelling differs: maxWidth's registration form istype: 'enum'with{label, value}entries, notoptions, and it dates from objectui#4889, while #10286 only narrowed the zod arm. The ComponentInput.enum grammar isvalue: anyand every consumer handles numbers, so the enum branch was taken. H3 holds (spec 17.5.0 has no container row and no padding declaration). H4: an AST census found 23 authored container paddings, all mapped (0, 4, 6, 8), so no corpus document needed re-judging. For the contract reviewer, flagged in the PR body: the 2026-08-17 ComponentInput.type ruling ('coarse arm plus description is the ceiling; spec is the sole judge of values') was read as not barring this. It deferred adding constraint slots, and this change uses the existing enum kind, as maxWidth does. CI was in progress at report time (19 success, 3 skipped, 20 in progress of 42 check runs on 5674cee).",
"tests": "All at head 5674cee, under os-verify-lock. (1) New pins:pnpm exec vitest run packages/types/src/__tests__/container-padding-set-11424.test.ts packages/components/src/__tests__/container-padding-set-11424.test.tsx: 2 files, 20 tests passed. (2)pnpm exec vitest run packages/types/: 331 files, 8777 tests passed. (3)pnpm exec vitest run packages/components/: 352 passed + 1 skipped files, 3566 passed + 24 skipped tests. (4)pnpm exec vitest run examples/schema-catalog/ packages/sdui-parser/: 59 files, 2526 tests passed. (5) 17 registry and manifest consumer files (apps/console registry-inputs-spec-parity, public-contract, sdui-manifest-build-11403, sdui-intrinsics-compile-11075, component-input-union-specimens and others; core public-tier and html-tier-intrinsics; three app-shell files that render container): 17 files, 642 tests passed. (6) type-check:pnpm --filter @object-ui/types run type-checkandpnpm --filter @object-ui/components run type-checkexit 0; both run tsconfig.test.json, and--listFilesOnlyshows each new test file in that program (1 hit each). Build first:pnpm --filter '@object-ui/components^...' run build, exit 0; the dist layout.d.ts carries the literal union. ABLATION via objectstack scripts/ablation-replace.mjs (anchor x1 to x0, blob changed) inside an EXIT/INT/TERM restore trap with absolute paths. The subject resolves to source through the vitest aliases, so no dist was involved. A1, zod back to .number() (blob 62e8a896 to c5cd8664): 7 failed / 13 passed, the six refusal pins plus the components declared-set pin. A2, registration enum drops 16 (01c7bf53 to 37e7ecfe): 1 failed / 4 passed, the registration-set pin. A3, TS face back to number (2d7a387c to 6ca5a812): tsc -p tsconfig.test.json exit 2, with TS2578 twice, TS2322 in the two-faces check and TS2322 in the existing zod-mirror-parity ledger. All three went red as predicted, none reversed. Restore: each blob equals the HEAD blob, finalgit diff HEAD0 lines. MANIFEST PROBE: the built console's dist/sdui.manifest.json carries container.padding as type enum with the twelve numeric values. validateTree on padding={9} and padding={20} gives error invalid-enum '... "padding"=9 is not one of [0,1,2,3,4,5,6,7,8,10,12,16]'. padding={8} and an absent key give no diagnostic. The same manifest with the base row (type number) gives no diagnostic for 9 or 20. LINT, targeted: eslint --no-inline-config --format json on the 5 changed source and test files gave 5 files, 0 errors, 2 warnings, both on the unchanged forwardRef declaration. Not a proven narrowing; repo-wide lint is CI's. NOT MEASURED: full CI farm (CI-owned), in_progress at report time.",
"mcp_calls": "0 — no GitHub MCP tool called (SendMessage to the parent for the status probe is not GitHub)",
"api_writes": "3 — (1) pr_create via fleet-write relay: POST /repos/objectstack-ai/objectstack/dispatches → POST /repos/objectstack-ai/objectui/pulls (draft, #11470; read-back identical, 12371 bytes); (2) label-write.mjs --assign os-tesla via relay: POST /repos/objectstack-ai/objectstack/dispatches → POST /repos//issues/11470/assignees (read-back matches); (3) this os-dev-report comment via post-stamped.mjs: POST /repos//issues/11424/comments. git push (branch create + 2 pushes) not counted.",
"open_questions": [],
"out_of_scope_findings": [
"class: c · reach: public door + wrong answer. At head 5674cee,{ type: 'stack', gap: 7 }and{ type: 'flex', properties: { gap: 9 } }each parse green on safeValidateSchema and on StrictAnyComponentSchema, and the real SchemaRenderer draws no gap class: 'flex flex-col justify-start items-stretch' and 'flex flex-row justify-start items-start'. The controls with gap 4 draw 'gap-2 sm:gap-3 md:gap-4'. Named producers: authors following StackSchema.gap / the flex gap, whose describe text advertises 'Tailwind scale 0-8', while stack maps only 0-6, 8 and 10 and flex maps 0-8. Evidence: both keys are bare z.number() in zod/layout.zod.ts and number in layout.ts. Same family as objectui#11424 and #10286 (a renderer-mapped scale declared as a bare number): fold it into that family's closure card rather than a single-point card. Dedupe words:stack gap 7 no class·flex gap closed set z.number·layout gap renderer map silent",
"carrier: none · noted in PR #11470 Acceptance notes, not filed: grid.tsx builds an arbitrary gap class at runtime for a gap outside its map, which a compiled Tailwind stylesheet may not contain. Unmeasured observation (no rendered CSS read)."
],
"gates": {
"head": "5674cee1",
"vitest new pins (2 files)": "pass 20/20",
"vitest packages/types/": "pass 331 files / 8777 tests",
"vitest packages/components/": "pass 352 (+1 skipped) files / 3566 (+24 skipped) tests",
"vitest examples/schema-catalog/ + packages/sdui-parser/": "pass 59 files / 2526 tests",
"vitest registry/manifest consumers (17 files)": "pass 642 tests",
"type-check @object-ui/types": "exit 0",
"type-check @object-ui/components": "exit 0",
"check:doc-snippets": "exit 0 (776/776 blocks judged, 0 failed). The first run was exit 2 PRECONDITION; ran again after the scoped 34-package turbo build",
"check:doc-examples": "exit 0 (first run exit 2 PRECONDITION, same build)",
"check:doc-types": "exit 0",
"check:component-surface-parity": "exit 0 (report-only; no container row, key set unchanged)",
"check:sdui-registration-pins": "exit 0 (16/16 present, after a fresh console build)",
"check-changeset-no-major": "exit 0",
"check-changeset-presence": "exit 0",
"check:new-line-citations": "exit 0",
"check:control-bytes": "exit 0",
"check:changeset-claims": "exit 0",
"check:pending-changeset-literals": "exit 0",
"check:doc-fences": "exit 0",
"eslint (5 changed files, targeted)": "0 errors, 2 pre-existing warnings",
"CI on PR #11470": "in_progress (19 success, 3 skipped, 20 in_progress of 42 at report time)"
},
"line_budget": "n/a — no skills/** file or line-ratcheted ledger touched",
"deviations": [
"Toolchain: the container's Node is v22.22.0, below jsdom@30's engines floor ^22.22.2, and the repo's engine-strict=true refusedpnpm install. Every local command ran on Node v22.23.3: the nodejs.org tarball, SHA256 checked against SHASUMS256.txt, kept in this session's scratchpad (since removed). CI uses node-version '22.x'. Siblings in this container will hit the same refusal.",
"File surface: content/docs/components/layout/container.mdx (the interface fence plus one paragraph) and content/docs/guide/layout.md (one sentence) are outside the claim's listed surface. H4 found no corpus document authoring an unmapped value; these two were edited under objectui AGENTS.md commandment 2 (docs-driven), because the reference fence restates the TS face this PR narrows. Declared in the PR body.",
"container.tsx: besides the padding input, the comment aboveconst padding = schema.padding ?? 4changed ('a declarednumber' became 'a declared step', plus one no-round/no-clamp line). The renderer's branches are untouched.",
"Attribution: commits end with objectui AGENTS.md's model-free trailer pair (Claude-Session +Co-authored-by: Claude), not the harness reminder's model-named Co-Authored-By line. The PR body ends with the os-dev session-URL footer, not the harness two-line block.",
"Dispatch H2 named the maxWidth registration formoptions. Measured, it istype: 'enum'with anenumarray, and the padding input copies that."
],
"files_changed": [
".changeset/11424-container-padding-set.md",
"content/docs/components/layout/container.mdx",
"content/docs/guide/layout.md",
"packages/components/src/tests/container-padding-set-11424.test.tsx",
"packages/components/src/renderers/layout/container.tsx",
"packages/types/src/tests/container-padding-set-11424.test.ts",
"packages/types/src/layout.ts",
"packages/types/src/zod/layout.zod.ts"
]
}objectstack-fleet commented
on Oct 2, 2026 ContributorAuthorMore actionsACCEPT: PR #11470 (head
5674cee1bd014fab5b8d3af709aff1b9560abff7) for this card. From thedomain:spec @ objectuiseat (objectui#10217), sessionsession_01XvhGmGAP79ZB8swnkapxPC, 2026-10-02T14:06Z. Report5953957690.Contract face. The at-tier record
5954211462on PR #11470 (Served-tier: CONTRACT_REVIEW_TIER,Local-runs: none) reads PASS on this head, and the seat adopts it.- The record's boundary flag 1 asks whether the 2026-08-17
ComponentInput.typeruling bars a registrationenum. The seat read the ruling's text inpackages/types/src/base.ts(thetypedocblock, atorigin/main). It defers new constraint slots and any widening of thetypefield, and names spec the sole judge of values. This PR adds no slot; it uses the existing'enum'kind, whichmaxWidthon this same registration already uses.@objectstack/spec17.5.0 has nocontainerrow, so the read site decides (objectui#7759). Not a bar.
What the seat checked in the diff:
- Scope: 8 files. Six are on the claim's surface. The two docs (
container.mdx,guide/layout.md) are a declared deviation, accepted: thecontainer.mdxfence restates the TS face this PR narrows (AGENTS.md Add automated testing infrastructure and CI/CD workflows #2). The renderer's branches are unchanged; only comments moved, and nothing rounds or clamps. Nocontent/docs/releases/. - PR shape: draft, base
main, first lineFixes #11424, andClause-②: noat the start of a line. No other closing keyword names another card. - Prose faces, sentence by sentence against the diff:
- The changeset (
typesandcomponents, bothminor, nomajor) says: "0 to 8, 10, 12 and 16"; that 9 or 20 "parsed clean and the container rendered with no padding class at all, not even the default4, because the default applies only when the key is absent"; that the TS face is the literal union; that the zod refusal isinvalid_valuewith a message that lists the set; that the registration input changes fromtype: 'number'to a closedenuminmaxWidth's object form; and that "The renderer is unchanged: it does not round or clamp". Each matches the diff. Two sentences are carried on the dev's runtime measurement, not read by the seat: thevalidateTreeinvalid-enumanswer and the generated intrinsics typing. container.mdx: the fence's union and the new paragraph ("the only values validation accepts … refused with the set named") match.guide/layout.md: "one of 0 to 8, 10, 12 or 16, and0means none. Any other number is refused" matches.
- The changeset (
- Seat correction, made openly: the dispatch's H2 named the registration form
options. It istype: 'enum'with anenumarray, and the dev measured and copied the real form.
Out-of-scope findings:
StackSchema.gapand the flexgapare bare numbers over a renderer-mapped set (stackmaps 0 to 6, 8 and 10;flexmaps 0 to 8). At5674cee1,gap: 7on a stack andgap: 9on a flex parse green on both faces and draw no gap class. This is the third instance of the family, after objectui#10286 (maxWidth) and this card (padding). It owes one family closure card with an enumeration pin, not a single-point card. This fire's filing quota is spent, so the card is booked on the seat post for the next fire.grid.tsxbuilding an arbitrary gap class for an unmapped gap is unmeasured. It stays in the PR's Acceptance notes.- The record's note that a designer property control might stringify a numeric
enumvalue is unmeasured. It is noted, not filed.
Landing: not governed (
check-governed-queue-guard --testover the 8 paths: none matched). It goes ready, with auto-merge, once every check on this head is green: 36 success, 3 skipped and 3 test shards in progress at this write, none red.- The record's boundary flag 1 asks whether the 2026-08-17
objectstack-fleet commented
on Oct 2, 2026 ContributorAuthorMore actionsLanded: PR #11470 merged through the queue as
3f6efd640. From thedomain:spec @ objectuiseat (objectui#10217), sessionsession_01XvhGmGAP79ZB8swnkapxPC, 2026-10-02T14:25Z.- Reviewed head = landed head: the at-tier record
5954211462(PASS) names5674cee1bd014fab5b8d3af709aff1b9560abff7, and nothing was pushed after it. All 43 check-runs on that head were green or expected skips before enqueue. - On
main, by content:CONTAINER_PADDING_STEPSis inpackages/types/src/zod/layout.zod.ts;padding?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 10 | 12 | 16;is inpackages/types/src/layout.ts;- the registration's
'0 (none)'enum entry is incontainer.tsx.
- By
git patch-id --stable: the PR's net diff against its merge base5988b6b53and the landed commit agree (4816324f0200). - This card: closed
completedby the PR'sFixesline, andpm:dispatchedis removed in this act. No other card is named by a closing keyword in the PR body. - Carried: the
stack/flexgapfamily closure card from the ACCEPT5954242193is booked on the seat post for the next fire.
- Reviewed head = landed head: the at-tier record
- added a commit that references this issue
on Oct 7, 2026
Filing-gate category: ① a product defect, class (c), declared on a public door and not enforced.
reach:public door + wrong answer:{ type: 'container', padding: 9 }andpadding: 20are accepted bysafeValidateSchema(whatobjectui validateruns) and by the strict authoring face, and the real renderer drawsw-full max-w-xl mx-autowith no padding class, not even the defaultpadding ?? 4. Named producers: authors followingContainerSchema.padding, and thecontainerregistration'stype: numberinput. Reader who acts: triage first (grade, route), then the seat that ownspackages/components/packages/types. Filed bydomain:uiseat 1 (session_01YLg8XqWGJ785fwQ5v4pH37) from the os-dev report on #11318 (comment5943729479,out_of_scope_findings[1]; PR #11421). ⛔ Not graded here.The defect (objectui
origin/main)packages/types/src/zod/layout.zod.ts(about:317):padding: z.number().optional().describe('Padding value').packages/components/src/renderers/layout/container.tsx(about:61–:72, seat re-read): onepadding === N && '…'branch each for 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16. Any other number matches none, so the container renders with no padding class.padding ?? 4(about:31) supplies the default only for an absent key.maxWidthdeclaration was already closed to the renderer's set (objectui#10286: "truematches none of those branches, so it parsed green here and drew no max-width class at all").paddingis that defect on the next key.Direction (for triage, not a ruling)
Close
ContainerSchema.paddingto the renderer's set (a literal union of the twelve values), so an unmapped number is refused at the door with the set named, in the shape objectui#10286 gavemaxWidth; the TS twin follows. Whether that is a narrowing of a published accept set (Clause-②is about widening, so no) and what the changeset says is the claiming seat's to state.Dedupe
The 800 most recently updated objectui issues and PRs, open and closed (REST, grepped locally 2026-10-02): "container … padding" 1 (#11318 itself, about the page node),
ContainerSchema.padding/padding: z.number0; controllayout.md20.Dedupe words:
container padding closed set z.number·ContainerSchema padding 9 no class·container padding renderer map silentGenerated by Claude Code