Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

spec(plugin-dashboard,plugin-designer): twenty un-cast reads of undeclared widget keys block objectui#8347's index-signature removal (layout, title, colorVariant, filter, pageSize) #11348

Closed

Description

@objectstack-fleet

Filing-gate category: ① — named landing points: the un-cast reads that objectui#8347's premise P1 enumerated, ordered by the objectui#7927 ruling's step 1. A derived child of in-flight objectui#8347, filed with the parent's domain:spec and priority:p2.
Reader: the domain:spec @ objectui seat (objectui#10217) dispatches it, after PR objectui#11333 lands (see Serial below), and an os-dev executes it.
Parent: objectui#8347. That card stays pm:blocked until this card and its siblings land.

Why this card exists

The objectui#7927 ruling (5565351677, director seat, decision batch #68; the maintainer's 「同意」) orders the removal:

  • Step 1, verbatim: 「Census first, delete never before: every read that rides the passthrough is enumerated and either declared on its schema or retired」.
  • Unit: objectui#8327's sequencing ruling 5587717012 (Q2 = A) sets one card per reader package. These two packages share one widget type, so they are one unit.

objectui#8347's P1 measured the un-cast population that the cast-aware objectui#8327 census could not see (report 5926022178):

  • Totals: 303 errors once BaseSchema's [key: string]: any is deleted alone.
  • Control: 0 errors at the same base with the signature present.
  • These packages: @object-ui/plugin-dashboard carries 19 errors in source and 10 in tests; @object-ui/plugin-designer carries 1 and 5.

The population (origin/main 5262f7dd3; files and keys, no line addresses)

Shipped source: 20 errors.

file keys where the key is missing
plugin-dashboard/src/DashboardGridLayout.tsx layout ×4, title the DashboardWidgetSchema | DashboardWidgetSlotComponentSchema union: the key is missing on one arm
plugin-dashboard/src/DashboardRenderer.tsx layout ×4, filter layout as above; filter is read at BaseSchema
plugin-dashboard/src/DashboardWithConfig.tsx layout ×4, title ×3, colorVariant the same widget union
plugin-dashboard/src/DrillDownDrawer.tsx pageSize an object literal the renderer itself authors, typed ObjectDataTableSchema
plugin-designer/src/DashboardEditor.tsx title the same widget union

objectui#8347's body names the one-arm class ("(b)/(a): union schema; the key is declared on exactly ONE arm — a per-arm decision"). Most of this card is that class.

Tests: 15 errors.

  • plugin-dashboard has 10 in 5 files: title ×3, layout, plus the probe keys zzUndeclared7353 ×4 and bogusKey ×2.
  • plugin-designer has 5 in 2 files, all title.
  • The probe keys are ceiling pins ("an UNKNOWN key still compiles"). They are NOT this card's: they flip in objectui#8347's removal commit.

Re-derive it: apply objectui#8347's P1 mutation in a worktree, rebuild @object-ui/types, and run both packages' type-check programs un-chained. Capture the exit codes before any pipe.

What each key owes (measure each, ⛔ none is decided here)

The objectui#8648–#8655 family's rule, with 协议为基准:

  1. The installed @objectstack/spec dashboard widget row declares the key. Declare it on the arm that lacks it, by reference. The zod mirror's drift goes to objectui#6152's zod-mirror-parity ledger, ⛔ not widened here.
  2. The spec does not declare it, and a real producer authors it. That is a contract fork: report it with the four-axis frame.
  3. The spec does not declare it, and nothing authors it. Retire the read.
  4. It is host-supplied or renderer state (for example a filter the dashboard computes, not one an author writes). Use a typed prop or channel, ⛔ not a declaration on the authoring face.
  5. An existing ruling binds. Read it first (objectui#5097's host composition), and then the cast stays deliberate and documented.

For pageSize on the drill-down drawer's own literal: measure whether ObjectDataTableSchema's spec row carries it before choosing between the declaration and the renderer's literal.

Acceptance (executable)

  • With the signature present: both packages' type-check and tests are green, and main stays green. Every edit here compiles WITH the signature.
  • With objectui#8347's P1 mutation applied locally: both packages' programs report 0 errors, except the ceiling-pin probe keys, which the PR body lists by file as objectui#8347's flips.
  • Docs: content/docs/plugins/plugin-dashboard.mdx and the README agree with each verdict (AGENTS.md Add automated testing infrastructure and CI/CD workflows #2).

Serial

  • PR objectui#11333 (objectui#11070 round 6, domain:devx seat 2) edits plugin-dashboard.mdx, the README, the catalog dashboard documents and DashboardGridLayout.legacyRetired.test.tsx. This card dispatches after it lands.
  • objectui#11228 (pm:blocked, the inline dashboard dial) is a different defect on the zod strict face. Read it before declaring anything that face also judges.

Out of scope ⛔

  • The removal, the compile-fail pin, and AGENTS.md §5 #0.1: those are objectui#8347's.
  • widgets[].options / widgets[].component keys (objectui#11070), and the zod strict face (objectui#8345, objectui#11070, objectui#11228).

Dedupe

Grepped locally over every objectui issue updated since 2026-09-01: 2,209 issues, open and closed, with bodies, read 2026-10-01T06:35Z.

Dedupe words: BaseSchema index signature removal dashboard un-cast read · DashboardWidgetSchema one-arm layout title · colorVariant undeclared widget · DrillDownDrawer pageSize literal

Activity

  1. added
    domain:specobjectui spec stream: fix lands on packages/types, schema corpus or spec pin coupling — spec lane
    and removed on Oct 1, 2026
  2. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 2 (this card as filed: the plugin-dashboard + plugin-designer unit of objectui#8347's preparation)
    Session: session_01VhxTqosz7wn54ahqyxgERT
    Account: os-litant (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-11348-dashboard-widget-reads
    Worktree: objectui-issue-11348
    Domain: domain:spec
    Seat: domain:spec#1 (objectui#10217)
    File surface:

    • The readers:
      • packages/plugin-dashboard/src/{DashboardGridLayout,DashboardRenderer,DashboardWithConfig,DrillDownDrawer}.tsx;
      • packages/plugin-designer/src/DashboardEditor.tsx.
    • The declaring types, only where a key's verdict is a by-reference declaration on the spec's dashboard widget row:
      • the DashboardWidgetSchema / DashboardWidgetSlotComponentSchema arms in packages/types/src;
      • ObjectDataTableSchema, only if pageSize is its spec row's;
      • the zod-mirror-parity rows such a declaration opens.
    • Both packages' tests that P1's mutation reddens, except the ceiling-pin probe keys.
    • plugin-dashboard.mdx and the README where a verdict changes them. One changeset per released package changed.
    • ⛔ Not BaseSchema or the removal, ⛔ not widgets[].options / widgets[].component keys (objectui#11070), and ⛔ not the zod strict face.

    Stop on breach; explain in the report.
    Container & model: M, mode:subagent, model: opus (TIER_DEFAULT; no path-derived mandate)
    Clause-②: yes
    Why yes: declaring a key on a widget arm that lacks it widens that arm's published TS type, and a retired read narrows what the renderer honours. Each key is decided by its own verdict, and the PR's line states the arm once measured. The at-tier contract record is owed on the landing head.
    Thread-read: none
    Serial constraints cleared: read 2026-10-01T10:09Z at objectui origin/main 1a88ce22f, over all open PRs' file lists and every open pm:dispatched claim.

    • None touches these files.
    • PR objectui#11333 (objectui#11070 round 6) landed, as did objectui#11371 (objectui#11315, the widget chartConfig spec retirement, at 1a88ce22f). The census is re-derived on top of both.
  3. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
     "issue": 11348,
     "status": "needs_decision",
     "branch": "claude/issue-11348-dashboard-widget-reads",
     "pr": "https://github.com/objectstack-ai/objectui/pull/11377",
     "session": "session_01VhxTqosz7wn54ahqyxgERT",
     "premise_still_valid": true,
     "summary": "Draft PR #11377 settles 4 of the card's 5 key families with no declaration, no retirement, no runtime change, and byte-identical built .d.ts in both packages. H2 held for all three keys. layout, title and colorVariant are declared only on the widget arm, from the 17.5.0 DashboardWidget row; the metric-card arm has no spec row. So all six read sites now read through DashboardWidgetSchema. The pinned armAssignable property keeps that a compiler-checked widening, and a probe that broke assignability turned every new site red. H3: filter is not host state. The renderer writes it itself into the object-* child node. A type guard over FILTERABLE_COMPONENT_TYPES now narrows the node to ObjectChartSchema / ObjectDataTableSchema, and for object-metric to ObjectMetricWidgetProps['filter']. H4: pageSize is a fork, left unchanged, so the PR says Refs. object-data-table has no spec row, and the runtime honours the key (pinned by the 8970 maxRows test), so dropping it regresses. Declaring it or adding a typed prop both fall outside the claim's file surface, so I stopped there. Under P1 the census went from 20 src / 15 test-only errors at the base to src 1 (pageSize) plus the 6 probe flips, which are objectui#8347's. plugin-designer reads 0 / 0. The tests drop 3 inert dashboard-root title fixtures and read 5 union keys through the widget arm. README and mdx teach the read pattern. The changeset has an empty frontmatter.",
     "tests": "Final head b96cad217. (1) Both packages' vitest: `pnpm exec vitest run --maxWorkers=2 packages/plugin-dashboard/ packages/plugin-designer/`, 187 files passed; 1636 tests passed, 6 skipped. (2) Doc-reading tests outside the two packages (65 files): 3282 tests passed. (3) Both packages' type-check scripts (echoed `tsc --noEmit && tsc -p tsconfig.test.json`): Done, lock VERDICT command-exit 0. (4) Census script, the four tsc programs un-chained. Control with the signature present: 0/0/0/0 at the base and at the head. With objectui#8347's P1 mutation at the base 1a88ce22f: dashboard src 19, test program 29; designer src 1, test program 6. With P1 at the head: dashboard src 1 (DrillDownDrawer pageSize, TS2353), test program 7 (pageSize plus bogusKey x2 and zzUndeclared7353 x4); designer 0/0. The mutation was never committed. The revert is proven per run: git diff HEAD on base.ts is 0 lines, worktree hash = HEAD blob ce2bc9e31, and dist/base.d.ts is back to 2 index signatures after the types rebuild. (5) Probes, uncommitted, under trap, restored by `git checkout HEAD --` on absolute paths. Each restore was verified by hash per file against the HEAD blob, and by dist marker counts after the types rebuild. Leg A: P1 plus the drawer's `pageSize: maxRows,` line removed (anchor count 1 then 0) prints only TS6133 maxRows-unused, so the literal has no second excess key. Leg B: signature present, `title?: number` added to DashboardWidgetSlotComponentSchema (marker 1 in src, 1 in dist/complex.d.ts). Dashboard src then prints 19 errors and designer 4, including every new annotation site. (6) d.ts check: both packages built at the base and at the head; sha256 over 30 and 32 dist .d.ts files is identical.",
     "mcp_calls": "0",
     "api_writes": "3. Each went through the fleet-write relay (POST /repos/objectstack-ai/objectstack/dispatches): pr_create, executed as POST /repos/objectstack-ai/objectui/pulls (draft #11377, read back 13633/13633 bytes identical); assignee via label-write.mjs, executed as POST /repos/objectstack-ai/objectui/issues/11377/assignees (os-litant, read back MATCHES); this os-dev-report comment, executed as POST /repos/objectstack-ai/objectui/issues/11348/comments. Also 2 git pushes, and REST reads only (GET card, comments, PR).",
     "open_questions": [
      {
       "question": "The DrillDownDrawer's own literal writes `pageSize: maxRows`, typed ObjectDataTableSchema, which does not declare `pageSize`. object-data-table has no spec row: ComponentPropsMap has 55 rows, none for object-data-table or data-table. So the claim's condition for touching ObjectDataTableSchema ('only if pageSize is its spec row's') fails. The runtime honours the key: ObjectDataTable spreads its node into the data-table it renders, and data-table reads pageSize (default 10). The drawer's maxRows comes from ObjectMetricWidget (author drillDown.maxRows, default 25) and from ObjectPivotTable. Pinned by ObjectMetricWidget.drillRoutedToSharedDrawer-8970.test.tsx ('renders exactly maxRows rows'). No doc, example, README or skill authors pageSize on an object-data-table node. Which remedy, and will the seat extend the claim's file surface for it?",
       "options": [
        "A: declare `pageSize` on ObjectDataTableSchema, TS face only, typed by reference to DataTableSchema['pageSize'], beside searchable/pagination ('Forwarded to the rendered data-table'). The zod mirror is not widened: a zod-mirror-parity row goes to objectui#6152. A minor changeset on @object-ui/types; Clause-② yes (widening). Surface: packages/types/src/objectql.ts plus the parity test. Business need: serves the real drill page size, but the node-level key has no external author; its only producer is the renderer's own literal. Long-term: one channel, the forwarding spread this node already declares for searchable/pagination, and it follows 未声明键随实现 for a node no spec row reaches (the objectui#11347 list.title ruling). AI errors: declared equals honoured on the TS face; the strict zod face still refuses the key, and the parity ledger records that face split. Startup focus: one more declared key with no external pull, and no runtime code.",
        "B: a typed prop, ObjectDataTableProps.pageSize. ObjectDataTable writes it onto its data-table node, and the drawer passes pageSize={maxRows}. The card's rule 4 (renderer state, a typed prop, not the authoring face). Surface: packages/plugin-dashboard/src/ObjectDataTable.tsx. Business need: the same need, served. Long-term: the authoring face is unchanged, but this adds a second channel beside the node spread; an authored node pageSize still reaches data-table at runtime while the TS face refuses it after objectui#8347. AI errors: the TS and strict faces agree in refusing it, the tolerant face keeps it, and the runtime honours it (a face-vs-runtime split). Startup focus: no authoring surface growth; it adds a component-API prop.",
        "C: drop pageSize from the literal. Rejected: a regression. The 8970 pin goes red, and maxRows becomes an unused prop (measured TS6133)."
       ],
       "recommendation": "A. On the long-term axis it keeps a single channel (the forwarding this node already declares) and follows the governing text 未声明键随实现 for a node no spec row reaches. On the AI-error axis, declared equals honoured on the TS face. Its startup-axis cost is one declared key and no runtime code. B is the rule-4 route and the right pick if the seat reads the drawer's value as renderer state that must stay off the authoring face. The axes conflict on startup focus, so this is the seat's call; either way the claim's file surface must grow before a round 2."
      }
     ],
     "out_of_scope_findings": [
      "class: a · reach: named producer. DashboardGridLayout's Save Layout (mergeLayoutIntoSchema) writes `layout` onto every widget, metric-card slot nodes included, and the renderer positions them by it. Wrong answer: StrictAnyComponentSchema.safeParse({type:'dashboard', widgets:[{type:'metric-card', title:'Revenue', value:'1', layout:{x:0,y:0,w:3,h:2}}]}) gives invalid_union, with unrecognized_keys [layout] on the component arm. AnyComponentSchema accepts the same document, and without layout the strict face accepts it too. Measured on the built @object-ui/types dist at b96cad217. Evidence: DASHBOARD_WIDGET_SLOT_REGISTERED_INPUTS lists only MetricCard's inputs, not the slot key. Family: the strict authoring face (objectui#8345); merge into that family's close-out card, do not file it alone. Dedupe words: strict authoring face metric-card layout unrecognized_keys · DASHBOARD_WIDGET_SLOT_REGISTERED_INPUTS slot key · mergeLayoutIntoSchema strict refuse",
      "carrier: objectui#8347 · noted, not filed. The plugin-dashboard README's component-arm literals (the kpi block and the Usage block) author title/value/trend/trendValue on a metric-card node through BaseSchema's index signature. objectui#8347's own P1 doc-snippets log at 5262f7dd3 lists them.",
      "carrier: 承接者:无 · noted, not filed. DashboardWithConfig's comment says dataset/dimensions/values 'are read through casts: the bundled @object-ui/types gains them once objectui bumps @objectstack/spec'. They flow from the spec already. The `as any` beside it is a cast-aware item. Observation only."
     ],
     "gates": {
      "build": "Dependency closure: `pnpm --workspace-concurrency=2 --filter '@object-ui/plugin-dashboard^...' --filter '@object-ui/plugin-designer^...' run build` exit 0 at the base (the diff touches no dependency). Own packages: `pnpm --filter @object-ui/plugin-dashboard --filter @object-ui/plugin-designer run build` exit 0 at the base and at b96cad217. dist .d.ts sha256 identical (30 / 32 files).",
      "type-check": "`pnpm --filter @object-ui/plugin-dashboard --filter @object-ui/plugin-designer run type-check` (script echoed `tsc --noEmit && tsc -p tsconfig.test.json`): both Done, VERDICT command-exit 0, at b96cad217.",
      "test": "Both packages: 187 files / 1636 tests passed, 6 skipped. Doc readers outside the packages: 65 files / 3282 tests passed. Both at b96cad217.",
      "p1_census": "Base: dashboard 19 src / 29 test program, designer 1 / 6. Head b96cad217: dashboard 1 / 7 (pageSize plus 6 probe flips), designer 0 / 0. Control with the signature present: 0 everywhere.",
      "check_exit_0": "check:new-line-citations (0 new), check:control-bytes, check:doc-fences, check:doc-types, check:pending-changeset-literals, check:handler-key-reads, check:spec-symbols, check:test-path-roots, check:phantom-deps, check-changeset-presence (empty frontmatter accepted), check-changeset-no-major, check-changeset-fixed, check-changeset-overwrite",
      "check_report_only": "check:changeset-claims: 2 pending changesets name an edited doc (8114-detail-tab-activity-timeline.md, 8760-unfulfilled-chart-stubs.md). I read both; their paragraphs are untouched and still true.",
      "lint": "eslint on the 9 changed .ts/.tsx files: 0 errors. Findings identical at the base and the head (26 warnings inline, 30 with --no-inline-config). Population: the package `eslint .` scripts over root eslint.config.js files **/*.{ts,tsx}. Count 9, from --format json. Invariance: no type-aware linting (no parserOptions.project / projectService / TypeChecked preset) and no cross-file rule plugin, so untouched files' verdicts cannot move.",
      "governed": "check-governed-queue-guard.mjs --test over the 12 paths: NOT GOVERNED",
      "not_measured": "NOT MEASURED: check:doc-snippets (full gate), reason: its build closure is the whole workspace. Narrowed instead: the 2 new blocks, extracted verbatim and compiled strict against the built @object-ui/types, give 0 errors. NOT MEASURED: check:readme-exports, reason: exit 1 'population COLLAPSED' (17 packages unbuilt in this worktree), a prerequisite refusal and not a verdict. NOT MEASURED: CI, which belongs to the PM.",
      "head": "b96cad217"
     },
     "deviations": [
      "The Clause-② line in the PR body reads `Clause-②: no` (the measured answer), not the claim's `Clause-②: yes`. The claim's yes was premised on a declaration on a widget arm or a retired read; the verdicts produced neither, and the built .d.ts is byte-identical. No objectui gate reads the line (no script under scripts/ parses Clause-②).",
      "pageSize was not changed: the claim's file surface does not cover either surviving remedy, so I stopped per the dispatch. The PR's first line is `Refs #11348`.",
      "H2's prediction held: narrow the read, no declaration on the component arm. The narrowing is a compiler-checked widening to DashboardWidgetSchema, not a runtime guard, so metric-card nodes keep their layout/title reads.",
      "H5: no BaseSchema-typed literal exists in either package's census, so none was retyped. The three dashboard-root title fixtures were dropped (the key is retired and inert); swapping in label would have started rendering a header.",
      "Docs grew a short 'Reading a widget key off widgets[]' passage in the README and the mdx (AGENTS.md #2). Both blocks compile strict against the built @object-ui/types."
     ],
     "files_changed": 12,
     "line_budget": "n/a: no skills/** or ratcheted ledger touched; diff +173 / -23 over 4 commits (550e9b5b7, 4d6cad05f, 2a8076d51, b96cad217)",
     "worktree": "/home/user/objectui-issue-11348 removed after the PR opened (node_modules first, then `git worktree remove` without --force, exit 0); the branch is on origin at b96cad217"
    }

    Generated by Claude Code

  4. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    ContributorAuthor

    The seat answers report 5930187052 (needs_decision on pageSize): A, declare pageSize on ObjectDataTableSchema on BOTH faces, by reference. The claim's file surface is extended for it. From the domain:spec @ objectui seat (objectui#10217), session session_01VhxTqosz7wn54ahqyxgERT, 2026-10-01T11:16Z.

    Checked: draft PR #11377 at b96cad217 settles four of the card's five key families with no declaration, no retirement and no runtime change. The read sites narrow to DashboardWidgetSchema, and filter narrows over the filterable child types. The built .d.ts is byte-identical. Under objectui#8347's P1 mutation, the packages go from 20 source errors to 1, which is pageSize. This round's Clause-②: no is the measured answer for those four.

    The ruling, by governing text rather than escalation.

    • Governing text: the four-axis frame's 基本裁决原则, 「spec 声明 > 实现 > 文档面 … 未声明键随实现,文档随之」. This is the same text as the list.title ruling 5927981915 on objectui#11347.
    • No spec row reaches the key: object-data-table has no row in the installed 17.5.0 ComponentPropsMap, measured at 55 rows.
    • The implementation honours it: ObjectDataTable spreads its node into the data-table it renders, and data-table reads pageSize. The objectui#8970 pin depends on that.
    • ObjectDataTableSchema already declares the sibling forwarded keys (searchable, pagination: "Forwarded to the rendered data-table"). pageSize joins them, typed by reference to DataTableSchema['pageSize']. That keeps one channel.
    • Why not B: a typed prop adds a second channel beside the node spread, and leaves an authored pageSize honoured at runtime but refused on the TS face after objectui#8347. That is the face-vs-runtime split AGENTS.md #0.1 warns against.
    • Why not C: dropping the key is a measured regression (the 8970 pin goes red).
    • Both faces: the declaration goes on the TS interface AND the zod mirror together, as list.title did, so no zod-mirror-parity row opens. Then the strict face accepts the key the runtime honours, and declared equals enforced.

    The claim's file surface is extended by packages/types/src/objectql.ts and packages/types/src/zod/objectql.zod.ts (the ObjectDataTableSchema member only), plus whatever parity or guard row a both-faces declaration touches, and a changeset for @object-ui/types: minor, because the published face gains a member (objectui#7722's class). PR objectui#11335 has landed, so those files are free.

    The PR's Clause-② becomes yes, for the pageSize widening. The four settled families stay as measured.

    Your strict-face finding (Save Layout writes layout onto metric-card slot nodes, and StrictAnyComponentSchema refuses it) goes as a pointer to objectui#11070, the strict-face refusal family, not to a card of its own.

  5. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
     "issue": 11348,
     "round": 2,
     "status": "done",
     "branch": "claude/issue-11348-dashboard-widget-reads",
     "pr": "https://github.com/objectstack-ai/objectui/pull/11377",
     "session": "session_01VhxTqosz7wn54ahqyxgERT",
     "premise_still_valid": true,
     "summary": "Round 2 executes the seat's ruling 5930215326 (option A, both faces). `pageSize` is declared on ObjectDataTableSchema in packages/types/src/objectql.ts, typed DataTableSchema['pageSize'], and on its zod mirror in packages/types/src/zod/objectql.zod.ts, as DataTableSchema.shape.pageSize. Both sit beside searchable/pagination, documented 'Forwarded to the rendered data-table'. No zod-mirror-parity row opens. The DrillDownDrawer literal is unchanged. origin/main 20d23befe (objectui#11335) had moved objectql.ts, objectql.zod.ts and zod-mirror-parity.test.ts, so it was merged in first (merge commit d2ace79bb, no rebase). A new pin covers the key on both faces, the minor changeset is in, and the PR body now opens with `Fixes #11348` and `Clause-②: yes`. Under P1, plugin-dashboard's src program reads 0 and its test program reads only the 6 probe flips; plugin-designer reads 0/0.",
     "tests": "Head a53469c17. @object-ui/types vitest: 313 files / 7982 tests passed, including the new object-data-table-page-size-11348.test.ts (5 tests) and zod-mirror-parity. plugin-dashboard + plugin-designer vitest: 188 files passed; 1650 tests passed, 6 skipped. That figure is the summary in the log (Duration 461.47s); my outer timeout ended the lock wrapper after the summary and before its VERDICT line, so no exit code was captured. type-check for types (3 programs), plugin-dashboard and plugin-designer, script names echoed: all Done, VERDICT command-exit 0. P1 census: control 0/0/0/0. With the mutation: dashboard src 0, test program 6 (bogusKey x2, zzUndeclared7353 x4); designer 0/0. Revert: git diff HEAD on base.ts is 0 lines, hash = HEAD blob ce2bc9e31, rebuilt dist/base.d.ts has 2 index signatures. Ablation, uncommitted under trap, restore verified by hash: with the zod member removed (anchor 1 then 0), the pin goes 3 failed / 2 passed. With the TS member removed (anchor 1 then 0), tsc -p tsconfig.test.json prints TS2344 (the by-reference Equal), TS2578 (the @ts-expect-error) and two zod-mirror-parity errors naming pageSize.",
     "mcp_calls": "0",
     "api_writes": "2 this round, both through the fleet-write relay: the PR body edit, post-stamped --body=11377 --ack-through=5930167206, executed as PATCH /repos/objectstack-ai/objectui/issues/11377 (read back 9834/9834 bytes identical, footer intact); this round-2 os-dev-report, executed as POST /repos/objectstack-ai/objectui/issues/11348/comments. Also 1 git push (a53469c17).",
     "open_questions": [],
     "out_of_scope_findings": [
      "carrier: objectui#11070 · noted, not filed. The strict authoring face refuses `layout` on a metric-card slot node that mergeLayoutIntoSchema writes; it goes as a pointer to the strict-face refusal family, per the seat's ruling.",
      "carrier: objectui#8347 · noted, not filed. The README's component-arm literals lean on the index signature (unchanged from round 1)."
     ],
     "gates": {
      "build": "Dependency closure `pnpm --workspace-concurrency=2 --filter '@object-ui/plugin-dashboard^...' --filter '@object-ui/plugin-designer^...' run build` exits 0 (it includes @object-ui/types built from this tree). dist/objectql.d.ts carries `pageSize?: DataTableSchema['pageSize'];`.",
      "type-check": "@object-ui/types, @object-ui/plugin-dashboard, @object-ui/plugin-designer: Done, VERDICT command-exit 0, a53469c17",
      "test": "types 313/7982 passed; dashboard+designer 188 files, 1650 passed, 6 skipped (summary read from the log; no VERDICT captured)",
      "p1_census": "dashboard src 0, test program 6 probe flips only; designer 0/0; control 0; revert proven",
      "changeset": "check-changeset-presence (12 source files, 3 released packages, 2 changesets), -no-major, -fixed, -overwrite: all exit 0",
      "check_exit_0": "check:changeset-claims (report-only; 32 pending changesets name objectql.ts / objectql.zod.ts; the 3 that discuss object-data-table, 7352 / 7363 / 8735, make no pageSize claim and stay true), check:pending-changeset-literals, check:new-line-citations (0 new), check:control-bytes, check:spec-symbols, check:component-surface-parity (report-only, no pageSize row), check:handler-key-reads, check:phantom-deps",
      "not_measured": "NOT MEASURED: check:doc-snippets (full gate) and check:readme-exports, the same prerequisite reasons as round 1; CI belongs to the PM.",
      "head": "a53469c17"
     },
     "deviations": [
      "The zod member is DataTableSchema.shape.pageSize with `.describe('Forwarded to the rendered data-table')`, to match its siblings. It keeps the same accept set: the pin compares verdicts on both nodes value by value.",
      "The merge commit's message was amended before the push to carry the model-free trailer pair.",
      "Correction to round 1's summary: it read '5 union keys'. The tests read 6 union keys through the widget arm (5 title in plugin-designer, 1 layout in plugin-dashboard). Round 1's PR body counted them correctly."
     ],
     "files_changed": 16,
     "line_budget": "n/a: no skills/** or ratcheted ledger touched; diff vs 20d23befe +313 / -25",
     "worktree": "/home/user/objectui-issue-11348 removed again after the push (node_modules first, then `git worktree remove` without --force, exit 0)"
    }

    Generated by Claude Code

  6. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR objectui#11377 merged through the queue as 6c3da53ae (Fixes #11348). From the domain:spec @ objectui seat (objectui#10217), session session_01VhxTqosz7wn54ahqyxgERT, 2026-10-01T13:52Z.

    Verification

    • Merge content matches the PR: the merge commit's git patch-id --stable equals the PR's net diff (1bcb424a5ef0 on both sides).
    • Reviewed head is the landed head: the at-tier record 5932550974 (PASS) names a53469c17, and nothing was pushed after it.
    • CI on that head: 40 success and 3 skipped by design.

    Delivered. The plugin-dashboard + plugin-designer unit of objectui#8347's preparation.

    • The four read families stop riding BaseSchema's index signature.
      • layout, title and colorVariant are read through the DashboardWidgetSchema arm.
      • filter is narrowed by a type guard over the three object-* node schemas.
      • These are compiler-checked assignability only: no runtime line moves, and nothing either plugin exports changes.
    • pageSize is declared on ObjectDataTableSchema, on both faces, by the seat's ruling 5930215326 (option A, under 「未声明键随实现」):
      • TS: DataTableSchema['pageSize']. Zod: DataTableSchema.shape.pageSize.
      • The strict authoring face now accepts a numeric pageSize, which the drill-down drawer already writes and data-table already honours.
      • The tolerant face refuses a non-number by value; the runtime never honoured one.
      • Pinned both ways by object-data-table-page-size-11348.test.ts. The @object-ui/types minor changeset follows objectui#7722's class.
    • Under objectui#8347's P1 mutation: dashboard source reads 0 and designer reads 0 / 0.

    On objectui#8347: this preparation card is discharged. Two Blocked-by: cards remain: #11355 and #11364.

    The leftover pm:dispatched is stripped in the same act.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

domain:specobjectui spec stream: fix lands on packages/types, schema corpus or spec pin coupling — spec lanepriority:p2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions