You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
spec(ui): refuse two or more measures on a dimensionless dashboard widget whose type declares no multi-measure rendering (pie, donut, funnel, scatter, radar, treemap, sankey): ruling D's principle, objectui#8894 Q1 #20958
Filed by the triage seat (objectstack-wide, seat post #6015, session_01AavokzJ5DndAwitDXvKy4U) as the spec half of triage's answer to objectstack-ai/objectui#8894's Q1. ⛔ Not a claim, ⛔ not a dispatch. Graded here: enhancement · priority:p3 · domain:spec · area:reports · pm:queue.
Why
Ruling D (maintainer, on objectui#8894, 5643392537) judged the protocol wrong where it admits measures that a widget type cannot render: 「协议不正确的应该先修改协议」. That narrowed the metric family. Its ADR-0087 entry named table and the chart families as the remedy: "type: 'table' renders a row of measures, and the chart families (bar / line / area / combo) render one mark per measure".
objectui#11261 (PR objectui#11278) delivers that for table / pivot and the bar / line / area / combo families. objectui#8894's next claim adds column / horizontal-bar, the bar family's orientations.
Measured by objectui#11261's dev (5920760284): the other seven ChartTypeSchema members, pie, donut, funnel, scatter, radar, treemap, sankey, with no dimension and two or more measures render values[0] and drop the rest. Every door accepts them.
Census: 0 authored dimensionless multi-measure widgets of any type in objectstack's examples or objectui's examples/apps.
So the spec admits a shape it does not declare how to render. That is ruling D's case, with zero pull.
Scope (packages/spec)
An object-level check beside checkDashboardWidgetMetricMeasureArity (packages/spec/src/ui/dashboard.zod.ts). A widget whose dimensions is empty or absent, whose values has two or more measures, and whose type is outside the multi-measure set is refused at values, naming the widget's id, the count and the type.
The multi-measure set is table, pivot, bar, column, horizontal-bar, line, area and combo.
The set is one exported constant, read by the check, the refusal text and objectui's mirror. ⛔ No second list.
The refusal steers: to table (a row of measures) or a bar-family type, or to one widget per measure.
An ADR-0087 entry (semantic, as the metric entry is, since splitting tiles is a layout decision). Clause-②: yes (a narrowing). Ships at once: nothing renders the dropped measures today.
Relaxing later is free. If one of the seven gains a declared multi-measure rendering (a radar of measures, a funnel of measure stages), it joins the set with no migration. ⛔ This card does not invent those renderings.
Pins
Each of the seven types, dimensionless with two measures, is refused.
The same type with one dimension, or with one measure, parses.
Each type in the multi-measure set parses dimensionless with three measures (the control).
The metric family's existing refusal is unchanged.
Then
objectui's mirror re-attaches the check (as PR objectui#11257 did for the metric family) at the spec bump. That is a coordination child this claim files.
objectui#8894's warning keeps its "a declared measure is not rendered" condition for stored rows.
Claim: PM loop round 1 · 2026-10-01T00:33Z
Session: session_017VaLJnYwhPsanVCe9dMCJU
Account: os-bill (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/issue-20958-dimensionless-multi-measure-refused
Worktree: objectstack-issue-20958
Domain: domain:spec
Seat: domain:spec#2 (seat post #18549)
File surface: packages/spec/src/ui/dashboard.zod.ts (one object-level check beside checkDashboardWidgetMetricMeasureArity, about :627, and the one exported multi-measure constant it, the refusal text and objectui's mirror read); its tests in packages/spec/src/ui/; one ADR-0087 semantic entry under packages/spec/src/migrations/entries/semantic/ and the regenerated migrations/registry.ts; the regenerated spec artefacts the edit moves (api-surface, references); fixtures in the consumer packages only where one authors a now-refused shape (the dev names each); one .changeset/20958-*.md (minor, BREAKING header, ADR-0087 marker). Stop on breach and explain in the report.
Container & model: M, mode:subagent, model: opus (dispatch-gates --tier: no path-derived mandate; floor sonnet · default opus · ceiling fable).
Clause-②: yes (narrowing)
Thread-read: none
Serial constraints cleared: read at this stamp against origin/main05be35259. No open PR touches packages/spec/src/ui/dashboard* or the dashboard migration entries, and no fleet pm:dispatched claim names them. objectui#11278 (the table / bar-family rendering) merged at 2026-09-30T22:58Z. Review: an at-tier contract review is owed before enqueue (a narrowing, plus a new export, on packages/spec/src/**).
os-dev-report
{
"issue": 20958,
"status": "done",
"branch": "claude/issue-20958-dimensionless-multi-measure-refused",
"pr": "#21053",
"session": "session_017VaLJnYwhPsanVCe9dMCJU — the parent's id (this run is a subagent of the domain:spec#2 PM)",
"premise_still_valid": true,
"summary": "Added DASHBOARD_WIDGET_MULTI_MEASURE_TYPES (the one exported list: table, pivot, bar, column, horizontal-bar, line, area, combo) and checkDashboardWidgetDimensionlessMeasureArity, chained onto DashboardWidgetSchema by identifier right after the metric check: a widget with dimensions absent or [] and two or more values on pie/donut/funnel/scatter/radar/treemap/sankey gets ONE custom issue at values naming id, count and type, listing the set (read from the constant) and steering to table, a bar-family type, or one widget per measure. The metric family is excluded so its existing refusal stays one issue and byte-identical, and the export returns on types outside ChartTypeSchema so objectui's wider-enum mirror is judged exactly as the spec door judges. ADR-0087 semantic entry 18.dashboard-widget-dimensionless-multi-measure-refused.ts plus the gen:migration-registry lap, a minor BREAKING changeset with the registered marker and Clause-② line, and regenerated api-surface/export-origins/ui.json (+2 each, 0 removed) and the values row of references/ui/dashboard.mdx. H1: one attachment point in this repo (the DashboardWidgetSchema superRefine chain), new check attached there. H2: refused by the schema alone at DashboardSchema, the dashboard metadata-type schema, ObjectStackDefinitionSchema, defineStack, os validate (fails at defineStack load) and the metadata save path (422 INVALID_METADATA, active and draft, 0 rows), with table/bar/pie-with-dimension controls passing. H3: 0 authored dimensionless multi-measure widgets on the seven (23 seven-type literals, all one dimension and one measure; objectui checkout 1263e40 reads 0 too), so no fixture triage and the stop condition did not fire. Merged origin/main 9b0de7d via os-regen-merge.sh before opening the PR and regenerated the two os-regen artifacts on the merged tree.",
"tests": "All at e1494c7 (merged tree) unless noted, each package's own vitest against its rebuilt dependency closure (per-package filters, not the full ...@objectstack/spec sweep): spec --project local 584 files / 17290 passed / 1 todo exit 0; spec typecheck (tsc + scripts + test layer) exit 0, ledger 52 files / 248 errors / 136 signatures held; metadata-protocol 195 passed + 3 skipped files, 2896 passed / 19 skipped tests, exit 0; lint 117 files / 5446 exit 0; service-analytics 150 / 3458 exit 0; sdui-parser 13 / 224 exit 0; platform-objects 59 / 948 exit 0; objectql --project local 348 / 6821 exit 0; metadata 56 / 836 exit 0; cli --project unit 239 / 3391 exit 0 (integration tier declared to CI: no spawn entry or integration file touched). Pre-merge at 1a0e75a the spec suite (584 / 17284) and metadata-protocol, lint, sdui-parser, platform-objects were also green. Ablation at committed 1a0e75a via scripts/ablation-replace.mjs, subject imported from src by relative path (no dist on the path): deleted only the .superRefine(checkDashboardWidgetDimensionlessMeasureArity) attachment; anchor x1 -> x0, marker x0 -> x1, blob b33ae8c4bd64 -> 209e3d201d54; RED vitest exit=1 27 failed / 274 passed (301); restored blob == HEAD blob b33ae8c4bd64, git diff HEAD empty; GREEN full spec suite at 1a0e75a after the restore. A first ablation attempt (replacement ');', a substring of the anchor) was refused by the tool because the replacement count could not rise; it restored and was not counted. check:generated at e1494c7: All 15 generated artifacts are up to date. Narrowed lint at e1494c7: eslint --no-inline-config --format json over the 5 touched .ts files = 5 files, 0 errors, 0 warnings; population: eslint --print-config returns a rule set for each (none ignored); invariance: no type-aware linting (parserOptions.project and projectService null; eslint.config.mjs states it never enables them), so untouched files' verdicts cannot move.",
"gates": "dispatch-gates --commands --repo objectstack-ai/objectstack at e1494c7 derived 113 commands; all 113 ran, every final exit 0. --ran reconciliation with exit-coded record: '113 derived, 113 run, 0 NOT-MEASURED, 0 UNRUN' and 'a DERIVED zero — all 113 recorded an exit code and none of them is 3'. Three first answers were not verdicts and were rerun to exit 0: pnpm --filter @objectstack/spec run check:skill-examples (exit 3 PREREQUISITE NOT MET, client-react unbuilt; after build: '259 prose examples type-check across 3 surface(s)'), pnpm check:dual-build-cjs-loads (exit 3, eight packages without dist; after build exit 0), pnpm check:query-options-erasure (killed by my own 240 s per-command cap, exit 124; uncapped 278 s exit 0, 'ratchet holds: 67 unswept non-test site(s) in 17 file(s), none new'). Verdict lines: check-adr-0087-registration --base origin/main exit 0 '[BREAKING+bang+clause-②-narrowing] registered dashboard-widget-dimensionless-multi-measure-refused'; check-changeset-no-major exit 0 'This diff introduces no major bump'; check:api-surface exit 0 'public API surface + factory signatures unchanged' (after regeneration); check:migration-registry, check:spec-changes, check:upgrade-guide, check:docs, check:nul-bytes, check:pm-widening-tells, check:spec-docblock-symbol-anchors, check:issue-citations, check:doc-authoring, check:widget-option-census all exit 0. Outside the 113 (CI's): the type-check lanes, path-scheduled CI jobs (Test Core shards, Dogfood, Temporal Conformance, Build Core) and the artifact-roster families are NOT MEASURED locally, reason: CI-owned whole-tree runs.",
"line_budget": "none owed: no skills/** in the diff",
"files_changed": [
".changeset/20958-dimensionless-multi-measure-refused.md",
"content/docs/references/ui/dashboard.mdx",
"packages/spec/api-surface/ui.json",
"packages/spec/export-origins/ui.json",
"packages/spec/src/migrations/entries/semantic/18.dashboard-widget-dimensionless-multi-measure-refused.ts",
"packages/spec/src/migrations/registry.ts",
"packages/spec/src/ui/dashboard.test.ts",
"packages/spec/src/ui/dashboard.zod.ts",
"packages/spec/src/ui/object-refinement-check-exports.test.ts"
],
"deviations": [
"Two new exports, not 'the one new exported constant' the dispatch noted beside Clause-②: the check is exported too, because object-refinement-check-exports.test.ts pins one export per custom check on the schema and objectui's mirror chains it by name. Clause-② yes (narrowing) covers both; the changeset's Clause-② line names both.",
"No STEP18_RATIONALE fragment added: the dispatch's hot-file note reads 'a major-18 entry adds its own fragment', but the metric-family precedent 09e16a5 added none and the step holds 52 fragments for 254 major-18 semantic entries (fragments accompany conversions). Followed the precedent; no other fragment touched. Conflict surfaced here rather than resolved silently.",
"Metric family excluded from the new check (card text reads 'outside the multi-measure set'): including it would double the metric family's existing refusal to two issues, which the card's pin 'the metric family's existing refusal is unchanged' forbids. Every type outside the set is still refused dimensionless, by exactly one of the two checks.",
"Merged origin/main (9b0de7d) once before opening the PR; origin/main moved further during verification (b253fad at the last fetch) and was not chased."
],
"mcp_calls": "0 — none",
"api_writes": "3 — each one repository_dispatch (POST /repos/objectstack-ai/objectstack/dispatches) executed by the fleet-write relay as objectstack-fleet[bot]: (1) pr_create = POST /repos/objectstack-ai/objectstack/pulls, run 36811500885, PR #21053 draft, body read back byte-identical (12957 bytes); (2) label-write --assign os-bill = POST /repos//issues/21053/assignees, run 36811546320, read back assignees os-bill; (3) this os-dev-report comment = POST /repos//issues/20958/comments via post-stamped. git push is not counted. Reads were unauthenticated single-card REST (issue 20958 and its comments, PR 21053).",
"objectui_mirror": "For the coordination child: import checkDashboardWidgetDimensionlessMeasureArity (signature (widget: { id?, type?, dimensions?, values? }, ctx: z.RefinementCtx) => void) and, for any UI listing the set, DASHBOARD_WIDGET_MULTI_MEASURE_TYPES from @objectstack/spec/ui; chain .superRefine(checkDashboardWidgetDimensionlessMeasureArity) in packages/types/src/zod/complex.zod.ts after the existing metric chain; add the name to the attached list of the 'DashboardWidgetSchema (complex.zod.ts)' row in packages/types/src/tests/spec-object-refinements-7715.test.ts (that census reads the spec object's check count and reddens by row name at the spec bump). Refusal shape: ONE issue, code 'custom', path ['values'], message opening: Widget ID declares N measures with no dimensions on type: 'T' (ID = widget id, N = count, T = authored type). The export already defaults a missing type and ignores types outside ChartTypeSchema, so re-attaching onto the mirror's wider, default-less type enum is sufficient.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none · noted, not filed — whether pie/donut/funnel/scatter/radar/treemap/sankey render several measures WITH a dimension is unmeasured and outside the card; the rule and its entry claim only the dimensionless shape (PR Acceptance notes).",
"carrier: none · noted, not filed — scripts/ablation-replace.mjs refuses a replacement that is a substring of its anchor (its count cannot rise); conservative and correct, remedy is a distinctive marker (PR Acceptance notes)."
]
}
ACCEPT — PR #21053 at head e1494c7206 · domain:spec seat 2 (session_017VaLJnYwhPsanVCe9dMCJU) · 2026-10-01T03:49Z
Reviewed against GitHub (the PR object, its file list, its diff and the head's check-runs), not against report 5924269260.
Shape: draft, base main, first line Fixes #20958 and no other closing keyword, Clause-②: yes (narrowing) at line start. That matches claim 5922292586 and the changeset: minor, feat(spec)!:, a BREAKING banner, the adr-0087: registered marker, and a FROM → TO table. The PR assignee is os-bill.
Scope: 9 files, all inside the claim's surface: dashboard.zod.ts, its two tests in src/ui/, the semantic entry 18.dashboard-widget-dimensionless-multi-measure-refused.ts, the regenerated migrations/registry.ts, api-surface/ui.json and export-origins/ui.json (+2 / 0 each), the regenerated references/ui/dashboard.mdx row, and the changeset. check-governed-merges.mjs --pr 21053 says NOT governed, 653 lines.
What changed: a dashboard widget with no dimensions and two or more values on pie, donut, funnel, scatter, radar, treemap or sankey is refused at values with ONE custom issue. The issue names the id, the count and the type, and steers to table, a bar-family type, or one widget per measure. The multi-measure set is one exported constant, DASHBOARD_WIDGET_MULTI_MEASURE_TYPES; the check, the refusal text and the values doc string read it.
Contract review: owed on the packages/spec/src/**, generated-references and changeset faces, and on the clause. The at-tier record 5924339179 on the PR is a PASS at e1494c7206fc, the head this lands. It answers all four dev deviations: two exports, not one; no step18 fragment, per precedent 09e16a574; the metric family stepped over so its refusal stays one issue; main moved after the dev's one merge, and the PR is still mergeable.
Evidence read:
H1: one attachment point, the DashboardWidgetSchema refine chain.
H2: every door refuses by the schema alone: defineStack, os validate, and the metadata save at 422 on active and draft.
H3: 0 authored dimensionless multi-measure widgets on the seven types, here and in objectui.
Ablation: removing the attachment turns 27 tests red, and the file is restored to blob equality.
Consumer suites: 8 packages green.
Gates: 113 derived, all exit 0, with a derived zero NOT MEASURED.
CI at e1494c7206, read at this stamp: the record names the runs still in progress. Landing waits for every check.
After landing: the seat files the objectui mirror coordination child from the report's objectui_mirror field: chain checkDashboardWidgetDimensionlessMeasureArity in packages/types/src/zod/complex.zod.ts, and name it in the refinement census row.
Findings: both go to Acceptance notes, not filed. Carrier: none. One is whether the seven types render several measures WITH a dimension (unmeasured, outside the card); the other is the ablation tool's substring refusal (correct as it stands).
Landed · PR #21053 MERGED through the merge queue as 11d28c17df (single parent a9d36d51b) · domain:spec seat 2 (session_017VaLJnYwhPsanVCe9dMCJU) · 2026-10-01T05:18Z
Verified by content, not by the merged flag. The 8 authored and regenerated files have the same blob in the merge commit as at the ACCEPTed head e1494c7206, the head the at-tier PASS 5924339179 covers. The generated migrations/registry.ts carries the entry dashboard-widget-dimensionless-multi-measure-refused. The merge commit is an ancestor of origin/main.
Closing keywords: the body carried Fixes #20958 only. This card closed completed, and no other card was named.
State:pm:dispatched comes off in this act.
objectui mirror: the seat files the coordination child in objectui in this round and links it here.
Pointer · domain:spec seat 2 (session_017VaLJnYwhPsanVCe9dMCJU) · 2026-10-01T05:20Z: the objectui mirror coordination child is filed as objectstack-ai/objectui#11334. It chains checkDashboardWidgetDimensionlessMeasureArity in packages/types/src/zod/complex.zod.ts and names it in the refinement census row, at objectui's next @objectstack/spec bump.
Activity
objectstack-fleet commentedon Oct 1, 2026
Claim: PM loop round 1 · 2026-10-01T00:33Z
Session:
session_017VaLJnYwhPsanVCe9dMCJUAccount:
os-bill(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-20958-dimensionless-multi-measure-refusedWorktree:
objectstack-issue-20958Domain:
domain:specSeat:
domain:spec#2(seat post #18549)File surface:
packages/spec/src/ui/dashboard.zod.ts(one object-level check besidecheckDashboardWidgetMetricMeasureArity, about:627, and the one exported multi-measure constant it, the refusal text and objectui's mirror read); its tests inpackages/spec/src/ui/; one ADR-0087 semantic entry underpackages/spec/src/migrations/entries/semantic/and the regeneratedmigrations/registry.ts; the regenerated spec artefacts the edit moves (api-surface, references); fixtures in the consumer packages only where one authors a now-refused shape (the dev names each); one.changeset/20958-*.md(minor, BREAKING header, ADR-0087 marker). Stop on breach and explain in the report.Container & model:
M,mode:subagent,model: opus(dispatch-gates--tier: no path-derived mandate; floor sonnet · default opus · ceiling fable).Clause-②: yes (narrowing)
Thread-read: none
Serial constraints cleared: read at this stamp against
origin/main05be35259. No open PR touchespackages/spec/src/ui/dashboard*or the dashboard migration entries, and no fleetpm:dispatchedclaim names them. objectui#11278 (thetable/ bar-family rendering) merged at 2026-09-30T22:58Z. Review: an at-tier contract review is owed before enqueue (a narrowing, plus a new export, onpackages/spec/src/**).Generated by Claude Code
objectstack-fleet commentedon Oct 1, 2026
os-dev-report
{
"issue": 20958,
"status": "done",
"branch": "claude/issue-20958-dimensionless-multi-measure-refused",
"pr": "#21053",
"session": "session_017VaLJnYwhPsanVCe9dMCJU — the parent's id (this run is a subagent of the domain:spec#2 PM)",
"premise_still_valid": true,
"summary": "Added DASHBOARD_WIDGET_MULTI_MEASURE_TYPES (the one exported list: table, pivot, bar, column, horizontal-bar, line, area, combo) and checkDashboardWidgetDimensionlessMeasureArity, chained onto DashboardWidgetSchema by identifier right after the metric check: a widget with dimensions absent or [] and two or more values on pie/donut/funnel/scatter/radar/treemap/sankey gets ONE custom issue at values naming id, count and type, listing the set (read from the constant) and steering to table, a bar-family type, or one widget per measure. The metric family is excluded so its existing refusal stays one issue and byte-identical, and the export returns on types outside ChartTypeSchema so objectui's wider-enum mirror is judged exactly as the spec door judges. ADR-0087 semantic entry 18.dashboard-widget-dimensionless-multi-measure-refused.ts plus the gen:migration-registry lap, a minor BREAKING changeset with the registered marker and Clause-② line, and regenerated api-surface/export-origins/ui.json (+2 each, 0 removed) and the values row of references/ui/dashboard.mdx. H1: one attachment point in this repo (the DashboardWidgetSchema superRefine chain), new check attached there. H2: refused by the schema alone at DashboardSchema, the dashboard metadata-type schema, ObjectStackDefinitionSchema, defineStack, os validate (fails at defineStack load) and the metadata save path (422 INVALID_METADATA, active and draft, 0 rows), with table/bar/pie-with-dimension controls passing. H3: 0 authored dimensionless multi-measure widgets on the seven (23 seven-type literals, all one dimension and one measure; objectui checkout 1263e40 reads 0 too), so no fixture triage and the stop condition did not fire. Merged origin/main 9b0de7d via os-regen-merge.sh before opening the PR and regenerated the two os-regen artifacts on the merged tree.",
"tests": "All at e1494c7 (merged tree) unless noted, each package's own vitest against its rebuilt dependency closure (per-package filters, not the full ...@objectstack/spec sweep): spec --project local 584 files / 17290 passed / 1 todo exit 0; spec typecheck (tsc + scripts + test layer) exit 0, ledger 52 files / 248 errors / 136 signatures held; metadata-protocol 195 passed + 3 skipped files, 2896 passed / 19 skipped tests, exit 0; lint 117 files / 5446 exit 0; service-analytics 150 / 3458 exit 0; sdui-parser 13 / 224 exit 0; platform-objects 59 / 948 exit 0; objectql --project local 348 / 6821 exit 0; metadata 56 / 836 exit 0; cli --project unit 239 / 3391 exit 0 (integration tier declared to CI: no spawn entry or integration file touched). Pre-merge at 1a0e75a the spec suite (584 / 17284) and metadata-protocol, lint, sdui-parser, platform-objects were also green. Ablation at committed 1a0e75a via scripts/ablation-replace.mjs, subject imported from src by relative path (no dist on the path): deleted only the .superRefine(checkDashboardWidgetDimensionlessMeasureArity) attachment; anchor x1 -> x0, marker x0 -> x1, blob b33ae8c4bd64 -> 209e3d201d54; RED vitest exit=1 27 failed / 274 passed (301); restored blob == HEAD blob b33ae8c4bd64, git diff HEAD empty; GREEN full spec suite at 1a0e75a after the restore. A first ablation attempt (replacement ');', a substring of the anchor) was refused by the tool because the replacement count could not rise; it restored and was not counted. check:generated at e1494c7: All 15 generated artifacts are up to date. Narrowed lint at e1494c7: eslint --no-inline-config --format json over the 5 touched .ts files = 5 files, 0 errors, 0 warnings; population: eslint --print-config returns a rule set for each (none ignored); invariance: no type-aware linting (parserOptions.project and projectService null; eslint.config.mjs states it never enables them), so untouched files' verdicts cannot move.",
"gates": "dispatch-gates --commands --repo objectstack-ai/objectstack at e1494c7 derived 113 commands; all 113 ran, every final exit 0. --ran reconciliation with exit-coded record: '113 derived, 113 run, 0 NOT-MEASURED, 0 UNRUN' and 'a DERIVED zero — all 113 recorded an exit code and none of them is 3'. Three first answers were not verdicts and were rerun to exit 0: pnpm --filter @objectstack/spec run check:skill-examples (exit 3 PREREQUISITE NOT MET, client-react unbuilt; after build: '259 prose examples type-check across 3 surface(s)'), pnpm check:dual-build-cjs-loads (exit 3, eight packages without dist; after build exit 0), pnpm check:query-options-erasure (killed by my own 240 s per-command cap, exit 124; uncapped 278 s exit 0, 'ratchet holds: 67 unswept non-test site(s) in 17 file(s), none new'). Verdict lines: check-adr-0087-registration --base origin/main exit 0 '[BREAKING+bang+clause-②-narrowing] registered dashboard-widget-dimensionless-multi-measure-refused'; check-changeset-no-major exit 0 'This diff introduces no major bump'; check:api-surface exit 0 'public API surface + factory signatures unchanged' (after regeneration); check:migration-registry, check:spec-changes, check:upgrade-guide, check:docs, check:nul-bytes, check:pm-widening-tells, check:spec-docblock-symbol-anchors, check:issue-citations, check:doc-authoring, check:widget-option-census all exit 0. Outside the 113 (CI's): the type-check lanes, path-scheduled CI jobs (Test Core shards, Dogfood, Temporal Conformance, Build Core) and the artifact-roster families are NOT MEASURED locally, reason: CI-owned whole-tree runs.",
"line_budget": "none owed: no skills/** in the diff",
"files_changed": [
".changeset/20958-dimensionless-multi-measure-refused.md",
"content/docs/references/ui/dashboard.mdx",
"packages/spec/api-surface/ui.json",
"packages/spec/export-origins/ui.json",
"packages/spec/src/migrations/entries/semantic/18.dashboard-widget-dimensionless-multi-measure-refused.ts",
"packages/spec/src/migrations/registry.ts",
"packages/spec/src/ui/dashboard.test.ts",
"packages/spec/src/ui/dashboard.zod.ts",
"packages/spec/src/ui/object-refinement-check-exports.test.ts"
],
"deviations": [
"Two new exports, not 'the one new exported constant' the dispatch noted beside Clause-②: the check is exported too, because object-refinement-check-exports.test.ts pins one export per custom check on the schema and objectui's mirror chains it by name. Clause-② yes (narrowing) covers both; the changeset's Clause-② line names both.",
"No STEP18_RATIONALE fragment added: the dispatch's hot-file note reads 'a major-18 entry adds its own fragment', but the metric-family precedent 09e16a5 added none and the step holds 52 fragments for 254 major-18 semantic entries (fragments accompany conversions). Followed the precedent; no other fragment touched. Conflict surfaced here rather than resolved silently.",
"Metric family excluded from the new check (card text reads 'outside the multi-measure set'): including it would double the metric family's existing refusal to two issues, which the card's pin 'the metric family's existing refusal is unchanged' forbids. Every type outside the set is still refused dimensionless, by exactly one of the two checks.",
"Merged origin/main (9b0de7d) once before opening the PR; origin/main moved further during verification (b253fad at the last fetch) and was not chased."
],
"mcp_calls": "0 — none",
"api_writes": "3 — each one repository_dispatch (POST /repos/objectstack-ai/objectstack/dispatches) executed by the fleet-write relay as objectstack-fleet[bot]: (1) pr_create = POST /repos/objectstack-ai/objectstack/pulls, run 36811500885, PR #21053 draft, body read back byte-identical (12957 bytes); (2) label-write --assign os-bill = POST /repos//issues/21053/assignees, run 36811546320, read back assignees os-bill; (3) this os-dev-report comment = POST /repos//issues/20958/comments via post-stamped. git push is not counted. Reads were unauthenticated single-card REST (issue 20958 and its comments, PR 21053).",
"objectui_mirror": "For the coordination child: import checkDashboardWidgetDimensionlessMeasureArity (signature (widget: { id?, type?, dimensions?, values? }, ctx: z.RefinementCtx) => void) and, for any UI listing the set, DASHBOARD_WIDGET_MULTI_MEASURE_TYPES from @objectstack/spec/ui; chain .superRefine(checkDashboardWidgetDimensionlessMeasureArity) in packages/types/src/zod/complex.zod.ts after the existing metric chain; add the name to the attached list of the 'DashboardWidgetSchema (complex.zod.ts)' row in packages/types/src/tests/spec-object-refinements-7715.test.ts (that census reads the spec object's check count and reddens by row name at the spec bump). Refusal shape: ONE issue, code 'custom', path ['values'], message opening: Widget
IDdeclares N measures with nodimensionsontype: 'T'(ID = widget id, N = count, T = authored type). The export already defaults a missing type and ignores types outside ChartTypeSchema, so re-attaching onto the mirror's wider, default-less type enum is sufficient.","open_questions": [],
"out_of_scope_findings": [
"carrier: none · noted, not filed — whether pie/donut/funnel/scatter/radar/treemap/sankey render several measures WITH a dimension is unmeasured and outside the card; the rule and its entry claim only the dimensionless shape (PR Acceptance notes).",
"carrier: none · noted, not filed — scripts/ablation-replace.mjs refuses a replacement that is a substring of its anchor (its count cannot rise); conservative and correct, remedy is a distinctive marker (PR Acceptance notes)."
]
}
objectstack-fleet commentedon Oct 1, 2026
ACCEPT — PR #21053 at head
e1494c7206·domain:specseat 2 (session_017VaLJnYwhPsanVCe9dMCJU) · 2026-10-01T03:49ZReviewed against GitHub (the PR object, its file list, its diff and the head's check-runs), not against report
5924269260.main, first lineFixes #20958and no other closing keyword,Clause-②: yes (narrowing)at line start. That matches claim5922292586and the changeset:minor,feat(spec)!:, a BREAKING banner, theadr-0087: registeredmarker, and a FROM → TO table. The PR assignee isos-bill.dashboard.zod.ts, its two tests insrc/ui/, the semantic entry18.dashboard-widget-dimensionless-multi-measure-refused.ts, the regeneratedmigrations/registry.ts,api-surface/ui.jsonandexport-origins/ui.json(+2 / 0 each), the regeneratedreferences/ui/dashboard.mdxrow, and the changeset.check-governed-merges.mjs --pr 21053says NOT governed, 653 lines.dimensionsand two or morevaluesonpie,donut,funnel,scatter,radar,treemaporsankeyis refused atvalueswith ONE custom issue. The issue names theid, the count and the type, and steers totable, a bar-family type, or one widget per measure. The multi-measure set is one exported constant,DASHBOARD_WIDGET_MULTI_MEASURE_TYPES; the check, the refusal text and thevaluesdoc string read it.packages/spec/src/**, generated-references and changeset faces, and on the clause. The at-tier record5924339179on the PR is a PASS ate1494c7206fc, the head this lands. It answers all four dev deviations: two exports, not one; nostep18fragment, per precedent09e16a574; the metric family stepped over so its refusal stays one issue;mainmoved after the dev's one merge, and the PR is still mergeable.DashboardWidgetSchemarefine chain.defineStack,os validate, and the metadata save at 422 on active and draft.e1494c7206, read at this stamp: the record names the runs still in progress. Landing waits for every check.objectui_mirrorfield: chaincheckDashboardWidgetDimensionlessMeasureArityinpackages/types/src/zod/complex.zod.ts, and name it in the refinement census row.Generated by Claude Code
objectstack-fleet commentedon Oct 1, 2026
Landed · PR #21053 MERGED through the merge queue as
11d28c17df(single parenta9d36d51b) ·domain:specseat 2 (session_017VaLJnYwhPsanVCe9dMCJU) · 2026-10-01T05:18Ze1494c7206, the head the at-tier PASS5924339179covers. The generatedmigrations/registry.tscarries the entrydashboard-widget-dimensionless-multi-measure-refused. The merge commit is an ancestor oforigin/main.Fixes #20958only. This card closedcompleted, and no other card was named.pm:dispatchedcomes off in this act.Generated by Claude Code
objectstack-fleet commentedon Oct 1, 2026
Pointer ·
domain:specseat 2 (session_017VaLJnYwhPsanVCe9dMCJU) · 2026-10-01T05:20Z: the objectui mirror coordination child is filed as objectstack-ai/objectui#11334. It chainscheckDashboardWidgetDimensionlessMeasureArityinpackages/types/src/zod/complex.zod.tsand names it in the refinement census row, at objectui's next@objectstack/specbump.Generated by Claude Code
feat(spec)!: a dimensionless dashboard widget declares two or more me…
feat(spec)!: a pie / donut / funnel / treemap / sankey widget takes o…
test(spec): the second ui/ file group's test titles state each cited …