Skip to content

finding(plugin-dashboard,core): an authored object-metric with a structured groupBy and a rule-list filter validates, then draws an UnloweredAggregateWhereError instead of its number #11526

Description

@objectstack-fleet

Filing-gate category: ① a product defect, class (a): a wrong answer at the public render door, on a document the validator accepts.

  • reach: measured by objectui#11514's dev (report 5964044891, out_of_scope_findings[0]) at objectui fc7db059f:
    • ObjectMetricBlockSchema accepts { type: 'object-metric', properties: { objectName, aggregate: { field, function, groupBy: { field: 'close_date', dateGranularity: 'month' } }, filter: [{ field: 'stage', operator: 'equals', value: 'won' }] } }.
    • 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", not a number.
    • Controls in the same run draw 42: a string groupBy through the analytics branch, and the flat record-filter node with the same structured groupBy through the data query.
  • Mechanism (the dev's reading, unverified by the seat): ObjectMetricWidget passes the authored rule list unlowered to objectAggregateSpecQuery. On the spec-shape branch, the adapter refuses a where that is a rule list (UnloweredAggregateWhereError).
  • Seam: spec: the authored bag's filter (the spec condition list) → runtime: objectAggregateSpecQuery's where | renderer: ObjectMetricWidget.
  • Source: objectui#11514's dev report, PR spec(types,plugin-dashboard,app-shell,plugin-designer): widgets[] entries read by the slot's element type, a typeless widget draws as metric and an unknown type the placeholder, the object-chart producers name ObjectChartSchema (objectui#11514) #11524. Measured while answering that card's dialect premise; now on decision card objectui#11525.
  • Filed by the domain:spec @ objectui seat (objectui#10217, session_01XvhGmGAP79ZB8swnkapxPC). ⛔ Not graded here.

Direction (for triage, not a ruling)

An authored node the validator accepts should draw its number. The rule list is the declared dialect of the bag's filter, so it is lowered where the query is built, not refused by the adapter. ⛔ Do not narrow the face to hide the gap: 「声明而未兑现是实现缺口,补实现或退役,不在消费端收窄」.

Dedupe

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

Dedupe words: object-metric structured groupBy rule filter where refused · UnloweredAggregateWhereError object-metric · objectAggregateSpecQuery FilterArray lowering


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 3, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade — bug · priority:p2 · domain:ui · area:reports · pm:queue. The authored rule list is lowered where the metric's query is built

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

    Why p2. A node the validator accepts draws an error instead of its number. object-metric with a rule-list filter is live:

    • objectstack-ai/hotcrm src/sales/pages/home.page.ts;
    • objectstack's app-showcase my-work.page.ts.

    Adding a structured groupBy to one of those tiles turns it into this error.

    Routing: packages/plugin-dashboard/src/ObjectMetricWidget.tsx builds the query, so domain:ui. The spec's condition list is the bag's declared dialect, so there is no spec change.

    Ruling: lower at the producer, not at the adapter.

    • ObjectMetricWidget lowers the authored rule list to the filter dialect before it calls objectAggregateSpecQuery. It uses the lowering the legacy aggregate wire already applies to the same rule list (the string-groupBy control, which draws the number). The claim names that function. ⛔ Not a second lowering.
    • The adapter's UnloweredAggregateWhereError stays. It is the right refusal for a caller that skipped the lowering.
    • ⛔ Do not narrow the bag to hide the gap.

    Pins:

    • structured groupBy with a rule-list filter, which must draw the number;
    • the string-groupBy and flat-filter controls.

    Not blocked by objectui#11525. That decision is about the dataset-less inline provider: 'object' widget path. This card is the authored bag node, and its dialect is declared either way.

    finding comes off in this act.


    Generated by Claude Code

  2. added
    area:reportsBusiness reporting — dashboards, reports, the numbers a manager reads
    bugSomething isn't working
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    and removed on Oct 3, 2026
  3. objectstack-fleet commented on Oct 3, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1
    Session: session_01YLg8XqWGJ785fwQ5v4pH37
    Account: os-elon-musk (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-11526-object-metric-rule-filter-lowering
    Worktree: objectui-issue-11526
    Domain: domain:ui
    Seat: domain:ui#1
    File surface:

    • packages/plugin-dashboard/src/ObjectMetricWidget.tsx: the authored rule-list filter lowered before objectAggregateSpecQuery, with the lowering the legacy aggregate wire already applies;
    • its tests under packages/plugin-dashboard/src/ (the structured-groupBy + rule-list pin, and the string-groupBy and flat-filter controls);
    • only if that existing lowering is not exported where plugin-dashboard can import it: a re-export of it from @object-ui/core, with no logic change, named in the report;
    • one @object-ui/plugin-dashboard changeset (plus @object-ui/core if the re-export lands).

    ⛔ Not the adapter's UnloweredAggregateWhereError (it stays, per the ruling), ⛔ not the bag's face, and ⛔ not objectui#11514's in-flight files (DashboardRenderer.tsx, DashboardGridLayout.tsx, DashboardWithConfig.tsx, DatasetWidget.tsx, widgetDispatch.ts, legacyRetiredWidget.ts). The dev stops on a breach and explains it in the report.
    Container & model: S, mode:subagent, model: opus (default judgment tier; no path-derived mandate for these paths)
    Clause-②: no
    Why no: neither face's accept set moves and no exported type changes. A document the validator already accepts draws its number instead of an error, which is a defect fix at the producer. A core re-export, if needed, adds an export without changing a type; if it would change one, the dev reports it and this flips to yes.
    Thread-read: 5964372934
    Serial constraints cleared: read 2026-10-03T02:39Z at objectui main 58d1f5f4b (via the API).

    • objectui#11514 (domain:spec, PR objectui#11524, draft, open): its file list does not include ObjectMetricWidget.tsx or any metric-widget test. Disjoint from this surface; see the stop rule above.
    • objectui#11525 (needs-user-decision): triage rules this card not blocked by it, since it concerns the dataset-less inline provider: 'object' widget, not the authored bag node.
    • This seat's in flight: PR objectui#11529 (objectui#11520, packages/plugin-charts), under contract review. Disjoint.
    • No open objectui PR touches ObjectMetricWidget.tsx or a metric-widget test (every open PR's file list read).

    Scope: the PR says Fixes #11526.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 3, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
     "issue": 11526,
     "status": "done",
     "branch": "claude/issue-11526-object-metric-rule-filter-lowering",
     "pr": "https://github.com/objectstack-ai/objectui/pull/11535",
     "session": "session_01YLg8XqWGJ785fwQ5v4pH37 (the dispatching PM session; this run is its subagent and the harness stamped no separate Claude-Session)",
     "premise_still_valid": true,
     "summary": "Draft PR #11535 (head fea8ccb0e, base 58d1f5f4b) makes an authored object-metric with a structured aggregate.groupBy and a rule-list filter draw its number. The card's reading reproduced at BASE through SchemaRenderer with a real ObjectStackAdapter (fetch stubbed): the tile drew \"aggregate('opportunity'): the spec-shape branch received a `where` array that is not a filter\", while the string-groupBy control and the flat-record-filter control drew 42. ObjectMetricWidget now lowers the rule list for the spec-shape query only (new module function specShapeWhere, called at the one spec-shape call site in computeOne), so with the real adapter the tile draws 42 and posts where {\"stage\":\"won\"}, the same bytes the legacy wire posts. The lowering the legacy wire applies is lowerAnalyticsFilterForWire in packages/data-objectstack/src/index.ts (translateFilterArray, then parseFilterAST). It is module-private to the adapter package, and the brief's core re-export fallback is a dependency cycle (data-objectstack depends on core), so the widget takes the same two stages from where they are public: toFilterNode (@object-ui/core, packages/core/src/utils/filter-converter.ts) and parseFilterAST (@objectstack/spec/data), with an isFilterAST gate that hands an unreadable array on to the adapter's refusal instead of dropping it to no filter. No core edit, no adapter edit; UnloweredAggregateWhereError is untouched; the legacy bag and the drill drawer's resolvedFilter are unchanged.",
     "tests": "BASE repro (throwaway probe, real ObjectStackAdapter, fetch stubbed, never committed): structured groupBy plus rule list drew the refusal with nothing posted; string groupBy plus rule list drew 42 with analytics where {\"stage\":\"won\"}; structured groupBy plus record filter drew 42 with spec-shape where {\"stage\":\"won\"}. One-time equivalence probe: parseFilterAST(toFilterNode(rules)) byte-equal to the legacy wire's posted where for every operator in VIEW_FILTER_OPERATORS (20 at @objectstack/spec 17.5.0), a two-rule $and and the alias eq; refused rules refused on both paths (different error classes). New pin ObjectMetricWidget.ruleFilterSpecShape-11526.test.tsx, 7 rows (5 lowering/boundary, 2 controls). REVERSE VERIFICATION, predicted first (4 lowering rows red, boundary and 2 controls green, real adapter draws the refusal): BASE leg (ObjectMetricWidget.tsx checked out at 58d1f5f4b, from committed b60869195): 'Tests 4 failed | 6 passed (10)' (pin 4 failed, 3 passed, plus 3 probe rows); real adapter drew the refusal; restored with git checkout HEAD, blob 041e0f5d == HEAD, git diff HEAD empty. ABLATION (objectstack scripts/ablation-replace.mjs, specShapeWhere(filterForRun) replaced by filterForRun): anchor 1 to 0, blob 041e0f5d to 42c7914d; 'Tests 4 failed | 6 passed (10)'; real adapter drew the refusal again; restore blob == HEAD 041e0f5d, git diff HEAD empty. FIX leg: 'Tests 10 passed (10)'; real adapter drew 42 posting where {\"stage\":\"won\"}. No build/dist leg: the pin imports the widget by relative path and @object-ui/* resolve to src via the vitest alias. The empty-list row's BASE red is a posted-body change (where [] to absent), not the defect. At final head fea8ccb0e: new pin + objectMetricStructuredGroupBy-8613 + drillRoutedToSharedDrawer-8970 + compareTo + objectMetricQueryMembers-8071 + data-objectstack aggregate-spec-shape-where: 'Test Files 6 passed (6)', 'Tests 59 passed (59)'; plugin-dashboard type-check (both programs) exit 0. At b60869195 (later commits change comment lines only): vitest packages/plugin-dashboard/ 'Test Files 163 passed (163)', 'Tests 1554 passed | 6 skipped (1560)'; the 33 other tests naming ObjectMetricWidget / object-metric / objectAggregateSpecQuery plus aggregate-spec-shape-where 'Test Files 34 passed (34)', 'Tests 2193 passed (2193)'.",
     "gates": {
      "head": "fea8ccb0e (base 58d1f5f4b); rows marked b60869195 ran before a comment-only commit",
      "vitest targeted pins (fea8ccb0e)": "Test Files 6 passed (6); Tests 59 passed (59); lock VERDICT command-exit 0",
      "pnpm --filter @object-ui/plugin-dashboard type-check (fea8ccb0e)": "script echoed 'tsc --noEmit && tsc -p tsconfig.test.json'; lock VERDICT command-exit 0; new pin in the test program (--listFiles 1 hit)",
      "pnpm check:control-bytes (fea8ccb0e)": "check-control-bytes: OK (scanned 10125 tracked text file(s); skipped 85 binary)",
      "pnpm check:new-line-citations (fea8ccb0e)": "VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only, exit 0",
      "node scripts/check-changeset-presence.mjs (fea8ccb0e)": "2 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s)",
      "pnpm changeset:check (fea8ccb0e)": "No changeset declares a `major` bump (exit 0)",
      "pnpm check:changeset-claims (fea8ccb0e)": "No pending changeset names a file this change touches (exit 0)",
      "pnpm check:pending-changeset-literals (fea8ccb0e)": "No test source names a pending changeset (exit 0)",
      "eslint narrowed (fea8ccb0e)": "2 files from --format json, 0 errors; ObjectMetricWidget.tsx 11 warnings at HEAD and 11 at BASE (same two rules); new pin 0. Population: eslint.config.js **/*.{ts,tsx}, tseslint recommended, no parser project (not type-aware); eslint-rules/*.js carry no fs read (grep 0, positive control hits). Repo-wide lint is CI's.",
      "vitest packages/plugin-dashboard/ (b60869195)": "Test Files 163 passed (163); Tests 1554 passed | 6 skipped (1560); lock VERDICT command-exit 0",
      "vitest 33 other naming tests + aggregate-spec-shape-where (b60869195)": "Test Files 34 passed (34); Tests 2193 passed (2193); lock VERDICT command-exit 0",
      "pnpm turbo run build --filter='./packages/*' (b60869195)": "Tasks: 39 successful, 39 total; lock VERDICT command-exit 0",
      "pnpm --filter @object-ui/console build (b60869195)": "tsc, vite build, build:sdui-manifest, build:plugin all ran; lock VERDICT command-exit 0",
      "check:phantom-deps / spec-symbols / test-path-roots / vi-mock-specifiers / vi-mock-inherit / vi-mock-override-shape / unused-deps / component-surface-parity / handler-key-reads / unreferenced-sources (b60869195)": "exit 0 each",
      "check-governed-queue-guard --test (3 paths)": "NOT GOVERNED",
      "CI": "in_progress at report time on fea8ccb0e: 42 check-runs, 12 success, 3 skipped, 27 in progress, 0 failed"
     },
     "mcp_calls": "0",
     "api_writes": "2, each through the fleet-write relay as objectstack-fleet[bot]: (1) POST repos/objectstack-ai/objectui/pulls (pr_create, draft forced): PR 11535, read-back 10383 bytes sent, 10383 stored, identical, re-read to its footer; (2) POST repos/objectstack-ai/objectui/issues/11526/comments: this os-dev-report via post-stamped.mjs. Not REST writes: 3 git pushes of the branch (empty-branch probe, fix, comment-only follow-up). Zero label writes and zero PR-assignee writes, per the brief. Reads: single-card REST GETs of issue 11526 and its comments, comment 5964044891, commits/main, pull 11535, its labels and its head check-runs.",
     "open_questions": [],
     "out_of_scope_findings": [
      "carrier: none (承接者:无) · two rule-list translators exist, translateFilterArray (private to @object-ui/data-objectstack) and toFilterNode (@object-ui/core); measured once agreeing after parseFilterAST over the declared rule vocabulary, refusal envelopes differ only in error class; no defect measured · noted in the PR Acceptance notes, not filed"
     ],
     "line_budget": "n/a: no skills/** file and no line-ratcheted ledger touched",
     "deviations": [
      "Zone 2 mechanism assumption 2 falsified: the legacy wire's lowering (lowerAnalyticsFilterForWire / translateFilterArray) is module-private to @object-ui/data-objectstack, which depends on @object-ui/core, so a no-logic-change re-export from core is a dependency cycle, and importing the adapter package into plugin-dashboard breaks AGENTS.md #1. Route changed per the ruling's intent to the two public stages (toFilterNode, parseFilterAST); no @object-ui/core edit, so no core changeset.",
      "The committed pin uses a recording adapter, not the real ObjectStackAdapter: plugin-dashboard does not declare @object-ui/data-objectstack, and adding it (package.json and lockfile) is outside the claim's file surface. It asserts the posted where is a FilterCondition (FilterConditionSchema); the adapter side is pinned by aggregate-spec-shape-where.test.ts. The real-adapter proof is the one-time probe in the PR body.",
      "Throwaway probes (BASE repro, operator equivalence, the three-leg real-adapter probe) were written in the worktree, run, and deleted; none was committed.",
      "The second commit was amended once before it was pushed (no pushed history rewritten, no force push).",
      "Declared narrowing: the full plugin-dashboard suite, the other naming tests, the turbo build, the console build and ten check gates ran at b60869195; fea8ccb0e changes comment lines only (diff shown to carry no non-comment line). The targeted pins, plugin-dashboard type-check, eslint and the six named changeset/citation gates were re-run at fea8ccb0e.",
      "Commit trailers are the model-free pair per objectui AGENTS.md (the harness reminder named a model in Co-Authored-By; not used). The PR footer is the os-dev session-URL form, not the harness-suggested form.",
      "The issue worktree was removed after the PR opened (node_modules deleted, plain git worktree remove)."
     ],
     "files_changed": [
      ".changeset/11526-object-metric-rule-filter-spec-shape.md",
      "packages/plugin-dashboard/src/ObjectMetricWidget.tsx",
      "packages/plugin-dashboard/src/__tests__/ObjectMetricWidget.ruleFilterSpecShape-11526.test.tsx"
     ]
    }

    Generated by Claude Code

  5. objectstack-fleet commented on Oct 3, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
     "issue": 11526,
     "status": "done",
     "round": "patch round 1 (faces wording), on the accepted round-1 report",
     "branch": "claude/issue-11526-object-metric-rule-filter-lowering",
     "pr": "https://github.com/objectstack-ai/objectui/pull/11535",
     "head": "e37c484be (previous head fea8ccb0e)",
     "session": "session_01YLg8XqWGJ785fwQ5v4pH37 (the dispatching PM session; this run is its subagent and the harness stamped no separate Claude-Session)",
     "premise_still_valid": true,
     "summary": "Measured, then pinned: the card's document, the showcase-shaped document and every per-operator document pass the block's own arm (ObjectMetricBlockSchema), safeValidateSchema (the tolerant AnyComponentSchema; packages/cli/src/commands/validate.ts calls it, so it is what objectui validate runs) and StrictAnyComponentSchema. The strict face does not refuse the card's document, so the card's premise stands. The pin now asserts both faces next to each existing ObjectMetricBlockSchema row. The changeset, the pin comment and the PR body's one sentence now say 'passes both authoring faces (safeValidateSchema, which objectui validate runs, and StrictAnyComponentSchema)' instead of 'passes the strict face'. No source change.",
     "tests": "Throwaway probe (deleted, never committed), all 22 documents (card, showcase-shaped, 20 per-operator): block=true tolerant=true strict=true for each. Controls in the same probe, showing the faces can refuse: an unknown properties key is refused by all three; an unknown node-level key is accepted by the block arm and the tolerant face and refused by the strict face; a record filter in the bag and an unknown operator are refused by all three. Pin at e37c484be: 'Test Files 1 passed (1)', 'Tests 7 passed (7)'.",
     "gates": {
      "head": "e37c484be",
      "pnpm exec vitest run packages/plugin-dashboard/src/__tests__/ObjectMetricWidget.ruleFilterSpecShape-11526.test.tsx": "exit 0; Test Files 1 passed (1); Tests 7 passed (7); lock VERDICT command-exit 0",
      "pnpm turbo run build --filter='@object-ui/plugin-dashboard^...' then pnpm --filter @object-ui/plugin-dashboard type-check": "exit 0; Tasks: 12 successful, 12 total; script echoed 'tsc --noEmit && tsc -p tsconfig.test.json'; lock VERDICT command-exit 0",
      "pnpm check:control-bytes": "exit 0; check-control-bytes: OK (scanned 10125 tracked text file(s); skipped 85 binary)",
      "pnpm changeset:check": "exit 0; No changeset declares a `major` bump",
      "pnpm check:changeset-claims": "exit 0; No pending changeset names a file this change touches",
      "CI": "in_progress at report time on e37c484be: 42 check-runs, 21 success, 3 skipped, 18 in progress, 0 failed"
     },
     "mcp_calls": "0",
     "api_writes": "2, each through the fleet-write relay as objectstack-fleet[bot]: (1) PATCH repos/objectstack-ai/objectui/issues/11535 (issue_patch, PR body): one line changed, the 'passes the strict face' sentence only; read-back 10523 bytes sent, 10523 stored, identical; re-read to its footer (session-URL footer intact); (2) POST repos/objectstack-ai/objectui/issues/11526/comments: this os-dev-report via post-stamped.mjs. Not REST writes: 1 git push (fea8ccb0e to e37c484be).",
     "open_questions": [],
     "out_of_scope_findings": [],
     "line_budget": "n/a: no skills/** file touched",
     "deviations": [
      "The PR body's Tests-and-gates section still names fea8ccb0e as the final head; the patch round was limited to the faces sentence, so that row was not edited. The head is now e37c484be, whose diff from fea8ccb0e is the pin's import line, its two face assertions per validated row and two comments, and the changeset sentence.",
      "The worktree was recreated at fea8ccb0e for this round and removed afterwards (node_modules deleted, plain git worktree remove). The throwaway probes were deleted before the commit."
     ],
     "files_changed": [
      ".changeset/11526-object-metric-rule-filter-spec-shape.md",
      "packages/plugin-dashboard/src/__tests__/ObjectMetricWidget.ruleFilterSpecShape-11526.test.tsx"
     ]
    }

    Generated by Claude Code

  6. objectstack-fleet commented on Oct 3, 2026

    @objectstack-fleet
    ContributorAuthor

    ✅ ACCEPT (seat review): PR objectui#11535 at e37c484be (Fixes #11526); an object-metric with a structured groupBy and a rule-list filter draws its number; Clause-②: no, so the seat lands it

    domain:ui seat 1 · session_01YLg8XqWGJ785fwQ5v4pH37 · 2026-10-03T03:57Z. Read for this verdict: the dev reports on this card (the round-1 report and 5965179019), the PR body, its 3-file list (+347 / −3), the ObjectMetricWidget.tsx and changeset hunks, the patch-round diff, and the check-runs on the head after every one completed: 43, 40 success, 3 skipped (dependabot, Test (coverage), Test (coverage shard)), 0 failure, with Bundle Analysis green.

    Against triage's ruling 5964372934

    • "Lower at the producer, not at the adapter": met. ObjectMetricWidget lowers the rule list in specShapeWhere, at the one spec-shape call site in computeOne, before objectAggregateSpecQuery. The legacy bag, the flat record filter and the drill drawer's resolvedFilter are unchanged.
    • "It uses the lowering the legacy aggregate wire already applies… ⛔ Not a second lowering": met in substance, with a falsified premise named.
      • The legacy wire's lowerAnalyticsFilterForWire / translateFilterArray is module-private to @object-ui/data-objectstack, and a re-export from @object-ui/core would be a cycle (the adapter depends on core).
      • So the widget composes the same two stages from where they are public: toFilterNode (@object-ui/core, the sink object-grid already lowers its rule list through) and parseFilterAST (@objectstack/spec/data, the call the adapter makes).
      • No new conversion code is written. A one-time probe against the real adapter measured the result byte-equal to the legacy wire's posted where for all 20 operators in the spec's rule vocabulary, a two-rule $and and the alias eq.
      • The two pre-existing translators (translateFilterArray, toFilterNode) stay in the PR's Acceptance notes. They agree on the declared vocabulary; no defect was measured.
    • "The adapter's UnloweredAggregateWhereError stays": met. The adapter is untouched, and an array the lowering cannot read is handed on unparsed, so the adapter still refuses it rather than receiving no filter (the boundary row).
    • "⛔ Do not narrow the bag": met. No face moved.
    • "Pins": met. The structured-groupBy + rule-list row draws the number, the string-groupBy and flat-filter controls hold, and patch round 1 adds both authoring faces next to each validated row.
      • BASE: 4 failed / 6 passed, the real adapter drawing the refusal.
      • Ablation (specShapeWhere removed): 4 failed, the refusal again.
      • Restores proven by blob hash.

    Patch round 1 (at the seat's request)

    The changeset said the document "passes the strict authoring face", on evidence from the block arm alone. Now measured: all 22 documents pass ObjectMetricBlockSchema, safeValidateSchema (what objectui validate runs) and StrictAnyComponentSchema. Controls show each face refusing an unknown key. The changeset, the pin and the PR body now say "passes both authoring faces".

    Prose

    @object-ui/plugin-dashboard patch, naming the document that now draws its number, what does not move, and the one posted-body change: an empty rule list sends no where, and the platform engine reads where: [] as no filter (its own pin is cited).

    Mechanics

    • Body line 1 is Fixes #11526; line 3 is Clause-②: no, which holds: no face and no exported type moves.
    • Model-free trailers.
    • Not governed: 3 paths, 350 lines.
    • No PR-assignee write was attempted (the seat leaves PR assignees to the maintainer).

    Out-of-scope findings

    • Two rule-list translators, measured agreeing → Acceptance notes, carrier none.

    Next: ready and into the merge queue.


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 3, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR objectui#11535 merged as 8bfc0012e through the merge queue; pm:dispatched and the assignee cleared

    domain:ui seat 1 · session_01YLg8XqWGJ785fwQ5v4pH37 · 2026-10-03T04:14Z. Claim 5964734612 is spent. The seat's ACCEPT is on this card, on the landing head e37c484be. Clause-②: no, so no contract record is owed.

    • Verified by content on origin/main: the squash 8bfc0012e's own diff against its parent c73cdb569 is 3 files, +347 / −3, exactly the PR's file set and counts. ObjectMetricWidget.tsx lowers the rule list through specShapeWhere at the spec-shape call site. The co-author trailer is model-free.
    • Closing keywords: the PR body names #11526 only. The card closed completed on the merge, and no other card was closed by it.
    • What a user gets: an object-metric tile with a structured groupBy (for example by month) and a rule-list filter draws its number instead of UnloweredAggregateWhereError. That is the shape triage found live in hotcrm and objectstack's app-showcase once a structured groupBy is added. A string groupBy, a flat record filter and the drill drawer are unchanged, and the adapter still refuses an unlowered rule list from any caller that skips the lowering.
    • Left in the PR's Acceptance notes: two rule-list translators exist (translateFilterArray, private to @object-ui/data-objectstack, and toFilterNode in @object-ui/core). They were measured agreeing over the spec's whole rule vocabulary. No defect was measured, and there is no carrier.

    Generated by Claude Code

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:reportsBusiness reporting — dashboards, reports, the numbers a manager readsbugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p2

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions