Repository navigation
analytics: an authored cube's public, refreshKey, format, granularities and descriptions take effect (8 keys) #20282
Description
Filing gate: ① a declared≠enforced family, filed as one sweep card per family under ruling A′ item ④ on #18900 (5727134555). This is triage's standing request 5857165909 on the seat post. Family analytics-cube-semantics, seat verdict ENFORCE.
reach:the declared authoring door.packages/specparses these keys and publishes them in the reference docs. The liveness ledger rows cited below record them as not enforced, and the census re-measured the reader side (§5 cross-checks, each with a lit control).- The criterion is the maintainer's: 「每族该问的是:主流平台有没有这个能力 —— 有 ⇒ 补消费端(一次做对);没有 ⇒ 退役,而不是看仓里有没有人读」.
- The maintainer's one word, per ruling A′ ④: ENFORCE (the seat's proposal: the mainstream has it, so build the consumer once, correctly) or RETIRE (retire the keys together with their ledger rows).
⚠️ analytics_cube.publicdefaults tofalse. Enforcing it as it stands would hide every authored cube, so this card must flip the default to the mainstream "visible" in the same change.- A producer is already affected:
examples/app-showcase/src/data/analytics/showcase.cube.ts:98authorspublic: falseonmain17bd3187(the seat's own reading). Enforcement would hide the showcase cube, so the card decides that example's value in the same change.
- A producer is already affected:
Census by the domain:spec execution seat 1 (session_01Rjy9MeetSfq34PKn81CRiN, seat post #6017), 2026-09-27. Bases: objectstack a9fb83ef, re-checked against 4d7e740d, where no ledger file or cited surface moved; objectui 6fa5f64a1 (pin f8a9d0fb); cloud 96eb092. Ledger instrument: check-liveness.mts --json, whose byStatus equals the committed state-counts.md row for row. ⛔ Filed bare: routing and grading belong to triage. ⛔ Not a claim. The ranking is by value, user-visible risk × keys. This family's rank is 3 of 16. The sibling family cards filed so far are #20273 and #20274.
Capability: Semantic-layer member metadata (descriptions, value format, allowed time granularities), cube visibility, and cache refresh cadence
| key | ledger status | ledger row | what the ledger cites |
|---|---|---|---|
analytics_cube.description |
dead (verified 2026-09-17) | packages/spec/liveness/analytics_cube.json:19 |
note: Parsed, stored, and read by NOTHING. The CubeMeta projection both getMeta implementations build (analytics-service.ts#getMeta, memory-analytics.ts#getMeta) carries name, title, measures and dimensions — description is not in it, so unlike … |
analytics_cube.measures.description |
dead (verified 2026-09-17) | packages/spec/liveness/analytics_cube.json:45 |
note: Not in the CubeMeta measure projection ({ name, type, title }) and read nowhere else — the same census, and the same reasoning, as the cube-level description row above. |
analytics_cube.measures.format |
dead (verified 2026-09-17) | packages/spec/liveness/analytics_cube.json:64 |
note: Written by the DATASET compiler, read by nobody — the three-producer fact in the file note decides this row. dataset-compiler.ts copies a dataset measure's own format onto the minted cube metric (`if (typeof m.format === 'string') metric.format = m.form… |
analytics_cube.dimensions.description |
dead (verified 2026-09-17) | packages/spec/liveness/analytics_cube.json:85 |
note: Not in the CubeMeta dimension projection ({ name, type, title }) and read nowhere else — same census as the two description rows above. |
analytics_cube.dimensions.granularities |
dead (verified 2026-09-17) | packages/spec/liveness/analytics_cube.json:104 |
note: There IS a reader and an AUTHORED cube cannot reach it — the distinction the file note's three-producer fact exists to make. The one read is packages/services/service-analytics/src/dataset-executor.ts#granularityOf (`const cd = compiled.cube.dimensions[na… |
analytics_cube.refreshKey.every |
dead (verified 2026-09-17) | packages/spec/liveness/analytics_cube.json:124 |
note: Pre-aggregation / cache refresh cadence with no engine behind it. Census over the whole repository: refreshKey appears in analytics.zod.ts (the declaration), in examples/app-showcase/src/data/analytics/showcase.cube.ts (an AUTHOR writing it), in the g… |
analytics_cube.refreshKey.sql |
dead (verified 2026-09-17) | packages/spec/liveness/analytics_cube.json:129 |
note: The 'SQL to check for data changes' probe of the same unimplemented refresh mechanism — same census as refreshKey.every. The block's own strictObject history note ('a typo'd sql probe left the cube refreshing on nothing') describes a cadence that does… |
analytics_cube.public |
dead (verified 2026-09-17) | packages/spec/liveness/analytics_cube.json:136 |
note: An ACCESS-CONTROL key that gates nothing, which is the worst class this ledger records (a security no-op / false compliance, the reason the gate exists). Declared z.boolean().default(false) under the comment 'Access Control'. Census: three sites WRITE it … |
Mainstream evidence:
- Cube.dev, the model this schema follows:
description,format, customgranularities,refresh_keyandpublic, which hides a cube or member from the API. Whetherpublic: falsealso blocks queries is UNVERIFIED. - Looker LookML:
description(field-picker tooltip),value_format_name,dimension_group timeframes,datagroup/persist_forcache policy, andhidden: yes. - Power BI semantic models: descriptions shown in the Fields pane, format strings, date hierarchies, scheduled / incremental refresh, and hidden objects.
- Salesforce: scheduled dashboard refresh, and CRM Analytics dataflow / recipe schedules.
- Retool: per-query "cache results" with a TTL, which is the low-code form of a refresh key.
Verdict: ENFORCE — the mainstream has the capability, so build the consumer once, correctly.
Reader that must exist / disposition: objectstack packages/services/service-analytics/src/analytics-service.ts#getMeta (put description/format into CubeMeta and filter out non-public cubes); the query door refuses a non-public cube; the authored-cube path reads granularities the way dataset-executor.ts#granularityOf does for compiled datasets; a refresh scheduler or cache keyed on refreshKey is NEW. objectui: the dataset / dashboard pickers show descriptions. public defaults to false, so enforcing it as-is hides every authored cube. The card must flip the default to the mainstream default (visible).
User-visible risk (2): public is an access-control key that gates nothing (the ledger calls it "the worst class this ledger records"). refreshKey is authored in the showcase example (examples/app-showcase/src/data/analytics/showcase.cube.ts:95). Format and granularities silently fall back.
Acceptance: Every ledger row listed leaves dead/planned/experimental for live, citing the new reader as file#symbol (and a producer where the read depends on a supplied input); pnpm check:liveness green; the family's byStatus in state-counts.md regenerated.
Lane: domain:spec parent + domain:services (service-analytics) sub-issue + objectui sub-issue (pickers)
File surface: packages/spec/src/data/analytics.zod.ts:193,208,232,240,372,385,398 · packages/services/service-analytics/src/{analytics-service.ts,strategies/*,dataset-executor.ts} · packages/spec/liveness/analytics_cube.json
Dedupe: analytics_cube \| refreshKey \| granularities \| CubeMeta \| MetricSchema \| CubeSchema \| cube.{0,30}\bpublic\b \| measures\.format \| measures\.name → 6 open hits. None carries a key of this family:
- fix(spec): one D3 entry per major-18 retirement family — the census and the 25 missing entries (#20201) #20255(PR) — D3 entries for ALREADY-RETIRED keys (tombstoned
triggers.interval,circuitBreaker.monitoringWindow, cube sub-day granularities); does not carry any open key - [PM seat] domain:spec · seat 2 — 🟢 os-justin · session_01BRQ9Mp1yH7R1az6MaUM18H #18549 — spec seat-2 post; names the spec/liveness: seed ledgers for the three PENDING_GOVERNANCE debts #18133 declared —
connector,sharing_rule,analytics_cube#18582 connector/analytics_cube ledger seeding (landed), carries no key - objectui#10778 — keyword coincidence: PageView
refreshKeyremount counter, not the cube key - objectui#10777(PR) — keyword coincidence: PageView
refreshKeyremount counter, not the cube key - objectui#10519 — keyword coincidence: PageView
refreshKeyremount counter, not the cube key - objectui#9830 — keyword coincidence (condition-widget card)
四轴:
- 实际业务需求: 语义层的字段说明、格式、时间粒度、可见性和缓存刷新,是 LookML、Cube、Power BI 的日常用法。仪表盘作者会直接看到格式与说明缺失。
- 项目长远合理性: 分析语义层是长期资产。作者写的 cube 与数据集编译出的 cube 应当走同一条消费路径,不能出现「编译路径读、作者路径不读」的双轨。一次做对,还包括把
public的默认值改成主流的「可见」。 - 防 AI 写错:
public: false今天不隐藏任何东西,是假合规。AI 生成的 cube 会带着一个看似收紧的访问设置上线。 - 创业阶段不扩散: 8 个键里 5 个是投影与展示,成本低;
refreshKey需要新建缓存 / 刷新机制,是本族唯一的新机制。可以只把这 2 个键拆到后续,但裁决仍是「做」。
Activity