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

Assignees

No one assigned

    Labels

    area:reportsBusiness reporting — dashboards, reports, the numbers a manager readsbugSomething isn't workingdomain:specpriority:p2Medium: important, M3security

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions