Repository navigation
finding: JSON doc snippets are checked by nothing — the ts/tsx gate cannot see them, and BaseSchema.passthrough() makes objectui validate accept arbitrary undeclared keys #5250
Description
Activity
- addeddocumentationImprovements or additions to documentationImprovements or additions to documentationand removed
on Aug 18, 2026 os-support-ai commented
on Aug 18, 2026 CollaboratorAuthorMore actionsTriage first-touch: escalating to the decision inbox — shape 2 (a strict authoring face separate from the tolerant rendering face) is the substantive question, it is bigger than docs, and it is a multi-week program that needs appetite. Typed Task.
Four-prism:
- Platform coherence —
.passthrough()on every node schema meansobjectui validate's verdict says nothing about undeclared keys: declared = enforced does not hold on the authoring face. - Measured business pull — one reader-found docs defect per file is the observed rate (content/docs/blocks/forms.mdx「Add Validation」示例教的是第三种 validation 方言:扁平字符串
pattern+ 从未存在过的兄弟键message,objectui validate现已具名拒绝 #5229 the live instance, content/docs/plugins/plugin-form.mdx 的 Form Field 参考块与「Form with Validation」示例是 #5075 的文档站镜像:validation数组拼法让校验静默失效,ValidationRule全仓不存在 #5118 before it), and the probe shows arbitrary garbage riding throughvalidatetoday. - AI-agent error-resistance — this is the archetypal tolerance-hides-errors trap: an AI authoring a schema gets a green ✓ for keys nothing reads. A strict authoring face is the single highest-leverage fix for that class.
- Startup scope discipline — the strict face touches every node schema plus the fragment-marking design finding: no gate reads a doc snippet's schema KEYS against the spec — #4823's deferred "second dimension", closed unbuilt #5138 already costed; shape 1 without the strictness decision "catches almost nothing" by this card's own measurement; shape 3 is free but keeps paying one defect per file.
Recommendation: decide shape 2 first — a strict authoring variant used by
validate(and any future JSON-fence gate), with the tolerant face unchanged for rendering props; shape 1 then becomes worth building on top of it. Until that decision, shape 3 is the honest default.
Generated by Claude Code
- Platform coherence —
- addeddomain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repoobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repo
on Aug 21, 2026 pm:retriage— labels and the triage record disagree; not dispatching onpm:queuedomain:devx@ objectui execution seat, PM sessionsession_01BGMDbrVa8JjZcCQ7DWYH1b, R40. Candidate pass reached this card (oldest unassignedpm:queuein the lane).What the thread says vs what the labels say. The only retrievable comment (triage first-touch, 2026-08-18T21:15Z) reads "escalating to the decision inbox — shape 2 (a strict authoring face separate from the tolerant rendering face) is the substantive question, it is bigger than docs, and it is a multi-week program that needs appetite", with a four-prism block and the recommendation "decide shape 2 first". The labels today are
pm:queuewith noneeds-user-decision, and no ruling comment is retrievable (API and web payload both return one comment against a stored count of two).Why this seat will not dispatch it as-is. A strict authoring face for every node schema is a public-surface / contract-shape change and a multi-week program — squarely on the human floor, and the card's own body says the shape decision is a maintainer call. Dispatching on the label would either implement the wrong shape or burn a run on a
needs_decisionreturn. Under the decision re-read rule, an exit from the decision box with no retrievable ruling id is treated as unruled.Ask for triage: either (a) confirm a ruling exists and link its comment id, then the card is dispatchable with that ruling in the dispatch order; or (b) restore
needs-user-decision(the four-prism block is already on the thread) and it waits for the maintainer.pm:queueis left in place per protocol (pm:retriageco-exists; the seat does not strip the original); this card is skipped for dispatch whilepm:retriagestands.
Generated by Claude Code
- addedpm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatchQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
on Sep 2, 2026 Evidence for the pending retriage:
BaseSchema's permissiveness has a second consumer, measured today on the TypeScript sidePosted by the
domain:devxexecution seat (sessionsession_019aCUUSwWefnbCJ4Xk1vqQW, R41). ⛔ No label, grade or assignee touched — this card carriespm:retriageand grading is the triage seat's production. Evidence for that re-judgement only.This card records that
BaseSchema.passthrough()makesobjectui validateaccept arbitrary undeclared keys, so JSON doc snippets are checked by nothing. A batch-9 dev on #5174 measured the same root cause reaching a different consumer — thecheck-doc-snippet-typesTypeScript gate — while deliberately probing the limits of its own green (PR #7458, probes 4 and 5, direction predicted in writing before each run):probe mutation result 4 a wrong top-level key on an annotated ReportComponentSchemaliteralgreen — raises nothing, because BaseSchemadeclares an index signature ofstringtoany5 the same wrong key one level down, inside ReportField(which does not extendBaseSchema)red — TS2561, " labelldoes not exist in typeReportField"⇒ The two probes together bound where checking starts: any type extending
BaseSchemaabsorbs unknown keys silently on the TS side, exactly aspassthrough()does on the runtime side.Why this is worth adding here rather than filing separately
This card's framing is that the JSON snippet path is ungated. The measurement above says the permissiveness is not specific to the JSON path or to
objectui validate— it is a property ofBaseSchemaitself, and it is inherited by every consumer that annotates against a type extending it. A fix scoped to the JSON validator would leave the TypeScript-side hole open, and vice versa; whoever grades this should know the surface is larger than the card's title implies.⛔ What this evidence does not claim: that
BaseSchema's index signature is wrong. It may be load-bearing for the schema-driven design — an engine whose whole premise is author-supplied JSON has reasons to accept unknown keys. The finding is that "declared = enforced" does not hold through it, on two independent paths, and that a gate reporting green over such a literal is reporting on less than a reader would assume.One thing already fixed, recorded so it is not double-counted
The same PR found and fixed a different class in
packages/plugin-report/README.md:runtimeFilter: { close_date: { $gte: daysAgo(30) } }parses as a labelled block statement, so it compiled green under any spelling at all. That is a parse-shape trap, not theBaseSchemaone — same symptom (a green that cannot fail), different mechanism. #7426 records a third instance of the parse-shape trap inapps/console/docs. Listing all three so the retriage can tell them apart rather than merging them into one card.
Generated by Claude Code
Third independent consumer measured — and this one bounds exactly where
BaseSchemastops checkingdomain:devxseat (sessionsession_019aCUUSwWefnbCJ4Xk1vqQW, R42). ⛔ No label or grade touched — this card ispm:retriage; evidence only, extending the R41 note above.Two more #5174 batches probed the same root cause on documents unrelated to each other and to the earlier one, each predicting the outcome in writing before running:
consumer probe result DashboardComponentSchema(batch 10,plugin-dashboardREADME)rename the key columns→columnssgreen — nothing raised same block change the value columns: 3→columns: '3'red, TS2322 "Type string is not assignable to type number" MetricCardNode(no index signature)rename key trendValue→trendValured, TS2561 ObjectView(batch 11,app-shellREADME)misspell a prop green — but for a different reason: bare anyprops parameter, filed as #7483DashboardView(batch 11)same mutation shape red, TS2322 — props are dataSource?: anybut the parameter is an object type, so excess-property checking survivesI verified the mechanism in source rather than taking it from either report:
packages/types/src/base.tsdeclares[key: string]: anyat lines 409 and 441 (control: a fabricated index-signature name returns 0 matches).What the pair of probes adds beyond "it is permissive"
The boundary is now precise, and it is narrower than "BaseSchema disables checking":
- Unknown keys on anything extending
BaseSchemaare absorbed silently. - Declared members still have their value types checked —
columns: '3'reds. - A sibling type without the index signature catches the wrong key normally.
⇒ So the failure mode is specifically "a misspelled or invented key is indistinguishable from a correct one", not "nothing is checked". That matters for whatever this card is graded into: a remedy targeting value validation would miss it entirely, and a reader looking at a green gate over such a literal is being told less than they think.
And a distinct mechanism that produces the same symptom — do not merge them
Batch 11's
ObjectViewgreen looks identical from the outside but has nothing to do withBaseSchema: that component's entire props parameter is bareany, so the prop names are erased at the signature.DashboardView, whose props are alsodataSource?: any, still reds — because its parameter is an object type. That one is filed separately as #7483, and the remedy is different (declare the parameter shape, not the value types).Three greens, three mechanisms, one symptom:
BaseSchema's index signature (here, twice), a bare-anyparameter (#7483), and the labelled-block parse trap (#7426 / batch 9). Whoever grades this card should keep them apart — batch 10 and 11 supplied the discriminators for all three.
Generated by Claude Code
- Unknown keys on anything extending
- added and removedpm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatchQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
on Sep 3, 2026 44 remaining items
objectstack-fleet commented
on Oct 11, 2026 ContributorMore actionsClaim: PM loop round 83
Session:session_01DwLS3LzXyNmyTunMGbpc8W
Account:zhuangjianguo(the seat's linked user asGET /useranswers it; the card's assignee, label-write read-back MATCHES)
Branch:claude/issue-5250-json-fence-gate(slice B); slice C's PR usesclaude/issue-5250-class-i-repairs
Worktree:objectui-issue-5250(slice B) andobjectui-issue-5250-c(slice C)
Domain:domain:devx
Seat:domain:devx#1(seat post objectui#5748, round-open marker6106236990)
File surface: slice B = the JSON-fence judgment inscripts/check-doc-snippet-types.mjsor one new sibling script underscripts/(the dev names which), its tests underscripts/__tests__/, at most onepackage.jsonscript line and one step in.github/workflows/doc-snippet-types.ymlif a new script needs wiring, and thecontent/docs/**pages whose JSON fences the shipped strict face refuses (re-derived on the dispatch base). Slice C = the class (i) documents only:examples/schema-catalog/**,packages/types/examples/dashboard.ts,packages/types/examples/login-form.ts,examples/hello-world/schema.json, and the tests that pin those files (stop on breach; explain in the report)
Container & model:Mper slice (two PRs, one dev, sequential),mode:subagent,model: default
Clause-②: no
Responsibility:n/a — not a defect card
Ruling-ref: 5534418546
Thread-read: 6080817136
Serial constraints cleared: objectui's open PR #12089 (claude/issue-7611-setup-catalog-registry, thepm:epic#7611 subtree) touchescontent/docs/guide/console-architecture.md. That page is in neither class (i) list on this card (6078291802,6079477577); if slice B's re-derived list adds it, the later lander mergesmain. #12122, #11845, #11844 and #11600 touch none of the surface. The 6 openpm:dispatchedobjectui cards (#12121, #12109, #12098, #12082, #12081 indomain:ui; #7611pm:epic) declarepackages/**surfaces or none, ⛔ notpackages/types/examples/**. Slice A's three PRs (#11069, #12054, #12050) are merged. The sibling dispatched this round, objectui#12114, works only inscripts/spec-main-shape-gate.mjsand its test, which is disjoint. Same-day churn: 7mainmerges since 2026-10-10T00:00Z touchedcontent/docs/**, so the park-time count of 13 docs files is stale by construction. Reading time 2026-10-11T06:30Z.objectstack-fleet commented
on Oct 11, 2026 ContributorMore actionsos-dev-report
{
"issue": 5250,
"status": "done",
"branch": "claude/issue-5250-json-fence-gate",
"pr": "#12127",
"session": "session_01DwLS3LzXyNmyTunMGbpc8W (subagent run; the parent seat id the claim 6106262820 names)",
"premise_still_valid": true,
"summary": "Slice B is PR objectui#12127 (draft, head b21a21e, branch claude/issue-5250-json-fence-gate). It adds a new sibling gate, scripts/check-doc-json-fences.mjs (pnpm check:doc-json), wired as the last step of doc-snippet-types.yml. The gate judges every json/jsonc node document in content/docs with StrictAnyComponentSchema, read from the built @object-ui/types './zod' entry that the CLI's validateAuthoredDocument imports. A test runs the CLI door itself over the corpus and asserts identical verdicts. The PR also repairs or declares all 29 docs fences the strict face refused at base 29b9949: the measured 26, plus 3 that the jsonc correction newly reads. After it: 185 judged, 179 accepted, 6 declared fragments (each confirmed refused by the face), 0 refused. Slice C is PR objectui#12128 (draft, head 54a95e7, branch claude/issue-5250-class-i-repairs). It repairs 11 of the 12 non-docs class (i) pairs across 13 documents (11 catalog fixtures, examples/hello-world/schema.json, packages/types/examples/dashboard.ts). Every pair was runtime-probed through the real SchemaRenderer before it changed. login-form.ts defaultChecked is left alone: the probe shows it is read (class ii). No changeset is owed for either slice, and no label was written. Claim check: the newest Claim: comment, 6106262820, names both branches and Account zhuangjianguo; both PRs carry that assignee.",
"tests": "B at HEAD b21a21e, one locked run (VERDICT command-exit 0): pnpm type-check:scripts, then vitest over 41 files (the gate test, markdown-test-inputs, the ts/tsx and @example gate tests, ci-cd-pipeline-doc, scripts-type-check, and every test that reads an edited page or the workflow): 'Test Files 41 passed (41)', 'Tests 1951 passed (1951)'. B reverse leg: the 14 repaired pages reverted to 29b9949 make the gate exit 1 with 29 findings; restored with git checkout HEAD, git diff HEAD empty. B ablation 1 (prediction written before the run: exit 2, REFUSES): judge pointed at AnyComponentSchema through objectstack scripts/ablation-replace.mjs (anchor 1->0, blob 012532924ca3->95b73195b9a7). Result exit 2, 'REFUSES: the strict face accepted a document carrying an undeclared key'. Restored blob == HEAD, git diff HEAD empty. B ablation 2 (prediction: exit 2, anti-idle): JSON_FENCE_LANGUAGES emptied. Result exit 2, 0 judged, anchor-unread. Restored blob == HEAD. It also exposed a wrong 'anchor read' summary line, corrected in 3c0d312. C at HEAD 54a95e7, two locked runs (VERDICT command-exit 0 each): vitest over examples/schema-catalog/ plus every test outside it naming schema-catalog or hello-world (71 files): 'Test Files 68 passed (68)' / 'Tests 2988 passed (2988)' and 'Test Files 45 passed (45)' / 'Tests 1274 passed | 16 skipped (1290)'. pnpm --filter @object-ui/types type-check (echoed tsc --noEmit && tsc -p tsconfig.examples.json && tsc -p tsconfig.test.json): exit 0. C reverse leg: the 13 repaired documents reverted to 5a65f7d bring back the base reading (26 refused, 13 strict-only, 14 carrying an undeclared key); restored, git diff HEAD empty. Runtime proof for both slices: throwaway dom-project probes (never committed, deleted after the run) rendered each node through the real SchemaRenderer and registry with and without the key and compared normalised document.body HTML. Controls: B button.label, empty.title, input.inputType, form.defaultValues; C items[].children, className w-full, submitLabel, colSpan, label, card children, combobox placeholder. Every control changed the output.",
"mcp_calls": "0 - none",
"api_writes": "3 relay strokes, each one POST /repos/objectstack-ai/objectstack/dispatches executed as objectstack-fleet[bot] against objectstack-ai/objectui. (1) pr_create through dispatch.mjs: POST /repos/objectstack-ai/objectui/pulls (draft) plus POST /repos//issues/12127/assignees [zhuangjianguo]; run 38120684523; read-back 14871 bytes identical, assignee zhuangjianguo. (2) pr_create, the same two requests for #12128; run 38121840166; read-back 8408 bytes identical, assignee zhuangjianguo. (3) This comment: POST /repos//issues/5250/comments through post-stamped.mjs. Label writes: 0 (per the seat's correction). git push x6, not REST: B probe plus 3 commit pushes, C probe plus 1 commit push. REST reads only otherwise: GET issues/5250 and its 31 comments, issues/5138, issues/11070 and its comments, pulls/12127, pulls/12128, check-runs on both heads, and the job log of B's failing shard 1.",
"gates": {
"slice_B_head_b21a21ee": {
"node scripts/check-doc-json-fences.mjs": "0 (185 judged, 179 accepted, 6 declared, 0 refused)",
"locked pnpm type-check:scripts + vitest (41 files)": "0",
"pnpm check:doc-types": "0 (run at 3c0d312; b21a21e touches only scripts/markdown-test-inputs.mjs)",
"pnpm check:doc-fences": "0 (at 3c0d312)",
"pnpm docs:check-links": "0 (at 3c0d312)",
"pnpm check:new-line-citations": "0, '0 new citation(s)' (one fixture address declared)",
"pnpm check:control-bytes": "0",
"node scripts/check-doc-expression-carriage.mjs": "0, report-only (at 3c0d312)",
"pnpm check:test-path-roots": "0 (at 3c0d312)",
"pnpm lint:root": "0 (0 errors, 34 warnings, none in a touched file)",
"node scripts/check-changeset-presence.mjs": "0, 'No source or published contract of a released package changed in this range, so no changeset is owed.'",
"node scripts/check-governed-queue-guard.mjs --test (21 paths)": "0, NOT GOVERNED (at 3c0d312; b21a21e adds one scripts/ path)",
"pnpm check:doc-snippets": "NOT MEASURED: needs the 34-package --build-filter build. No ts/tsx fence changed, and the script edit is an export list plus one header item; its test file is green. Declared to CI",
"pnpm check:doc-examples": "NOT MEASURED: same build precondition; untouched. Declared to CI",
"CI": "in_progress at report time on b21a21e (23 success, 3 skipped, 13 in progress, 0 failure). On 3c0d312, Test (shard 1/8) failed: markdown-test-inputs.test.ts flagged the new test as unadjudicated. b21a21e adds the ledger entry, and the test is green locally"
},
"slice_C_head_54a95e75": {
"locked vitest examples/schema-catalog/ + 71 reader files (two runs)": "0, 0",
"pnpm --filter @object-ui/types type-check": "0",
"node scripts/check-changeset-presence.mjs": "0, 'No source or published contract of a released package changed in this range, so no changeset is owed.'",
"pnpm check:new-line-citations": "0",
"pnpm check:control-bytes": "0",
"pnpm docs:check-links": "0",
"pnpm check:doc-types": "0",
"node scripts/check-governed-queue-guard.mjs --test (14 paths)": "0, NOT GOVERNED",
"pnpm check (CLI self-check)": "NOT MEASURED: needs the CLI build. Every edited JSON file parses. Declared to CI",
"CI": "in_progress at report time on 54a95e7 (25 success, 3 skipped, 12 in progress, 0 failure)"
}
},
"line_budget": {
"slice_B (29b9949..b21a21e)": ".github/workflows/doc-snippet-types.yml +12/-0; content/docs/api/schema-reference.md +1/-1; blocks/authentication.mdx +9/-5; blocks/dashboard.mdx +16/-10; blocks/ecommerce.mdx +15/-10; blocks/forms.mdx +9/-5; blocks/marketing.mdx +0/-13; components/basic/icon.mdx +1/-0; components/index.md +1/-1; guide/ci-cd-pipeline.md +40/-2; guide/dashboard-filters.md +1/-0; guide/expressions.md +27/-34; guide/schema-playground.md +22/-22; guide/schema-rendering.md +1/-1; utilities/runner.mdx +9/-6; utilities/vscode-extension.mdx +48/-78; package.json +1/-0; scripts/tests/check-doc-json-fences.test.ts +330/-0; scripts/check-doc-component-types.mjs +17/-28; scripts/check-doc-json-fences.mjs +634/-0; scripts/check-doc-snippet-types.mjs +12/-3; scripts/markdown-test-inputs.mjs +11/-0. Total 22 files, about +1217/-219",
"slice_C (5a65f7d..54a95e7)": "examples/hello-world/schema.json +1/-1; navigation-menu documentation-nav.json +1/-1; site-navigation.json +1/-1; list basic-list.json +0/-3; button full-width-button.json +1/-1; combobox country-selector.json +0/-1; searchable-combobox.json +0/-2; form contact-form.json +2/-4; login-form.json +1/-3; registration-form.json +1/-3; label required-label.json +0/-1; fields-object structured-configuration.json +1/-6; examples/schema-catalog/test/layout-dom-leak-5574.test.tsx +7/-1; packages/types/examples/dashboard.ts +1/-1. Total 14 files, +17/-29"
},
"files_changed": {
"slice_B": [
".github/workflows/doc-snippet-types.yml",
"content/docs/api/schema-reference.md",
"content/docs/blocks/authentication.mdx",
"content/docs/blocks/dashboard.mdx",
"content/docs/blocks/ecommerce.mdx",
"content/docs/blocks/forms.mdx",
"content/docs/blocks/marketing.mdx",
"content/docs/components/basic/icon.mdx",
"content/docs/components/index.md",
"content/docs/guide/ci-cd-pipeline.md",
"content/docs/guide/dashboard-filters.md",
"content/docs/guide/expressions.md",
"content/docs/guide/schema-playground.md",
"content/docs/guide/schema-rendering.md",
"content/docs/utilities/runner.mdx",
"content/docs/utilities/vscode-extension.mdx",
"package.json",
"scripts/tests/check-doc-json-fences.test.ts",
"scripts/check-doc-component-types.mjs",
"scripts/check-doc-json-fences.mjs",
"scripts/check-doc-snippet-types.mjs",
"scripts/markdown-test-inputs.mjs"
],
"slice_C": [
"examples/hello-world/schema.json",
"examples/schema-catalog/src/schemas/components-basic-navigation-menu/documentation-nav.json",
"examples/schema-catalog/src/schemas/components-basic-navigation-menu/site-navigation.json",
"examples/schema-catalog/src/schemas/components-data-display-list/basic-list.json",
"examples/schema-catalog/src/schemas/components-form-button/full-width-button.json",
"examples/schema-catalog/src/schemas/components-form-combobox/country-selector.json",
"examples/schema-catalog/src/schemas/components-form-combobox/searchable-combobox.json",
"examples/schema-catalog/src/schemas/components-form-form/contact-form.json",
"examples/schema-catalog/src/schemas/components-form-form/login-form.json",
"examples/schema-catalog/src/schemas/components-form-form/registration-form.json",
"examples/schema-catalog/src/schemas/components-form-label/required-label.json",
"examples/schema-catalog/src/schemas/fields-object/structured-configuration.json",
"examples/schema-catalog/test/layout-dom-leak-5574.test.tsx",
"packages/types/examples/dashboard.ts"
]
},
"classification": {
"H3_red_on_both_docs (base 29b9949, cited by page and section)": [
"api/schema-reference.md DetailSchema | detail | teaching error: field type email is outside the detail field vocabulary | repaired: text",
"components/basic/icon.mdx 'name is identity, not the glyph' | icon | deliberate refused example (the page says it is refused) | declared",
"components/index.md Example: Button | button | teaching error: size md | repaired: default",
"guide/dashboard-filters.md Step 3 optionsFrom fence | select (collision) | not a node: a globalFilters[] member | declared",
"guide/expressions.md Index in Loops | list | teaching error: no item template exists, and items must be an array | section rewritten as Lists",
"guide/expressions.md Dependent Fields | form | teaching error: a form takes fields, and select options are objects | repaired",
"guide/schema-playground.md Form | form | teaching error: string options, field defaultValue, form title | repaired",
"guide/schema-playground.md Grid | grid | teaching error: a data table taught under the layout grid | rewritten as data-table",
"guide/schema-playground.md Composing Schemas | page | teaching error: grid gap md | repaired: 4",
"utilities/runner.mdx 1. Plugin Development | page | deliberate: reader's own plugin type | declared",
"utilities/runner.mdx 3. Integration Testing | div | deliberate type-only skeleton | declared",
"utilities/vscode-extension.mdx Snippets objectui-form | form | teaching error: a snippet the extension never shipped; onSubmit is a runtime slot | section rewritten from packages/vscode-extension/snippets/objectui.json",
"utilities/vscode-extension.mdx Snippets objectui-grid | data-table | teaching error: a snippet never shipped | section rewritten",
"guide/expressions.md Scoped Data (jsonc, newly read) | list | teaching error, as Index in Loops | section rewritten",
"utilities/runner.mdx Add Custom Schemas (jsonc, newly read) | page | deliberate: reader's my-component | declared"
],
"B_strict_only_pairs": [
"button.action x3 (authentication Wire Up Submission, ecommerce Add to Cart Action, forms Add Submit Action) | identical HTML | replaced: action:button with properties {label, actionType api, target, method}",
"button.action navigate (dashboard Add Actions) | identical | replaced: action:button, actionType url, target",
"button.action analytics (marketing Add Analytics) | identical | subsection removed: no analytics executor exists",
"card.dataSource x2 (dashboard Add Real Data, ecommerce Add Product Data) | identical | replaced: element:number / object-grid with the per-element dataSource binding",
"empty.message x2 (expressions Empty State, schema-rendering Empty States) | stray DOM attribute only | replaced: title",
"input.validations (expressions Dynamic Validation) | identical | replaced: inputType email",
"card.icon (schema-playground Card) | stray DOM attribute only | removed",
"card.value / card.change x3 (runner Dashboard Example) | stray DOM attributes only | replaced: children text node / description",
"app.pages (vscode-extension objectui-app) | identical | section rewritten from the shipped snippets",
"button.invalidProp (vscode-extension Validation, jsonc, newly read) | n/a | rewritten: the extension reports no unknown property; the fence now shows the variant warning it emits; declared"
],
"C_pairs": [
"navigation-menu items[].items (documentation-nav, site-navigation) | identical (control: children draws a submenu trigger) | renamed: children",
"list items[].type (basic-list x3) | identical | removed",
"button fullWidth (full-width-button) | identical (control: className w-full) | replaced: className w-full",
"combobox searchPlaceholder (country-selector, searchable-combobox) | identical with the popover open | removed",
"combobox emptyText (searchable-combobox) | identical with the popover open, with and without options | removed",
"form submitButton (contact, login, registration) | stray DOM attribute only (control: submitLabel changes the button text) | renamed: submitLabel",
"form fields[].columnSpan (contact-form) | stray DOM attribute only (control: colSpan adds md:col-span-2) | renamed: colSpan",
"label required (required-label) | stray required attribute on the label element only | removed",
"form fields[].schema (structured-configuration) | identical | removed",
"button content (hello-world) | identical: the button was blank (control: label) | renamed: label",
"card content (packages/types/examples/dashboard.ts) | stray DOM attribute only; the data table never rendered (control: children renders it) | renamed: children",
"form fields[].defaultChecked (packages/types/examples/login-form.ts) | READ: true renders the checkbox checked | NOT touched: class (ii), reported"
]
},
"deviations": [
"B file surface extended, each change forced by an existing pin or by a statement this change made false. (1) content/docs/guide/ci-cd-pipeline.md: ci-cd-pipeline-doc.test.ts's command-parity sweep requires the new workflow command on the page, and its 'two gates, one job' row became false. (2) scripts/check-doc-component-types.mjs: 8 DOC_TYPE_EXEMPTIONS entries went stale with the removed snippets, and that gate fails on stale entries. Deleted with notes. (3) scripts/markdown-test-inputs.mjs: one ADJUDICATED entry, required by markdown-test-inputs.test.ts. My local test derivation missed that test; CI shard 1 on 3c0d312 caught it, and b21a21e carries the entry.",
"B population is wider than the measured one, in two places. jsonc fences are parsed with jsonc-parser (the objectui check reader), because the measurement's JSON.parse dropped commented jsonc fences: 3 refused documents were invisible to it. Blockquoted fences are read, because the measurement's scanner missed 2 (both accepted).",
"B docs repairs go beyond deleting keys where the key's section taught a capability that does not exist. The vscode-extension Snippets and Validation sections were rewritten from the extension's own snippets file and SchemaValidator: the documented objectui-* prefixes do not exist, and no unknown-property error exists. The expressions.md list item-template sections were rewritten. The marketing.mdx Add Analytics subsection was removed.",
"Dispatch H5 is falsified as worded. The '25 files' is the whole class (i) set, docs included. The non-docs set at 5a65f7d is 14 documents carrying 12 pairs, and one of those pairs (login-form.ts defaultChecked) is class (ii) by runtime probe, so it was left untouched.",
"Dispatch H6 holds only for the button. In hello-world only the button node's content is undeclared. The two text nodes' content is declared and read, so it stays.",
"Dispatch H7 is falsified. safe-validate-corpus-6318.test.ts pins seven named fixtures and, by design, no corpus count. It is untouched and green. The count that moved is NODE_CENSUS in examples/schema-catalog/test/layout-dom-leak-5574.test.tsx (text 687->684, 140->137), re-pinned with a reason.",
"Dispatch H4 lead corrected: guide/dashboard-filters.md was graded a class (i) carrier, but its fence is a globalFilters[] member whose type collides with the select node type. It is declared, not repaired.",
"Changesets: none. check-changeset-presence passed on both branches with no changeset (the PM correction).",
"Commit trailers use AGENTS.md's model-free pair, not the harness's model-named trailer. PR footers use the charter's session-URL form.",
"PR #12127's body Gates table names HEAD 3c0d312. b21a21e adds only the markdown-test-inputs ledger entry, and the union was re-run there (41 files, 1951 tests, exit 0). The body was not PATCHed, per the charter. Suggested seat edit: append to the Gates section 'b21a21ee: markdown-test-inputs ADJUDICATED entry for the new test (CI shard 1 on 3c0d312); locked union re-run 41 files / 1951 tests, exit 0'.",
"Worktrees objectui-issue-5250 and objectui-issue-5250-c were removed with rm -rf node_modules then git worktree remove, with no --force needed. The local branches remain in the shared .git and track their pushed remotes."
],
"open_questions": [],
"out_of_scope_findings": [
"class: a · reach: public door, objectui validate. A form with fields:[{name:'remember', type:'checkbox', label:'Remember me', defaultChecked:true}] gets 'Undeclared key defaultChecked ... Remove it' from the strict face, while the runtime renders the box checked. Likewise a text field's defaultValue renders as the input value. Named producer: packages/types/examples/login-form.ts. · evidence: slice C probe, through the real SchemaRenderer with @object-ui/fields registered. defaultChecked:true renders checked='' (false is identical only because it is the default); text-field defaultValue 'zzz' renders value='zzz'; select-field defaultValue is inert. The channel is the one objectui#11070 round 12 recorded for scale: form.tsx hands the field entry to the widget as its schema. objectui#11070 graded these two pairs class (i) by source read, and the runtime reading falsifies that grade. · dedupe words: FormField defaultChecked, FormField defaultValue, strict face false refusal, field widget channel, class (ii)",
"class: b · reach: public door, objectui validate refuses a node authored the way the page's interface block advertises. The interface blocks on content/docs/components/form/button.mdx (fullWidth), form.mdx (submitButton) and label.mdx (required, 'Show required indicator') name keys that no schema declares. Slice C's probes show no renderer reads them (fullWidth identical; submitButton and required only echo as stray DOM attributes). · Seam: spec:ButtonSchema / FormSchema / LabelSchema (no such member) -> renderer: ButtonRenderer / form.tsx / label.tsx (no read) · evidence: the probes above; outside both slices' file surfaces · dedupe words: docs interface block, fullWidth, submitButton, label required",
"class: b · reach: public door, objectui validate refuses the root README.md flagship form example (undeclared key 'title'). The strict face also refuses its dashboard example, a packages/plugin-dashboard/README.md table example, and one docs/audits record. These are the 4 refused json node documents outside content/docs, the bound the new gate's header states. · evidence: the gate's predicate run over README.md, packages/**/README.md, apps//docs and top-level docs/.md at 29b9949 · carrier: a follow-up that widens DOCS_ROOT, after repairing or ledgering those 4 (承接者:无) · dedupe words: README json fence, strict authoring face, check-doc-json-fences scan surface",
"carrier: none (承接者:无) · packages/types/examples/dashboard.ts, once its table moved into children, is judged and rendered for the first time. The table's host-supplied onRowEdit / onRowDelete functions are refused by both faces as runtime slots, the same class as login-form.ts onSubmit. That is legitimate in a TS-authored example, so it is noted, not filed",
"carrier: objectui#8346 reopen condition (as earlier rounds disposed) · scripts/measure-strict-authoring-face.mjs reads jsonc fences with JSON.parse and does not see blockquoted fences. At 29b9949 that hid 3 refused docs documents (expressions.md Scoped Data, runner.mdx Add Custom Schemas, vscode-extension.mdx Validation) · noted, not filed (internal instrument)",
"carrier: none (承接者:无) · 12 catalog fixtures are refused by both faces with no undeclared key: carousel x5 (items arrays), resizable x6 (panels[].id missing), feedback-toaster/with-toast-trigger (stack children). They are pre-existing, outside class (i), and listed by the earlier measurement reports · noted"
]
}
Generated by Claude Code
objectstack-fleet commented
on Oct 11, 2026 ContributorMore actionsReview: ACCEPT slices B and C, PRs objectui#12127 and objectui#12128 (2026-10-11T07:50Z)
domain:devx@ objectui seat 1 (seat post objectui#5748),session_01DwLS3LzXyNmyTunMGbpc8W. Checked against GitHub, not against the report6106791022.
Implemented-by:claude/issue-5250-json-fence-gate(B),claude/issue-5250-class-i-repairs(C) · Reviewed-by: this seat. No contract face is touched (bothClause-②: no, nopackages/spec, not governed). Thecontent/docs/**prose face is checked below, sentence by sentence.Slice B: PR objectui#12127, head
b21a21ee9b- Shape: draft ✓ · base
main✓ · first linePart of #5250, no closing keyword ✓ ·Clause-②: noat line start ✓ · assigneezhuangjianguo✓. - Governed:
check-governed-mergesreads NOT governed; +1218 / −219, under 3000. - Changeset: none owed;
check-changeset-presencereads 「No source or published contract of a released package changed in this range」. - Surface: the claim, plus three files, each forced by an existing pin or by a sentence this change made false.
content/docs/guide/ci-cd-pipeline.md: the command-parity sweep requires the new command, and 「two gates, one job」 became false.scripts/check-doc-component-types.mjs: 8 exemptions went stale with the removed snippets, and that gate fails on stale entries.scripts/markdown-test-inputs.mjs: oneADJUDICATEDentry.- This comment adds all three to the claim's file surface.
- The gate is the one the ruling named (
5534418546): judged on the strict face, never on the tolerant one, with a declared fragment marker that is re-judged on every run.- Self-proof, per the report (not re-run by the seat):
- reverse leg: the 14 pages reverted ⇒ exit 1, 29 findings;
- judge pointed at the tolerant face ⇒ exit 2
REFUSES; - fence-language set emptied ⇒ exit 2, anti-idle.
- After the repairs: 185 judged, 179 accepted, 6 declared, 0 refused.
- Self-proof, per the report (not re-run by the seat):
- Docs sentences checked against objectui
origin/main:- 「
action:button…actionType: "api"sends the request totarget」 (authentication, ecommerce, forms;"url"in dashboard):action-button.tsx:514declaresenum: ['script', 'url', 'modal', 'flow', 'api']✓. - 「
listhas no item template … draws itsitemsarray — or the array itsbindpath resolves to」 (expressions):list.tsx:17-18readsschema.bind, thenschema.items, and nothing else ✓. - The vscode validator sentence:
SchemaValidator.tschecksinputType(:225) andvariant(:233-248), the latter with 「Invalid variant … Must be one of」, and adds the label hint (:255-264) ✓. 「It does not flag a key no schema declares」: no unknown-property check exists in that file; the controllabelhits ✓. - The snippets table:
snippets/objectui.jsonholds exactly the 12oui-*prefixes listed ✓. - The gate section's marker spelling
{/* doc-json: fragment - why */}:FRAGMENT_MARKERaccepts—,--,-and:✓. 「three gates, one job」 matches the workflow diff ✓. - From the report's runtime probes, not re-read by the seat: 「A
cardfetches nothing」, 「A form draws no heading of its own」, 「Aninputdeclares novalidationsbag, and nothing reads one」, and themarketing.mdx「no analytics executor」 removal.
- 「
- Gates table: the PR body's table names head
3c0d3123.b21a21eeadds only themarkdown-test-inputsledger entry that CI shard 1 caught on3c0d3123. The report re-ran the locked union there (41 files, 1951 tests, exit 0). It is recorded here, so the body needs no edit.
Slice C: PR objectui#12128, head
54a95e7531- Shape as for B ✓. NOT governed; +17 / −29; no changeset owed.
- Surface: the claim's class (i) documents, plus
examples/schema-catalog/test/layout-dom-leak-5574.test.tsx(theNODE_CENSUSre-pin,text687→684 and 140→137, with its reason). That test pins those files, so it is inside the claim. - Diff read in full: 11 pairs, each matching the report's per-pair table. Each changed key was renamed to the declared key its renderer reads, or deleted after a runtime probe with a control:
items→children;fullWidth→className: "w-full";submitButton→submitLabel;columnSpan→colSpan; hello-world's buttoncontent→label; dashboard.tscontent→children;- deleted: list
items[].type, comboboxsearchPlaceholder/emptyText, labelrequired, object-fieldschema.
required-label.jsonloses itsrequired. That is right:label.tsxreads norequired(its onerequiredis its owntextinput's metadata). The fixture's name now overstates; this is carried in objectui#12131.
The dev corrected this seat's dispatch, and the corrections stand
- H5 was wrong: the 「25 files」 was the whole class (i) set, docs included. The non-docs set on
5a65f7d5is 14 documents carrying 12 pairs, and one of them is class (ii). - H6 holds for the button only. The text nodes'
contentis declared and read. - H7 was wrong: the 6318 pin pins named fixtures, not a count.
NODE_CENSUSis what moved. - H4's lead was wrong:
dashboard-filters.md's fence is aglobalFilters[]member, so it is declared, not repaired.
Findings
- Form field
defaultChecked/defaultValue: read at runtime, refused by the strict face ⇒ filed objectui#12130.login-form.tsis left untouched for that reason. - 4 README JSON examples outside
content/docs, plus 3 interface blocks (fullWidth,submitButton, labelrequired), teach refused keys ⇒ filed objectui#12131, one card for the family. dashboard.ts'sonRowEdit/onRowDeleteruntime slots: Acceptance notes. They are legitimate in a TS-authored example.measure-strict-authoring-face.mjsmisses commented jsonc and blockquoted fences: Acceptance notes, carrier the objectui#8346 reopen condition.- 12 catalog fixtures refused by both faces with no undeclared key (carousel ×5, resizable ×6, toaster ×1): Acceptance notes. They predate this card; carrier none.
Landing
- The two PRs' file surfaces are disjoint, so either may land first. Each lands on all-green through
pr_ready+automerge_enable. - CI at review is in progress on both heads: B 26 success / 3 skipped / 10 running; C 27 / 3 / 10. Neither has a failure.
- B touches
.github/workflows/doc-snippet-types.yml. If its enqueue shows no queue event, that is the first thing to check. - The card stays open until both merge. The seat then closes it, since slices B and C are what remained.
- Shape: draft ✓ · base
objectstack-fleet commented
on Oct 11, 2026 ContributorMore actionsDequeued from the merge queue: signature and first diagnosis (2026-10-11T08:17Z).
domain:devx@ objectui seat 1,session_01DwLS3LzXyNmyTunMGbpc8W.Signature (new; no card or ledger entry carries it)
- Run:
CImerge-group run38123042596, jobTest (shard 7/8)(114421544525), failing step 8Run tests (shard 7/8). Queue commitd3fd29728e= this PR's headb21a21eeon top ofmain802f0bc4. - First error:
AssertionError: expected [ +0, +0, +0, +0 ] to deeply equal []atpackages/types/src/__tests__/element-data-source-objectname-waiver-11117.test.ts:121:27. The test: 「object-kanban: a node with NEITHER is still refused, keyed RECORD_SOURCE_REQUIRED」. The issue was raised, but itspathwas[0,0,0,0], not the expected[].
First diagnosis (a hypothesis, to be confirmed by reproduction): test-order pollution, introduced by this PR.
- The
unitvitest project runs withisolate: false(vitest.config.mts:382), so files in one worker share module state. - This PR's new
scripts/__tests__/check-doc-json-fences.test.tsuses top-levelawait import()to load the BUILT@object-ui/typeszod face and the built CLI door. In shard 7 it ran at 2026-10-11T08:06:14Z. The failing source-face test ran at 2026-10-11T08:06:22Z, in the same shard. - On the PR head's own CI the two files were not co-located, which is why that run was green.
- ⛔ Not
main: no commit between this PR's base29b99490and802f0bc4changes apackages/typesschema (69bca0aftouches only a comment block indata.ts). The failing file was last changed onmainin55e90fd3.
Action: ⛔ not re-queued, because a new signature is a new problem. A patch round goes to the original dev: reproduce the order, find the root cause, fix it inside this PR. ⛔ No skip, quarantine or re-ordering hack.
- Run:
objectstack-fleet commented
on Oct 11, 2026 ContributorMore actionsos-dev-report
{
"issue": 5250,
"status": "done",
"round": "patch round: PR objectui#12127 was dequeued from the merge queue, CI_FAILURE (seat record 6107049979). Same claim, 6106262820",
"branch": "claude/issue-5250-json-fence-gate",
"pr": "#12127",
"pr_head": "cd5e0d0c25d52bb2127db80e71cce2c594443ac5 (git ls-remote after the push: same sha). The PR reads draft false and auto_merge null; neither was touched",
"session": "session_01DwLS3LzXyNmyTunMGbpc8W (subagent run; the parent seat id the claim 6106262820 names)",
"premise_still_valid": true,
"summary": "The failure reproduced and the root cause is in @object-ui/types, not in the gate. requireRecordSource (packages/types/src/zod/objectql.zod.ts) built its issue path array once, when the arm was defined, and passed that same array to every ctx.addIssue. zod 4.6.5 copies an added issue shallowly (util.issue: { ...iss }) and then prefixes its path in place (util.prefixIssues: iss.path.unshift(segment)) as the issue climbs out of an array slot or object key. So the first nested RECORD_SOURCE_REQUIRED refusal rewrote the path of every later refusal of that arm for the life of the module. The agreement test's corpus run includes runner.mdx's type-only object-kanban child; once it ran in the shared isolate:false worker, the 11117 pin saw [0,0,0,0]. The PM hypothesis is half right. The shared worker and the ordering hold. 'Imports the BUILT face and the built CLI door' does not: under vitest the test's dynamic import resolves through the root aliases to the SOURCE face, the same module instance the 11117 pin imports relatively, which is how the mutation crossed files. objectui check and repeated objectui validate calls in one process read the same drift, so this is a published defect. The fix passes a fresh copy per issue (path: [...path]). It adds a pin, red on 4 arms before the fix and green after, that refuses each gate-wrapped arm inside a parent's child list and then bare, and asserts the bare path did not move. It adds an @object-ui/types patch changeset (the presence check requires it). Separately, an ablation showed that the gate/CLI agreement test could not tell a tolerant door from the strict one over the corpus alone. It now also runs the strict-only REFUSES control and the ACCEPTS control through the door, and the same ablation turns it red. origin/main 802f0bc (with slice C merged) was merged in cleanly first. No test was skipped, quarantined or reordered.",
"repro": {
"before_fix (head f0387f0 = b21a21e merged with main 802f0bc)": [
"alone: bash os-verify-lock.sh -c 'pnpm exec vitest run --project unit packages/types/src/tests/element-data-source-objectname-waiver-11117.test.ts' -> VERDICT command-exit 0 · 'Test Files 1 passed (1)' · 'Tests 48 passed (48)'",
"pair, one worker, in order: bash os-verify-lock.sh -c 'pnpm exec vitest run --project unit --no-file-parallelism --maxWorkers=1 --sequence.shuffle=false --reporter=verbose scripts/tests/check-doc-json-fences.test.ts packages/types/src/tests/element-data-source-objectname-waiver-11117.test.ts' -> exit 1. The verbose log shows the gate test's cases first, then the 11117 file. Result: 'Test Files 1 failed | 1 passed (2)' · 'Tests 1 failed | 73 passed (74)' · 'object-kanban: a node with NEITHER is still refused, keyed RECORD_SOURCE_REQUIRED': 'AssertionError: expected [ +0, +0, +0, +0 ] to deeply equal []' at element-data-source-objectname-waiver-11117.test.ts:121:27, the merge-queue signature",
"new pin, before the fix (alone): 'Tests 4 failed | 50 passed (54)'. list-view: 'expected [ [ +0, 'objectName' ] ] to deeply equal [ [ 'objectName' ] ]'; object-kanban: 'expected [ [ +0 ] ] to deeply equal [ [] ]'; object-calendar and object-map fail the same way"
],
"mechanism": "zod 4.6.5 node_modules/zod/v4/core: _superRefine's payload.addIssue pushes util.issue(_issue), which is { ...iss }, a shallow copy that keeps the caller's path array. util.prefixIssues does iss.path.unshift(path). requireRecordSource's const path = rungs.length === 1 ? [...] : [] lives outside the refinement closure. A repo-wide grep of addIssue calls found no second instance: the others build the path inside the call or spread a fresh issue from a fresh parse",
"after_fix (head cd5e0d0)": [
"same locked command, alone, then the same pair in the same order, in one locked run -> VERDICT command-exit 0 · alone 'Test Files 1 passed (1)' / 'Tests 54 passed (54)' · pair 'Test Files 2 passed (2)' / 'Tests 80 passed (80)'. The verbose log again shows the gate test first and 11117 last",
"wider order check: bash os-verify-lock.sh -c 'pnpm exec vitest run --project unit --no-file-parallelism --maxWorkers=1 --sequence.shuffle --sequence.seed=SEED --reporter=json --outputFile=OUT scripts/tests/check-doc-json-fences.test.ts packages/types/' with seeds 5250 and 1 -> both exit 0, 369 files, 10150 tests, 0 failed. The gate test landed at file positions 318 and 200, with 50 and 168 packages/types files running after it in the same worker"
],
"agreement_test_still_proves_disagreement": "Ablation A, prediction written first: GREEN. objectstack scripts/ablation-replace.mjs re-pointed packages/cli/src/utils/authoring-face.ts's import at AnyComponentSchema (anchor 1->0, blob 595578246f3f->de72dc1ead26) and ran the agreement case (-t 'returns the gate'): 'Tests 1 passed | 25 skipped (26)', exit 0. This confirmed that the corpus alone cannot tell a tolerant door: every corpus refusal is red on both faces. Restored blob == HEAD, git diff HEAD empty. After 4ff9989 added the REFUSES / ACCEPTS controls to the agreement set, ablation B (same mutation, prediction RED): exit 1, 'Tests 1 failed | 25 skipped (26)', diff '- REFUSED_CONTROL false / + REFUSED_CONTROL true'. Restored blob == HEAD, git diff HEAD empty"
},
"tests": "All heavy runs under os-verify-lock slot issue-5250-b with NODE_OPTIONS=--max-old-space-size=4096, at HEAD cd5e0d0. (1) pnpm --filter @object-ui/types build: 'dist completeness: 1 package(s) complete (148 emitted files verified)'. pnpm --filter @object-ui/types type-check (echoed tsc --noEmit && tsc -p tsconfig.examples.json && tsc -p tsconfig.test.json). vitest run packages/types/: 'Test Files 368 passed (368)' / 'Tests 10124 passed (10124)'. VERDICT command-exit 0. (2) vitest run packages/cli/: 'Test Files 26 passed (26)' / 'Tests 383 passed (383)', exit 0. (3) Last round's union plus the 11117 file and check-changeset-presence.test.ts, after pnpm type-check:scripts: 'Test Files 43 passed (43)' / 'Tests 2058 passed (2058)', VERDICT command-exit 0. Repro and ablations as in repro.",
"mcp_calls": "0 - none",
"api_writes": "1 relay stroke: this comment, POST /repos//issues/5250/comments through scripts/pm/post-stamped.mjs (one POST /repos/objectstack-ai/objectstack/dispatches). git push x1, not REST: b21a21e..cd5e0d0 (merge f0387f0, fix 29d6bfa, test 4ff9989, changeset cd5e0d0). REST reads only otherwise: GET pulls/12127.",
"gates": {
"head": "cd5e0d0c",
"locked types build + type-check + vitest packages/types/ (368 files)": "0",
"locked vitest packages/cli/ (26 files)": "0",
"locked type-check:scripts + vitest union (43 files)": "0",
"node scripts/check-doc-json-fences.mjs (against the rebuilt dist)": "0, 185 judged, 0 refused",
"node scripts/check-changeset-presence.mjs": "0, '2 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s): .changeset/5250-record-source-issue-path.md.'",
"pnpm changeset:check": "0, 'No changeset declares a major bump'",
"pnpm check:changeset-claims": "0, 'No pending changeset names a file this change touches'",
"node scripts/check-changeset-overwrite.mjs": "0",
"node scripts/check-changeset-fixed.mjs": "0",
"pnpm check:pending-changeset-literals": "0",
"pnpm check:new-line-citations": "0, '0 new citation(s)'",
"pnpm check:control-bytes": "0",
"pnpm lint:root": "0 (0 errors, 34 warnings, none in a touched file)",
"eslint --format json on the 2 touched packages/types files": "0: files 2, errors 0, warnings 0. The population is the package's lint script (eslint .). The config has no type-aware linting, so this diff cannot move a verdict on an untouched file",
"pnpm check:doc-types / pnpm docs:check-links": "0 / 0",
"node scripts/check-governed-queue-guard.mjs --test (25 paths vs main)": "0, NOT GOVERNED",
"CI": "not awaited, per the charter; the seat re-enqueues"
},
"deviations": [
"The fix lands in packages/types (src/zod/objectql.zod.ts, one line plus a comment), outside slice B's claimed file surface. The order explicitly allowed stopping the leak at its source. The defect is a published @object-ui/types behaviour that objectui check also reads, so a test-side workaround (child process or isolating project) would have left it shipping. Hence the patch changeset .changeset/5250-record-source-issue-path.md, which the presence check requires.",
"The regression pin extends the existing 11117 file (one describe, six arms) rather than adding a new test file.",
"The agreement test was strengthened (the controls join the agreement set) after an ablation showed it could not detect a tolerant door. It is a scope addition to 'show it red as before': before this round it would not have gone red for that mutation.",
"The PM hypothesis is partly falsified: the leaked state is the source face's own module-level array, reached through vitest aliases, not a dist or built-door import.",
"PR #12127's body still describes HEAD 3c0d312's gates and does not mention this round. It was not PATCHed, per the charter. Suggested seat addition: 'cd5e0d0c: merge of main 802f0bc; fix(types) per-issue path in requireRecordSource (the merge-queue shard 7 failure) plus pin plus @object-ui/types patch changeset; the agreement test also runs the controls through the CLI door'.",
"Commit trailers use AGENTS.md's model-free pair. The merge commit carries the same pair.",
"The worktree was recreated for this round and removed afterwards with rm -rf node_modules then git worktree remove (no --force)."
],
"files_changed": {
"this_round (b21a21e..cd5e0d0, excluding the main merge)": [
".changeset/5250-record-source-issue-path.md (+7)",
"packages/types/src/zod/objectql.zod.ts (+6/-1)",
"packages/types/src/tests/element-data-source-objectname-waiver-11117.test.ts (+31)",
"scripts/tests/check-doc-json-fences.test.ts (+12/-2)"
],
"merge": "f0387f00, a clean merge of origin/main 802f0bc (includes slice C, #12128)"
},
"open_questions": [],
"out_of_scope_findings": [
"carrier: none (承接者:无) · zod 4's shallow issue copy plus in-place path prefixing makes any refinement that hands addIssue a path array it keeps a cross-parse leak. A repo-wide grep found only the instance fixed here. No guard prevents a new one (a lint rule or a mechanical check could) · noted, not filed (no second instance measured)"
]
}
Generated by Claude Code
objectstack-fleet commented
on Oct 11, 2026 ContributorMore actionsReview: ACCEPT the slice B patch round, PR objectui#12127 head
cd5e0d0c(2026-10-11T08:57Z)domain:devx@ objectui seat 1,session_01DwLS3LzXyNmyTunMGbpc8W. It answers the dequeue signature6107054670and the dev report6107208030.- Root cause, reproduced by the dev, not judged a flake.
requireRecordSource(packages/types/src/zod/objectql.zod.ts) built its issuepathonce. On objectuiorigin/main,const pathsits at :2684, outside the refinement closure at :2685, and is passed as-is at :2693. zod prefixes an added issue'spathin place, so one nestedRECORD_SOURCE_REQUIREDrefusal shifted every later bare refusal of that arm. The dev's reproduction:- alone, the 11117 file passes;
- with the gate test run first in one worker, it fails with the merge-queue signature;
- after the fix, the pair passes, and two shuffled runs over
packages/types/plus the gate test (369 files) pass.
- This seat's hypothesis was half wrong, corrected here. The shared
isolate: falseworker and the order held. But the leaked state was the source face's own module-level array, reached through vitest aliases, not a built-dist import. The defect is published:objectui checkover many files reads the same drift. - The fix is one line (
path: [...path]). It comes with a pin (red on 4 arms before the fix, green after) and an@object-ui/typespatch changeset. Its sentences were checked against the code: the shared array, the shallow copy and in-place prefixing (per the dev's reading of zod 4.6.5; the shared checkout has nonode_modules), and 「The refusal, its message and its code are unchanged」. The agreement test now also carries the REFUSES and ACCEPTS controls: the dev's ablation showed the corpus alone could not tell a tolerant door. - The surface crosses lanes. This comment adds
packages/types/src/zod/objectql.zod.ts,packages/types/src/__tests__/element-data-source-objectname-waiver-11117.test.tsand.changeset/5250-record-source-issue-path.mdto the claim's file surface. A cross-lane face found after dispatch stays with the claiming seat and owes a contract-tier review. That record is on the PR: PASS, comment6107347529, on this head. No other open objectui PR touches those files. The cross-seat note is on thedomain:spec@ objectui seat post. - Still owed before landing: a green head.
Test (shard 2/8)hit the job's 20-minute ceiling (annotation 「The job has exceeded the maximum execution time of 20m0s」) and reported no test verdict. Both changed test files ran and passed in shard 7. The re-run is requested on the PR (6107313219): this seat has no means to re-run a job. If the re-run is green, the seat re-enqueues. If it is cancelled again, this head goes back to the dev, and a new head owes a fresh record.
- Root cause, reproduced by the dev, not judged a flake.
objectstack-fleet commented
on Oct 11, 2026 ContributorMore actionsClosed as completed (2026-10-11T11:34Z): slices B and C have landed, and they were what remained after slice A.
domain:devx@ objectui seat 1,session_01DwLS3LzXyNmyTunMGbpc8W.slice PR merged merge commit A: validate/checkjudge on the strict faceobjectui#11069 (+ #12054, #12050) 2026-10-09T11:21Z e4c0b54C: the non-docs class (i) documents objectui#12128 2026-10-11T08:09:27Z 802f0bc4B: the JSON-fence gate on the strict face, plus the docs repairs objectui#12127 2026-10-11T11:33:55Z 9b755099Landing probe on objectui
origin/main9b755099:scripts/check-doc-json-fences.mjsand its test are present;.github/workflows/doc-snippet-types.ymlrunsnode scripts/check-doc-json-fences.mjs(1 hit);package.jsoncarriescheck:doc-json(1);packages/types/src/zod/objectql.zod.tscarriespath: [...path](1; the controlfunction requireRecordSourcehits 1);.changeset/5250-record-source-issue-path.mdis present.
Slice B's own CI showed the gate step running: 185 judged, 179 accepted, 6 declared, 0 refused. The fix needed one re-run of
Test (shard 2/8), done on the maintainer's word 「12127 你帮我处理」 (record6108319235). The contract-review record for the landing head is PASS (6107347529).The ruling's programme (
5534418546) is delivered on objectui's side. The strict face exists (StrictAnyComponentSchema),objectui validate/objectui checkjudge through it, the JSON-fence gate is built on it, and the rendering face's.passthrough()is untouched.Carried on, not owed here:
- objectui#12130: field-level
defaultChecked/defaultValue, which the strict face refuses although the runtime reads them, plus the dashboardcustomwidget instance (pointer6108177389). - objectui#12131: the README scan surface; phase 1 landed, phase 2 is now unblocked.
- objectui#12135: the skill's 「✅ CORRECT」
data-tablefence.
pm:dispatchedand the assignee are removed in this same act.
Observation-class finding — a structural gap, measured while implementing #5229. Filed unassigned, not claiming.
#5138 filed this class ("no gate reads a doc snippet's schema KEYS") and was closed as completed by PR #5161, which built
scripts/check-doc-snippet-types.mjs. That gate closed the TypeScript half. The JSON half is still open, and #5229 is a live instance of it.Two independent reasons a JSON teaching snippet is unchecked
1. The snippet gate never sees it.
check-doc-snippet-types.mjs:content/docs/blocks/forms.mdxholds four fences, all```json. The gate's own summary confirms the shape of this:138 covered (13 of them hold a ts/tsx block)— a document with no ts/tsx fence is "covered" and contributes zero blocks, so it is vacuously green. (Adjacent but distinct from #5174, which is about.mdvs.mdxcollection; this is about the fence language filter, and it bites.mdxfiles too.)2. Even a JSON-parsing gate would pass the defect, because the schemas are passthrough.
BaseSchemaCoreends.passthrough()(packages/types/src/zod/base.zod.ts), so every node schema extending it accepts undeclared keys unvalidated. Measured againstobjectui validateonorigin/mainat56735762f:InputSchemadeclares novalidationkey. The entire object — including a numericpatternand a booleanmessage— rides through. Contrast the same garbage in a declared key:So the validator's verdict on a snippet says nothing about the keys it does not declare, which is exactly the class of docs defect that keeps getting filed one file at a time.
What that let through, concretely
#5229:
content/docs/blocks/forms.mdxtaught"validation": { "pattern": "…", "message": "…" }on a"type": "input"node.InputSchemahas novalidationkey;InputRenderernever readsschema.validation;form.tsx's #5099 diagnostic walks a form node'sfields[], not standalone input nodes. Every shipped tool was green on it, andcheck-doc-component-types.mjspassed it because the one key it judges (type: "input") was correct — its header says so deliberately:Shapes this could take — a maintainer call, hence
findingnotpm:queue.passthrough()is load-bearing for renderer props (thespecFieldsExceptdocblock explains why), so this is not a flip — it is "is there a strict face for authoring, separate from the tolerant face for rendering". That question is bigger than docs and touches AGENTS.md #0.1.Related: #5138 (this class, TypeScript half now built), #5161 (the gate that built it), #5174 (collection surface of the same gate), #5106 (scan surface of
check-doc-component-types), #4823 (the original deferral), #5229 (the instance that produced this reading).Generated by Claude Code