Skip to content

analytics: an authored cube's public, refreshKey, format, granularities and descriptions take effect (8 keys) #20282

Description

@objectstack-fleet

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/spec parses 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.public defaults to false. 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:98 authors public: false on main 17bd3187 (the seat's own reading). Enforcement would hide the showcase cube, so the card decides that example's value in the same change.

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, custom granularities, refresh_key and public, which hides a cube or member from the API. Whether public: false also blocks queries is UNVERIFIED.
  • Looker LookML: description (field-picker tooltip), value_format_name, dimension_group timeframes, datagroup / persist_for cache policy, and hidden: 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:

四轴:

  • 实际业务需求: 语义层的字段说明、格式、时间粒度、可见性和缓存刷新,是 LookML、Cube、Power BI 的日常用法。仪表盘作者会直接看到格式与说明缺失。
  • 项目长远合理性: 分析语义层是长期资产。作者写的 cube 与数据集编译出的 cube 应当走同一条消费路径,不能出现「编译路径读、作者路径不读」的双轨。一次做对,还包括把 public 的默认值改成主流的「可见」。
  • 防 AI 写错: public: false 今天不隐藏任何东西,是假合规。AI 生成的 cube 会带着一个看似收紧的访问设置上线。
  • 创业阶段不扩散: 8 个键里 5 个是投影与展示,成本低;refreshKey 需要新建缓存 / 刷新机制,是本族唯一的新机制。可以只把这 2 个键拆到后续,但裁决仍是「做」。

Activity

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

Metadata

Metadata

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions