This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
Commit 42687ba
fix(types): header-bar refusals and nine
Fixes #10959
Clause-②: no — message, `.describe()` and docblock text only; every
accept or refuse verdict stays byte-identical.
Implemented by the `os-dev` agent dispatched from the `domain:spec @
objectui` seat, session
`https://claude.ai/code/session_012UwY3ahMixEFkfTUxMVkYm`
(`mode:subagent`). Base `1345e182d`, head `7089f691c`.
## What changed
Only the false clause changes. It changes on 18 sites of two kinds. The
objectui#10928 wording names `not-a-container`, which would be false
here, so it is not reused.
- **Refusal strings (zod face).** These are the 9 `HeaderBarSchema`
refusals: `title`, `logo`, `nav`, `left`, `center`, `right`, `sticky`,
`height` (objectui#10387) and `variant` (objectui#10286). Each message
is also its `.describe()` text, through `retirementTombstone`.
- Before: "no error, no warning, no element" (for `variant`, "no
class").
- After: "no render-time error or warning and no element; only the
parser tier's `unknown-prop` warning noticed it". `variant` keeps "no
class" in place of "no element".
- **`body?: never` docblocks (TS face, emitted `.d.ts`).** There are 9:
`box`, `span`, `container`, `flex`, `stack`, `grid`, `scroll-area` in
`layout.ts`, and `toggle`, `form` in `form.ts` (objectui#8284).
- Before: "rendered an EMPTY element with no error and no warning".
- After: "rendered an EMPTY element with no render-time error or
warning; only the parser tier's `unknown-prop` warning noticed it".
- **New pin:**
`packages/types/src/__tests__/unknown-prop-parser-tier-clause-10959.test.ts`.
- **Changeset:** `.changeset/10959-unknown-prop-parser-tier-clause.md`,
`@object-ui/types: patch`.
## The parser tier, measured before the clause was written
**Instrument.** A one-shot probe, deleted and not committed. It sat
under `packages/components/src/renderers/__tests__/` and built the
manifest from the live registry the way
`container-declaration-ratchet.test.tsx` does: every KNOWN key, through
`manifestFromConfigs`. It imported `components`, `fields` and 18 of the
19 `plugin-*` packages (all but `plugin-designer`). Then it ran
`validateTree` once per leg. It also rendered each leg through the real
`SchemaRenderer`, spying on `console.warn` and `console.error`, and
compared the HTML with the leg's control.
**Population and result.**
| population | legs | what each leg adds |
|---|---|---|
| `header-bar` and `ui:header-bar` (inputs `crumbs`, `search`,
`actions`, `rightContent`) × the 9 keys × every value the objectui#10387
/ objectui#10286 pins use (strings, a node, a node list, booleans,
numbers, the 4 `variant` spellings) | 44 | exactly one `unknown-prop`
warning; HTML byte-identical to the control; 0 console warnings, 0
console errors |
| the bare and `ui:` key of the 9 `body` nodes (18 keys, each declares
the `children` input and no `body` input) × `body` as a list, a single
node and a scalar | 54 | exactly one `unknown-prop` warning (the
`checkRetiredBodyDialect` sentence that names `children`); HTML
byte-identical to the control; 0 console warnings, 0 console errors |
**Answer to the mechanism assumption about value shape.** Scalar and
list give the same code on these nine. `checkRetiredBodyDialect` answers
`not-a-container` only where the registration declares no `children`
input, and all 18 keys declare it. So the list, the single node and the
scalar all draw `unknown-prop`.
**Controls.**
- `accordion` and `input` declare no `children` input. There a `body`
list draws `not-a-container`, a scalar `body` draws `unknown-prop`, and
an invented key draws `unknown-prop`. So the probe can tell the two
codes apart.
- The `header-bar` control renders a `header` element with 0 console
warnings and 0 console errors.
- A first run rendered `header-bar` bare. It logged the `useSidebar`
provider error on the control and on every leg alike, so its render
comparison proved nothing.
- That run was discarded. The render leg was re-run inside
`sidebar-provider`, the context the containment ratchet uses for the
sidebar parts.
**The same answer before each retirement (source reading, not
executed).** The strings and docblocks are in the past tense, so the
pre-retirement tree was read too.
- At `236a71fe3`, the parent of the objectui#8284 tombstone commit
`b1777aef3`:
- `validate.ts` had no `body` in its base-prop set and no
`checkRetiredBodyDialect`, so an undeclared key drew `unknown-prop`;
- none of the nine registrations declared a `body` input (zero quoted
`'body'` / `"body"` in the nine files).
- `header-bar.tsx` did not change between `6214db63f` (2026-09-11) and
the two retirements (objectui#10286 `a05c35063`, objectui#10387
`9b281519f`). Read at `a05c35063`, its registration declared the same
four inputs it declares today.
## Census, base `1345e182d` vs head `7089f691c`
These counts are over joined text: JSDoc continuations and `'…' + '…'`
joins are removed, and an escaped quote is unescaped.
| file | old string clause | new string clause | old docblock clause |
new docblock clause | control: `header-bar` refusal head | control:
objectui#8284 docblock sentence | control: objectui#10928 clause |
absent token |
|---|---|---|---|---|---|---|---|---|
| `zod/navigation.zod.ts` | 9 → 0 | 0 → 9 | 0 → 0 | 0 → 0 | 9 / 9 | 0 /
0 | 10 / 10 | 0 / 0 |
| `layout.ts` | 0 → 0 | 0 → 0 | 7 → 0 | 0 → 7 | 0 / 0 | 7 / 7 | 12 / 12
| 0 / 0 |
| `form.ts` | 0 → 0 | 0 → 0 | 2 → 0 | 0 → 2 | 0 / 0 | 2 / 2 | 28 / 28 |
0 / 0 |
- Over all 67 non-test `.ts` files of `packages/types/src` at base
(enumerated from the ref with `git ls-tree`, not from the working tree),
the old string clause and the old docblock clause occur only in these
three files.
- **Emitted `dist`**, after `pnpm --filter @object-ui/types build` at
head:
- old string clause 0, new 18 (`zod/navigation.zod.js` and
`zod/index.zod.js`, 9 each);
- old docblock clause 0, new 9 (`layout.d.ts` 7, `form.d.ts` 2).
- **On the built dist**, `safeValidateSchema` on `header-bar` answers as
follows:
- with `title`: `invalid_type` at path `title`, and the message carries
the new clause and not the old one;
- with `variant`: the same;
- control (only `crumbs`): success.
## Every other byte, and only string and comment lines
- Take each head file and substitute the old clause back for the new
one: 9, 7 and 2 substitutions. Each result is byte-identical to the base
file.
- `git diff -U0` over the three files: every changed line is a `+ '…'`
string-literal line (zod) or a ` * ` JSDoc continuation line. No other
line changed.
- On the docblock face, the replaced text wraps onto three lines where
the old text used two. The joined text differs only in the clause.
- The objectui#10387 and objectui#10286 pins (codes, paths, message
heads) pass unchanged.
## Reverse verification (ablation), after the fix was committed
**Instrument.** objectstack's `scripts/ablation-replace.mjs`, in WRAP
mode, run from this worktree. The anchor must hit exactly once, and the
on-disk blob must move. The tool proves each restore (blob == HEAD, `git
diff HEAD` empty), and the driver re-proves it independently. The types
tests import `../zod/*` source and read `layout.ts` / `form.ts` from
disk, so no build sits between a mutation and the run.
| leg: the old clause put back into | blob mutated to | red / 7 | red
tests |
|---|---|---|---|
| `variant`'s string | `59f587b96` | 2 | the `variant` arm, the
`header-bar` population |
| `title`'s string | `c80665c61` | 2 | the `title` arm, the `header-bar`
population |
| `BoxSchema.body` docblock | `2383fde4f` | 2 | the `BoxSchema`
docblock, the docblock population |
| `GridSchema.body` docblock (not named by the pin) | `a3ac19fa8` | 1 |
the docblock population |
| `ToggleSchema.body` docblock in `form.ts` (not named by the pin) |
`5e4c2ac67` | 1 | the docblock population |
Each leg restored to its HEAD blob (`ad46ba82c`, `a90b246c7`,
`daad6d395`) with an empty `git diff HEAD`. After the run, `git status
--porcelain` was empty.
## The pin
It follows the house style of PR objectui#10956's pin.
`@object-ui/types` declares no workspace dependency, so the pin holds
the prose, not the parser.
- **Zod face.**
- For `title` and `variant`, one per clause form, it asserts code
`invalid_type` and path `[key]` first, then the clause substring. It
also asserts that neither the old clause nor `not-a-container` appears.
- Then the population: every `HeaderBarSchema` member whose refusal is
an objectui#10387 / objectui#10286 retirement carries the clause.
Non-vacuity is by name (`title`, `variant`).
- **TS face.** Precedent for pinning docblock text:
`layout-default-jsdoc-7361.test.ts`.
- The `body` docblocks of `BoxSchema` and `FormSchema` carry the clause.
- Then the population: every docblock in `layout.ts` and `form.ts` that
carries objectui#8284's sentence carries it too. Non-vacuity: both files
are reached.
- The repo root comes from the pin's own `import.meta.url`, never the
cwd (`check:test-path-roots` passes).
- **Where the parser half lives.** The `body` half is pinned in
`packages/sdui-parser`, by "the retired `body` spelling follows the SAME
predicate" (`containment-declared-slot-9910.test.ts`) and "a `body`
child list under a CONTAINER draws `unknown-prop` naming `children`"
(`body-dialect-6771.test.ts`). The `header-bar` half is `validateTree`'s
generic undeclared-key branch, and no pin there names `header-bar`. See
Open question.
## Dispatch assumptions, checked
1. **Holds.** Counts are 9 / 7 / 2 on base `1345e182d`, a descendant of
`328abeb55` (`merge-base --is-ancestor` exit 0), with controls. See
Census.
2. **Holds, and made more exact.** Every key and every value shape draws
`unknown-prop`. None draws `not-a-container`, because all 18 `body` keys
declare `children`. See the table.
3. **Does not hold.** The objectui#10928 pin
(`content-channel-parser-tier-clause-10928.test.ts`) does not name the 8
`HeaderBarSchema` sites. Its population walk reads only the family-D
`body` / `children` members (`reads NEITHER content channel:`). It
passes unchanged at head, so it is not edited. The 8 sites appear only
in PR objectui#10956's description.
4. **Not re-scanned by this dev.** The PM files-API scan is taken as
given. This diff touches none of PR objectui#10972's or PR
objectui#10977's files.
## Gates, head `7089f691c`
All ran after the last commit. Exit codes were captured before any pipe.
- `pnpm --filter @object-ui/types build` → 0. It includes
`check-dist-completeness`: 134 emitted files verified.
- `pnpm --filter @object-ui/types type-check` → 0. `tsc -p
tsconfig.test.json --listFiles` includes the new pin.
- `pnpm --filter @object-ui/types lint` → 0, with 0 errors. The new file
has no warnings; the package has 295 existing `no-explicit-any`
warnings.
- `pnpm exec vitest run packages/types/` → 0: 269 files and 5962 tests
passed.
- The tests outside `types` that read the edited files, plus the parser
pins named above → 0: 9 files, 276 tests.
- `scripts/__tests__/check-doc-component-types.test.ts`,
`check-spec-symbol-derivation.test.ts`,
`one-authority-per-exported-name-6273.test.ts` and
`check-pending-changeset-literals.test.ts`;
- the three `header-bar` component tests;
- `body-dialect-6771` and `containment-declared-slot-9910`.
- `check-changeset-presence`, `check-changeset-no-major`,
`check-changeset-fixed` and `check-changeset-overwrite` → 0.
- `check-changeset-claims` → 0. It is report-only. It lists 17 pending
changesets that name an edited file. None of them quotes either clause
this PR changes. The only pending changeset carrying the old string
clause is objectui#10928's, about the family-D refusals, and that is
still true.
- `pnpm check:control-bytes`, `check:new-line-citations` (0 new),
`check:pending-changeset-literals`, `check:test-path-roots` and
`check:phantom-deps` → 0.
- `check-governed-queue-guard --test` over the 5 paths → NOT GOVERNED.
- Declared to CI: repo-wide `pnpm lint`, full `pnpm test` and the other
workflow gates.
## Acceptance notes
Same family, not changed here, and left for the seat to route. Each
carries the old silence claim, and the parser tier answers it (live
registry, same probe):
- `zod/form.zod.ts`, the `FormSchema.mode` refusal (objectui#10286):
"every spelling rendered the same form — no error, no warning". `form`
with `mode` draws `unknown-prop`.
- `data-display.ts`, the `TimelineSchema.events` docblock
(objectui#6170): "drew an EMPTY rail, with no error and no warning". A
bare `timeline` with `events` draws `unknown-prop`. The live registry
resolves that key to `plugin-timeline`'s `view` registration, so this
reading is about that registration. This file is PR objectui#10972's
surface.
- `base.ts`, the `bind` docblock: "`data-table` … renders its header
over an empty body, with no error and no warning". `data-table` with
`bind` draws `unknown-prop`.
- `zod/objectql.zod.ts`, the `exportOptions` describe text
(objectui#7762): "no error, no warning, no console line". `object-grid`
with an `exportOptions` array draws `type-mismatch`.
Boundary: the names `grid` and `form` also exist as `view:grid`,
`view:form` and `field:grid`. Those are different registrations and node
types, which the `GridSchema` / `FormSchema` docblocks do not describe.
None of them declares `children`, so a `body` list there draws
`not-a-container`.
## Open question
Should a live-registry pin in `packages/components` also hold the parser
behaviour the `header-bar` clause describes? No such pin exists today.
This PR does not add one: it is outside the claimed file surface, and
the same question is open from PR objectui#10956.
---
_Generated by [Claude
Code](https://claude.ai/code/session_012UwY3ahMixEFkfTUxMVkYm)_
---------
Co-authored-by: Claude <noreply@anthropic.com>body docblocks name the parser tier's unknown-prop warning (objectui#10959) (#10980)1 parent deca847 commit 42687ba
5 files changed
Lines changed: 236 additions & 27 deletions
File tree
- .changeset
- packages/types/src
- __tests__
- zod
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
877 | 877 | | |
878 | 878 | | |
879 | 879 | | |
880 | | - | |
881 | | - | |
| 880 | + | |
| 881 | + | |
| 882 | + | |
882 | 883 | | |
883 | 884 | | |
884 | 885 | | |
| |||
2131 | 2132 | | |
2132 | 2133 | | |
2133 | 2134 | | |
2134 | | - | |
2135 | | - | |
| 2135 | + | |
| 2136 | + | |
| 2137 | + | |
2136 | 2138 | | |
2137 | 2139 | | |
2138 | 2140 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
70 | 70 | | |
71 | 71 | | |
72 | 72 | | |
73 | | - | |
74 | | - | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
75 | 76 | | |
76 | 77 | | |
77 | 78 | | |
| |||
109 | 110 | | |
110 | 111 | | |
111 | 112 | | |
112 | | - | |
113 | | - | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
114 | 116 | | |
115 | 117 | | |
116 | 118 | | |
| |||
583 | 585 | | |
584 | 586 | | |
585 | 587 | | |
586 | | - | |
587 | | - | |
| 588 | + | |
| 589 | + | |
| 590 | + | |
588 | 591 | | |
589 | 592 | | |
590 | 593 | | |
| |||
712 | 715 | | |
713 | 716 | | |
714 | 717 | | |
715 | | - | |
716 | | - | |
| 718 | + | |
| 719 | + | |
| 720 | + | |
717 | 721 | | |
718 | 722 | | |
719 | 723 | | |
| |||
747 | 751 | | |
748 | 752 | | |
749 | 753 | | |
750 | | - | |
751 | | - | |
| 754 | + | |
| 755 | + | |
| 756 | + | |
752 | 757 | | |
753 | 758 | | |
754 | 759 | | |
| |||
799 | 804 | | |
800 | 805 | | |
801 | 806 | | |
802 | | - | |
803 | | - | |
| 807 | + | |
| 808 | + | |
| 809 | + | |
804 | 810 | | |
805 | 811 | | |
806 | 812 | | |
| |||
1079 | 1085 | | |
1080 | 1086 | | |
1081 | 1087 | | |
1082 | | - | |
1083 | | - | |
| 1088 | + | |
| 1089 | + | |
| 1090 | + | |
1084 | 1091 | | |
1085 | 1092 | | |
1086 | 1093 | | |
| |||
0 commit comments