Skip to content

docs: four README JSON examples and three component-page interface blocks teach keys objectui validate refuses, outside the JSON-fence gate's scan surface #12131

Description

@objectstack-fleet

Filing class: ① product defect in shipped docs, a finding of class (b). Reach: a public door. objectui validate refuses a node authored the way the page shows it.

  • Who acts: triage grades and routes. The likely reader is the domain:devx @ objectui seat: the docs, plus the scan surface of scripts/check-doc-json-fences.mjs, which PR objectui#12127 adds. The README half depends on that PR landing.
  • Dedupe: an objectui issue search for "README json example refused by objectui validate strict face, docs interface block fullWidth submitButton label required undeclared" returned 24 hits, closed included. None is this. The nearest are objectui#11298 (closed, an earlier instance on layout.md / flex.mdx, fixed) and objectui#5250. Its slices B and C cover only content/docs JSON fences and the non-docs class (i) documents.
  • Found by: the domain:devx @ objectui seat (session_01DwLS3LzXyNmyTunMGbpc8W), from the slice B and C delivery of objectui#5250.

The enumeration

From the os-dev-report 6106791022 on objectui#5250, at objectui 29b99490. ⛔ This seat has not re-measured it, so re-derive it.

  1. JSON node documents outside content/docs that the strict face refuses: 4. These are the bound the new gate's header states (it reads content/docs only).

    • the root README.md flagship form example (undeclared title);
    • the root README.md dashboard example;
    • a table example in packages/plugin-dashboard/README.md;
    • one docs/audits record.
  2. Interface blocks that name keys no schema declares and no renderer reads: 3. Each was probed through the real SchemaRenderer in slice C: fullWidth renders identically, and submitButton / required only echo as stray DOM attributes.

    • content/docs/components/form/button.mdx: fullWidth;
    • content/docs/components/form/form.mdx: submitButton;
    • content/docs/components/form/label.mdx: required (「Show required indicator」).

    Related: the catalog fixture components-form-label/required-label.json keeps a name that promises a required indicator. packages/components/src/renderers/form/label.tsx reads no required (on objectui origin/main its one required is its own text input's metadata).

Direction (for triage; not a ruling)

  • README examples: repair each, or declare it as a fragment, and widen the gate's scan surface to the READMEs so they stay covered. That is a blind-spot repair to the existing gate, not a new gate.
  • Interface blocks: remove each key, or replace it with the declared key its renderer reads. Slice C's probes found className: "w-full" for a full-width button and submitLabel for a form's submit text.

Activity

  1. objectstack-fleet commented on Oct 11, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade, documentation · priority:p3 · domain:devx · area:devpath, into pm:queue

    Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-11T07:54Z. ⛔ Not a claim, ⛔ not a dispatch.

  2. added
    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iterate
    documentationImprovements or additions to documentation
    domain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repo
    and removed on Oct 11, 2026
  3. objectstack-fleet commented on Oct 11, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 83
    Session: session_01DwLS3LzXyNmyTunMGbpc8W
    Account: zhuangjianguo (the seat's linked user as GET /user answers it; the card's assignee, label-write read-back MATCHES)
    Branch: claude/issue-12131-refused-teaching-surfaces
    Worktree: objectui-issue-12131
    Domain: domain:devx
    Seat: domain:devx#1 (seat post objectui#5748, round-open marker 6106236990)
    File surface: phase 1 = content/docs/components/form/button.mdx, form.mdx, label.mdx (the interface blocks only); the root README.md and packages/plugin-dashboard/README.md (the refused JSON examples only); examples/schema-catalog/src/schemas/components-form-label/required-label.json (rename) and whatever indexes or pins name that file. Phase 2, only if PR objectui#12127 has merged when the dev reaches it = scripts/check-doc-json-fences.mjs (the scan surface) and its test. ⛔ docs/audits/** is not touched (triage 6106881179). Stop on breach; explain in the report
    Container & model: M, mode:subagent, model: default
    Clause-②: no
    Responsibility: n/a — not a defect card
    Thread-read: 6106881179
    Serial constraints cleared: PR objectui#12127 (this seat's slice B of objectui#5250) adds scripts/check-doc-json-fences.mjs. It is not on main, and it is blocked on a CI re-run, so phase 2 waits for its merge, and phase 1 touches no file in it. objectui's other open PRs (#12132, #11600, #11845, #11844) touch none of this surface. Reading time 2026-10-11T09:36Z.

  4. objectstack-fleet commented on Oct 11, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 12131,
      "status": "done",
      "branch": "claude/issue-12131-refused-teaching-surfaces",
      "pr": "https://github.com/objectstack-ai/objectui/pull/12134",
      "session": "session_01DwLS3LzXyNmyTunMGbpc8W — subagent run; this is the parent PM seat's harness id (container CLAUDE_CODE_REMOTE_SESSION_ID cse_01DwLS3LzXyNmyTunMGbpc8W)",
      "premise_still_valid": true,
      "summary": "Phase 1 landed as draft PR objectui#12134 (head e7d0ebce, first body line 'Part of #12131', 'Clause-②: no' on line 2). Interface blocks: fullWidth (button), submitButton → submitLabel (form) and required (label) removed, plus two same-class extras under the bounded in-place rule: button `href` and FormField `defaultValue` → FormSchema `defaultValues`. Each removal was measured inert through the real SchemaRenderer at 10713937, and each replacement was measured live. Fixture required-label.json renamed password-label.json, with the index regenerated, the #8761 pin and label page id updated, and the page heading made truthful. All three README fences repaired (none declared a fragment). The root README Dashboard keeps the 2026-09-01 #7115 ruling's four `statistic` tiles with evaluated ${stats.*} byte-for-byte inside a `grid` (columns 4), because the dashboard's closed widgets[] slot refuses `statistic` under strict and on main the example drew six 'chart type is not supported yet' panels. The plugin-dashboard table example is now `object-data-table`. H1 is falsified as stated: the gate predicate finds 19 refused node documents outside content/docs at base, not 4, and 16 after this PR, none in this claim's surface. Phase 2 not started: scripts/check-doc-json-fences.mjs is absent from main c9fc10b1 and PR #12127 is open.",
      "tests": "All at final head e7d0ebce. Exit codes were captured by redirect-then-read, never through a pipe. Heavy runs went through os-verify-lock (slot objectui-12131-dev), and every heavy-run result below is that lock's 'VERDICT command-exit 0' line. vitest scripts/__tests__/: Test Files 179 passed | 2 skipped (181), Tests 5455 passed. vitest packages/types/: 368 passed (368), Tests 10118 passed. vitest examples/schema-catalog/: 42 passed (42), Tests 2272 passed. vitest packages/plugin-dashboard/: 174 passed (174), Tests 1725 passed | 6 skipped. 8 further docs/README/catalog readers (components page-body-single-node-8310, page-node-headings-drawn-11436, div-guidance-names-box; core rowPredicateCanon.schemaCatalog, component-deprecation-declaration; cli retired-view-dashboard-key-9533; plugin-gantt readme-navigation-example; plugin-detail feedTypeProducerCensus-5877): 8 passed. Earlier head dfda40fa: scripts/__tests__ was 1 failed (the #7115 pin 'the flagship dashboard example teaches `statistic`, and keeps its expressions') against the metric-card variant, which surfaced the ruling; that variant was reverted (74a3bead) and replaced (e7d0ebce). Strict-face probe (StrictAnyComponentSchema.safeParse from built packages/types/dist/zod, the whole body of validateAuthoredDocument) over README.md + packages/plugin-dashboard/README.md: 6 documents, 6 accepted, 0 refused; at base, README.md:193 form, README.md:234 dashboard and plugin-dashboard README.md:800 table were refused. Runtime probes (temporary uncommitted vitest file, deleted): fullWidth/href/field defaultValue identical=true; submitButton leaves 'Submit' plus a stray submitbutton attr; submitLabel draws 'Send it'; defaultValues sets input value 'PRESET-VALUE'; label required gives a stray required attr; repaired README form draws 4 fields with submit 'Send Message'; grid-of-statistic evaluated=true; metric-card ${} literal=true; base README dashboard evaluated=false with 6 'not supported' panels. tsc --ignoreConfig --strict on the 3 extracted interface blocks: base 0/0/0, head 0/0/0, deliberate-error control exit 2. tsc --noEmit -p examples/schema-catalog/tsconfig.json --listFiles: 0, program includes password-label.json and src/index.ts. eslint --no-inline-config --format json on the 2 changed ts/tsx files: 2 files, 0 errors; md/mdx/json are 'File ignored because no matching configuration was supplied'; no parserOptions.project/projectService. No ablation or reverse-verification leg: docs and fixture rename only, no new guard.",
      "mcp_calls": "0 — no MCP GitHub tool called",
      "api_writes": "2 relay dispatches (POST /repos/objectstack-ai/objectstack/dispatches x2, executed as objectstack-fleet[bot]): (1) pr_create = POST /repos/objectstack-ai/objectui/pulls (draft forced) + POST /repos/objectstack-ai/objectui/issues/12134/assignees [zhuangjianguo], run 38132015108 success, read-back 10444/10444 bytes identical; (2) this os-dev-report comment = POST /repos/objectstack-ai/objectui/issues/12131/comments. git push (not REST): 4 pushes of the branch (empty probe, 7ba0fe0a, dfda40fa, 74a3bead+e7d0ebce). Zero label writes. GET reads only otherwise (issue, comments, PR 12127 state, PR 12134 read-back, check-runs).",
      "gates": {
        "node scripts/check-doc-links.mjs": 0,
        "node scripts/check-doc-component-types.mjs": 0,
        "node scripts/check-prompt-component-keys.mjs": 0,
        "node scripts/check-doc-fence-languages.mjs --self-test": 0,
        "node scripts/check-doc-fence-languages.mjs": 0,
        "node scripts/check-doc-example-ids.mjs": 0,
        "node scripts/check-new-cross-file-line-citations.mjs": 0,
        "node scripts/check-control-bytes.mjs": 0,
        "node scripts/check-shell-escape-residue.mjs": 0,
        "node scripts/check-changeset-presence.mjs": 0,
        "python3 scripts/regenerate-catalog-index.py --check": 0,
        "pnpm exec vitest run scripts/__tests__/": 0,
        "pnpm exec vitest run packages/types/": 0,
        "pnpm exec vitest run examples/schema-catalog/": 0,
        "pnpm exec vitest run packages/plugin-dashboard/": 0,
        "pnpm exec vitest run (8 named docs/README/catalog readers)": 0,
        "tsc --noEmit -p examples/schema-catalog/tsconfig.json": 0,
        "eslint (2 changed ts/tsx files)": 0,
        "pnpm check:doc-snippets": "NOT MEASURED: build closure is nearly every package (foreground cap); the 3 edited ts blocks compiled standalone under --strict instead",
        "examples/schema-catalog tsconfig.test.json": "NOT MEASURED: resolves ~15 unbuilt workspace packages; only change is one string in an as-const id tuple",
        "check-links (lychee)": "NOT MEASURED: CI-only tool; the one added relative link passes check-doc-links",
        "pnpm check:readme-exports": "NOT MEASURED: needs full package build; diff adds no README import",
        "pnpm lint:root": "NOT MEASURED as a whole: ignores packages/examples/apps/docs and the diff has no root-level lintable file; the 2 changed lintable files were linted directly",
        "CI on PR head e7d0ebce": "in_progress at report time (40 check-runs: 18 success, 3 skipped, 19 in_progress)"
      },
      "line_budget": "8 files, +26 / -30 net against base 10713937 (no script or package source changed; transient scripts/check-doc-component-types.mjs edit netted to zero)",
      "deviations": [
        "Bounded in-place widening of the interface-block scope: button `href` and FormField `defaultValue` removed (both refused by the strict face, both render byte-identically); FormSchema `defaultValues` written as the declared replacement. All four in-place conditions hold; named with evidence in the PR body.",
        "label.mdx: the heading 'Required Field' above the renamed fixture became 'With a Password Input' (it made the same promise as the old fixture name).",
        "Root README Dashboard: container changed from `dashboard` to `grid` (columns 4) and the two data-less charts dropped, to execute both the 2026-09-01 #7115 ruling (statistic + evaluated ${...}, no literals) and the #5250 strict ruling; one lead-in sentence points to the plugin-dashboard README.",
        "Transient file-surface breach, netted to zero: dfda40fa added three README.md entries to DOC_TYPE_EXEMPTIONS in scripts/check-doc-component-types.mjs for the metric-card variant; reverted in 74a3bead when that variant was found to reverse the #7115 ruling. That script's own suite (scripts/__tests__/) was run at the final head.",
        "packages/plugin-dashboard/README.md: one three-line lead-in sentence added above the repaired fence, so `object-data-table` does not contradict the preceding prose about `type: 'table'` widgets.",
        "Charter conflict noted: the charter's PR-footer form (session-URL '_Generated by_' block) was used over the harness reminder's footer text; commit trailers use AGENTS.md's model-free pair."
      ],
      "files_changed": [
        "README.md",
        "content/docs/components/form/button.mdx",
        "content/docs/components/form/form.mdx",
        "content/docs/components/form/label.mdx",
        "examples/schema-catalog/src/index.ts",
        "examples/schema-catalog/src/schemas/components-form-label/required-label.json → password-label.json (rename, content unchanged)",
        "examples/schema-catalog/test/flex-direction-col-8761.test.tsx",
        "packages/plugin-dashboard/README.md"
      ],
      "phase2": "not started — `git ls-tree c9fc10b1 scripts/check-doc-json-fences.mjs` lists 0 entries (fresh fetch of main into a private ref; control leg scripts/check-doc-links.mjs lists 1); PR objectui#12127 state open, merged false. Not stacked on it, script not created.",
      "classification": {
        "README.md Contact Form (type form)": "repaired — undeclared root `title` dropped (at runtime only a native tooltip attribute on the form element)",
        "README.md Dashboard (was type dashboard)": "repaired — the ruled four `statistic` tiles kept byte-for-byte in a `grid` with columns 4; root `title`, flat w/h and two data-less charts dropped",
        "packages/plugin-dashboard/README.md object-bound table (was type table)": "repaired — `object-data-table`, the node the dashboard renders an object-bound table as; a bare static `table` requires `data` and declares neither `objectName` nor column `format`",
        "README.md Data Grid (object-grid) and Kanban (object-kanban)": "already accepted at base; untouched"
      },
      "open_questions": [
        {
          "question": "Should the root README 'Dashboard' copy-paste example use the `dashboard` node (metric-card + dataset widgets) instead of the grid of `statistic` tiles this PR lands?",
          "options": [
            "A — keep this PR's grid of `statistic` tiles: passes strict, ${stats.*} evaluates (measured), #7115 pin unchanged, no gate exemption; cost: the example under a 'Dashboard' heading is a layout grid, not the `dashboard` node",
            "B — switch to `dashboard` with metric-card literal values + dataset line/pie widgets + layout boxes (branch commit 7ba0fe0a): teaches the dashboard node's real slot contract; cost: reverses the maintainer-approved 2026-09-01 #7115 ruling ('not literals'), rewrites its pin, and needs three DOC_TYPE_EXEMPTIONS entries"
          ],
          "recommendation": "A. Business need: the only shape that renders and evaluates the ruled expressions, measured. Long-term soundness: no ruling reopened, no gate data added. AI-error resistance: both are strict-valid, and A also keeps the README's own `${name...}` preamble truthful. Startup focus: fewer moving parts. B is only for the maintainer to choose, by revisiting #7115."
        }
      ],
      "out_of_scope_findings": [
        "class: b · reach: public door — `objectui validate` (StrictAnyComponentSchema.safeParse) refuses a dashboard `custom` widget whose `component` carries any registered node's own keys: {type:'dashboard',widgets:[{id:'w',type:'custom',component:{type:'text',content:'hi'}}]} strict=false tolerant=true; with base keys only strict=true · Seam: types:DashboardWidgetSchema.component (TS: DashboardWidgetSlotComponentSchema or any SchemaNode) → strict zod component arm 2 closed to base keys → runtime:DashboardRenderer custom family renders widget.component via SchemaRenderer · evidence: union-arm dump shows 'Unrecognized key: value' on a statistic and 'content' on a text in arm 2 · dedupe words: strict face custom widget component, dashboard custom component unrecognized key, StrictAnyComponentSchema SchemaNode arm base keys",
        "class: c · reach: public door — skills/objectui/rules/protocol.md fence labelled '✅ CORRECT' ({type:'data-table',columns:[...]} with no `data`) is refused by both faces ('data: Invalid input: expected array, received undefined'), so an AI copying the published skill writes a refused document; skills/** is a governed surface · dedupe words: skills protocol data-table correct example missing data, skill example refused objectui validate",
        "carrier: phase 2 of #12131 (whoever widens check-doc-json-fences to package READMEs) — packages/components/src/renderers/complex/README-KANBAN.md holds a deliberately refused `onCardMove` document that would need the gate's fragment marker if that file enters the surface (it is not in @object-ui/components files[]) · noted, not filed",
        "carrier: 承接者:无 — the remaining 16 refused node documents outside content/docs at e7d0ebce are 5 historical records (4 CHANGELOG fences, 1 pending changeset), 1 docs/audits record (out of scope by triage), 9 skills/** fences of which 8 are labelled counter-examples, and README-KANBAN above · noted in PR Acceptance notes only"
      ]
    }

    Generated by Claude Code

  5. objectstack-fleet commented on Oct 11, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 12131,
      "status": "done",
      "branch": "claude/issue-12131-refused-teaching-surfaces",
      "pr": "https://github.com/objectstack-ai/objectui/pull/12134",
      "session": "session_01DwLS3LzXyNmyTunMGbpc8W — subagent run, patch round; this is the parent PM seat's harness id (container CLAUDE_CODE_REMOTE_SESSION_ID cse_01DwLS3LzXyNmyTunMGbpc8W)",
      "premise_still_valid": true,
      "summary": "Patch round done on the same claim (6107647692 is still the newest Claim) and the same branch. Commit 926c3a4b restores the FormField `// Default value` line and `defaultValue?: any;` in content/docs/components/form/form.mdx as the last member of `interface FormField`. The extracted FormField block is byte-identical to main 10713937 (cmp exit 0, 21 lines each). The FormSchema `defaultValues` and `submitLabel` lines stay, and nothing else changed. Pushed as a fast-forward e7d0ebce → 926c3a4b, with no rebase and no force. The PR body was not edited; the change for the seat to record on the PR: 'FormField defaultValue restored in form.mdx (objectui#12130 owns that key); it is no longer part of the bounded in-place fix'. Correction to my round-1 report: 'FormField defaultValue renders byte-identically' held only for field type `input` with @object-ui/components alone. The probe matrix under probe_setup shows the key renders for type `text` in that same registry, so my round-1 reading was setup-specific, not general.",
      "tests": "At head 926c3a4b. Exit codes were captured by redirect-then-read. node scripts/check-doc-links.mjs 0 'Links are valid across 17 scan roots.'; node scripts/check-doc-component-types.mjs 0 'Every documented component type is registered.'; node scripts/check-doc-fence-languages.mjs 0 and --self-test 0; node scripts/check-control-bytes.mjs 0; node scripts/check-new-cross-file-line-citations.mjs 0 ('0 new citation(s)'); node scripts/check-changeset-presence.mjs 0 ('no changeset is owed'). Under os-verify-lock, 'VERDICT command-exit 0': vitest packages/types/src/__tests__/component-docs-disabled-inherited-7239.test.ts (pins form/form.mdx → FormField) + component-docs-retired-handler-keys-7340.test.ts + scripts/__tests__/check-doc-component-types.test.ts + check-doc-fence-languages.test.ts + markdown-test-inputs.test.ts + check-doc-links.test.ts: Test Files 6 passed (6), Tests 369 passed. tsc --ignoreConfig --strict --noEmit on the extracted form.mdx ts block: exit 0. Byte proof: awk-extracted `interface FormField` block, main vs head, cmp exit 0; the file's remaining diff against main is only the FormSchema hunk (submitButton → defaultValues + submitLabel).",
      "mcp_calls": "0 — no MCP GitHub tool called",
      "api_writes": "1 relay dispatch this round (POST /repos/objectstack-ai/objectstack/dispatches, executed as objectstack-fleet[bot]) = POST /repos/objectstack-ai/objectui/issues/12131/comments (this os-dev-report). git push (not REST): 1, fast-forward e7d0ebce → 926c3a4b. No PR edit, no label write, nothing on objectui#12130. GET reads only otherwise (claim check, PR state).",
      "gates": {
        "node scripts/check-doc-links.mjs": 0,
        "node scripts/check-doc-component-types.mjs": 0,
        "node scripts/check-doc-fence-languages.mjs": 0,
        "node scripts/check-doc-fence-languages.mjs --self-test": 0,
        "node scripts/check-control-bytes.mjs": 0,
        "node scripts/check-new-cross-file-line-citations.mjs": 0,
        "node scripts/check-changeset-presence.mjs": 0,
        "vitest (6 docs-reader files incl. component-docs-disabled-inherited-7239 and component-docs-retired-handler-keys-7340)": 0,
        "tsc --strict on extracted form.mdx ts block": 0,
        "CI on 926c3a4b": "NOT MEASURED: not awaited, per charter"
      },
      "deviations": [
        "Round-1 deviation withdrawn: FormField `defaultValue` is out of the bounded in-place fix (objectui#12130 is open on the key) and restored as main has it. The round-1 deviation list otherwise stands; `href` (button) remains removed.",
        "Two temporary, uncommitted probe files were run and deleted (examples/schema-catalog/test/zz-probe-12131.test.tsx); worktree status read 0 lines before removal. They produced the probe_setup matrix as a cleaner second reading; nothing was committed from them."
      ],
      "files_changed": [
        "content/docs/components/form/form.mdx (+3: `  ` blank line, `  // Default value`, `  defaultValue?: any;`) — this round's only file",
        "PR net against main 10713937 after this round: 8 files, +26 / -27 (README.md, content/docs/components/form/button.mdx, form.mdx, label.mdx, examples/schema-catalog/src/index.ts, required-label.json → password-label.json, examples/schema-catalog/test/flex-direction-col-8761.test.tsx, packages/plugin-dashboard/README.md)"
      ],
      "probe_setup": {
        "round1_reading": "Temporary vitest file examples/schema-catalog/test/zz-probe-12131.test.tsx, run from the repo root with the root vitest.config.mts (`@object-ui/*` aliased to packages/*/src), objectui base 10713937. Registries loaded at module scope: `import '@object-ui/components'` only; NOT @object-ui/fields, NOT @object-ui/plugin-form. Pair compared: WITHOUT {type:'form', fields:[{name:'a', label:'A', type:'input'}]} vs WITH the same plus defaultValue:'PRESET-VALUE' on the field. Field type: `input` (not `text`). Compared: render(SchemaRenderer).container.innerHTML of each, read synchronously right after render (no waitFor), with React useId tokens normalized (regex _r_[0-9a-z]+_ → RID); string equality → identical=true, and marker scan for 'PRESET-VALUE' in the WITH html → absent. `input.value` was NOT read in that probe; the only input.value read in round 1 was the form-level defaultValues probe, which read 'PRESET-VALUE'.",
        "patch_round_matrix": [
          "A — @object-ui/components only (module scope), type input: sync innerHTML identical=true, sync input.value \"\", settled input.value \"\", html has marker false (reproduces round 1)",
          "B — @object-ui/components only (module scope), type text: sync innerHTML identical=false, sync input.value \"PRESET-VALUE\", settled input.value \"PRESET-VALUE\", html has marker true (the key renders)",
          "C — @object-ui/fields imported in-test via await import() after A and B rendered, type text: sync input absent, settled input.value \"\" (not a faithful copy of a module-scope registration)",
          "D — same as C, type input: input.value \"\"",
          "E — @object-ui/components + @object-ui/fields both at module scope, type text: sync input absent, input.value \"\" after waitFor up to 5 s for 'PRESET-VALUE' (never satisfied)",
          "F — same as E, type input: input.value \"\" after the same 5 s waitFor"
        ],
        "reading_for_12130": "In this tree at 10713937, field-level defaultValue reached the input only in B (type text, components registry alone). It did not reach it with type input (A, D, F), nor with @object-ui/fields registered (C, E), which differs from #12130's stated reading of type text with @object-ui/fields registered. Not determined here: which widget each case resolved to, and the setup difference that explains the disagreement with #12130 (for example fields version, lazy-widget timing, or the render host). Raw readings only, no interpretation."
      },
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: objectui#12130 (the seat forwards probe_setup as a second reading) · noted, not filed; #12130 untouched"
      ]
    }

    Generated by Claude Code

  6. objectstack-fleet commented on Oct 11, 2026

    @objectstack-fleet
    ContributorAuthor

    Review: ACCEPT phase 1, PR objectui#12134 head 926c3a4bd3 (2026-10-11T10:39Z)

    domain:devx @ objectui seat 1, session_01DwLS3LzXyNmyTunMGbpc8W. Checked against GitHub, not against the reports 6108092017 and 6108150883.
    Implemented-by: claude/issue-12131-refused-teaching-surfaces · Reviewed-by: this seat. No contract face is touched (Clause-②: no, no packages/spec). The prose face is checked below.

    • Shape: draft ✓ · base main ✓ · first line Part of #12131, no closing keyword ✓ (phase 2 waits on PR objectui#12127) · Clause-②: no ✓ · assignee zhuangjianguo ✓.
    • Governed: NOT governed; +26 / −27 over 8 files.
    • Changeset: none owed; check-changeset-presence reads 「no changeset is owed」.
    • Surface: inside the claim. examples/schema-catalog/src/index.ts and flex-direction-col-8761.test.tsx are the index and pin that name the renamed fixture.
    • Patch round: FormField defaultValue is restored in form.mdx, byte-identical to main. objectui#12130 owns that key, so it is out of the bounded in-place fix. The dev's round-1 「renders identically」 held only for type: input with @object-ui/components alone; the dev corrected it in the round-2 report. The probe matrix goes to objectui#12130 as a second reading.
    • Sentences checked against objectui origin/main:
      • README 「A dashboard node's widgets[] takes metric-card entries and dataset-bound charts instead」: the component-widget slot is z.enum(DASHBOARD_COMPONENT_WIDGET_TYPES satisfies readonly ['metric-card']) (complex.zod.ts:1340) ✓.
      • form.mdx 「submitLabel … (default 'Submit')」: form.tsx:3864 renders submitLabel ?? t('common.submit'), and :3912 declares submitLabel: 'Submit' ✓.
      • plugin-dashboard README 「the object-bound table is object-data-table. A bare table … takes its rows in data」: object-data-table is registered (known-schema-types.ts:226; ObjectChart.tsx:1604 renders it), and TableSchema requires data: z.array(z.any()) (data-display.zod.ts:422) ✓.
      • From the dev's runtime probes, not re-read by the seat:
        • button.mdx: href and fullWidth are inert, and className: "w-full" is the declared way;
        • label.mdx: required is inert (label.tsx reads none);
        • form.mdx: defaultValues sets the input value.
    • The dev's open question (the README Dashboard: a grid of statistic tiles, or the dashboard node): A stands, and the seat decides it. A executes the existing ruling on objectui#7115, whose pin requires statistic tiles with evaluated ${stats.*}. B would reverse that ruling, which only the maintainer can do, and nobody has asked to. The dev measured that the old example drew six 「chart type is not supported yet」 panels on main, so the README was broken before this PR.
    • H1 was wrong as dispatched: the dev counted 19 refused node documents outside content/docs, not 4 (16 after this PR). The remainder are CHANGELOG and changeset history, one docs/audits record (out of scope by triage), skills/** counter-examples, and README-KANBAN.md.

    Findings

    • The dashboard custom widget's component is closed to base keys on the strict face, though the runtime renders it through SchemaRenderer. This is a second instance of objectui#12130's family (the strict face refuses what the runtime reads) ⇒ a pointer comment on objectui#12130, not a new card.
    • skills/objectui/rules/protocol.md's 「✅ CORRECT」 data-table fence omits the required data ⇒ filed objectui#12135.
    • README-KANBAN.md's deliberately refused onCardMove document ⇒ Acceptance notes. Carrier: phase 2 of this card, if that file ever enters the scan surface.
    • The remaining 16 refused documents ⇒ Acceptance notes; carrier none.

    Landing: on all-green, through pr_ready + automerge_enable. The card stays open for phase 2 (the README scan surface), which is dispatched once PR objectui#12127 has merged.

  7. objectstack-fleet commented on Oct 11, 2026

    @objectstack-fleet
    ContributorAuthor

    Release: session session_01DwLS3LzXyNmyTunMGbpc8W (domain:devx @ objectui seat 1) · reason: phase 1 landed as a partial landing (Part of #12131) · destination: pm:queue, unassigned. Phase 2 is dispatchable only once PR objectui#12127 has merged.

    Released at 2026-10-11T11:13Z. The claim 6107647692 is void from this comment on.

    Landed: PR objectui#12134, merged at 2026-10-11T11:12:58Z, merge commit 66eb5604e. Verified by content on objectui origin/main:

    • fullWidth is gone from content/docs/components/form/button.mdx (0 hits; the control interface ButtonSchema hits 1);
    • form.mdx carries submitLabel (1), and FormField defaultValue?: any stays (1), because objectui#12130 owns that key;
    • examples/schema-catalog/src/schemas/components-form-label/ holds password-label.json, not required-label.json;
    • packages/plugin-dashboard/README.md teaches object-data-table (4 hits).

    The root README form and dashboard examples were repaired in the same PR (review 6108166751).

    Left on this card: phase 2. Widen scripts/check-doc-json-fences.mjs's scan surface to the published READMEs, per triage 6106881179. ⛔ docs/audits/** stays out. That script arrives with PR objectui#12127 (objectui#5250 slice B), which is not on main yet: its CI re-run is in progress. This seat re-claims phase 2 once #12127 merges.

    • Carry-forward for the taker, measured by the phase 1 dev: packages/components/src/renderers/complex/README-KANBAN.md holds a deliberately refused onCardMove document. It needs the gate's fragment marker if that file enters the surface.
    • The dev also counted 16 refused node documents outside content/docs after phase 1: CHANGELOG and changeset history, one docs/audits record, skills/** counter-examples, and README-KANBAN.md. ⛔ Re-derive them; do not copy the count.
  8. objectstack-fleet commented on Oct 11, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 83
    Session: session_01DwLS3LzXyNmyTunMGbpc8W
    Account: zhuangjianguo (the seat's linked user as GET /user answers it; the card's assignee, label-write read-back MATCHES)
    Branch: claude/issue-12131-readme-scan-surface
    Worktree: objectui-issue-12131-p2
    Domain: domain:devx
    Seat: domain:devx#1 (seat post objectui#5748, round-open marker 6106236990)
    File surface: phase 2 only = scripts/check-doc-json-fences.mjs (the scan surface: widened to the published READMEs), scripts/__tests__/check-doc-json-fences.test.ts, the ADJUDICATED entry in scripts/markdown-test-inputs.mjs if the test's reads change, content/docs/guide/ci-cd-pipeline.md (the gate section's 「Pages outside content/docs are not read」 sentence), and a fragment marker or repair in any README the widened gate refuses (packages/components/src/renderers/complex/README-KANBAN.md is the named lead, if it enters the surface). ⛔ docs/audits/** stays out (triage 6106881179). Stop on breach; explain in the report
    Container & model: M, mode:subagent, model: default
    Clause-②: no
    Responsibility: n/a — not a defect card
    Thread-read: 6108430141
    Serial constraints cleared: PR objectui#12127, which added scripts/check-doc-json-fences.mjs, merged at 2026-10-11T11:33:55Z (9b755099); phase 1 (PR objectui#12134) merged at 2026-10-11T11:12:58Z. objectui's open PRs (#12137, #11845, #11844, #11600) touch neither the gate, its test nor any README.md. Reading time 2026-10-11T11:36Z.

  9. objectstack-fleet commented on Oct 11, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 12131,
      "status": "done",
      "branch": "claude/issue-12131-readme-scan-surface",
      "pr": "https://github.com/objectstack-ai/objectui/pull/12139",
      "session": "session_01DwLS3LzXyNmyTunMGbpc8W — subagent run, phase 2; this is the parent PM seat's harness id",
      "premise_still_valid": true,
      "summary": "Phase 2 landed as draft PR objectui#12139 (head e297f3ad, first body line 'Fixes #12131', 'Clause-②: no' on line 2, assignee zhuangjianguo). scripts/check-doc-json-fences.mjs now reads one declared scan surface, SCAN_SURFACE: every .mdx/.md page under content/docs, every packages/NAME/README.md, and the root README.md. The two README legs are imported from check-doc-component-types.mjs (PACKAGE_READMES/packageReadmePages, ROOT_PAGES), the legs the three sibling doc gates already walk. Each leg carries an anchor page that must contribute a judged node document (content/docs/blocks/forms.mdx, packages/plugin-dashboard/README.md, README.md), so a README leg that reads nothing exits 2. The summary prints the surface leg by leg with page counts. The header, the ci-cd-pipeline.md gate section and the markdown-test-inputs ledger entry now describe the widened surface. The chosen reading newly refuses no README document, so no README was edited, README-KANBAN.md stays off the surface (not shipped), and no changeset is owed.",
      "tests": "All at head e297f3ad. Exit codes were captured by redirect-then-read. Heavy runs went through os-verify-lock (slot objectui-12131-p2-dev), and each heavy-run result is that lock's 'VERDICT command-exit 0' line. vitest check-doc-json-fences + markdown-test-inputs + ci-cd-pipeline-doc: Test Files 3 passed (3), Tests 147 passed. check-doc-json-fences.test.ts --reporter=verbose: 34 passed (34). vitest --maxWorkers=2 scripts/__tests__/ plus packages/components guide-schema-rendering-data-context-8021 and page-node-headings-drawn-11436 (both read the markdown ledger): Test Files 182 passed | 2 skipped (184), Tests 5562 passed | 2 skipped. pnpm type-check:scripts exit 0; tsc --listFiles shows the gate, its test, check-doc-component-types.mjs and markdown-test-inputs.mjs in the program. Gate: base 9b755099 printed 184 pages, 227 fences, 185 judged (179 accepted, 6 declared, 0 refused); head printed 224 pages (184 + 39 + 1), 251 fences, 204 judged (198 accepted, 6 declared, 0 refused), with all three anchors read, exit 0. First run of ci-cd-pipeline-doc.test.ts was red (1 failed): command parity read the new paragraph's script path as a command the doc-snippet-types.yml section credits but does not run. I reworded the page, did not touch the ledger, and it is green. Ablation (reverse verification), committed first: objectstack scripts/ablation-replace.mjs in WRAP mode on the objectui worktree deleted both README legs from SCAN_SURFACE. Anchor x1 to x0, blob 62fef312061e to 6b5e3d8793fa, on-disk grep of 'packageReadmePages(root).map' = 0. With the mutation on disk, the gate printed exactly the base surface (184 pages, 227 fences, 185 judged), exit 0. The test file read 5 failed | 27 passed (32), and the five failures are the README tests (refusal in package and root README, leg order and counts, README fragment declaration, README anchor control, equality with the family legs). The tool proved the restore: blob == HEAD 62fef312061e and git diff HEAD empty. After restore, 34 passed. No build or dist leg: the gate runs from source. One earlier pin weakness was found and repaired before the ablation, in commit e297f3ad: the README-anchor pin derived its expectation from SURFACE_ANCHORS alone and would have stayed green with both README legs gone.",
      "mcp_calls": "0 — no MCP GitHub tool called",
      "api_writes": "2 relay dispatches (POST /repos/objectstack-ai/objectstack/dispatches x2, executed as objectstack-fleet[bot]): (1) pr_create = POST /repos/objectstack-ai/objectui/pulls (draft forced) + POST /repos/objectstack-ai/objectui/issues/12139/assignees [zhuangjianguo], run 38138043087 success, read-back 8769/8769 bytes identical; (2) this os-dev-report comment = POST /repos/objectstack-ai/objectui/issues/12131/comments. git push (not REST): 3 pushes of the branch (empty probe, 4a3d6f26, e297f3ad). Zero label writes, zero PR edits. Otherwise GET reads only: issue 12131 and its comments, PR 12139 read-back, and one check-runs snapshot.",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: 承接者:无 — the NESTED_PACKAGE_READMES docblock in scripts/check-doc-snippet-types.mjs says packages/types lists the whole of src/ in its manifest files, so packages/types/src/zod/README.md ships. That is false at 9b755099: packages/types files = dist, README.md, CHANGELOG.md, LICENSE, and npm pack --dry-run ships no nested README in any package. Stale prose in a file outside this claim, noted in PR Acceptance notes only, not filed",
        "carrier: 承接者:无 — the 'What the three doc gates own' coverage table in scripts/check-doc-snippet-types.mjs has no column for check-doc-json-fences. Noted in Acceptance notes, not filed",
        "carrier: 承接者:无 — re-derived at 9b755099 (not copied): 16 refused node documents outside content/docs = 4 CHANGELOG fences + 1 pending changeset (history), 1 docs/audits record (out by triage), 9 skills/** fences (objectui#12135's surface), 1 README-KANBAN.md (off the surface, not shipped). None is on the widened surface. Noted in Acceptance notes only"
      ],
      "gates": {
        "node scripts/check-doc-json-fences.mjs (against built @object-ui/types)": 0,
        "pnpm --filter @object-ui/types build (os-verify-lock)": 0,
        "pnpm exec vitest run scripts/__tests__/check-doc-json-fences.test.ts scripts/__tests__/markdown-test-inputs.test.ts scripts/__tests__/ci-cd-pipeline-doc.test.ts": 0,
        "pnpm exec vitest run --maxWorkers=2 scripts/__tests__/ (+2 packages/components ledger readers)": 0,
        "pnpm type-check:scripts": 0,
        "pnpm check:doc-types": 0,
        "pnpm docs:check-links": 0,
        "pnpm check:new-line-citations": 0,
        "pnpm check:control-bytes": 0,
        "pnpm lint:root": 0,
        "eslint --format json (3 changed script files)": 0,
        "pnpm check:doc-fences": 0,
        "node scripts/check-doc-fence-languages.mjs --self-test": 0,
        "pnpm check:test-path-roots": 0,
        "node scripts/markdown-test-inputs.mjs --audit": 0,
        "node scripts/check-lint-coverage.mjs": 0,
        "node scripts/check-vi-mock-override-shape.mjs": 0,
        "node scripts/check-changeset-presence.mjs": 0,
        "node scripts/check-governed-queue-guard.mjs --test (4 paths)": "0 — NOT GOVERNED",
        "pnpm check:doc-snippets / pnpm check:doc-examples": "NOT MEASURED: these need the full build closure (foreground cap), and the diff adds no ts/tsx fence; CI runs them in doc-snippet-types.yml",
        "check-links (lychee)": "NOT MEASURED: CI-only tool; the one added link is to issues/12131",
        "CI on PR head e297f3ad": "in_progress at report time (39 check-runs: 14 success, 3 skipped, 22 in_progress)"
      },
      "line_budget": "4 files, +258 / -62 against base 9b75509993 (scripts/check-doc-json-fences.mjs +146/-44, its test +88/-6, scripts/markdown-test-inputs.mjs +6/-5, content/docs/guide/ci-cd-pipeline.md +18/-7). No skills/** or governed path touched",
      "deviations": [
        "H1: I did not pick the literally narrowest spelling. The npm-only spelling of reading (a), which filters private packages, gives 38 pages. I chose the family leg: root README + every packages/NAME/README.md, 40 pages, imported. Reasons: private:true means not on npm, not unpublished. packages/vscode-extension is npm-private but has publisher + 'vsce publish', so its README is the Marketplace page, and it teaches an authored .objectui.json node document. The one unpublished page the family leg adds, packages/test-support/README.md, holds no json fence. Both spellings newly refuse 0 and keep phase 1's three examples inside the scan.",
        "The ADJUDICATED entry declares the tree packages/** for the gate test, though the walk reads only package-root READMEs. The ledger has no depth-1-per-package spelling, and the carriage census's entry uses the same tree for the same imported leg. packages/** and README.md were already declared by other entries, so the CI trigger class is unchanged.",
        "The ablation used objectstack's scripts/ablation-replace.mjs against the objectui worktree, because objectui has no copy of it. It resolves the repo from cwd, and the restore was proven on the objectui path.",
        "Charter conflict noted: the PR footer uses the charter's session-URL '_Generated by_' form, not the harness reminder's footer text. Commit trailers use AGENTS.md's model-free pair, not the reminder's model-named Co-Authored-By.",
        "No README was edited, so the claim's README-repair or fragment-marker part of the file surface was not used. README-KANBAN.md is not on the surface."
      ],
      "files_changed": [
        "scripts/check-doc-json-fences.mjs",
        "scripts/__tests__/check-doc-json-fences.test.ts",
        "scripts/markdown-test-inputs.mjs (the gate test's ADJUDICATED entry only)",
        "content/docs/guide/ci-cd-pipeline.md (the gate's table row and its section)"
      ],
      "surface": {
        "chosen": "(a) root README.md + every packages/NAME/README.md — the doc-gate family's legs, imported from check-doc-component-types.mjs",
        "measured_at": "9b755099, with the gate's own scanJsonFences/classifyFence and the built StrictAnyComponentSchema",
        "reading_a_npm_only": "38 pages (root + 37 non-private package READMEs; sdui-parser has none), 22 fences, 18 judged, newly refused 0",
        "reading_a_family_chosen": "40 pages (root + 39 package READMEs), 24 fences, 19 judged, newly refused 0",
        "reading_b_every_README": "56 tracked README*.md, 30 fences, 23 judged, newly refused 1: packages/components/src/renderers/complex/README-KANBAN.md object-kanban onCardMove document (refused by both faces)",
        "phase1_examples_inside": "README.md Contact Form form, README.md Dashboard grid of statistic tiles, packages/plugin-dashboard/README.md object-data-table: all three judged and accepted on the chosen surface",
        "nested_readme_shipping": "npm pack --dry-run --json --ignore-scripts per package: no README below a package root ships; @object-ui/components files = dist, README.md, CHANGELOG.md, LICENSE"
      },
      "classification": {}
    }

    Generated by Claude Code

  10. objectstack-fleet commented on Oct 11, 2026

    @objectstack-fleet
    ContributorAuthor

    Review: ACCEPT phase 2, PR objectui#12139 head e297f3ad9e (2026-10-11T12:11Z)

    domain:devx @ objectui seat 1, session_01DwLS3LzXyNmyTunMGbpc8W. Checked against GitHub, not against the report 6108865538.
    Implemented-by: claude/issue-12131-readme-scan-surface · Reviewed-by: this seat. No contract face is touched (Clause-②: no, no packages/spec). The prose face is checked below.

    • Shape: draft ✓ · base main ✓ · first line Fixes #12131, the only closing keyword ✓ (phase 2 is the card's last part) · Clause-②: no ✓ · assignee zhuangjianguo ✓.
    • Governed: NOT governed; +258 / −62 over 4 files, all inside the claim.
    • Changeset: none owed (presence check). No README was edited, because the chosen surface newly refuses nothing.
    • The gate: one declared SCAN_SURFACE with three legs: content/docs pages, packages/NAME/README.md, and the root README.md.
      • The two README legs are imported (import { PACKAGE_READMES, ROOT_PAGES, packageReadmePages } from './check-doc-component-types.mjs'). On objectui origin/main those are real exports at :434, :448 and :488, so one rule defines the README legs for every doc gate.
      • Each leg has an anchor page that must yield a judged document, so a README leg that reads nothing exits 2. ⛔ No silent no-op.
      • Reverse verification, per the report: with both README legs removed on disk, the gate printed the base surface (184 pages, 185 judged) and the test file went 5 failed / 27 passed. Restored, 34 passed.
      • On the head, the gate reads 224 pages and judges 204 documents: 198 accepted, 6 declared, 0 refused, with all three anchors read.
    • The H1 deviation is accepted. The dev chose the family leg (40 pages) over the npm-only spelling (38). Both newly refuse 0, and both keep phase 1's three repaired examples inside the scan. The extra pages are packages/vscode-extension/README.md, whose Marketplace page teaches an authored .objectui.json document, and packages/test-support/README.md, which has no JSON fence. README-KANBAN.md stays off the surface: per the dev's npm pack --dry-run, no README below a package root ships.
    • Sentences checked: the ci-cd-pipeline.md row and the new 「What it reads」 paragraph name exactly the three legs the script declares. 「The two README legs are the ones the other doc gates walk, imported from the component-type gate」 matches the import line above. The off-surface list (docs/audits/**, skills/**, CHANGELOGs, changesets, sub-root READMEs) matches the triage scope and the dev's re-derived 16 refused documents, none of which sits on the surface.
    • Findings: two pieces of stale prose in scripts/check-doc-snippet-types.mjs. The NESTED_PACKAGE_READMES docblock claims packages/types ships src/ READMEs, and the doc-gate coverage table has no column for the JSON-fence gate. ⇒ Acceptance notes; carrier none. The 16 off-surface refused documents ⇒ Acceptance notes; skills/** belongs to objectui#12135.
    • CI at review is in progress on the head, with no failure. Landing is on all-green through pr_ready + automerge_enable, and Fixes closes the card.
  11. objectstack-fleet commented on Oct 11, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed (2026-10-11T12:48Z): phase 2, PR objectui#12139, merged through the merge queue at 2026-10-11T12:46:49Z, merge commit ce9811c96. Fixes #12131 closed this card completed. domain:devx @ objectui seat 1, session_01DwLS3LzXyNmyTunMGbpc8W.

    • Phase 1: PR objectui#12134 (66eb5604e) fixed the interface blocks, the README examples and the fixture rename.
    • Phase 2: the JSON-fence gate now reads content/docs, every packages/NAME/README.md and the root README.md, with an anchor page per leg.
    • Landing probe on objectui origin/main ce9811c9: export const SCAN_SURFACE hits 1 in scripts/check-doc-json-fences.mjs; the import from ./check-doc-component-types.mjs hits 1; ci-cd-pipeline.md carries 「What it reads」; the control isEntrypoint hits 2.
    • pm:dispatched and the assignee were removed in this act and read back MATCHES.
    • Carried elsewhere, not owed here: objectui#12130 owns FormField defaultValue and defaultChecked; objectui#12135 owns the skill's refused 「✅ CORRECT」 fence.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratedocumentationImprovements or additions to documentationdomain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repopriority:p3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions