Repository navigation
feat(types)!: ObjectMapConfigSchema is strict, so objectui validate refuses an undeclared map key (objectui#5157) - #10997
Conversation
…red map key is refused `ObjectMapSchema.map` is this object, so `safeValidateSchema` (and `objectui validate` with it) now refuses a `map` block carrying an undeclared key with an `unrecognized_keys` issue at `map` that names the key, while `ObjectMap` keeps rendering and warns through its existing `safeParse` channel. `.shape` is unchanged. Pins: the validate face (red without `.strict()`), the runtime face (renders and the warning names the key), and the pre-landing sweep of every `map` block found in authored metadata, held as a fixture. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
A `'@object-ui/types': minor` changeset that states the narrowing: `objectui validate` refuses an undeclared `map` key by name, `objectui check` stays advisory, and the runtime keeps rendering and warning. The plugin-map README, the plugin-map docs page and the types README say the block is closed. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
…g warn pin Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
|
changeset-claim-re-read
|
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
…kdown-input ledger `object-map-config-strict-5157.test.ts` names `content/docs/fields/location.mdx` and `content/docs/plugins/plugin-map.mdx` as provenance on its sweep fixture rows and opens neither, so it is recorded with an empty `reads` and both pages under `notRead`. The declared entries, and so what `--list` / `--changed` answer for any path, are unchanged. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
Contract reviewServed-tier: ① Derived judgments1. The change matches the ruling: PASS.
2. The sweep: PASS. I re-derived it with
3. The pins, judged by reading: PASS.
4. BLOCKER: CI is red.
5. Rendering of the nested refusal.
6. Docs and changeset: wording defects (blocking; fix in the same commit as item 4).
7. No generalisation: PASS. Only the one closer changed. The siblings (the calendar block, ② Semver level
③ Boundary flags
Implemented-by: VERDICT: FAIL To land, the PR needs:
Separately, the seat should file the |
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
…at named it before A `latitudeFieId` typo leaves the block with no coordinate binding, so `ObjectMap` draws the "Map configuration required" refusal (objectui#8169), not a map. The plugin-map README and docs page now say the component does not throw, renders from the declared keys and warns naming the key, and that a binding-less typo draws that refusal; both qualify "at `map`" as the root-node answer. The schema docblock, the runtime pin's docblock and the changeset no longer describe the pre-#8169 empty map, and the changeset says what did name the key before (only a TypeScript author's compiler). Frontmatter unchanged. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
Contract reviewServed-tier: This is an in-seat delta review of fix round 1: ① Derived judgments
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS |
…re-qualify objectstack#3546 (objectui#10803, batch 8) (objectstack-ai#11012) Fixes objectstack-ai#10803 Clause-②: no Dispatched implementation of the `domain:ui` seat objectstack-ai#1 claim (comment `5873413663`) on objectui#10803, batch 8, session `https://claude.ai/code/session_01DuWo5bdP9SdVebamn99GGk`. Citations only: no sentence's claim moves, the one edited pending changeset keeps a byte-identical frontmatter, and no runtime string moves, so the only new changeset is an empty-frontmatter sweep. No test pins any changed text (**The literal-anchor sweep**), so no test file is edited. This batch carries release `5872268200`'s two lists (the seat's ruling A in ACCEPT `5870953708`, which review `5870922323` read the same way): - the **10 in-class lines that cite a dead objectstack number written bare**: `objectstack-ai#9934` seven times, "PR `objectstack-ai#6281`" twice, "objectstack PR `objectstack-ai#8452`" once; - the **6 live-but-wrong `objectstack-ai#3546` lines** that mean objectstack#3546: five written bare, one written with this repository's name. Numbers are written in code spans in this body when they are the dead or wrong spelling, so GitHub does not link them to the unrelated objectui items they would resolve to. ## Why `Fixes` Both lists read **0** after this batch (**Census**), and the closure census over the card's two classes (pending `.changeset/*.md` prose and non-test `packages/*/src`) finds nothing else dead: - **Bare numbers**, batch 7's instrument (printed under **Census**): 965 distinct at the branch point, 961 at this head. The 916 between 100 and 25000 at the branch point were each read once as objectstack issues: 877 answer 200 and 39 answer 404. The 39 were read again as objectstack issues and as pulls (404 each) and as objectui issues (200 each). Three of them are this batch's (`objectstack-ai#9934`, `objectstack-ai#6281`, `objectstack-ai#8452`), gone at this head. The other 36 remain, and each sentence was read: every one cites an objectui card or pull request, and each answers 200 in objectui with the subject its sentence names. - **The instrument's blind spot** (a number written after `/`, `-` or `.`, as in `objectui#9469/objectstack-ai#8649`): 46 numbers between 100 and 25000 appear only in that form at this head. Read as objectstack issues: 45 answer 200; one answers 404, `objectstack-ai#8649`, which sits in two lines as `objectui#9469/objectstack-ai#8649` and means objectui#8649 (200). - **Qualified citations** at this head: every distinct `objectui#N` and objectui issue or pull URL (2723 numbers) answers 200; every distinct `objectstack#N` and objectstack issue or pull URL (345 numbers) answers 200, except objectstack#14026, which answers 301 (transferred to objectui#10102, re-qualified by batch 6). So nothing dead is left in the card's classes, and nothing in them resolves to the wrong repository as far as these instruments see. **Acceptance notes** 1 and 2 record what is outside the classes, and what could not be measured. ## Premise, re-measured on `origin/main` `665025908` (the branch point) - **The three dead numbers.** objectstack `issues/N` and `pulls/N` answer 404 for 9934, 6281 and 8452 (the in-range census read each as an issue a second time). Lit controls in the same run: objectstack issues 3546, 3391, 5775 and 8326 answer 200; objectstack `pulls/13267` and `pulls/16920` answer 200. - **What they resolve to here.** objectui `objectstack-ai#9934` is a CI finding about the `needs:contract-review` label; objectui PR `objectstack-ai#6281` is an app-shell Studio grid change; objectui `objectstack-ai#8452` is a `not_contains` operator bug. None is what its sentence meant. - **`objectstack-ai#3546`, both repositories.** objectstack#3546 (200) is "detail/form 面的 edit/delete 按钮接入服务端 effective 操作集", the effective operation set on detail and form surfaces, which each of the six sentences describes. objectui `objectstack-ai#3546` (200) is the missing-i18n-keys card, unrelated. The 96 `objectui#3546` lines in the locale packs and the "slice seven" line in `.changeset/3880-es-done-listo.md` are that i18n card, and are untouched. - **The landing commits**, each read over REST (`commits/SHA`) and checked with `compare/SHA...main`, which answers `behind_by 0` for each, i.e. each is an ancestor of objectstack `main`: - `79c46da90`, "feat(contract): producer-side user-facing marking for hook refusal messages — userMessage channel (objectstack-ai#9934) (objectstack-ai#9992)", 2026-08-19: `ApiErrorSchema.userMessage`, and the dispatcher door (`packages/runtime/src/http-dispatcher.ts`) emits it as a declared sibling of `code` and `message`; - `85ec26d28`, "spec: SDUI props — enforce or remove (objectstack-ai#5775) (objectstack-ai#6281)", 2026-08-07: retires `page:card.body` in favour of `children`, with an ADR-0087 D2 conversion; - `27358d517`, "feat(spec,rest): add batch recordIds to security/explain (objectstack-ai#8326) (objectstack-ai#8452)", 2026-08-13. - These are the landings release `5872268200` names; review `5870922323` read all three against their messages. Batch 7 already cites `79c46da90` and `85ec26d28` at other sites in these classes. - The one edited changeset, `.changeset/7980-agent-key-envelope-read.md`, is pending: it is present in `.changeset/` on `main`. This checkout is not shallow. ## Census (the enumeration pin for this batch) The two lists (REF = a commit or tree): ``` git grep -nP '(?:^|(?<=[^\w#&/.\-]))#(9934|6281|8452|3546)(?![0-9A-Za-z_])' REF -- '.changeset/*.md' 'packages/*/src/**' ':!**/__tests__/**' ':!**/*.test.*' ':!**/*.spec.*' ':!**/test/**' ':!**/tests/**' | wc -l git grep -n 'objectui#3546' REF -- '.changeset/*.md' 'packages/*/src/**' ':!**/__tests__/**' ':!**/*.test.*' ':!**/*.spec.*' ':!**/test/**' ':!**/tests/**' ':!packages/i18n/src/locales/**' | wc -l ``` | REF | bare four | `objectui#3546` outside the locale packs | |:--|:--|:--| | `665025908` (branch point) | **15**: `objectstack-ai#9934` 7, `objectstack-ai#6281` 2, `objectstack-ai#8452` 1, `objectstack-ai#3546` 5 | **2**: the `plugin-detail` line and the i18n card's own line in `3880-es-done-listo.md` | | `8fe632d96` (this head) | **0** | **1**: the `3880-es-done-listo.md` line, which is the i18n card and stays | - Lit controls at this head: `objectstack#3546` reads 10 lines against 3 at the branch point (the 6 re-qualified here, and one in this PR's sweep changeset); the 96 `objectui#3546` lines in the locale packs are unchanged. - The bare-number instrument, batch 7's (the census of **Why `Fixes`**): ``` git grep -hoP '(?:^|(?<=[^\w#&/.\-]))#\d+(?![0-9A-Za-z_])' REF -- '.changeset/*.md' 'packages/*/src/**' ':!**/__tests__/**' ':!**/*.test.*' ':!**/*.spec.*' ':!**/test/**' ':!**/tests/**' | sort -u | wc -l ``` 965 at the branch point, 961 at this head: exactly `objectstack-ai#3546`, `objectstack-ai#6281`, `objectstack-ai#8452` and `objectstack-ai#9934` are gone, and nothing is new. The blind-spot reading replaces the lookbehind class with `[^\w#&]`. ## Citation form - **An objectstack commit** is written as batches 6 and 7 wrote their stand-ins: objectstack and the 9-character backticked sha of the commit on objectstack `main` that landed the change the sentence rests on. - **A bare `objectstack-ai#3546`** becomes `objectstack#3546`, including inside the `[objectstack-ai#3546]` tags that open four comments; the one written with this repository's name is re-qualified the same way. ## Mapping | site | before | after | |:--|:--|:--| | `.changeset/7980-agent-key-envelope-read.md` | "(the `objectstack-ai#9934` channel, whose presence *is* the marking)" | "(the objectstack `79c46da90` channel, …)" | | app-shell `index.ts`, the note above the `readEnvelopeFailureText` export | "(the `objectstack-ai#9934` channel, which rides through the 5xx prose withhold untouched)" | "(the objectstack `79c46da90` channel, …)" | | app-shell `utils/apiErrorEnvelope.ts`, the `userMessage` bullet | "the END USER (`objectstack-ai#9934`)" | "the END USER (objectstack `79c46da90`)" | | app-shell `utils/apiErrorEnvelope.ts`, the `errorFromThrown` bullet | "… has emitted the channel since `objectstack-ai#9934`" (a quotation) | "… has emitted the channel since [objectstack `79c46da90`]" (**Special cases** 1) | | app-shell `PackageFormDialog.tsx`, `readEnvelopeUserMessage`'s docblock | "(`error.userMessage`, `objectstack-ai#9934`)" | "(`error.userMessage`, objectstack `79c46da90`)" | | app-shell `StudioDesignSurface.tsx`, the package-switcher failure read | "the producer's `objectstack-ai#9934` channel" | "the producer's channel (objectstack `79c46da90`)" | | app-shell `packages-io.ts`, `duplicatePackage`'s failure arm | "has emitted since `objectstack-ai#9934`" | "has emitted since objectstack `79c46da90`" | | components `containers.tsx`, the `PageCardRenderer` `body` read | "objectstack#5775 (PR `objectstack-ai#6281`, ADR-0087 D2)" | "objectstack#5775 (objectstack `85ec26d28`, ADR-0087 D2)" | | components `containers.tsx`, the `card` registration's `children` input | "objectstack#5775 (PR `objectstack-ai#6281`)" | "objectstack#5775 (objectstack `85ec26d28`)" | | plugin-grid `hooks/useRecordCrudVerdicts.ts` | "shipped in objectstack PR `objectstack-ai#8452`" | "shipped in objectstack `27358d517`" | | app-shell `RecordDetailView.tsx`, two comments | "[`objectstack-ai#3546`] …" | "[objectstack#3546] …" | | app-shell `RelatedRecordActionsBridge.tsx` | "[`objectstack-ai#3546`] Intersect the child object's …" | "[objectstack#3546] …" | | plugin-detail `renderers/record-details.tsx` | "[`objectstack-ai#3546`] Also AND inline-editability …" | "[objectstack#3546] …" | | plugin-form `fieldWriteGate.ts` | "`objectstack-ai#3546` intersects that with the server's effective API operation set" | "objectstack#3546 intersects …" | | plugin-detail `index.tsx`, the `inlineEdit` input comment | "(`objectui#3546`)" | "(objectstack#3546)" | Each `objectstack-ai#9934` sentence is about the `userMessage` channel that `79c46da90` added; each `objectstack-ai#6281` sentence is about the `page:card` `body` retirement that `85ec26d28` carries; the `objectstack-ai#8452` sentence is about the batch `recordIds` form that `27358d517` shipped. ## Special cases (the judgement calls) 1. **A quotation.** The `apiErrorEnvelope.ts` bullet quotes the note beside `sendThrownError` in objectstack's `packages/rest/src/package-routes.ts`, verbatim. That note still reads "since objectstack-ai#9934" on objectstack `main` (`e956924` at the time of this PR); there the number means objectstack's card, which answers 404, and here it resolves to the unrelated objectui item. The quote keeps its words and takes the commit in square brackets, the editorial mark for a substituted word. The note's claim is the one `79c46da90` carries: its `http-dispatcher.ts` hunk adds the `userMessage` spread to the dispatcher door's `extra`. 2. **Line breaks moved** only where the stand-in made a line markedly longer: app-shell `index.ts`, `StudioDesignSurface.tsx` and `packages-io.ts`. Elsewhere the one line just grows, as batch 7's `objectstack#3391/objectstack#3546` lines did. 3. **Wording kept.** "the `objectstack-ai#9934` channel" becomes "the objectstack `79c46da90` channel" in two places, and "the producer's channel (objectstack `79c46da90`)" in `StudioDesignSurface.tsx`, where "the producer's objectstack … channel" would read as if the producer were objectstack. No other word moves. ## The literal-anchor sweep (both test-pin classes, ruling `5861900779`) - **Instrument.** Every string, template and regex literal in the 4108 tracked test and script files (104609 distinct strings, 2339 regexes), read with the TypeScript scanner. - **Test.** Does its occurrence count DROP between `665025908` and this head in any of the 14 changed files, raw or comment-flattened? - **Result.** 30 distinct literals drop, every one generic: digits, punctuation, whitespace and character classes (`#\d+`, `\d{3}`, `[:#]`, `\s+`), the bare words `objectui` and `objectui#`, `/objectui#\d+/`, and comma-and-line-break fragments. None is a changed phrase, a dead number or a `objectstack-ai#3546` tag. A search of tests for the changed spellings finds them only in test doc comments (listed in **Acceptance notes** 1), which no assertion reads. ## Held **By the serial rule: nothing.** Open PRs were mapped at the branch point before the first edit (7 open) and again before the push (7 open; objectui#11003 and objectstack-ai#10997 have since merged, and objectui#11010 and objectstack-ai#11006 have opened). - **objectui#10990** and **objectui#11010** share `packages/app-shell/src/index.ts`. objectui#10990's hunk is in the side-effect import list, near the Cloud widgets; objectui#11010's is one line in the `views` type export list. This PR's two changed lines are in the note above the `readEnvelopeFailureText` export, more than ninety lines above both hunks. - **objectui#5400** (Version Packages) carries `.changeset/7980-agent-key-envelope-read.md`, which it consumes at release; it regenerates and is not a hold. If it lands first, that file's one changed line has already published, and this PR's hunk there conflicts with the deletion. - Trial merges with this head (`git merge-tree --write-tree`): clean for objectui#11010, objectstack-ai#11006, objectstack-ai#10990, objectstack-ai#10930 and objectstack-ai#10777. objectui#10278 conflicts in `ObjectGrid.tsx`, `plugin-grid/README.md` and `content/docs/plugins/plugin-grid.mdx`, and conflicts in the same three files against the branch point alone; none is in this diff. ## Changesets - `.changeset/10803-dead-citation-sweep-eighth-batch.md`, EMPTY frontmatter. It covers the comment-only edits in 5 released packages (`app-shell`, `components`, `plugin-detail`, `plugin-form`, `plugin-grid`) and the one edited pending changeset; no published behaviour changes through them. It writes no bare number itself. - No runtime string moves, so there is no `patch` changeset (amendment `5860244997` Q1 = A applies to none of these lines: the `plugin-detail` `index.tsx` line is a comment beside the `inlineEdit` input, not its `description` string). ## Proof of prose-only (C4), against `665025908` - **Source.** Each of the 12 touched `.ts` / `.tsx` files was parsed at `665025908` and at this head with TypeScript 6.0.3's `createSourceFile`, and re-printed by `createPrinter({ removeComments: true })`: 12 of 12 prints are identical, with 0 parse diagnostics. Lit controls on the same instrument: editing a string literal moves the print; re-spacing a comment does not. - **Changesets.** The frontmatter block of `.changeset/7980-agent-key-envelope-read.md` is byte-identical at `665025908` and this head (md5); the overwrite gate below agrees. - **Scope of the diff:** 14 files, +39 / −20: 1 edited and 1 new changeset, and 12 non-test source files in 5 released packages. No test file. ## Gates, on this head `8fe632d96` Each line is the gate's own verdict and exit code, captured by redirect-then-`$?`. - `node scripts/check-changeset-presence.mjs`, exit 0: "12 source file(s) of 5 released package(s) changed, and this change declares 1 changeset(s): .changeset/10803-dead-citation-sweep-eighth-batch.md." - `pnpm changeset:check`, exit 0: "All workspace packages are in the changeset fixed group." / "No changeset declares a `major` bump." - `node scripts/check-changeset-overwrite.mjs` (report-only), exit 0: "1 changeset(s) added, 1 modified, 0 deleted"; for the modified one, `declared at base` equals `declares now` ("@object-ui/app-shell: minor, @object-ui/console: patch"). - `pnpm check:changeset-claims` (report-only), exit 0: "Every package declared across those 1 body(ies) is either not negated …", and the standing notice "15 pending changeset(s) describe a file this change touches". Read against the diff: a pending changeset quoting a replaced spelling would carry a bare number the census sees, and the census reads 0 in `.changeset/`. - `pnpm check:control-bytes`, exit 0: "check-control-bytes: OK (scanned 9291 tracked text file(s); skipped 85 binary)." A `grep -P` control-byte self-scan of the 14 files finds none. - `pnpm check:new-line-citations`, exit 0: "VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only -> exit 0". - `pnpm check:pending-changeset-literals`, exit 0: "No test source names a pending changeset." - Also run over the touched comments, on the tree this head carries: `pnpm check:spec-symbols` exit 0 ("spec member citations: 1424 sources + 184 documentation pages; nothing cites a key its spec symbol does not declare."); `pnpm check:installed-pin-claims` exit 0 ("OK"); `pnpm check:comment-mask-corpus` exit 0 (1 disagreeing file, within the ceiling objectui#7882 holds open); `node scripts/check-hand-rolled-comment-mask.mjs` exit 0 ("OK every carrier is a DEBT entry, and every DEBT entry still carries one."); `pnpm check:handler-key-reads` exit 0 ("every judged read is a declared member of its arm"). - The governed-surface predicate over the 14 paths, exit 0: "NOT GOVERNED — 14 path(s) checked against 5 governed surface(s); none matched." Lit control `AGENTS.md`: exit 3. **Tests and type-check**, through the shared verify lock, on `8fe632d96`. - `scripts/__tests__/`, the whole directory, whose whole-tree scanners read the touched files and changesets: `Test Files 177 passed | 2 skipped (179)`, `Tests 5350 passed | 2 skipped (5352)`, `VERDICT command-exit 0`. - `packages/components/`, `plugin-detail/`, `plugin-form/` and `plugin-grid/`, whole packages, in one run: `Test Files 847 passed | 2 skipped (849)`, `Tests 8441 passed | 33 skipped (8474)`, `VERDICT command-exit 0`; the source files were byte-identical to this head's. - `packages/app-shell/`, whole package: `Test Files 1 failed | 863 passed | 1 skipped (865)`, `Tests 1 failed | 8835 passed | 9 skipped (8845)`. The one failure is `AppContent.inaccessibleAppStrand.test.tsx`, 'bounces to the DECLARED landing where the deployment declares one', a network-escape guard trip (a real socket at `localhost:3000/api/v1/meta`) under the full suite on a shared box. That file is not in this diff, and C4 shows no code token moves; re-run alone three times on this head it reads `Tests 6 passed (6)` each, and the CI test shards are green on this head. - Type-check: `turbo run build` of the 28-package dependency closure (`Tasks: 28 successful, 28 total`), then `pnpm --workspace-concurrency=2` with the 5 package filters `run type-check`: 5 script echoes, 5 `Done`, `VERDICT command-exit 0`. - No red leg: the sweep found no anchor to move, so there is no pin whose old copy should fail. CI on `8fe632d96`: 43 check-runs, 39 success, 3 skipped, 1 failure; `Spec Main Shape Gate` success. The failure is `Bundle Analysis`, step "Check console performance budget", which fails the same way on `main` at this PR's branch point `665025908` and at `d6d8fb9d7` and `2049b03df` after it; this diff moves no code token. ## Acceptance notes 1. **Outside the card's two classes, as it stands** (whole tree at this head, bare spelling): `objectstack-ai#9934` in 3 test doc-comment lines in 2 files and in 1 `apps/console` source line (`AgentConnectSection.tsx`, "the objectstack-ai#9934 channel"); `objectstack-ai#6281` in 1 test doc-comment line; `objectstack-ai#8452` in 1 test doc-comment line; bare `objectstack-ai#3546` in 23 test lines in 14 files and 19 published `CHANGELOG.md` lines in 8 files. `apps/console`, tests and `CHANGELOG` history are outside the classes this card carries (triage `5858031244`; release `5861553562`: recorded, not carried). 2. **Not measured: `framework#N` and `cloud#N`.** The two classes also cite 82 distinct `framework#N` and 43 distinct `cloud#N` numbers. Neither repository is on this card's lists, and both answer 403 through this container's proxy, so no reading of them is offered. 3. **Left as the brief allows.** The two test comments that call objectui#8652 `pm:blocked` (it reads `pm:on-hold`) and batch 7's sweep-changeset phrase "declared separately below" are in files this PR does not touch, and stay. --- _Generated by [Claude Code](https://claude.ai/code/session_01DuWo5bdP9SdVebamn99GGk)_ Co-authored-by: Claude <noreply@anthropic.com>
…e parser tier answers (objectui#10981) (objectstack-ai#11006) Fixes objectstack-ai#10981 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 `4b742f41d`. PR objectstack-ai#10986 landed on `zod/objectql.zod.ts` meanwhile, so `main` `665025908` was merged in before the final push. Head `ebd156ef5`. ## What changed Only the false clause changes, on four sites. Each clause names the code the parser tier answers for that key and value shape, as measured on the live registry (next section). | site | face | before | after | |---|---|---|---| | `zod/form.zod.ts`, the `FormSchema.mode` refusal (objectui#10286) | zod message and `.describe()`, one string through `retirementTombstone` | "rendered the same form — no error, no warning" | "rendered the same form — no render-time error or warning; only the parser tier's `unknown-prop` warning noticed it" | | `data-display.ts`, the `TimelineSchema.events` docblock (objectui#6170) | TS face, emitted `.d.ts` | "drew an EMPTY rail, with no error and no warning" | "drew an EMPTY rail, with no render-time error or warning; only the parser tier's `unknown-prop` warning noticed it" | | `base.ts`, the `data-table` sentence in the `BaseSchema.bind` docblock | TS face, emitted `.d.ts` | "renders its header over an empty body, with no error and no warning" | "renders its header over an empty body, with no render-time error; nothing on the page says why, but a render-time console warning (`[ObjectUI] DataTable bind:`, objectui#6575) and the parser tier's `unknown-prop` warning both name it" | | `zod/objectql.zod.ts`, the note on `OBJECT_GRID_EXPORT_OPTIONS_GUIDANCE` (objectui#7762) | source note on a non-exported constant; it ships in the emitted JS, in no `.d.ts` | "no error, no warning, no console line" | "no render-time error, warning or console line (only the parser tier's `type-mismatch` warning noticed it)" | - **Why `base.ts` has its own wording.** That site was not silent at render either. `data-table` has logged `[ObjectUI] DataTable bind:` for an authored `bind` since objectui#6575 (`aff3d7aef`, 2026-08-28). The docblock was written a day later (`99a3c2db6`, 2026-08-29). `merge-base --is-ancestor aff3d7a 99a3c2d` answers 0, with the control leg `94d4876df` also answering 0. So "only the parser tier noticed it" would be false there too. - **Why `exportOptions` names `type-mismatch`.** The `object-grid` registration declares `exportOptions` as `type: 'object'`. So `checkType` answers an array, not the undeclared-key branch. - **New pin:** `packages/types/src/__tests__/silence-clause-parser-tier-closure-10981.test.ts`. - **Optional item, taken:** `packages/components/src/renderers/__tests__/header-bar-unknown-prop-parser-tier-10981.test.tsx`, a new file beside `container-declaration-ratchet`. - **Changeset:** `.changeset/10981-silence-clause-parser-tier-closure.md`, `@object-ui/types: patch`. ## The parser tier, measured before each clause was written **Instrument.** The same as PR objectstack-ai#10980: a one-shot probe, deleted and never committed, under `packages/components/src/renderers/__tests__/`. - It imported the components renderers, `fields` and 18 of the 19 `plugin-*` packages (all but `plugin-designer`). `plugin-tree` has no vitest alias, so it came in by relative source path. - The manifest was built from every KNOWN registry key through `manifestFromConfigs`, the way `container-declaration-ratchet.test.tsx` builds it. - Each leg ran `validateTree` on a control and on the control plus the one key, and reports only the diagnostics that key added. - Each leg also rendered through the real `SchemaRenderer`, inside `PredicateScopeProvider` and `SchemaRendererProvider` with a stub data source, all inside `act`. `console.warn` and `console.error` were spied, and the HTML was compared with the control's. | site | keys | value shapes | the parser tier adds | render leg | |---|---|---|---|---| | `FormSchema.mode` | `form`, `ui:form`. Bare `form` resolves to `ui:form`; `view:form` is `skipFallback` | `edit`, `read`, `disabled`, `create`, `view` (the objectui#10286 pin's set) | exactly one `unknown-prop` on `mode`, 10 of 10 legs | 0 warnings, 0 errors on every variant. HTML equals the control's except for one `mode` attribute on the form element | | `TimelineSchema.events` | `timeline` (resolves to `view:timeline`), `view:timeline`, `plugin-timeline:timeline` (the `TimelineRenderer` registration `TimelineSchema` describes) | 2 events; `[]`; `items` plus `events` | exactly one `unknown-prop` on `events`, 7 of 7 | byte-identical HTML, 0 warnings, 0 errors | | `BaseSchema.bind` on `data-table` | `data-table`, `ui:data-table` | `bind: 'users'` and `bind: 'app.settings.users'`, each with `data` absent and with `data: []` | exactly one `unknown-prop` on `bind`, 8 of 8 | byte-identical HTML (the "No results" body in both), 0 errors, and exactly 1 console warning on every variant: `[ObjectUI] DataTable bind: … is ignored` | | `exportOptions` | `object-grid`, `plugin-grid:object-grid` | `['csv', 'xlsx']`, `['csv']`, `[]` | exactly one `type-mismatch` ("expected an object"), 6 of 6 | the control is `{ formats: ['csv', 'json'] }`, the default an array loses to. Byte-identical HTML, the export control and the rows present in both, 0 warnings, 0 errors | **Controls.** - `form` with an invented key draws `unknown-prop`. `view:form` with `mode: 'edit'` draws nothing, because that registration declares `mode`. - On `object-grid`: an `exportOptions` object draws nothing, a string draws `type-mismatch`, and an invented key draws `unknown-prop`. So the probe tells the two codes apart on one node. - `accordion` with a `body` list draws `not-a-container`, the third code. - With `data` absent, the `data-table` control already carries `missing-required-prop` on `data`; the table above counts only what `bind` adds. - The first control render in the file logged one `react-i18next` initialisation warning. No variant did. **The same answer before each retirement (source reading, not executed).** The `mode`, `events` and `exportOptions` sentences are past tense. - `FormSchema.mode`, at `a05c35063^`, the parent of the objectui#10286 commit: the `ui:form` registration declared the same 13 inputs as today, none named `mode`. `plugin-form`'s `form` was `namespace: 'view', skipFallback: true`. `validate.ts` had the same base-prop set, without `mode`, and one `unknown-prop` branch. - `TimelineSchema.events`, at `195052fff^`, the parent of the objectui#6170 tombstone commit: neither `plugin-timeline:timeline` nor `view:timeline` declared `events`. A `git log -G` for an `events` input name over `packages` finds no registration that ever declared one, back to the shallow boundary (2026-07-20). - `exportOptions`, at `f08d1a86a^`, the parent of the objectui#7762 refusal: `GRID_QUERY_INPUTS` declared `exportOptions` as `type: 'object'`. It had done so since `375efb402` (2026-08-17), and objectui#7762 was filed on 2026-09-05. `checkType` gave a single non-enum arm `type-mismatch`, as today. - `BaseSchema.bind` is present tense, measured today. - The history reads ran on a deepened checkout (`git fetch --deepen=4000`, shallow boundary 2026-07-20). ## Census over joined text (the closure nail) **Instrument.** A one-shot script. It enumerates the non-test `.ts` files of `packages/types/src` from the ref with `git ls-tree` and reads each one from the ref. It joins JSDoc and line-comment continuations and `'…' + '…'` concatenations, and unescapes quotes. Then it counts: - A: "no (adjective) error" and "no (adjective) warning" within 60 characters, with no sentence break; - B: the same, in reverse order; - C: "no (adjective) error or / nor / and (adjective) warning", the family's corrected shape; - D: "without (an) error or / and warning"; - E: "neither error nor warning"; - F: "silent…" within 80 characters of a negated warning, in either order; - G, the wide net: any negated warning ("no warning", "without a warning", "never warns", …); - H, the wider net over other nouns: "no diagnostic", "no console line", "without complaint", "not a warning". | reading | base `4b742f41d` | main `665025908` | head `ebd156ef5` | |---|---|---|---| | files enumerated | 67 | 67 | 67 | | A | 4 | 4 | 0 | | B, D, E | 0 | 0 | 0 | | C, and how many are followed by "the parser tier's" | 302, 300 | 302, 300 | 302, 302 | | F | 1 | 1 | 0 | | G | 6 | 6 | 2 | | H | 25 | 25 | 24 | | control: the objectui#10928 clause | 282 | 282 | 282 | | control: the objectui#10959 tail | 18 | 18 | 20 | - **Positive control.** C fires on every one of the 300 known objectui#10928 / objectui#10959 control strings. A fires on exactly the four sites the card names, which were found independently. - **Every non-control hit at base, read.** - A is the four sites and nothing else. The two C hits without the parser tier's clause are two of the four (`base.ts`, `data-display.ts`). F is the fourth site again. - G adds two hits that say "no warning window" (`objectql.ts`, `zod/objectql.zod.ts`, objectui#6475). That is a deprecation window, not a silence claim, so they stay. - H is outside the card's phrasing family. It is listed under Acceptance notes and not changed. ## Every other byte, and only comment and string lines - Substitute the old clause back for the new one on joined text: each head file equals its base file, 4 of 4, against `4b742f41d` and again against `665025908`. - The first four ablation legs put the old clause back with the anchor tool. Each mutated blob equals the base blob byte for byte: `eba1c495f`, `4dfce4ac6`, `b1abfe909` and `e2c561734` are the base blobs of the four files. - `git diff -U0` over the four files: every changed line is a ` * ` JSDoc line or a `+ '…'` string-literal line. - The objectui#10286, objectui#6170, objectui#7762 and `bind` pins pass unchanged; they are in the full `types` run. - **Emitted `dist`**, after `pnpm --filter @object-ui/types build` at head: - the old clauses, both spellings: 0 files; - the `mode` clause: `zod/form.zod.js`, `zod/index.zod.js`; - the `events` clause: `data-display.d.ts`; the `bind` clause: `base.d.ts`; - the `exportOptions` note: `zod/objectql.zod.js`, `zod/index.zod.js` (the emitted JS keeps comments). ## 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 equals HEAD and `git diff HEAD` is empty. - The driver re-proved each restore independently, and ran inside an EXIT / INT / TERM trap. - The types pin imports `../zod/*` source and reads the files from disk. The components pin resolves the registry from source through the vitest aliases. So no build sits between a mutation and a run. | leg | red | red tests | |---|---|---| | the old clause back into `FormSchema.mode` | 3 / 9 | the `mode` arm, the spelling walk, the pairs walk | | the old clause back into `TimelineSchema.events` | 3 / 9 | the `events` docblock, the pairs walk, the parser-tier walk | | the old clause back into `BaseSchema.bind` | 3 / 9 | the `bind` docblock, both walks | | the old clause back into the `exportOptions` note | 2 / 9 | the note, the pairs walk | | the note names `unknown-prop` in place of `type-mismatch` | 1 / 9 | the note | | `zod/ai.zod.ts`, which the pin does not name: an objectui#10928 clause loses its parser-tier half | 1 / 9 | the parser-tier walk | | `header-bar.tsx` starts declaring `title` (components pin) | 4 / 6 | both population legs, both lit controls | - Every leg restored to its HEAD blob (`3a595a747`, `33e3a4770`, `a12a28cf1`, `4e75a80cf` twice, `a40e67ff6`, `ce3850854`) with an empty `git diff HEAD`. After the run, `git status --porcelain` was empty. - **The first `header-bar` attempt was a no-op.** Its replacement contained the anchor, so the tool refused (anchor count 1 to 1) and ran no test. It was re-run with a replacement that does not contain the anchor. The table shows the second run. ## The pins **`silence-clause-parser-tier-closure-10981.test.ts`.** It follows the house style of PR objectstack-ai#10956 and PR objectstack-ai#10980. `@object-ui/types` imports no workspace package, so it holds the prose. - **Zod face.** `FormSchema.mode` is read through its refusal: code `invalid_type` and path `['mode']` first, then the clause. The walk covers every spelling of the objectui#10286 pin, and the `.describe()` text. - **`exportOptions`.** The bare array is refused with `invalid_type` at `['exportOptions']`, with exactly the `.describe()` string. Then the note above `OBJECT_GRID_EXPORT_OPTIONS_GUIDANCE` must carry the clause and name no `unknown-prop`. - **TS face.** The `TimelineSchema.events` and `BaseSchema.bind` docblocks. - **The closure walk.** It reads every non-test `.ts` file of `packages/types/src` from disk, with the root taken from the pin's own `import.meta.url`. - No joined text may pair "no error" with "no warning" (patterns A, B, D, E). - Every C phrasing must have "the parser tier's" within 80 characters after it. - Non-vacuity, by name: the four site files are reached, and both earlier waves' clauses are found. **`header-bar-unknown-prop-parser-tier-10981.test.tsx`.** It answers the open question from PR objectstack-ai#10956 and PR objectstack-ai#10980, on the live components registry. - On `header-bar` and `ui:header-bar`, each of the 9 refused keys draws exactly one `unknown-prop` naming the key. This holds in every value shape the objectui#10387 and objectui#10286 pins refuse. - The control draws nothing. - The lit control shows `crumbs` declared, and no refused key declared. ## Dispatch assumptions, checked 1. **Holds.** There are exactly four sites, one per file, on `4b742f41d` and on `665025908`. The census was widened to patterns A–H above, with controls. 2. **Holds, and made more exact.** - `form` with `mode` draws `unknown-prop`: for all five spellings, on `form` and `ui:form`. - A bare `timeline` with `events` draws `unknown-prop`. The bare key resolves to `view:timeline`. The docblock describes `TimelineRenderer`, which is registered as `plugin-timeline:timeline` (`skipFallback`). That registration also answers `unknown-prop`, so the clause is true for the node the docblock names and for the bare key. - `data-table` with `bind` draws `unknown-prop`. But "only the parser tier noticed it" would be false there, because a render-time console warning fires too (objectui#6575). The site names both. - `object-grid` with an `exportOptions` array draws `type-mismatch`: for three array shapes, on both keys. 3. **Holds**, by source reading at the parent of each retirement. See above. 4. **Changed during the run.** PR objectstack-ai#10986 landed (`8aa68b159`) on `zod/objectql.zod.ts`. `main` `665025908` was merged in before the final push, with no conflict. The note edited here is away from that hunk. PR objectstack-ai#10997 had not landed at `665025908`. ## Gates, head `ebd156ef5` All ran after the merge commit. Exit codes were captured before any pipe. - `pnpm --filter @object-ui/types build` → 0. Its `check-dist-completeness` verified 134 emitted files. - `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 295 warnings are existing `no-explicit-any` ones; none is in the new file. - `pnpm exec vitest run packages/types/` → 0: 272 files and 5993 tests passed. - Outside `types` → 0: 27 files and 931 tests passed. - The script tests that read `packages/types/src`: `body-dialect-producer-scan`, `changeset-polarity-census`, `check-action-forward-parity`, `check-changeset-claims`, `check-component-surface-parity`, `check-doc-component-types`, `check-doc-example-types`, `check-handler-key-read-sites`, `check-readme-exports`, `check-spec-symbol-derivation`, `component-node-vocabulary-7434`, `one-authority-per-exported-name-6273`, `check-pending-changeset-literals`, `spec-symbol-ledger-types-7265`, `unconsumed-widget-option-claim-6186`, `vite-types-zod-lazy`; - `component-fixture-declared-keys` in `examples/schema-catalog`; - the new components pin, `container-declaration-ratchet`, the four `header-bar` component tests, `skill-guide-data-table-binding` and `data-table-bind-diagnostic`; - the parser pins `body-dialect-6771` and `containment-declared-slot-9910`. - `pnpm --filter '@object-ui/components^...' build`, then `pnpm --filter @object-ui/components type-check` → 0. `tsconfig.test.json --listFiles` includes the new components pin. `eslint` over the two new test files → 0, with no findings. - `check-changeset-presence`, `check-changeset-no-major`, `check-changeset-fixed`, `check-changeset-overwrite` → 0. `check-changeset-claims` → 0; it is report-only. - `pnpm check:control-bytes`, `check:new-line-citations` (0 new), `check:pending-changeset-literals`, `check:test-path-roots`, `check:phantom-deps` and `check:self-import` → 0. - `check-governed-queue-guard --test` over the 7 paths → NOT GOVERNED. - Declared to CI: repo-wide `pnpm lint`, full `pnpm test` and the other workflow gates. ## Acceptance notes Not changed here, and left for the seat to route. - **Same false claim, outside this package.** `skills/objectui/rules/protocol.md`, the "Readers only." paragraph, says a `bind` on `data-table` renders its header over an empty body "no error, no warning". The render leg and the parser leg above both contradict it. It is on the governed `skills/**` surface, outside this card. - **Same claim in unpublished test prose.** The headers of `base-bind-declared.test.ts` and `object-grid-export-options-refusal-7762.test.ts` repeat it. `mirror-partial-record-narrowing-8516.test.ts` has a different "no error and no warning" claim, about grid columns. All three are test files, outside the census. - **Pending changesets.** `.changeset/7762-object-grid-export-options-bare-array-refusal.md` and `.changeset/6575-data-table-bind-diagnostic.md` describe the pre-fix behaviour in the old words. Pending changesets are out of scope here. - **Adjacent wording, left in place.** - The `base.ts` heading "the one documented silent failure" stays. The corrected sentence now says in which sense it is silent: nothing on the page. - The `exportOptions` guidance string says an array "is silently dropped for the csv/json default". That is present tense about the renderer, and "silently" alone is outside the phrasing family. - **H, the "no diagnostic" nouns (24 at head).** Most are scoped to a named tier or instrument: "on either face" (`objectql.ts`), "zero unresolved-module diagnostics" from `tsc`, `checkType` by name, the TS index signature. A few are unscoped claims about an authored value: `ai.ts` (`maxResults`), `crud.ts`, `data-display.ts` (three) and `zod/data-display.zod.ts`. They were not measured here. - **Observation.** A `mode` on a `form` reaches the DOM as an inert `mode` attribute on the form element. The visible form is identical. - **Boundary.** `view:form` declares `mode` (enum `create`, `edit`, `view`). It is a different registration and node type, which the `FormSchema` docblock does not describe. - **A parser-tier finding, reported to the seat.** `validateTree` answers `bind` with `unknown-prop` on `list` and `tree-view` too, although both read `bind` through `useDataScope`. No registration declares a `bind` input, and the parser's base-prop set has no `bind`. --- _Generated by [Claude Code](https://claude.ai/code/session_012UwY3ahMixEFkfTUxMVkYm)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
Fixes #5157
Clause-②: yes — a published schema's accept set narrows: an undeclared key inside an
object-mapnode'smapblock stops validating.Ruling-ref: 5328158731 (B, the
mapblock only) and 5871202958 (batch #238 item 2, letter A, maintainer 「同意」 2026-09-28T13:48Z)Fix round 1 (
bf4797f85fandd5c28d4da2, following contract review5873208537):markdown-test-inputsledger entry for the new pin (CI'sTest (shard 1/8));latitudeFieIdtypo draws the "Map configuration required" refusal, not a map);No code line moved.
Implemented by the
domain:uiseat 2 dispatch, sessionhttps://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN, claim comment 5872032029.What changed
ObjectMapConfigSchema(packages/types,zod/objectql.zod.ts) closes with.strict().ObjectMapSchema.mapis this object, so the declared face, the runtime checkObjectMapruns and the validate face now share one accept set..shapeis unchanged: the same eight keys, soObjectMap'sFLAT_MAP_CONFIG_KEYS(derived from.shapeminusstyle, seven keys) and the view flatten whitelists (hand-listed, pinned against.shape) see the same keys as before.packages/plugin-map/src/ObjectMap.tsxis not changed. Its existingsafeParseof the block now fails on an undeclared key, and the existingconsole.warnnames the key.mapblock is closed. No sentence anywhere said the block tolerated unknown keys, or that validate accepted them. The types README said the whole rendering face, every named mirror included, is tolerant, so it now names themapblock as a closed sub-block on that face.'@object-ui/types': minor. It states the narrowing and the measured breakage, which is none.Pins: red on base, green on head
"Base" here means the head tree with
.strict()ablated. The ablation usedablation-replace.mjs(objectstackorigin/maincopy): anchor}).strict();went x1 to x0, and the blob went7ef2545fa19cto4d0b11cad207. The restore was proven by blob == HEAD (7ef2545fa19c) and an emptygit diff HEAD. The pins resolve@object-ui/types/zodthrough the root vitest alias topackages/types/src/zod/index.zod.ts, so nodist/is involved.safeValidateSchemarefuses the typo block: exactly one issue,unrecognized_keysatmap, keyslatitudeFieIdobject-map-config-strict-5157.test.tsObjectMapSchemarefuses it at the same pathObjectMapConfigSchemarefuses it, naming the key at the block rootdiv'schildren, is refused.shapestill declares the same eight keys; every declared key together parsesmapblock and validated inside anobject-mapnode (40 rows)locationField) renders the map and places the marker the declared keys bindObjectMap.strictConfigWarn-5157.test.tsx[ObjectMap] Invalid map configurationis warned, and its arguments namelatitudeFieIdRun totals: base
Tests 5 failed / 46 passed (51), headTests 51 passed (51). Exactly the four (ii) refusal rows went red, plus the runtime warn row. That fifth red is expected. At base the typo parses clean, so the warning never fires, and that silence is the card's own symptom. The runtime row that is green on both sides is the render half. The pin's map still draws, with no throw, because its fixture also bindslocationField. The card's ownlatitudeFieIdtypo alone leaves no coordinate binding, so it draws the "Map configuration required" refusal (objectui#8169) rather than a map.The sweep (iii)
I re-derived the population with
git ls-treeplus agit grepfor amapkey. It covers objectuiexamples/apps/contentat40c076fc2dand objectstackexamples/appsat3cf6449389. I reconciled every hit by hand, and I did not reuse the old report's list.content/docs/plugins/plugin-map.mdxhas 13 brace-literal blocks plus themapConfigvariable in its TypeScript Support section.content/docs/fields/location.mdxhas 1. The schema-catalogplugin-mapJSON has 3 (event-venue-finder,real-time-delivery-tracking,store-locator-map). The one other grep hit is a catalog entry keyedmap(id/meta/schema), which is not a config block.titleField+locationField: the app-showcasetask.view.tsmap list view, andtask-map-marker-title.test.ts. The other hits are a translations label, the view keyedmap, and a comment, none of them a config block.SWEEPfixture, with each row naming its source by path and a quoted anchor, never a line address. The fixture header says the population is a snapshot. The three catalog entries are also re-read live and validated whole byObjectMap.catalogRecordSource-6939.test.tsx, which is green on head.The nested-document measurement
Measured with the built CLI (
packages/cli/dist/cli.js) against built@object-ui/types, on fixtures from the seat's scratchpad. For base, I rebuilt@object-ui/typeswith.strict()ablated. A dist preflight read theObjectMapConfigSchemacloser indist/zod/index.zod.jsas});, and afterwards I restored and rebuilt, and the closer read}).strict();again.objectui validate, root typo node: head exits 1:base exits 0 with
✓ Schema is valid!.objectui validate, the same node inside adiv'schildren: head exits 1. The top-level issue is generic, but the arm detail printed under it names the key:That is 1 of 10 arm sub-lines. The other nine are the non-matching arms (
expected object / string / number / boolean / null). base exits 0 with✓ Schema is valid!andChildren: 1.objectui check(advisory) over a directory holding the root typo, the nested typo, a root typo that also carriesclassName, and the clean node exits 0 on both sides:⚠️ 1 file carries a registered ObjectUI component type but did not validate as an ObjectUI schema, then prints✓ All checks passed.✓ All checks passed.checkvalidates only to recognise a file. A root that carries a structural key (children,className, …) is admitted without being validated, so the nested typo and theclassNametypo stay invisible tocheck. The command's own description sends the verdict toobjectui validate.⇒ The rendered refusal names the key at both depths, so under the ruling's condition this needs no follow-up card. The noise around the nested line is recorded in the Acceptance notes.
Gates
Everything below is at head
d68b1086ed. Test runs went throughos-verify-lock.sh, and every verdict line is quoted from that run.pnpm exec vitest run --maxWorkers=2 packages/types/ packages/cli/plus the 31 test files outside those packages that readObjectMapConfigSchema/ObjectMapSchema/FLAT_MAP_CONFIG_KEYSor author anobject-map(found withgit grep), plusexamples/schema-catalog/test/. Result:Test Files 358 passed (358),Tests 9311 passed (9311).pnpm exec vitest run --maxWorkers=2 packages/plugin-map/plus the new types pin:Test Files 34 passed (34),Tests 243 passed (243).pnpm --filter @object-ui/types type-check,@object-ui/plugin-map type-checkand@object-ui/cli type-check:VERDICT command-exit 0. Both new test files are in their package'stsconfig.test.json(--listFilesOnly, 1 hit each). Theplugin-map^...dependency closure was built first.strict-authoring-face-8345.test.ts,zod-mirror-parity.test.ts) are inside the types run above, and green.check-changeset-presence:✅ 3 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s).check-changeset-no-major:✅ No changeset declares a major bump.check-changeset-overwrite:✅ No pre-existing changeset was modified or deleted.check:changeset-claims(report-only) exits 0. It lists 22 pending changesets that name a file this change touches. I re-read the seven that mentionmap, strip or tolerance, and none describesObjectMapConfigSchema's accept set.check:pending-changeset-literals:✅.check:new-line-citations:VERDICT new-cross-file-line-citations: 0 new citation(s).check:control-bytes:✅ OK. A self-scan of the changed files for control bytes found none.check:spec-symbols:✅.check-doc-links:Links are valid across 17 scan roots.check:doc-fences,check:doc-types,check-prompt-component-keys,check:test-path-roots,check:vi-mock-specifiers: all✅.✅ NOT GOVERNED.--no-inline-config --format json: 0 errors, 0 warnings on the two new pins. The one warning inobjectql.zod.tspredates this change. This is a narrowed run: the config enables no type-aware linting, so this diff cannot move another file's verdict. The repo-wide lint is CI's.@object-ui/types/zodis not in the console's eager closure. The console build's own guard printed[plugin assert-types-zod-stays-lazy] ... 1 chunk(s) holding the validators, none in the eager closure, andpnpm check:eager-closurereads✅ Console eager closure is 3103.9 KB gzipped ... (budget: 3104.5 KB, headroom: 0.6 KB). That is the same reading the dispatch quoted, so the delta is 0.0 KB at the gate's precision.git merge-tree --write-tree origin/main HEADagainst a freshorigin/mainf667c1df97exits 0 (clean). None of the four commits that landed since the base touch these files.check:doc-snippets/check:doc-examples. Reason: they compile against every built package. This diff adds no code fence and changes no TypeScript declaration, so CI's run is the reading.Acceptance notes
safeParse, so nothing is warned. The ablation above shows it.FLAT_MAP_CONFIG_KEYSstays at 8 keys..shapehas 8 keys.FLAT_MAP_CONFIG_KEYSfilters outstyleand has 7, before and after.invalid_union, and nine of those lines describe arms that were never candidates. That is a readability note on the CLI's arm printer, not a missing diagnostic. I filed no card.objectui checkadmits a file whose root carries a structural key without validating it, so no depth ofmaptypo in such a file reachescheck. It is advisory by its own description. Recorded, not filed.warnOnTopLevelStyleUrlinObjectMap.tsxstill says@objectstack/speclist-view schemas "declare nomapblock at all". On spec 17.4.0,ListViewSchemadeclaresmap, and it refuseslatitudeFieIdwithunrecognized_keysatmap. That is a stale comment in a file this change does not touch. Noted, not fixed here, and no carrier.object-calendarnode'scalendarblock (spec-derived, kept.passthrough()) and plainz.objectconfig schemas such asSortConfigSchema,DrillDownConfigSchemaandReportExportConfigSchema. Not measured and not touched: the standing condition keeps generalisation out of this card.Generated by Claude Code