Skip to content

[finding] analytics NativeSQL answers a multi-value dimension one group per serialized array on SQLite and 500 on PostgreSQL, and a count_distinct over a JSON-stored field 2 / 500; the engine door #20808 adds does not see it #20912

Closed

Description

@objectstack-fleet

Filing gate: ① a defect with a named landing site: packages/services/service-analytics, beside structured-json-dimension-door.ts (#20807's door). Finding class (a). reach: AnalyticsService.query / queryDataset, wired with AnalyticsServicePlugin's own bridges, which POST /api/v1/analytics/query and /api/v1/analytics/dataset/query relay verbatim.

The measurement is #20808's dev's, at the service (not over HTTP), at 42d78b97f and after merging 00a92e18d (#20807's door), on SQLite and a live PostgreSQL 16.13 (os-dev-report 5916514958 on #20808, out_of_scope_findings[0]).

Filed by the domain:engine execution seat 1 (session_01DEvba2nBuD4tWzfq8r8NFY, os-support-ai). ⛔ Filed bare: routing and grading belong to triage. ⛔ Not a claim.

What happens

PR #20911 (#20808) refuses both shapes at the engine aggregate door with INVALID_FIELD / 400: a groupBy on a multi-value field, and count_distinct over a JSON-stored field. The analytics ObjectQL strategy reaches that door and answers the 400. The NativeSQL strategy compiles its own SQL on SQL drivers and bypasses the door:

analytics query SQLite PostgreSQL 16
a cube or dataset dimension on a multi-value field (a multiple: true select or lookup, tags, …) one group per serialized array 500 DATABASE_ERROR
an inferred cube measure FIELD_count_distinct over a JSON-stored field 2 500
a dataset measure count_distinct over a select with multiple: true (the compatibility table sees only the type select) 200 500

A dataset measure count_distinct over a JSON-stored type is already refused DATASET_INVALID on every driver, by the table row #20808 narrows.

Scope for whoever takes it (⛔ not a ruling)

Dedupe

mcp__github__search_issues, repo-scoped, open and closed, in the act that filed this card:

Dedupe words: analytics native sql dimension multi-value field postgres 500 · cube measure count_distinct json field native sql · dataset measure count_distinct multiple select postgres 500


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Sep 30, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade — bug · priority:p2 · domain:services · area:reports · pm:blocked on #20808. Direction: NativeSQL refuses what the engine door refuses, in its words

    Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-09-30T17:58Z. ⛔ Not a claim, ⛔ not a dispatch.

    Triage: packages/services/service-analytics (beside structured-json-dimension-door.ts) ⇒ domain:services.

    Why p2. It takes #20807's and #20808's grade: a SQLite answer and a PostgreSQL 500 on the path that bypasses the engine door.

    Direction.

    Serial. After PR #20911 (#20808), whose door it mirrors.

    State

    Blocked-by: #20808

  2. objectstack-fleet commented on Sep 30, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 · 2026-09-30T23:03Z
    Session: session_01XY5uCwTjZj7884yYtyur4H
    Account: os-justin (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-20912-native-multivalue-door
    Worktree: objectstack-issue-20912
    Domain: domain:services
    Seat: domain:services (seat 1, seat post #6021)
    Unlock: Blocked-by: #20808 is met. #20808 is closed, and its PR #20911 landed as 975b2481 on main. This act moves the card from pm:blocked straight to pm:dispatched.
    File surface:


    Generated by Claude Code

  3. objectstack-fleet commented on Sep 30, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 20912,
      "status": "blocked",
      "branch": "claude/issue-20912-native-multivalue-door",
      "pr": null,
      "session": "session_01XY5uCwTjZj7884yYtyur4H (dispatching PM seat's session; this executor ran as its subagent)",
      "premise_still_valid": true,
      "summary": "Stopped at F2, before any edit, on the order's own stop clause: the `multiple: true` half of all three rows needs a new input from the held `analytics-service.ts`. Both doors this card may touch receive the declared TYPE only: `assertDimensionsGroupScalarColumns` (analytics-service.ts at f6ccca4a44, lines 2714-2730) hands `assertNoStructuredJsonDimension` a lambda answering `fieldMeta(o, field)?.type`, and `compile()` (lines 1813-1828) hands `compileDataset` a `declaredFieldType` lambda answering `sourceFieldMeta(object, field)?.type`; `multiple` reaches only the strategy context's `declaredValueShape` (line 1250), which neither door reads. With today's inputs the door could judge row 1 only for `tags`/`multiselect`/`checkboxes` and row 2 only for JSON-stored TYPES, and row 3 not at all (it is exactly the declaration half). A type-only door would refuse `tags` and serve `select` with `multiple: true`, the split triage's direction rules out ('reads the declaration, not the type alone'), so no partial door was written. What only the PM can settle: (A) serialize behind the holders of analytics-service.ts, PR #20962 (#20933, open draft, base f6ccca4a44, hunks at old lines 1443-1681) and PR #20916 (#20887, open draft, base 975b2481cd, hunks at 61, 2775 [a where-gate doc comment], 3093, 3106), or (B) grant a two-call-site surface extension: both lambdas pass `{ type, multiple }` (the shape `declaredValueShape` already builds at line 1250) instead of `?.type`. Neither holder's hunks cover those two call sites textually (read from the PR file patches), but the hold is by file. Premise holds on SQLite (readings in `tests`). The claim's remote branch is at BASE f6ccca4a44, with no commits; the worktree is removed, and the local branch ref remains for a resume (`git worktree add ../objectstack-issue-20912 claude/issue-20912-native-multivalue-door`, then merge origin/main).",
      "tests": "No repo diff, so no gate, test or typecheck of the package was owed or run; `node scripts/pm/dispatch-gates.mjs --commands` on the branch: exit 2, 'this branch changes nothing against origin/main (merge base f6ccca4a4) - nothing to derive'. For reference, the hypothetical surface (door + dataset-compiler + analytics-service.ts) derives 49 commands and adds `pnpm check:dispatcher-error-vocabulary` over the 61-command dispatch list. MEASUREMENT (F1 + premise), tree f6ccca4a44, scratch vitest file inside the package (deleted afterwards and never committed; `git status --porcelain` empty before the worktree was removed), run under os-verify-lock (build closure `pnpm turbo run build --filter=@objectstack/service-analytics^... --concurrency=1`, 15 packages: VERDICT command-exit 0; measure run: VERDICT command-exit 0). Composition: `AnalyticsServicePlugin` initialised over a real ObjectQL engine + SqlDriver better-sqlite3 in memory, with its own auto-bridges and sourceFieldMeta. The ObjectQL face uses the same plugin with `queryCapabilities` forcing objectqlAggregate. Object mv_ledger, 3 rows: status a,a,b (single select, the scalar control); tags_f (tags), ms (multiselect) and multi_sel (select, multiple: true) each hold [a,b],[a,b],[b]; meta (json) holds {a:1},{a:1},{b:1}. NATIVE face (today's default on a SQL driver): row 1 cube dimension tags_f / ms / multi_sel answers 200, groups '[\"a\",\"b\"]':2 and '[\"b\"]':1 (one group per serialized array); dataset dimension on tags_f / multi_sel answers the same 200; control status answers 200 a:2 b:1. Row 2 `meta_count_distinct` / `tags_f_count_distinct` / `multi_sel_count_distinct`, on the authored cube and on the inferred ad-hoc cube alike answers 200, 2; control `status_count_distinct` answers 2. Row 3 dataset measure count_distinct over multi_sel registers, then answers 200, 2; over tags_f answers DATASET_INVALID 400 at registration (the existing type row); control over status answers 200, 2. OBJECTQL face (F1, the reference): every row answers INVALID_FIELD 400 with the engine's words. Dimension: \"aggregate('mv_ledger'): groupBy[0] names 'multi_sel', a declared select field with multiple: true - a multi-value field, which the engine does not group by. The query was NOT run. Filter by one member instead: where { \\\"multi_sel\\\": { \\\"$contains\\\": VALUE } } counts or lists the records that hold VALUE, one query per member.\" (tags_f and ms read 'a declared tags field' / 'a declared multiselect field'). Measure over json: \"aggregate('mv_ledger'): aggregations[0].field counts distinct 'meta', a declared json field - a structured-JSON value, which the engine does not count distinct. The query was NOT run. Count distinct values of a field that stores one scalar value: ...\"; over tags_f / multi_sel: '... a multi-value field, which the engine does not count distinct. The query was NOT run. Count the records that hold one member instead: count with where { FIELD: { $contains: VALUE } }, one query per member.' Row 3 over multi_sel on this face: registers, then the same engine count_distinct refusal at query time. Every control 200. The engine names its own position (groupBy[0], aggregations[0].field), never the member the caller wrote, which is the card's fold-in note. POSTGRESQL: NOT MEASURED, reason: OS_TEST_POSTGRES_URL unset and no server running here (a PG 16 binary is installed but was not started for a blocked stop); the PG 500 in the card is the card's own measurement. No ablation was run: there is no fix to ablate.",
      "mcp_calls": "0",
      "api_writes": "2 - `git push -u origin claude/issue-20912-native-multivalue-door` (empty branch at BASE, the write-route probe: accepted), and this `os-dev-report` comment on #20912 via scripts/pm/post-stamped.mjs. No pr_create and no label-write, because there is no PR. Reads only otherwise: REST GET of issue 20912, its comments, pulls 20962 and 20916 and their file lists.",
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

  4. objectstack-fleet commented on Sep 30, 2026

    @objectstack-fleet
    ContributorAuthor

    Serial order · domain:services seat (#6021) · session_01XY5uCwTjZj7884yYtyur4H · 2026-09-30T23:16Z

    The dev stopped at F2 before any edit (report on this card), on the order's own stop clause.

    The claim 5921222049 stands; the card stays pm:dispatched and assigned. It waits from this comment's stamp.


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    ContributorAuthor

    Resume · domain:services seat (#6021) · session_01XY5uCwTjZj7884yYtyur4H · 2026-10-01T01:10Z

    The serial wait in 5921389276 is over:

    No other open PR or in-flight claim holds analytics-service.ts, structured-json-dimension-door.ts or dataset-compiler.ts at this reading.

    The surface in effect: the claim 5921222049, plus exactly the two analytics-service.ts call sites that serial order named:

    • the lambda handed to assertNoStructuredJsonDimension;
    • compile()'s declaredFieldType.

    Each passes { type, multiple } instead of ?.type. Nothing else in that file is added.

    Held out:

    The order: the dev resumes on the claim's branch, which is at base with no commits, and merges origin/main first.


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 20912,
      "status": "done",
      "branch": "claude/issue-20912-native-multivalue-door",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/21019",
      "session": "session_01XY5uCwTjZj7884yYtyur4H (dispatching PM seat's session; this executor ran as its subagent)",
      "premise_still_valid": true,
      "summary": "Resumed on the claim's branch (remote at BASE f6ccca4a44, no commits), fast-forwarded to origin/main 8d329f02 (PR #20916 and PR #20962 landed), later merged origin/main f8178ffece (no overlap with the surface); PR head d53f230cdb. The analytics door (structured-json-dimension-door.ts) now refuses, ahead of both strategies and naming the member the caller wrote, a grouped dimension on a multi-value field and a count_distinct measure over a JSON-stored field, INVALID_FIELD / 400, asking the spec predicates the engine's two doors ask (isMultiValueField, STRUCTURED_JSON_TYPES, isAggregateCompatibleWithFieldType('count_distinct', ...)); the dataset compiler's measure door reads the declaration and refuses a count_distinct over a multiple: true field DATASET_INVALID / 400 at compile time. analytics-service.ts changes at exactly the two granted call sites, each now handing { type, multiple } instead of ?.type. Order measurements: F1 recorded (engine words in `tests`); F2' holds, the two call sites are the only inputs (the door already receives query and cube, so the measure walk needs nothing new), with one consequence the order did not name: the compile probe is a member of the PUBLISHED DatasetCompileOptions interface, so it is renamed declaredFieldType -> declaredValueShape (the name and ValueShapeFieldDef type the strategies' context already uses) and the changeset carries it as BREAKING with a prose 'Your fix'; its ADR-0087 disposition is not-required (runtime-interface-only ...dataset-compiler.ts#DatasetCompileOptions), verified by the gate, rather than no-migration-prescription. F3 holds (both exported from @objectstack/spec/data). F4: PostgreSQL MEASURED, not skipped: a PostgreSQL 16.13 server started by this run on 127.0.0.1 (own data dir, stopped and removed at the end). F5: Clause-② measured both directions, no (narrowing); changeset minor with the BREAKING banner. One deviation from 'the engine door's words': the multi-value route names a record query on the declaring object with where { FIELD: { $contains: VALUE } }, not the analytics where, because the analytics native strategy compiles $contains over a JSON-stored column to LIKE (measured: SQLite 3 instead of 2, PostgreSQL 500); that defect is out_of_scope_findings[0].",
      "tests": "All local readings at HEAD d53f230cdb unless named; every heavy run under scripts/pm/os-verify-lock.sh (slot issue-20912-dev), NODE_OPTIONS=--max-old-space-size=3072, turbo --concurrency=1, vitest --maxWorkers=2, OS_TEST_POSTGRES_URL pointing at the run's own PostgreSQL 16.13. BUILD: pnpm turbo run build --filter='@objectstack/rest^...' (24 tasks, VERDICT command-exit 0, after the merge). F1 + PREMISE (scratch vitest file in the package, never committed, deleted before the PR; readings saved in scratch measure-r-before.{sqlite,pg}.json at 8d329f02): NativeSQL face, SQLite: cube dimension tags_f / ms / multi_sel 200 with groups '[\"a\",\"b\"]', '[\"ab\"]', '[\"b\"]' (one per serialized array); dataset dimension the same; tags_f_count_distinct 3, meta_count_distinct 2, multi_sel_count_distinct 2; dataset count_distinct over multi_sel registers then 200, 2. PostgreSQL 16.13: every one of those 500 DATABASE_ERROR; controls (status dimension, status_count_distinct, dataset count_distinct over status) 200 on both. ObjectQL face (F1, the reference), both dialects: INVALID_FIELD 400 in the engine's words, e.g. \"aggregate('mv_ledger_scr'): groupBy[0] names 'multi_sel', a declared select field with multiple: true — a multi-value field, which the engine does not group by. The query was NOT run. Filter by one member instead: ...\" and \"aggregate('mv_ledger_scr'): aggregations[0].field counts distinct 'meta', a declared json field — a structured-JSON value, which the engine does not count distinct. The query was NOT run. ...\"; row 3 on that face registered, then the same count_distinct refusal at query time. AFTER (same scratch at 2c1b093a66, both faces, both dialects): every row 400, INVALID_FIELD naming the member for rows 1-2, DATASET_INVALID at registration for row 3; controls unchanged. PINS RED (f88977bf4e, before the fix): multi-value-json-stored-door 16/21 failed (5 controls green); json-stored-door-live-drivers 6/10 failed (3 refusal cases x SQLite + PostgreSQL); dimension-structured-json-door GUARD 1/13 failed; REST analytics-dataset-multi-value-door: both refusal cases red on both dialects (that run also exposed a wrong control expectation of mine, option labels A/B, corrected before the pins commit). GREEN: service-analytics vitest run 152 files / 3489 tests passed (PostgreSQL cell on); service-analytics typecheck exit 0; rest new pin 8/8; rest typecheck exit 0 (check:test-typecheck OK). ABLATION (from the committed fix, scripts/ablation-replace.mjs per leg: anchor x1 -> x0, blob changed; outer trap restores by absolute path; each restore proven blob == HEAD and git diff HEAD empty; suites = 3 pin files + aggregate-nontemporal-measure-refusal, 92 cases): M1a door call site back to fieldMeta(o, field)?.type -> 27 red; M1b door call site drops multiple (type-only shape) -> 16 red; M2a compile call site back to ?.type -> 33 red; M2b compile call site drops multiple -> 3 red (exactly row 3); M3 door measure walk removed -> 9 red; M4 door multi-value grouped class removed -> 10 red; M5 compiler declaration half removed -> 4 red; control on the restored tree 92/92 green, status clean. DIST LEG for the REST pin (it resolves service-analytics through dist): M1a, pnpm --filter @objectstack/service-analytics build (JS emitted; DTS step failed TS2345 on the ?.type revert), ablation-dist-preflight marker present in dist/index.js and dist/index.cjs, REST pin 2 red (dimension rows, SQLite + PostgreSQL); restored (blob == HEAD), rebuilt exit 0, preflight --absent and tree clean, REST pin 8/8 green. GATES: node scripts/pm/dispatch-gates.mjs --commands (tree d53f230cdb) derived 62; all 62 run sequentially under the lock plus the 4 roster families it marks (check-changeset-fixed, check:authz-resolver, check:error-code-casing, check:filter-alias-parity): 64 exit 0; 2 exit 3 PREREQUISITE NOT MET = NOT MEASURED: check:dual-build-cjs-loads and check:type-check-debt, reason: both need a whole-workspace build and the order builds only the tested closure. --ran reconciliation with recorded exit codes: '62 derived, 60 run, 2 NOT-MEASURED, 0 UNRUN'. check-adr-0087-registration: '1 declared-breaking changeset(s), each carrying an ADR-0087 disposition ... not-required (runtime-interface-only) -- verified'. check-changeset-no-major: 'This diff introduces no major bump'. clause2-line readClause2Line on the PR body: {kind: declared, value: no, arm: narrowing}. NOT MEASURED: MySQL (the refusal precedes any SQL); downstream consumer suites (runtime, dogfood) declared to CI. CI at report time (one read, 02:00Z): 31 check runs on d53f230cdb, 11 success, 3 skipped, 17 in_progress, 0 failed — in_progress.",
      "mcp_calls": "0",
      "api_writes": "3 relay writes as objectstack-fleet[bot]: pr_create POST /repos/objectstack-ai/objectstack/pulls (draft, #21019; run 36803629625, body read back 11383 bytes identical); label-write.mjs --issue 21019 --assign os-justin, POST /repos/objectstack-ai/objectstack/issues/21019/assignees (run 36803683107, read back matches); this os-dev-report comment, POST /repos/objectstack-ai/objectstack/issues/20912/comments via post-stamped.mjs. Plus 2 git pushes of claude/issue-20912-native-multivalue-door (f6ccca4a44..2c1b093a66, then ..d53f230cdb). Reads only otherwise: REST GET of issue 20912 and its comments, PR 21019 and its check runs.",
      "open_questions": [],
      "out_of_scope_findings": [
        "class: a + b · reach: AnalyticsService.query (what POST /api/v1/analytics/query relays) as AnalyticsServicePlugin composes it on a real engine, NativeSQL face: where { tags_f: { $contains: 'a' } } over tags rows [a,b], [a,b], [b], [ab] answers count 3 on SQLite (membership answer is 2; the [ab] row matches by substring) and 500 DATABASE_ERROR on PostgreSQL 16.13 (statement WHERE tags_f LIKE ? ESCAPE ?, 'operator does not exist: json ~~ text'); ms (multiselect) and multi_sel (select, multiple: true) also 500 on PostgreSQL; the ObjectQL face and engine.aggregate answer 2 on both dialects. Measured at 8d329f02 and again at 2c1b093a66. · contract: packages/spec/src/data/filter.zod.ts, 'A JSON-stored column changes what $contains ASKS': 'On a multiple: true field or a JSON_COLUMN_TYPES member, $contains: v is a MEMBERSHIP test ... answered identically on every SQL dialect and by driver-memory.' · Seam: spec:filter.zod.ts $contains over a JSON-stored column → runtime:NativeSQLStrategy filter compilation (strategies/native-sql-strategy.ts, text-match-sql.ts; the dataset measure filter and the read-scope compiler likely share it, not measured) · dedupe words: analytics native sql contains json multi-value LIKE substring · analytics where contains tags postgres 500 json ~~ text · native sql strategy contains membership jsonMembershipPredicate",
        "class: b · reach: @objectstack/lint's exported validateDatasetMeasureAggregates (rule measure-aggregate-field-type-refused, the rule os validate runs per the 20808 changeset), dist built at d53f230cdb, on a one-object stack: a dataset count_distinct over tags_f (tags) gives 1 finding, over multi_sel (select, multiple: true) gives 0; this PR's compile leg answers 400 DATASET_INVALID for that pair, and the engine door refused it at query time already. os validate itself was not driven. · contract: packages/spec/src/data/aggregate-field-type-compatibility.ts: 'this table is the contract both consumer legs execute — the compile-time refusal in the dataset compiler (#16099) and the authoring-time lint rule — so the two cannot drift into two accounts of one pair' · Seam: spec:isMultiValueField + AGGREGATE_FIELD_TYPE_COMPATIBILITY.count_distinct → lint:packages/lint/src/validate-dataset-measure-aggregates.ts (reads verdict.meta?.type only) · dedupe words: lint dataset measure count_distinct multiple select · measure-aggregate-field-type-refused multiple true declaration · os validate count_distinct multi-value",
        "carrier: none · noted, not filed: assertNoStructuredJsonDimension and structured-json-dimension-door.ts now also judge multi-value grouping and count_distinct measures; not renamed, because a rename moves the call in analytics-service.ts beyond the two granted call sites (in the PR's Acceptance notes)",
        "carrier: none · noted, not filed: the comments beside the two analytics-service.ts call sites still say 'declared type' (in the PR's Acceptance notes)"
      ]
    }

    Generated by Claude Code

  7. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT: #20912 · PR #21019 at d53f230c · domain:services seat (#6021) · session_01XY5uCwTjZj7884yYtyur4H · 2026-10-01T02:04Z

    The dev report is 5923231598, read on GitHub.

    Checklist, read on GitHub rather than from the report:

    • Shape: a draft onto main, 8 files, +1,175 / −53.
      • Source: structured-json-dimension-door.ts, dataset-compiler.ts and analytics-service.ts.
      • Pins: three in service-analytics/src/__tests__/, one re-judged there, and one REST route pin.
      • The changeset.
      • No governed path (the queue guard reads 0 of 8). Line 1 is Fixes #20912, and line 2 is Clause-②: no (narrowing), measured.
    • analytics-service.ts changes at exactly the two call sites the serial order 5921389276 granted. Each now hands { type, multiple } instead of ?.type. Read in the diff.
    • One consequence the order did not name, accepted as declared: dataset-compiler.ts's compile probe is a member of the published DatasetCompileOptions. It is renamed declaredFieldType → declaredValueShape, the name and ValueShapeFieldDef type the strategies' context already uses. The rename is in a file on the surface, and the changeset carries it as BREAKING with a prose remedy and the ADR-0087 not-required (runtime-interface-only …) disposition, which the gate verified. Its grade and that disposition are the at-tier review's to judge.
    • Measured on SQLite AND PostgreSQL 16.13 (a private server, stopped and removed):
      • before: every row was answered on the native path, wrong on SQLite and 500 on PostgreSQL;
      • after: 400 in the engine door's class, naming the member the caller wrote, at the door or at dataset compile;
      • the controls are unchanged.
    • Red first, then green:
      • service-analytics: 152 files, 3,489 tests passed, typecheck exit 0;
      • the REST pin: 8 / 8.
    • Ablation: seven legs, each turning exactly its predicted pins red. One reverts each call site to ?.type, and one drops multiple. Each restore was proven, and a dist leg covers the REST pin.
    • Gates: 62 derived. 60 were run plus the roster families, and 2 are NOT MEASURED (exit 3, whole-workspace build prerequisite). CI owns those.
    • CI at this reading: 15 success, 3 skipped, 13 in progress, 0 failed.

    One deviation from "the engine door's words", accepted: the multi-value refusal's remedy names a record query with $contains, not an analytics where. The analytics native $contains over a JSON-stored column is itself wrong today (below), so prescribing it would send authors into a second defect.

    Findings, line by line:

    Landing waits for every check green on the head and the at-tier contract review. After the merge, this seat checks that Fixes #20912 closed the card.


    Generated by Claude Code

  8. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:services seat (#6021) · session_01XY5uCwTjZj7884yYtyur4H · 2026-10-01T03:53Z

    PR #21019 merged through the merge queue as bb2eccf7 on origin/main, and Fixes #20912 closed this card completed.

    • Review: the at-tier contract review PASS on the landed head d53f230c is 5923426452.
    • Content check: the landed commit is a single-parent squash, and its git patch-id --stable equals that of the reviewed head d53f230c against its base f8178ffe.

    What now holds: the analytics door refuses, ahead of both strategies, INVALID_FIELD / 400, naming the member the caller wrote. It asks the same spec predicates the engine's two doors ask.

    • A grouped dimension on a multi-value field is refused.
    • A count_distinct measure over a JSON-stored field is refused.
    • The dataset compiler reads the declaration (multiple: true) and refuses a count_distinct over such a field, DATASET_INVALID / 400.

    For the release list: @objectstack/service-analytics ships a minor with the BREAKING banner (Clause-②: no (narrowing)). The published DatasetCompileOptions.declaredFieldType is renamed declaredValueShape ({ type, multiple }), and the changeset carries the one-line fix.

    Carried elsewhere:

    In the same act, this seat removes pm:dispatched and the assignee.


    Generated by Claude Code

  9. added 4 commits that reference this issue on Oct 7, 2026
    bb2eccf
    5dbeb7d
    39ab294
    3a7b6eb
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:servicespriority:p2Medium: important, M3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions