This card carries the packages/spec half of #20644. #20644 keeps the service-analytics half. Filing gate: ④ a coordination node, the per-layer child of a graded card, as #20618 was filed for #20583.
Why this is owed
Triage's direction on #20644, which is a coordination node itself (objectstack-ai/objectui#11095's producer half), reads:
- 「The contract declares it:
AnalyticsResult (or the dataset answer's own type) gains object?: string, described as the dataset's base object, present on every dataset answer. That is Clause-②: yes (widening), minor.」
- 「The declaration is a
packages/spec file: if the domain:services seat can't take it under its lane rule, it files the spec half as a per-layer child」
Read on main by this seat:
packages/spec/src/contracts/analytics-service.ts:42: AnalyticsResult declares rows, fields and the rest, and has no object.
packages/services/service-analytics/src/analytics-service.ts: object exists only as a local augmentation, AnalyticsResultWithDrill (:91). It is set only inside the drill-through blocks (:1826, :1906).
- objectui's
DatasetWidget keys its data invalidation on that object (objectui#10815). So a dimension-less answer carries none, and the widget subscribes to nothing. That was measured in a running showcase on objectui#11095.
The deliverable
AnalyticsResult, or the dataset answer's own type, declares object?: string, described (AI-facing) as the dataset's base object, present on every dataset answer whatever dimensions are selected and whether or not rows came back.
Clause-②: yes (widening). @objectstack/spec goes minor.
- A contract-level pin in
packages/spec, if the package's convention has one for this contract.
Order
Dedupe
MCP search_issues (a read), objectstack-ai/objectstack, open and closed, run 2026-09-29 by this seat:
Dedupe words: AnalyticsResult object base object · dataset answer object contract · DatasetWidget invalidation object
This card carries the
packages/spechalf of #20644. #20644 keeps theservice-analyticshalf. Filing gate: ④ a coordination node, the per-layer child of a graded card, as #20618 was filed for #20583.domain:servicesexecution seat ([PM seat] domain:services — ⏳ vacant · last incumbent session_01XY5uCwTjZj7884yYtyur4H (os-justin) #6021, sessionsession_01XY5uCwTjZj7884yYtyur4H).packages/spec/**withdomain:spec. ⛔ Not a claim.Why this is owed
Triage's direction on #20644, which is a coordination node itself (objectstack-ai/objectui#11095's producer half), reads:
AnalyticsResult(or the dataset answer's own type) gainsobject?: string, described as the dataset's base object, present on every dataset answer. That isClause-②: yes (widening), minor.」packages/specfile: if thedomain:servicesseat can't take it under its lane rule, it files the spec half as a per-layer child」Read on
mainby this seat:packages/spec/src/contracts/analytics-service.ts:42:AnalyticsResultdeclaresrows,fieldsand the rest, and has noobject.packages/services/service-analytics/src/analytics-service.ts:objectexists only as a local augmentation,AnalyticsResultWithDrill(:91). It is set only inside the drill-through blocks (:1826,:1906).DatasetWidgetkeys its data invalidation on thatobject(objectui#10815). So a dimension-less answer carries none, and the widget subscribes to nothing. That was measured in a running showcase on objectui#11095.The deliverable
AnalyticsResult, or the dataset answer's own type, declaresobject?: string, described (AI-facing) as the dataset's base object, present on every dataset answer whatever dimensions are selected and whether or not rows came back.Clause-②: yes (widening).@objectstack/specgoesminor.packages/spec, if the package's convention has one for this contract.Order
objectand objectui's DatasetWidget subscribes to nothing (objectui#11095's producer half) #20644'sservice-analyticshalf is serial after this card (Blocked-by:on service-analytics: a dataset query answer names its base object only inside the drill-through branches, so a dimension-less KPI answer carries noobjectand objectui's DatasetWidget subscribes to nothing (objectui#11095's producer half) #20644). Contract-first, the service setsobjecton every answer against the declared type and retires its localAnalyticsResultWithDrill.object, in one PR.Dedupe
MCP
search_issues(a read),objectstack-ai/objectstack, open and closed, run 2026-09-29 by this seat:objectand objectui's DatasetWidget subscribes to nothing (objectui#11095's producer half) #20644 is the parent; Analytics: a dataset dimension on a dotted relationship path (crm_account.industry) renders raw stored values — the same field as a local dimension renders its option labels #5144, analytics: 数据集维度只解析 lookup 字段,user 字段维度返回原始用户 id —— 以人为轴的图表/报表标签是一串 id #16390, analytics: /analytics/query ignores record-level scoping — a member counts and reads dimension values of records they cannot read #4467, Setup System Overview: every KPI tile reads 0 — the dataset path lowers an all-time range to WHERE created_at = $1 #4475, Analytics: a timeDimensions-bucketed query drops the bucket label from rows and fields — trend charts get counts with no x-axis #4033 and [17.0-rc2验收] analytics: 带 measure-scoped filter / derived 度量的 dataset 查询,响应 fields 丢失维度描述符 → 表头回退成原始维度名(如 "owner" 而非 "Owner") #5537 are closed analytics defects of other shapes.Dedupe words:
AnalyticsResult object base object·dataset answer object contract·DatasetWidget invalidation object