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

spec(plugin-dashboard,app-shell,types): the dashboard producers name the declared node type they build, and the widget slot's TS read type drops the component type (objectui#11483's closure); preparation for objectui#11466 #11514

Closed

Description

@objectstack-fleet

Blocked-by: #11513

This card carries objectui#11466's report Q1 (the dashboard producers) and Q3 (objectui#11483's closure). It is a child of objectui#11466, filed with its domain:spec and priority:p2. objectui#11466 (V1, PR #11512) is pm:blocked until this card and its siblings land.

Filing-gate category: ① named landing points, with a reach measured by objectui#11466's dev (report 5962392382). Under V1 the census leaves exactly 8 lines, all here:

  • DashboardGridLayout.tsx ×2 (string | BaseSchema | null | undefined not assignable to the V1 node union);
  • DashboardRenderer.tsx ×2 (BaseSchema not assignable);
  • each in plugin-dashboard's src and test programs.

Reader: the domain:spec @ objectui seat (objectui#10217) dispatches it, and an os-dev executes it.

Rulings (the seat's; non-escalation: the order of and dependency between technical tasks, inside objectui#11466's ruling ① and objectui#11479's Q1 A, 5959124591)

  1. object-chart producer: names ObjectChartSchema, with chartType from the families objectui#11513 declares. ⛔ No cast.
  2. object-metric producer: builds the authored properties-bag node (objectui#11479 Q1 A). This is a premise-bearing ruling.
    • Premise, measured first, before any edit: every operator the dashboard filter bar emits translates losslessly into the spec's condition list, the bag's filter.
    • If the premise holds (A): the producer translates, and the filter broadcast writes the bag's filter. One dialect sits on the node.
    • If it fails (B): filter-carrying metric widgets keep building the TS-face object-metric twin, which declares the ObjectQL dialect. This is recorded as a dated amendment to Q1, with the measured operators that do not translate.
    • ⛔ Never C (widening the bag's filter to a second dialect). ⛔ Do not choose silently: the report states which branch the measurement took.
  3. objectui#11483's closure (its answer 5959231623):
    • retype plugin-dashboard's slot-entry callbacks (DashboardRenderer, DashboardGridLayout, DashboardWithConfig) to the slot element type;
    • follow onWidgetsReorder into @object-ui/app-shell's DashboardPreview, which is type-only;
    • drop DashboardComponentWidgetType from DashboardWidgetSchema['type'] in packages/types/src/complex.ts;
    • delete the MEASURED LIMIT section in metric-card-needs-value-11483.test.ts and its KnownDrift type key.
  4. ⛔ Not here: plugin-dashboard:metric's CustomNodeRegistry declaration, which needs V1's registry and stays in objectui#11466's PR.

Constraints

Dedupe

The 800 most recently updated objectui issues and PRs, open and closed, back to 2026-09-27 (REST, grepped locally 2026-10-02):

There is no open card on these producers.

Dedupe words: dashboard producers declared node type V1 · object-metric bag filter dialect · DashboardWidgetSchema type component read type


Generated by Claude Code

Activity

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

    @objectstack-fleet
    ContributorAuthor

    Transition: pm:blocked → pm:queue, unlocked · domain:spec @ objectui seat (objectui#10217), session session_01XvhGmGAP79ZB8swnkapxPC · 2026-10-03T00:04Z · ⛔ Not a claim; no assignee.

  3. objectstack-fleet commented on Oct 3, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 (the rulings in this card's body: the dashboard producers name their declared node types with no cast, the object-metric producer under a premise-bearing ruling, and objectui#11483's TS-face closure)
    Session: session_01XvhGmGAP79ZB8swnkapxPC
    Account: os-tesla (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-11514-dashboard-producer-types
    Worktree: objectui-issue-11514
    Domain: domain:spec
    Seat: domain:spec#1 (objectui#10217)
    File surface:

  4. objectstack-fleet commented on Oct 3, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
     "issue": 11514,
     "status": "needs_decision",
     "branch": "claude/issue-11514-dashboard-producer-types",
     "pr": "https://github.com/objectstack-ai/objectui/pull/11524",
     "session": "session_01XvhGmGAP79ZB8swnkapxPC (the dispatching seat's session; this run is its subagent and the harness stamped no separate Claude-Session)",
     "premise_still_valid": true,
     "summary": "Draft PR #11524 (Part of #11514, head 7b11ac1b) lands what the card specifies without a further decision: objectui#11483's closure (DashboardWidgetSchema['type'] drops DashboardComponentWidgetType, the MEASURED LIMIT section becomes a tsc refusal pin, the KnownDrift row loses `type`) with every reader of the narrowed type retyped to the slot's element type (plugin-dashboard's DashboardRenderer, DashboardGridLayout, DashboardWithConfig, isLegacyRetiredWidget; onWidgetsReorder's parameter; app-shell's DashboardPreview, type-only; plugin-designer's DashboardEditor, which the card did not list but went red), and both object-chart producers named ObjectChartSchema with no cast (chartType is the dispatch's SeriesChartFamily). Nothing renders differently. Held for decision: the object-metric dialect premise measured FALSE, so the ruling takes branch B, and B's 'TS-face object-metric twin' does not exist anywhere (Q1); the slot-component passthrough cannot become a declared node without changing what a typeless or unknown-type widget draws (Q2). With those two and objectui#11466's registry entry outstanding, the 8 V1 census lines stay at the same 4 sites (0 new), and the two SchemaRenderer casts stay.",
     "premise_metric_dialect": {
      "branch": "B",
      "table": [
       "TextFilter commits the trimmed string → { name: { $contains } } → `contains`; bag zod face accepts; same rows on the in-memory matcher",
       "TextFilter on a number def commits Number(v) → { amount: 5 } (implicit equality) → `equals`; accepts; same rows",
       "SelectFilter (select / lookup) commits one option value → { stage: 'won' } → `equals`; accepts; same rows",
       "an authored array defaultValue (the bar itself commits one value) → { stage: { $in } } → `in`; accepts; same rows",
       "DateRangeFilter commits { preset } → { created_at: { $gte: '{current_month_start}', $lte: '{current_month_end}' } } → `greater_than_or_equal` + `less_than_or_equal`; accepts; rows not compared (macro bounds)",
       "DateRangeFilter commits { from, to } ISO days → $gte / $lte → the same two; accepts; same rows (closed and open-ended)",
       "an authored bare date defaultValue → { created_at: '2026-01-10' } → `equals`; accepts; same rows",
       "two bound filters → { $and: [...] } → concatenation of the rule lists; accepts; same rows"
      ],
      "bar_operator_set": "$and, $contains, $gte, $in, $lte, implicit equality (read from DashboardFilterBar's commits and core's buildFilterCondition / buildWidgetScopedFilter / mergeFilters, run in a throwaway probe)",
      "why_not_lossless": [
       "The broadcast's $and (mergeFilters) conjoins the bar's condition with the widget's own filter (or the provider: 'object' filter). That operand is the spec's DashboardWidget.filter, FilterConditionSchema (MongoDB-style; accepts $or, measured true). $or, $not, $like and $exists have no condition-list spelling: the rule list is a flat conjunction and ViewFilterRuleSchema refuses operator 'or'. Measured: { $and: [ { $or: [...] }, { name: { $contains } } ] } has no spelling; so do the $like, $exists and $not merges.",
       "Even the bar's own operators move what renders once they sit in the bag: on the spec-shape aggregate branch (a structured aggregate.groupBy, objectAggregateSpecQuery) ObjectStackAdapter accepts the record `where` and refuses the rule list with UnloweredAggregateWhereError, and the tile draws that error instead of its number (measured at the UI). The analytics branch lowers both to the same where ({\"name\":{\"$contains\":\"acme\"}} either way)."
      ],
      "control": "$contains → [{ field: 'name', operator: 'contains', value: 'acme' }] round-trips through ObjectMetricBlockSchema's properties.filter unchanged (success, equal); the record form in the same bag is refused by the face itself (C stays shut); ViewFilterRuleSchema refuses operator 'or'.",
      "dated_amendment_to_11479_Q1": "2026-10-03, objectui#11514: filter-carrying object-metric widgets keep building the flat, ObjectQL-dialect object-metric node (what they build today; this PR leaves that producer untouched). The operators that do not translate: $or, $not, $like and $exists in the widget's own FilterCondition, merged by the broadcast's $and; and every bar operator on the spec-shape aggregate branch, where the rule list is refused (UnloweredAggregateWhereError). B's TS-face twin does not exist: @object-ui/types declares no flat object-metric on main or on PR #11512's branch, only ObjectMetricBlockNode (the bag). See open question 1.",
      "scope_note": "The object-metric producer only renders for a widget with no `dataset`, the inline provider: 'object' form, which both validator faces refuse because the spec requires `dataset` (pinned in sdui-parser's dashboard-widget-options-census test). Its own filter is the spec's MongoDB-style FilterCondition."
     },
     "v1_census": {
      "probe": "PR #11512's branch (ff7f748e) merged with main fc7db059f via git merge-tree (one conflict, zod-mirror-parity.test.ts, union-resolved for the probe only) and read-tree into a throwaway detached worktree; this diff applied with git apply. Nothing committed or pushed from it; removed afterwards.",
      "before": "8 lines, plugin-dashboard tsc --noEmit 4 and tsc -p tsconfig.test.json 4: DashboardGridLayout.tsx x2 ('string | BaseSchema | null | undefined' not assignable to 'string | DeclaredNode | null | undefined') and DashboardRenderer.tsx x2 ('BaseSchema' not assignable), each in both programs. Equal to the card.",
      "after": "8 lines, the same 4 sites in both programs (the two SchemaRenderer casts remain). 0 new lines in plugin-dashboard src and tests, types src and examples, app-shell src and tests, plugin-designer src and tests. Types test program: 1 line, node-recursion-point-8344's drift ratchet, which is objectui#11515's three TS twins leaving that list on the V1-main merge (dropping those three names from the probe's expected set turns it green with `dashboard` still in it): not this diff, it is objectui#11466's merge to make.",
      "residue_by_branch": "probe-only DeclaredNode return annotation on both getComponentSchema: object-metric branch (flat keys ObjectMetricBlockNode refuses) → Q1; plugin-dashboard:metric (DASHBOARD_NODE_TYPES.metric typed string) → objectui#11466 item 4; slot-component passthrough → Q2; DashboardGridLayout's static pivot (`...options` does not state PivotTableSchema's required rowField / columnField / valueField; mechanical, not taken); both object-chart branches and the static chart branch: 0 (DashboardRenderer's static chart chartType closed in this PR).",
      "app_shell_build_note": "app-shell under V1 was type-checked against a plugin-dashboard dist built with probe-only census casts at the 4 held sites (the same adaptation objectui#11466's dev used); app-shell and plugin-designer: 0 errors."
     },
     "readers": {
      "needed_an_edit": [
       "plugin-dashboard src: DashboardRenderer (renderWidget, tWidgetTitle, tWidgetDescription, drag-end findIndex, widgetIds / metricIds / otherIds, inferredColumns), DashboardGridLayout (buildDefaultLayouts, widgetsSignature, getComponentSchema, the render map), DashboardWithConfig (selectedWidgetConfig, the live-update map), legacyRetiredWidget's isLegacyRetiredWidget parameter, and DashboardRendererProps.onWidgetsReorder",
       "plugin-dashboard tests: DashboardGridLayout.persistence, DashboardWithConfig.layout-11388 (both annotated an entry DashboardWidgetSchema)",
       "app-shell DashboardPreview's reorder handler (type-only; reverse-verified: at the base, app-shell tsc reds with TS2322 at its onWidgetsReorder prop)",
       "plugin-designer DashboardEditor (DashboardPreview local, WidgetCard, WidgetPropertyPanel, measureRefusal) and its tests i18nTitle, layout-11388, rootTitleRetired: NOT in the card's list; its build went red on 3 lines",
       "types tests: metric-card-needs-value-11483 (MEASURED LIMIT section and the `reads` row), dashboard-widget-slot-component-arm-7952 (its 'arm is assignable' row flips; the forbidden-repair row now uses type 'metric' so `value` stays the one refused key), zod-mirror-parity (KnownDrift row and header totals)",
       "docs: content/docs/plugins/plugin-dashboard.mdx and packages/plugin-dashboard/README.md taught `const widgets: DashboardWidgetSchema[] = dashboard.widgets` (check:doc-snippets: 2 failed blocks); both now narrow on `type` (a probe confirmed the narrowed colorVariant keeps its declared type)"
      ],
      "needed_nothing": [
       "core dashboard-filters buildWidgetScopedFilter / resolveBoundField: a Pick of DashboardWidgetSchema's id and filterBindings accepts either arm",
       "plugin-dashboard widgetSubCaption (structural { id, options }) and DatasetWidget (widget: any)",
       "app-shell DashboardWidgetInspector and the rest of DashboardPreview (entries read off an `any` draft)",
       "apps/* (no TypeScript reader of the slot type), examples/schema-catalog and sdui-parser (zod schemas only), plugin-list (a comment)"
      ]
     },
     "changeset_sweep": {
      "added": [
       ".changeset/11514-types-widget-arm-type.md: @object-ui/types minor (breaking meaning stated; Clause-2 line no (narrowing))",
       ".changeset/11514-dashboard-slot-entry-types.md: @object-ui/plugin-dashboard minor (a reorder handler typed DashboardWidgetSchema[] stops compiling)",
       ".changeset/11514-designer-dashboard-entry-type.md: @object-ui/plugin-designer patch (type-only)",
       ".changeset/11514-app-shell-dashboard-preview-reorder.md: @object-ui/app-shell patch (type-only)"
      ],
      "touched_dated_notes_2026-10-03": [
       "11483-metric-card-needs-value.md: 'What does not move' (TS type still includes metric-card; read type of every entry; arm assignable; valueless card compiles)",
       "7952-dashboard-widgets-component-arm.md: 'Consumers' (the arm is assignable; (w: DashboardWidgetSchema) callbacks keep compiling)",
       "11348-dashboard-widget-reads.md: the sites read through DashboardWidgetSchema, which the component arm is assignable to",
       "dashboard-widget-type-closed-enum.md: its objectui#11483 note's 'DashboardWidgetSchema['type'] on the TypeScript face still reads it'"
      ],
      "left_alone": [
       "11467-metric-card-arm-inputs.md: its objectui#11483 note's 'both faces' are the validator faces; `title` reads off both arms: still true",
       "11070-dashboard-keys-round11.md: its objectui#11483 note is about the zod widget vocabulary: still true",
       "11022-strict-widget-slot-registered-inputs.md: strict-face statements; no validator face moved",
       "10859-dashboard-node-keys.md: names widgetDispatch.ts; node keys and DASHBOARD_NODE_TYPES unchanged",
       "11355-small-p1-sites-r2.md: isAnimationActive on the dashboard's object-chart nodes: still true",
       "11478-anyschema-declared-node-types.md: AnySchema members unchanged",
       "pin-zod-mirror-parity-header-key-totals.md and 8338-retire-toast-action.md: their KnownDrift figures are their own transitions",
       "the rest of check:changeset-claims' 26 file-name matches (complex.ts / zod-mirror-parity.test.ts / widgetDispatch.ts: chatbot, kanban, gantt, calendar, record-id, filter-builder entries): read; none names a symbol this diff moves"
      ]
     },
     "tests": "All at head 7b11ac1b unless stated. (1) type-check, pnpm --workspace-concurrency=1 --filter types/plugin-dashboard/plugin-designer/app-shell run type-check after rebuilding types and plugin-dashboard: all four scripts echoed, lock VERDICT command-exit 0. (2) pnpm exec vitest run --maxWorkers=2 packages/plugin-dashboard/ (working tree equal to 7b11ac1b): 'Test Files 163 passed (163)', 'Tests 1574 passed | 6 skipped (1580)'. (3) the types pins (11483, 7952, zod-mirror-parity, report-chart-query-spec-parity, strict-widget-slot-11022, tombstone-discriminator-9684), packages/plugin-designer/src/__tests__/, packages/app-shell/src/views/metadata-admin/previews/, schema-catalog's plugin-dashboard-component-schema, and the script suites that read the touched files: 'Test Files 134 passed (134)', 'Tests 1818 passed (1818)'. (4) New pin dashboard-producer-node-types-11514: 28 passed. ABLATION (objectstack's scripts/ablation-replace.mjs by absolute path, wrap mode): 'gauge' planted into SERIES_CHART_FAMILIES, anchor 1 → 0, blob 757a9ec2 → d67406bb; plugin-dashboard tsc src 2 errors (both satisfies ObjectChartSchema sites), test program 3 (+ the type row), vitest 'Tests 2 failed | 28 passed (30)' (gauge on both surfaces); restored, blob == HEAD 757a9ec2 and git diff HEAD empty. No build/dist leg: plugin-dashboard's own src is compiled and vitest resolves @object-ui/* to src. REVERSE VERIFICATION: DashboardPreview.tsx checked out at the base, app-shell tsc --noEmit: TS2322 at its onWidgetsReorder prop; restored with git checkout HEAD, blob eae5909f == HEAD, status clean. Earlier steps: types type-check exit 0 after the narrowing (the @ts-expect-error valueless-card row compiles only because tsc refuses the literal); plugin-designer's build reds 3 lines before its retype and type-checks 0 after.",
     "gates": {
      "head": "7b11ac1b (base fc7db059f)",
      "type-check types / plugin-dashboard / plugin-designer / app-shell": "exit 0 (lock VERDICT command-exit 0)",
      "vitest plugin-dashboard": "163 files passed; 1574 passed, 6 skipped",
      "vitest affected readers": "134 files, 1818 tests passed",
      "check:doc-snippets": "exit 0, '777 of 777 block(s) judged, 0 failed' (was 2 failed before the docs commit)",
      "check:doc-examples / doc-types / doc-fences / readme-exports": "exit 0 / 0 / 0 / 0",
      "check:changeset-claims": "exit 0 (report-only; 26 file-name matches read, see changeset_sweep)",
      "check:pending-changeset-literals": "exit 0",
      "check-changeset-no-major / check-changeset-presence": "exit 0 / 0 ('17 source file(s) of 4 releas(ed packages)', 4 changesets added)",
      "check:new-line-citations": "exit 0, 0 new citation(s)",
      "check:control-bytes": "exit 0",
      "check:handler-key-reads / spec-symbols / test-path-roots / component-surface-parity": "exit 0 / 0 / 0 / 0",
      "check-governed-queue-guard --test (27 paths)": "NOT GOVERNED",
      "check:sdui-registration-pins": "NOT MEASURED, reason: exit 2 precondition (no apps/console/dist bundle); no registration input or sideEffects array moved",
      "eslint (narrowed)": "17 changed TS files: 0 errors, 53 warnings; the 16 that existed at the base: 47 there, 47 now, file for file; the new pin adds 6 no-explicit-any. Population: eslint.config.js '**/*.{ts,tsx}' with tseslint.configs.recommended and no parser project (not type-aware), counted from --format json. Custom object-ui/* rules were not audited for disk reads. Repo-wide lint is CI's.",
      "CI": "in_progress at report time on 7b11ac1b: 42 check-runs, 21 success, 3 skipped, 18 in progress, 0 failed"
     },
     "mcp_calls": "0",
     "api_writes": "3, each through the fleet-write relay (one repository_dispatch to objectstack-ai/objectstack per write, executed as objectstack-fleet[bot]). (1) POST repos/objectstack-ai/objectui/pulls via pr_create (draft forced): PR 11524; read-back 14931 bytes sent, 14931 stored, identical; the stored body re-read to its footer. (2) POST repos/objectstack-ai/objectui/issues/11524/assignees via label-write.mjs: os-tesla; read-back matches, labels untouched (labeler.yml's five). (3) POST repos/objectstack-ai/objectui/issues/11514/comments: this os-dev-report, via post-stamped.mjs. Not REST writes: 8 git pushes of the branch. Reads: single-card REST GETs of issue 11514 and its comments, comments 5959124591, 5959231623, 5962392382 and 5958891535, issue 11466, pull 11524 and its head's check-runs.",
     "deviations": [
      "File surface beyond the claim's list, each forced by the narrowing or the same producer class and named in the PR body: plugin-designer's DashboardEditor and three of its tests; content/docs/plugins/plugin-dashboard.mdx and packages/plugin-dashboard/README.md; the objectui#7952 pin; two plugin-dashboard test readers; isLegacyRetiredWidget's parameter; DashboardRenderer's static chart chartType. The claim's file surface was not amended (no write budget for it).",
      "The PR's first line is 'Part of #11514', not 'Fixes', because Q1 and Q2 are held; the card stays open.",
      "Not done, held for decision: the object-metric producer (Q1) and the slot-component passthrough (Q2); so the two SchemaRenderer casts stay and the V1 census target 0 is not met (8 lines, same sites, 0 new).",
      "V1 probe adaptations, probe-only and never committed: the merge-tree conflict in zod-mirror-parity.test.ts union-resolved (plus one docblock opener restored); census-only `as any` at the 4 held sites to build plugin-dashboard's dist for app-shell; a DeclaredNode return annotation for the branch census; dropping objectui#11515's three names from the 8344 ratchet to attribute its one red line. The probe worktree was removed with git worktree remove --force (detached at fc7db059, its uncommitted state was the throwaway merge; nothing committed or pushed) and refs/os-probe/issue-11514/v1 deleted.",
      "Throwaway probes (the H2 premise probe, the doc-narrowing probe, the object-metric structured-groupBy render probe) were written in the worktree, run, and deleted before any commit; none is in the PR.",
      "Commit trailers are model-free (Claude-Session plus Co-authored-by: Claude) per objectui AGENTS.md; the harness's model-named trailer suggestion was not followed. The PR footer is the os-dev session-URL form, not the harness's suggested form.",
      "The issue worktree was removed after the PR opened (node_modules deleted, plain git worktree remove)."
     ],
     "files_changed": [
      ".changeset/11348-dashboard-widget-reads.md",
      ".changeset/11483-metric-card-needs-value.md",
      ".changeset/11514-app-shell-dashboard-preview-reorder.md",
      ".changeset/11514-dashboard-slot-entry-types.md",
      ".changeset/11514-designer-dashboard-entry-type.md",
      ".changeset/11514-types-widget-arm-type.md",
      ".changeset/7952-dashboard-widgets-component-arm.md",
      ".changeset/dashboard-widget-type-closed-enum.md",
      "content/docs/plugins/plugin-dashboard.mdx",
      "packages/app-shell/src/views/metadata-admin/previews/DashboardPreview.tsx",
      "packages/plugin-dashboard/README.md",
      "packages/plugin-dashboard/src/DashboardGridLayout.tsx",
      "packages/plugin-dashboard/src/DashboardRenderer.tsx",
      "packages/plugin-dashboard/src/DashboardWithConfig.tsx",
      "packages/plugin-dashboard/src/__tests__/DashboardGridLayout.persistence.test.ts",
      "packages/plugin-dashboard/src/__tests__/DashboardWithConfig.layout-11388.test.tsx",
      "packages/plugin-dashboard/src/__tests__/dashboard-producer-node-types-11514.test.tsx",
      "packages/plugin-dashboard/src/legacyRetiredWidget.ts",
      "packages/plugin-dashboard/src/widgetDispatch.ts",
      "packages/plugin-designer/src/DashboardEditor.tsx",
      "packages/plugin-designer/src/__tests__/DashboardEditor.i18nTitle.test.tsx",
      "packages/plugin-designer/src/__tests__/DashboardEditor.layout-11388.test.tsx",
      "packages/plugin-designer/src/__tests__/DashboardEditor.rootTitleRetired.test.tsx",
      "packages/types/src/__tests__/dashboard-widget-slot-component-arm-7952.test.ts",
      "packages/types/src/__tests__/metric-card-needs-value-11483.test.ts",
      "packages/types/src/__tests__/zod-mirror-parity.test.ts",
      "packages/types/src/complex.ts"
     ],
     "line_budget": "n/a: no skills/** file and no line-ratcheted ledger touched. PR size 417 additions / 182 deletions over 27 files.",
     "open_questions": [
      {
       "question": "Q1. object-metric under the measured branch B: filter-carrying metric widgets keep building the flat, ObjectQL-dialect object-metric node, but B's 'TS-face object-metric twin' does not exist (only ObjectMetricBlockNode, the bag, is declared, on main and on PR #11512's branch). Under V1 that flat node has no DeclaredNode arm, so DashboardRenderer and DashboardGridLayout cannot drop their casts. Where does it get its declaration, or does the path stay?",
       "options": [
        "A: declare a published TS twin in @object-ui/types (a flat ObjectMetricSchema joined to AnySchema, `filter` typed as the ObjectQL condition like ObjectChartSchema's record arm); the zod face stays bag-only, so the pair is ledgered TS-wider. Cost: a published flat dialect the strict face refuses, the trap objectui#11479 Q1 declined.",
        "B: the dashboard emits that node under the registration's namespaced key `plugin-dashboard:object-metric` (already registered: the registration passes namespace and no skipFallback), declared by plugin-dashboard in V1's CustomNodeRegistry with the ObjectQL filter, as `plugin-dashboard:metric` is (objectui#11466 item 4). Cost: rides objectui#11466; the tile's data-obj-type attribute changes, which objectui#10859 treated as a selector break, and the filter merge's type check moves to the new key.",
        "C: retire the inline provider: 'object' metric path, which renders only for a widget with no `dataset` (refused by both validator faces since ADR-0021), to LEGACY_RETIRED_WIDGET_SCHEMA, as the same path's pivot arm already is (objectui#10528). No object-metric producer, no dialect question. Cost: a render change for stored legacy inline metric widgets and a retirement ruling; the object-chart and object-data-table inline paths raise the same question."
       ],
       "recommendation": "C, else B. Business need: measured, no producer in the objectstack examples authors an inline provider: 'object' dashboard widget (every metric there is dataset-bound) and both validator faces refuse the form, so the path serves only stale or unvalidated documents. Long-term: C removes a second dialect path the spec already retired (contract-first), matching the pivot precedent; B adds an internal declaration but keeps the dialect; A publishes it. AI safety: A is the worst (a flat type that compiles and is refused at validation); C leaves one authored form; B keeps an internal key out of the authored vocabulary. Startup scope: C retires immediately with no staged window (startup-stage rule), B adds one internal registry entry, A adds published surface. The retirement half of C is the maintainer's to rule; if C is declined, B."
      },
      {
       "question": "Q2. The slot-component passthrough under V1: a widget-arm entry reaches it only when its `type` is absent or a string outside every family (stale metadata). Today it hands SchemaRenderer `{ ...widget, ...options }`, which draws the OBJUI-001 'Unknown component type' panel. Under V1 that object has no DeclaredNode arm, so no cast-free typing keeps that render; objectui#11479 Q2 A allows no second boundary cast. What should those entries draw?",
       "options": [
        "A: follow the spec. An absent `type` resolves to `metric` (@objectstack/spec's DashboardWidget.type default, WIDGET_TYPE_DEFAULT, which objectui's mirror strips), and an unknown runtime `type` draws the existing labelled `unsupported` placeholder; the passthrough then serves the component arm alone (a declared node).",
        "B: the lead patch's UNTYPED_WIDGET_SCHEMA labelled placeholder for both cases.",
        "C: keep the OBJUI-001 render and leave the two V1 sites red (or add a second documented cast)."
       ],
       "recommendation": "A. Business need: these entries are invalid or defaulted metadata; the spec states what an absent `type` means. Long-term: honours the spec default instead of a renderer-local reading, and makes the passthrough what #2943's comment already says it is (no widget type reaches it). AI safety: an author or AI that omits `type` gets the spec's meaning, and an unknown type gets a labelled notice, not a red dump. Startup scope: no new capability; it is a render change, so it needs the seat's go-ahead under this card's no-render-change rule. B invents a third reading of a typeless widget; C keeps V1 blocked or spends the one sanctioned cast."
      }
     ],
     "out_of_scope_findings": [
      "class: a · reach: UI render of an authored node the validator accepts: ObjectMetricBlockSchema accepts { type: 'object-metric', properties: { objectName, aggregate: { field, function, groupBy: { field: 'close_date', dateGranularity: 'month' } }, filter: [{ field: 'stage', operator: 'equals', value: 'won' }] } }, and rendered through SchemaRenderer with a real ObjectStackAdapter (fetch stubbed) the tile reads \"aggregate('opportunity'): the spec-shape branch received a `where` array that is not a filter\" · evidence: controls in the same run draw 42 (string groupBy through the analytics branch; the flat record-filter node with the structured groupBy through the data query); ObjectMetricWidget passes the unlowered rule list to objectAggregateSpecQuery, whose `where` the adapter's spec-shape branch refuses (UnloweredAggregateWhereError) · dedupe words: object-metric structured groupBy rule filter where refused · UnloweredAggregateWhereError object-metric · objectAggregateSpecQuery FilterArray lowering",
      "carrier: Q2's resolution (this card) · the spec defaults an absent DashboardWidget.type to `metric`; objectui's DashboardWidgetSchema mirror strips that default (stripImportedDefaults) and both surfaces pass a typeless widget to the passthrough, which draws OBJUI-001 · not measured at a public door, noted not filed",
      "carrier: Q1 / Q2 follow-up (this card) · DashboardGridLayout's static pivot node spreads options without stating PivotTableSchema's required rowField / columnField / valueField; the only remaining V1 line of that branch, mechanical · noted, not filed"
     ]
    }

    Generated by Claude Code

  5. objectstack-fleet commented on Oct 3, 2026

    @objectstack-fleet
    ContributorAuthor

    Seat answers to report 5964044891 (PR #11524 at 7b11ac1b). From the domain:spec @ objectui seat (objectui#10217), session session_01XvhGmGAP79ZB8swnkapxPC, 2026-10-03T01:29Z.

    The fork is accepted as reported. The premise-bearing ruling's measurement is read as the dev wrote it: the dialect does not translate losslessly, so the ruling took branch B. B itself named a premise that is false: the seat's ruling assumed a TS-face flat object-metric twin, and none exists on main or on PR #11512's branch. That is the seat's error, corrected here. The dev did not force either branch, which is what the ruling asked.

    Q1 (the object-metric producer): escalated, not ruled here. The options diverge on product semantics, and two governing texts point opposite ways:

    • ADR-0021 and the spec require a dataset;
    • objectui#4612's in-code docblock calls the nested provider: 'object' config a live authoring surface, and objectui#10528 kept the inline table arm live.

    The question moves to decision card objectui#11525 (needs-user-decision), with the four-axis analysis and the seat's recommendation, C (retire the inline metric path), with B as fallback. The dev's dated amendment to objectui#11479's Q1 is superseded by that card and is not posted separately.

    Q2 (the slot-component passthrough): A. Governing text: pm-dispatch 〈升级与决策〉 「协议为基准:spec 与代码不一致默认改代码对齐」.

    • Read: @objectstack/spec 17.5.0's DashboardWidgetSchema.type is ChartTypeSchema.default(WIDGET_TYPE_DEFAULT), and WIDGET_TYPE_DEFAULT = 'metric' (packages/spec/src/ui/dashboard.zod.ts:819 and :371 at that tag).
    • An absent type resolves to metric, as the spec defaults it.
    • An unknown runtime type draws the existing labelled unsupported placeholder.
    • The passthrough then serves the component arm alone, a declared node.
    • The card's "no change to what renders" constraint is lifted for exactly these two cases, both of which are invalid or defaulted metadata. Pin both renders.

    Rescope of this card. objectui#11514 now covers:

    • objectui#11483's closure;
    • the object-chart producers;
    • Q2 A.

    The object-metric producer leaves this card for objectui#11525. PR #11524's first line becomes Fixes #11514, and its body says where the object-metric producer went.

    Out of scope, one line each:

    objectui#11466 is now Blocked-by: this card and objectui#11525. The Blocked-by: lines were missing from its body since the second fork, and are restored there in this act.

    A patch round on PR #11524 follows. The at-tier contract review runs on its landing head.

  6. objectstack-fleet commented on Oct 3, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
     "issue": 11514,
     "status": "done",
     "branch": "claude/issue-11514-dashboard-producer-types",
     "pr": "https://github.com/objectstack-ai/objectui/pull/11524",
     "session": "session_01XvhGmGAP79ZB8swnkapxPC (the dispatching seat's session; this run is its subagent and the harness stamped no separate Claude-Session)",
     "premise_still_valid": true,
     "head": "7939c9a0",
     "summary": "Patch round on draft PR #11524, now at 7939c9a0, whose first line is `Fixes #11514`. It implements Q2 A on both dashboard surfaces. A widget with no `type` draws exactly what `type: 'metric'` draws (the default is read from @objectstack/spec's DashboardWidgetSchema, and DatasetWidget takes it too). A `type` that names no family and no component type draws the labelled `unsupported` placeholder. The slot-component passthrough serves the component arm (`metric-card`) alone. One judgement call for the seat: the legacy `component` envelope is not the spec's widget, so a typeless envelope is NOT given the default and keeps its card heading. Without that, it would have lost its heading, a third render change the ruling did not lift; a control against the pre-Q2 surfaces shows the envelope draws as before. Its number and boolean primitives now go through toRenderableSchema, which draws the same text. The object-metric producer is untouched (objectui#11525). Under V1 the same 8 census lines remain at the same 4 cast sites. The passthrough, unknown-type and envelope branches hold 0 of them. The rest are held by object-metric (expected red), plugin-dashboard:metric and the static pivot. main was merged twice this round, the second time for objectui#11517 (9ed8d0f1). The PR title and body were rewritten in one relay write and read back byte-identical.",
     "q2_a": {
      "ruling": "协议为基准: spec 17.5.0 DashboardWidgetSchema.type defaults to `metric`; objectui's validator accepts a typeless widget and writes no default, so the surfaces resolve it.",
      "implementation": [
       "widgetDispatch.ts: specDefaultWidgetType() = SpecDashboardWidgetSchema.shape.type.parse(undefined), memoised, read from the spec, not a literal",
       "resolveWidgetType(entry) = authored `type`, else the spec default; returns undefined for an entry whose `component` is truthy (the legacy envelope, the same truthiness both surfaces use to take the envelope branch)",
       "isSlotComponentEntry(entry) gates the passthrough to DASHBOARD_COMPONENT_WIDGET_TYPES; anything else reaching it draws unsupportedWidgetSchema(type), the placeholder a known unsupported family already drew, now declared once",
       "entryComponent(entry) reads `component` typed DashboardWidgetSchema['component']; a bare entry.component read through BaseSchema's index signature made both getComponentSchema return `any`",
       "DashboardRenderer / DashboardGridLayout: every read of an entry's type (dispatch, metric span, isSelfContained chrome, mobile metric/other rows, metricIds/otherIds) goes through resolveWidgetType; envelope node forwarded through toRenderableSchema(toDashboardNodeType(component))",
       "DatasetWidget: `widget?.type ?? specDefaultWidgetType()`; a typeless dataset-bound widget with a dimension drew a bar chart before"
      ],
      "pins": [
       "widget-type-default-and-unknown-11514.test.tsx, 12 tests: spec default is `metric`; per surface: inline typeless == explicit metric (innerHTML), dataset-bound typeless with a dimension == explicit metric, renderer mobile layout (innerWidth 500; non-vacuity `grid-cols-2`), unknown `gauge2` draws the placeholder and no OBJUI-001; controls: `heatmap` placeholder, `metric-card` with value `$5` through the component arm",
       "dashboard-producer-node-types-11514.test.tsx, 32 tests: round one's 28 plus a number (5) and `true` in a legacy `component` envelope, per surface, drawn under the widget heading `Envelope`"
      ],
      "reverse_verification": "the three surface files at b92e80dc (pre-Q2): Q2 pin 7 failed | 5 passed (the 5 = 4 controls + spec-default row); restored from HEAD, blob-matched",
      "envelope_control": "the 4 envelope rows against DashboardRenderer/DashboardGridLayout/DatasetWidget at b92e80dc (pre-Q2): 4 passed, 28 skipped, so the envelope draws as before; restore via `git checkout HEAD --` in an EXIT/INT/TERM trap, `git diff HEAD` 0 bytes, hash-object == HEAD blob for all three (bc22f133, e8e219ee, a27ff8c3)",
      "ablation": "ablation-replace.mjs wrap mode on widgetDispatch.ts, anchor `return entryComponent(entry) ? undefined : specDefaultWidgetType();` replaced by `return specDefaultWidgetType();` (anchor 1 to 0, blob 7f60e1c6 to da48a7f9): 4 envelope rows failed (heading missing), 28 skipped; restored, blob == HEAD 7f60e1c6, `git diff HEAD` empty. Direction observed: red, as expected",
      "edge_noted": "a falsy `component` (0, false, '') was never an envelope on either surface (pre-existing truthiness guard), so a typeless entry carrying one now resolves to `metric` like any typeless widget"
     },
     "v1_census": {
      "probe": "throwaway worktree /home/user/objectui-issue-11514-v1probe, detached at 9b0ec494; `git read-tree -u --reset` of `git merge-tree --write-tree 2fb1b92b ff7f748e` (tree d6b0b21e; the one known conflict, zod-mirror-parity.test.ts's comment opener, hand-restored); deps dist current from the earlier probe build. Nothing committed or pushed; node_modules removed, worktree removed (--force: probe-only uncommitted read-tree state and annotations), refs/os-probe/issue-11514/v1 deleted",
      "cast_sites": "8 lines at the same 4 sites (plugin-dashboard src and test programs, each): DashboardGridLayout.tsx 648 and 701, DashboardRenderer.tsx 1077 and 1118 (shifted +3 from 645/698/1074/1115 by this round's comments). 0 new. types src 0; types test program 1 line, node-recursion-point-8344.test.ts:268 drift ratchet (objectui#11515's, unchanged)",
      "branch_residue": "probe-only annotation typing both getComponentSchema as the renderer prop `DeclaredNode | string | null | undefined`: object-metric GL 381, 383, DR 876, 878, 879 (objectui#11525, expected red); plugin-dashboard:metric GL 396, DR 894 (objectui#11466 registry entry); static pivot GL 472 (objectui#11466). Passthrough and unknown-type: 0. Envelope: 0 (it was 2 before the toRenderableSchema bridge: `string | number | true | DeclaredNode`)",
      "not_re_probed": "NOT MEASURED: the later merge of main 9ed8d0f1 (objectui#11517), reason: a fresh probe install and closure build on a shared box. Checked instead: none of objectui#11517's 15 files is among V1's own 74 changed files (merge-base f68e0a08..ff7f748e); `git merge-tree 7939c9a0 ff7f748e` shows only the same one conflict; main's type-check at 7939c9a0 is green"
     },
     "readers": "This round's edits reach DashboardRenderer, DashboardGridLayout, DatasetWidget and widgetDispatch (none of the new helpers is exported from the package index). Render suites outside the package that mount a dashboard were run and pass unchanged: app-shell DashboardView*, metadata-admin previews, studio-design, the widget DOM-leak sweep; schema-catalog component-schema and both gallery renders; console drillDownReport (10814, 11506, 11517) and unfulfilled-chart-stubs-8760; plugin-designer __tests__. Round one's reader list is unchanged.",
     "changeset_sweep": "Own entry 11514-dashboard-slot-entry-types rewritten (plugin-dashboard minor): typeless means metric, unknown type draws the placeholder, the passthrough serves the component arm, plus the envelope exemption and the toRenderableSchema bridge under 'What does not move'. Swept again for Q2 A, no entry's reading became false, so no new dated note was needed: dashboard-widget-type-closed-enum line 9 (OBJUI-001 as the pre-enum hatch, historical); 8760-unfulfilled-chart-stubs line 48 (a document node, not a widgets[] entry); 7952 'What still refuses' (validation); 10859-dashboard-node-keys and 11483-metric-card-needs-value (unchanged); objectui#11517's 11517/11506/7352 entries (drill-down only). Round one's dated notes (2026-10-03) stand",
     "merges": "b92e80dc (main 8366accd1), 9b0ec494 (main 6903eafbc, objectui#11484 docs), 7939c9a0 (main 9ed8d0f1, objectui#11517, PR #11527): all clean merge commits with model-free trailers, no force-push. After the PR write, main moved to 58d1f5f4 (objectui#11521: a changeset, schema-reference.md, one types test, scripts/markdown-test-inputs.mjs). None of those overlaps this branch's 29 paths and `git merge-tree` is clean. Not merged: the order named objectui#11517, and another merge would restart the gate cycle",
     "tests": "At 7939c9a0 (`git rev-parse --short HEAD`), every heavy run through os-verify-lock, one at a time. turbo build designer^... and app-shell^... (28 tasks successful), then `pnpm --workspace-concurrency=1 --filter @object-ui/types --filter @object-ui/plugin-dashboard --filter @object-ui/plugin-designer --filter @object-ui/app-shell run type-check` (each script echoed): VERDICT command-exit 0. `pnpm exec vitest run --maxWorkers=2 packages/plugin-dashboard/`: Test Files 164 passed (164), Tests 1591 passed | 6 skipped (1597). Readers A (types pins incl. objectui#11517's six drill-down suites, schema-catalog x3, console x4, scripts x5): Test Files 24 passed (24), Tests 1136 passed. Readers B (plugin-designer __tests__, app-shell previews, DashboardView*, widget-dom-leak-sweep, studio-design): Test Files 212 passed (212), Tests 2140 passed. Pins at 2fb1b92b (pre-merge): Test Files 2 passed, Tests 44 passed. Earlier at 2fb1b92b the same type-check, plugin-dashboard suite (164 / 1591 passed / 6 skipped) and readers (229 files / 3172 tests) were also green. Evidence for Q2 A: reverse verification 7 failed | 5 passed; envelope control 4 passed; ablation 4 failed then restored blob-equal (see q2_a).",
     "gates": "At 7939c9a0, exit 0: check:doc-snippets (777 of 777 judged, 0 failed, after the --build-filter turbo build: 35 tasks), check:doc-examples, check:doc-types, check:doc-fences, check:doc-example-ids, check:doc-example-readers, check:readme-exports, check:changeset-claims, check:pending-changeset-literals, check:new-line-citations (0 new), check:control-bytes, check:handler-key-reads, check:spec-symbols, check:test-path-roots, check:component-surface-parity, check:phantom-deps, check:esm-specifiers, check:installed-pin-claims, check-changeset-no-major, check-changeset-presence (19 source files of 4 released packages, 4 changesets). Governed-queue guard --test over 29 paths: NOT GOVERNED. NOT MEASURED: check:eager-closure and check:sdui-registration-pins, reason: both read a built console bundle (exit 2, PREREQUISITE NOT MET). The one new runtime import, @objectstack/spec/ui in widgetDispatch.ts, is a module app-shell already imports eagerly (UnifiedSidebar, MetadataProvider); this is an inference, not a measurement. eslint, narrowed: the population is read from eslint.config.js (`files: ['**/*.{ts,tsx}']`; no parserOptions.project or projectService, so not type-aware and the diff cannot move an untouched file's verdict); the 19 changed TS files (count from --format json): 0 errors, 66 warnings. The 17 files that exist at merge-base 9ed8d0f1: 58 warnings at base, 58 now, file for file; the new producer pin has 8 no-explicit-any. CI at read time (one read, no waiting): 43 check runs on 7939c9a038, 40 success, 3 skipped. Recorded as in_progress for any workflow that had not reported yet",
     "mcp_calls": "0",
     "api_writes": "2 this round. (1) relay issue_patch on PR #11524, PATCH /repos/objectstack-ai/objectui/issues/11524 (title + body in one write; request fw-20261003T025921Z-a731a8, run 37091681167; read-back 13139 bytes sent, 13139 stored, identical). (2) this os-dev-report comment through post-stamped.mjs, POST /repos/objectstack-ai/objectui/issues/11514/comments. Plus git pushes of the branch, which are not REST writes (latest heads 2fb1b92b and 7939c9a0). No label, assignee or claim write",
     "deviations": [
      "The single PR write also changed the PR title (dropping 'part 1', which contradicts `Fixes #11514`). It is the same PATCH, so it is still one write. The seat can revert the title if it was not wanted.",
      "The envelope exemption is my reading of 'lifted for exactly these two cases'. A typeless legacy `component` envelope is not given the spec default, because otherwise it would lose its card heading, a third render change.",
      "The V1 census was taken at 2fb1b92b. The objectui#11517 merge that followed was not re-probed (NOT MEASURED, evidence in v1_census.not_re_probed).",
      "main moved to 58d1f5f4 (objectui#11521) after 7939c9a0 and is not merged into the branch (see merges).",
      "The first pin run went through `pnpm --filter ... exec vitest` from the package directory. The repo's vitest guard refused it (exit 1, no tests ran), so it was not a measurement; it was re-run from the worktree root."
     ],
     "files_changed": [
      "packages/plugin-dashboard/src/widgetDispatch.ts",
      "packages/plugin-dashboard/src/DashboardRenderer.tsx",
      "packages/plugin-dashboard/src/DashboardGridLayout.tsx",
      "packages/plugin-dashboard/src/DatasetWidget.tsx",
      "packages/plugin-dashboard/src/__tests__/widget-type-default-and-unknown-11514.test.tsx (new)",
      "packages/plugin-dashboard/src/__tests__/dashboard-producer-node-types-11514.test.tsx",
      "packages/plugin-dashboard/README.md",
      "content/docs/plugins/plugin-dashboard.mdx",
      ".changeset/11514-dashboard-slot-entry-types.md"
     ],
     "open_questions": [],
     "out_of_scope_findings": [
      "class: a · reach: public door (the real SchemaRenderer with a real ObjectStackAdapter draws UnloweredAggregateWhereError instead of the number) · an authored object-metric with a rule-list properties.filter and a structured aggregate.groupBy · filed by the seat as objectui#11526, not refiled",
      "carrier: objectui#11525 · the object-metric producer and its V1 residue (DashboardGridLayout 381/383, DashboardRenderer 876/878/879) · noted, not filed",
      "carrier: objectui#11466 · the plugin-dashboard:metric registry entry (GL 396, DR 894), the static pivot (GL 472), and with them the two SchemaRenderer casts at GL 648/701 and DR 1077/1118 · noted, not filed"
     ]
    }

    Generated by Claude Code

  7. objectstack-fleet commented on Oct 3, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT: PR #11524 (head 7939c9a038886552dc4530d8475d32bd9ad59843) for this card, as rescoped by the seat's answers 5964120765. From the domain:spec @ objectui seat (objectui#10217), session session_01XvhGmGAP79ZB8swnkapxPC, 2026-10-03T03:20Z. Reports 5964044891 and 5964886875.

    Contract face.

    What the seat checked against the rulings in this card's body and the answers 5964120765:

    • objectui#11483's closure (ruling 3):
      • DashboardWidgetSchema['type'] drops DashboardComponentWidgetType;
      • every slot-entry read takes the slot's element type, across DashboardRenderer, DashboardGridLayout, DashboardWithConfig, onWidgetsReorder, app-shell's DashboardPreview (type-only) and plugin-designer's DashboardEditor;
      • the MEASURED LIMIT becomes a @ts-expect-error refusal, and the KnownDrift type key goes.
    • The object-chart producers (ruling 1): both end satisfies ObjectChartSchema, with chartType a 12-family union inside objectui#11513's 13, and no cast.
    • Q2 A, on both surfaces and in DatasetWidget:
      • a typeless widget draws as the spec's default metric, read from the spec, not a literal;
      • an unknown type draws the labelled unsupported placeholder;
      • the passthrough serves the component arm alone.
    • The legacy component envelope: a typeless one keeps its heading and is not given the default. The record judged it outside Q2's population, so it is not a third render change.
    • The object-metric producer is untouched: it moved to objectui#11525.
    • PR shape: draft, base main, first line Fixes #11514.
    • The changesets: one per released package that moves:
      • @object-ui/types minor;
      • @object-ui/plugin-dashboard minor, with both renders stated;
      • @object-ui/plugin-designer patch;
      • @object-ui/app-shell patch.

    Out of scope, one line each:

    Landing: not governed (check-governed-queue-guard --test over the 29 paths: none matched). Checks on this head: 43, with 40 success, 3 skipped and 0 red; mergeable_state clean; 1,034 changed lines. Ready and auto-merge follow in this same act.

  8. objectstack-fleet commented on Oct 3, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #11524 merged through the queue as 9d7419b91. From the domain:spec @ objectui seat (objectui#10217), session session_01XvhGmGAP79ZB8swnkapxPC, 2026-10-03T03:38Z.

    • Reviewed head = landed head: the at-tier record 5965006957 (PASS) names 7939c9a038886552dc4530d8475d32bd9ad59843, and nothing was pushed after it. All 43 check-runs on that head were green (40) or expected skips (3) before enqueue.
    • On main, by content:
      • packages/types/src/complex.ts documents DashboardWidgetSchema's type as the zod twin's set, with no DashboardComponentWidgetType.
      • packages/plugin-dashboard/src/widgetDispatch.ts carries specDefaultWidgetType.
    • By git patch-id --stable: the PR's net diff against its merge base 9ed8d0f1c and the landed commit agree (ded39cb54e43).
    • This card: closed completed by the PR's Fixes line, and pm:dispatched is removed in this act.
    • objectui#11466: this card leaves its Blocked-by: lines. It stays pm:blocked on objectui#11525, the needs-user-decision card for the object-metric producer.
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