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 个键拆到后续,但裁决仍是「做」。
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 request5857165909on the seat post. Familyanalytics-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).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.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.Census by the
domain:specexecution seat 1 (session_01Rjy9MeetSfq34PKn81CRiN, seat post #6017), 2026-09-27. Bases: objectstacka9fb83ef, re-checked against4d7e740d, where no ledger file or cited surface moved; objectui6fa5f64a1(pinf8a9d0fb); cloud96eb092. Ledger instrument:check-liveness.mts --json, whosebyStatusequals the committedstate-counts.mdrow 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 is3of 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
analytics_cube.descriptionpackages/spec/liveness/analytics_cube.json:19CubeMetaprojection bothgetMetaimplementations build (analytics-service.ts#getMeta,memory-analytics.ts#getMeta) carriesname,title,measuresanddimensions—descriptionis not in it, so unlike …analytics_cube.measures.descriptionpackages/spec/liveness/analytics_cube.json:45CubeMetameasure projection ({ name, type, title }) and read nowhere else — the same census, and the same reasoning, as the cube-leveldescriptionrow above.analytics_cube.measures.formatpackages/spec/liveness/analytics_cube.json:64dataset-compiler.tscopies a dataset measure's ownformatonto the minted cube metric (`if (typeof m.format === 'string') metric.format = m.form…analytics_cube.dimensions.descriptionpackages/spec/liveness/analytics_cube.json:85CubeMetadimension projection ({ name, type, title }) and read nowhere else — same census as the twodescriptionrows above.analytics_cube.dimensions.granularitiespackages/spec/liveness/analytics_cube.json:104packages/services/service-analytics/src/dataset-executor.ts#granularityOf(`const cd = compiled.cube.dimensions[na…analytics_cube.refreshKey.everypackages/spec/liveness/analytics_cube.json:124refreshKeyappears inanalytics.zod.ts(the declaration), inexamples/app-showcase/src/data/analytics/showcase.cube.ts(an AUTHOR writing it), in the g…analytics_cube.refreshKey.sqlpackages/spec/liveness/analytics_cube.json:129refreshKey.every. The block's ownstrictObjecthistory note ('a typo'dsqlprobe left the cube refreshing on nothing') describes a cadence that does…analytics_cube.publicpackages/spec/liveness/analytics_cube.json:136z.boolean().default(false)under the comment 'Access Control'. Census: three sites WRITE it …Mainstream evidence:
description,format, customgranularities,refresh_keyandpublic, which hides a cube or member from the API. Whetherpublic: falsealso blocks queries is UNVERIFIED.description(field-picker tooltip),value_format_name,dimension_group timeframes,datagroup/persist_forcache policy, andhidden: yes.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⚠️
granularitiesthe way dataset-executor.ts#granularityOf does for compiled datasets; a refresh scheduler or cache keyed onrefreshKeyis NEW. objectui: the dataset / dashboard pickers show descriptions.publicdefaults 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):
publicis an access-control key that gates nothing (the ledger calls it "the worst class this ledger records").refreshKeyis 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:triggers.interval,circuitBreaker.monitoringWindow, cube sub-day granularities); does not carry any open keyconnector,sharing_rule,analytics_cube#18582 connector/analytics_cube ledger seeding (landed), carries no keyrefreshKeyremount counter, not the cube keyrefreshKeyremount counter, not the cube keyrefreshKeyremount counter, not the cube key四轴:
public的默认值改成主流的「可见」。public: false今天不隐藏任何东西,是假合规。AI 生成的 cube 会带着一个看似收紧的访问设置上线。refreshKey需要新建缓存 / 刷新机制,是本族唯一的新机制。可以只把这 2 个键拆到后续,但裁决仍是「做」。