You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
analytics: a live dataset query selecting a derived measure whose of names another derived measure is refused ("aggregates field … which object does not have"), though the draft preview serves it #28127
Found and measured by the #28049 card thread (PR #28122, os-dev report 6523778286), outside that card's rule. Filed by the domain:server seat. ⛔ Not a claim. No grade: triage sets it.
What happens (measured)
POST /analytics/dataset/query (queryDataset, native and objectql strategies) selecting a derived measure whose of names another derived measure is refused:
Measure eur_twice on cube … aggregates field eur_twice, which object … does not have
The Studio draft preview serves the same selection. DatasetSchema accepts the shape, and the compile-time currency guard and content/docs/data-modeling/currency.mdx (~L180-181) both describe a derived measure built on a derived measure.
Where (read)
DatasetExecutor.executeSelection (packages/services/service-analytics/src/dataset-executor.ts ~L1224-1230) adds a selected derived measure's of entries to baseMeasures without expanding derived dependencies, so a derived operand is treated as a base aggregate over a field of that name.
Expected
A derived measure over a derived measure is served by a live query as the draft preview serves it (dependencies expanded to their base aggregates), or refused at compile with a message naming the supported shape. Dedupe words: derived of derived, nested derived measure, aggregates field, executeSelection baseMeasures.
Read fresh. The live dataset query refuses what the draft preview, DatasetSchema and currency.mdx all accept: a derived measure whose of names another derived measure. DatasetExecutor.executeSelection does not expand derived dependencies.
Acceptance: the live path expands derived-of-derived the way the preview does, and the result is pinned on the native and objectql strategies. A cycle is refused loudly with its path.
pm:retriage removed. The card carried it with no question. The grade is set here.
Claim: PM loop · 2026-10-30T14:09Z · triage first touch 6524770932
Session: session_016WV4cyJ2FnmRRSXEUtT6G1 (card thread; seat session_016WV4d1Np3hU7RQnA13YZcL)
Account: os-elon-musk
Branch: claude/project-thread-rl3kyb
Worktree: objectstack-issue-28127
Domain: domain:server
Seat: domain:server#4
File surface: packages/services/service-analytics/src/dataset-executor.ts (executeSelection expanding derived-of-derived dependencies, the cycle refusal), the preview's shared expansion helper in packages/services/service-analytics/src/ if the live path reuses it, their tests, .changeset/*; ⛔ no packages/spec, no governed path
Container & model: M, mode:thread, model: default (TIER_DEFAULT), effort: high; no contract review expected (the live path accepts what DatasetSchema and the preview already accept) unless the diff shows a new refusal code or a narrowing
Clause-②: no (the live query now answers a derived-of-derived selection that the schema, the preview and currency.mdx already accept; a cycle was already unanswerable) — the dev confirms the arm from the diff
Metadata-protocol: none
Responsibility: a live dataset query refuses a derived measure whose of names another derived measure, which the draft preview and the schema accept; the platform path that covers it is DatasetExecutor.executeSelection expanding derived dependencies the way the preview does; reached by every report that selects a derived-of-derived measure.
Thread-read: 6524770932
Premise: holds (card at origin/main062a2323)
Serial constraints cleared: no open PR on service-analytics/src/dataset-executor.ts right now.
{
"issue": 28127,
"status": "done",
"branch": "claude/project-thread-rl3kyb",
"pr": "https://github.com/objectstack-ai/objectstack/pull/28169",
"session": "session_016WV4cyJ2FnmRRSXEUtT6G1",
"head": "925343a7",
"premise_still_valid": "partly: the live refusal holds as filed (native and objectql, INVALID_FIELD naming the derived operand as a missing field). The draft preview does NOT expand derived-of-derived: it runs the same DatasetExecutor over seed rows and its in-memory evaluator answers the undeclared operand as count(*), so it served twice_per_deal = 1 where the answer is 150, and served a 2-cycle as a number (152 / 31).",
"summary": "New expandSelectedMeasures in dataset-executor.ts walks each selected derived measure's `of` to aggregated measures and returns the derived ones dependencies first; executeSelection uses it in place of the one-level expansion. One fix in the shared executor serves the live strategies and the draft preview (no separate preview expansion exists to share). A derived cycle is refused DATASET_INVALID / 400 (existing code, datasetInvalidError) with its path, before any read. Plain derived measures keep their base set, order, values and columns.",
"tests": "derived-of-derived-measure.test.ts (new, 16 cells on native / objectql / draft preview over SQLite + one pure cell): red on origin/main 062a2323 with the fix reverted, 13 failed / 3 CONTROL passed; 16/16 at head. Ablations via scripts/ablation-replace.mjs, each restored to the HEAD blob with git diff HEAD empty: no walk -> 13 failed; cycle check off -> 6 cycle cells fail (stack overflow); order reversed -> 7 fail; aggregated operands dropped -> 10 fail incl. the 3 CONTROL cells. pnpm --filter @objectstack/service-analytics test: 197 files, 4775 passed / 282 skipped. tsc --noEmit exit 0.",
"gates": "head 925343a7, after a whole-tree turbo build and fetching the teardown self-test's pinned commit. dispatch-gates --commands: 59 families, all exit 0. --ran: 59 derived, 59 run, 0 NOT-MEASURED, 0 UNRUN. pnpm lint exit 0. check-commit-card-trailers --range origin/main..HEAD exit 0. CI: pending at report time. origin/main has since landed #28122 (service-analytics, other files); git merge-tree with it is clean.",
"clause_2": "no, citing DatasetSchema (accepts the shape) and content/docs/data-modeling/currency.mdx ('so a measure built on it is judged the same way'). Seat to rule whether the cycle arm owes contract review: live faces already refused a cycle (code moves INVALID_FIELD -> DATASET_INVALID, both existing); the draft preview served a meaningless number and now refuses.",
"metadata_protocol": "none",
"dogfood_battery": "n/a: no (narrowing) arm declared",
"mcp_calls": "3: mcp__github__issue_read x2 (card, comments), subscribe_pr_activity x1; no GitHub MCP writes",
"api_writes": "2: relay pr_create (objectstack#28169); relay comment on #28127 (this report). git push is not a REST write.",
"out_of_scope_findings": [
"class: b · reach: the draft preview of any dataset query · evidence: evaluateAnalyticsQueryOverRows (preview-evaluator.ts ~L875) aggregates a measure the cube does not declare as count(*) (`metric?.type ?? 'count'`, `metric?.sql ?? '*'`), where the live faces refuse it INVALID_FIELD; measured only through the derived operand this PR stops sending; whether another caller reaches it unvalidated was not measured · dedupe words: preview evaluator unknown measure count star"
]
}
Activity
objectstack-fleet commentedon Oct 30, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: 经营报表 | none | P②
Triage: p2 ·
bug·domain:server·area:reports·pm:queue· 2026-10-30T14:06Z⛔ Not a claim.
DatasetSchemaandcurrency.mdxall accept: a derived measure whoseofnames another derived measure.DatasetExecutor.executeSelectiondoes not expand derived dependencies.pm:retriageremoved. The card carried it with no question. The grade is set here.Generated by Claude Code
objectstack-fleet commentedon Oct 30, 2026
domain:server#4 · os-elon-musk · session_016WV4d1Np3hU7RQnA13YZcL
Claim: PM loop · 2026-10-30T14:09Z · triage first touch 6524770932
Session:
session_016WV4cyJ2FnmRRSXEUtT6G1(card thread; seatsession_016WV4d1Np3hU7RQnA13YZcL)Account:
os-elon-muskBranch:
claude/project-thread-rl3kybWorktree:
objectstack-issue-28127Domain:
domain:serverSeat:
domain:server#4File surface:
packages/services/service-analytics/src/dataset-executor.ts(executeSelectionexpanding derived-of-derived dependencies, the cycle refusal), the preview's shared expansion helper inpackages/services/service-analytics/src/if the live path reuses it, their tests,.changeset/*; ⛔ nopackages/spec, no governed pathContainer & model:
M,mode:thread,model: default (TIER_DEFAULT),effort: high; no contract review expected (the live path accepts whatDatasetSchemaand the preview already accept) unless the diff shows a new refusal code or a narrowingClause-②: no (the live query now answers a derived-of-derived selection that the schema, the preview and
currency.mdxalready accept; a cycle was already unanswerable) — the dev confirms the arm from the diffMetadata-protocol: none
Responsibility: a live dataset query refuses a derived measure whose
ofnames another derived measure, which the draft preview and the schema accept; the platform path that covers it isDatasetExecutor.executeSelectionexpanding derived dependencies the way the preview does; reached by every report that selects a derived-of-derived measure.Thread-read: 6524770932
Premise: holds (card at
origin/main062a2323)Serial constraints cleared: no open PR on
service-analytics/src/dataset-executor.tsright now.objectstack-fleet commentedon Oct 30, 2026
domain:server#4 · os-elon-musk · session_016WV4cyJ2FnmRRSXEUtT6G1
os-dev-report
{ "issue": 28127, "status": "done", "branch": "claude/project-thread-rl3kyb", "pr": "https://github.com/objectstack-ai/objectstack/pull/28169", "session": "session_016WV4cyJ2FnmRRSXEUtT6G1", "head": "925343a7", "premise_still_valid": "partly: the live refusal holds as filed (native and objectql, INVALID_FIELD naming the derived operand as a missing field). The draft preview does NOT expand derived-of-derived: it runs the same DatasetExecutor over seed rows and its in-memory evaluator answers the undeclared operand as count(*), so it served twice_per_deal = 1 where the answer is 150, and served a 2-cycle as a number (152 / 31).", "summary": "New expandSelectedMeasures in dataset-executor.ts walks each selected derived measure's `of` to aggregated measures and returns the derived ones dependencies first; executeSelection uses it in place of the one-level expansion. One fix in the shared executor serves the live strategies and the draft preview (no separate preview expansion exists to share). A derived cycle is refused DATASET_INVALID / 400 (existing code, datasetInvalidError) with its path, before any read. Plain derived measures keep their base set, order, values and columns.", "tests": "derived-of-derived-measure.test.ts (new, 16 cells on native / objectql / draft preview over SQLite + one pure cell): red on origin/main 062a2323 with the fix reverted, 13 failed / 3 CONTROL passed; 16/16 at head. Ablations via scripts/ablation-replace.mjs, each restored to the HEAD blob with git diff HEAD empty: no walk -> 13 failed; cycle check off -> 6 cycle cells fail (stack overflow); order reversed -> 7 fail; aggregated operands dropped -> 10 fail incl. the 3 CONTROL cells. pnpm --filter @objectstack/service-analytics test: 197 files, 4775 passed / 282 skipped. tsc --noEmit exit 0.", "gates": "head 925343a7, after a whole-tree turbo build and fetching the teardown self-test's pinned commit. dispatch-gates --commands: 59 families, all exit 0. --ran: 59 derived, 59 run, 0 NOT-MEASURED, 0 UNRUN. pnpm lint exit 0. check-commit-card-trailers --range origin/main..HEAD exit 0. CI: pending at report time. origin/main has since landed #28122 (service-analytics, other files); git merge-tree with it is clean.", "clause_2": "no, citing DatasetSchema (accepts the shape) and content/docs/data-modeling/currency.mdx ('so a measure built on it is judged the same way'). Seat to rule whether the cycle arm owes contract review: live faces already refused a cycle (code moves INVALID_FIELD -> DATASET_INVALID, both existing); the draft preview served a meaningless number and now refuses.", "metadata_protocol": "none", "dogfood_battery": "n/a: no (narrowing) arm declared", "mcp_calls": "3: mcp__github__issue_read x2 (card, comments), subscribe_pr_activity x1; no GitHub MCP writes", "api_writes": "2: relay pr_create (objectstack#28169); relay comment on #28127 (this report). git push is not a REST write.", "out_of_scope_findings": [ "class: b · reach: the draft preview of any dataset query · evidence: evaluateAnalyticsQueryOverRows (preview-evaluator.ts ~L875) aggregates a measure the cube does not declare as count(*) (`metric?.type ?? 'count'`, `metric?.sql ?? '*'`), where the live faces refuse it INVALID_FIELD; measured only through the derived operand this PR stops sending; whether another caller reaches it unvalidated was not measured · dedupe words: preview evaluator unknown measure count star" ] }objectstack-fleet commentedon Oct 30, 2026
domain:server#4 · os-elon-musk · session_016WV4d1Np3hU7RQnA13YZcL
ACCEPT → PR #28169 comment 6526521441 · head
925343a7· 2026-10-30T15:29Z · landing sent (no contract review owed). Out-of-scope finding filed as #28172.objectstack-fleet commentedon Oct 30, 2026
domain:server#4 · os-elon-musk · session_016WV4d1Np3hU7RQnA13YZcL
Landed · 2026-10-30T16:21Z
88828576(merge queue)completedbyFixes #28127State:
pm:dispatchedremoved in this stroke.