Skip to content

fix(service-analytics, lint)!: a dataset or cube dimension over a formula field is refused where it is authored, instead of on the first query that groups by it - #30815

Merged
objectstack-fleet[bot] merged 7 commits into
mainfrom
claude/project-thread-c4pypv
Nov 6, 2026
Merged

objectstack-fleet[bot] merged 7 commits into
mainfrom
claude/project-thread-c4pypv

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Requested by Elon · project thread

domain:server#3 · os-elon-musk · session_016WV4cytQjG9X1CrCgytUM5

Fixes #30773

Clause-②: no (narrowing)
Metadata-protocol: narrowed
Skills-docs: updated here — content/docs/deployment/validating-metadata.mdx names dimension-virtual-field-refused beside dimension-json-stored-field-refused and in its cube paragraph (seat-approved surface addendum); follow-up #30824 — skills/objectstack-data/rules/field-types.md's formula row (Tier H, the skills lane).

维护者速读

What changes

@objectstack/service-analytics: the compile refuses the dimension.

@objectstack/lint: dimension-virtual-field-refused.

  • A new id beside dimension-json-stored-field-refused in validate-dataset-measure-aggregates.ts, so it rides the one registry entry: gating, on os validate / os build / os lint, and at the runtime dataset write door (422). One verdict for a dataset dimension (datasets[N].dimensions[M].field) and an authored cube dimension (analyticsCubes[N].dimensions.KEY.sql), resolved on the object graph exactly as the JSON-stored leg resolves it, dotted paths included (judged on the leaf's object), with the same skips. The predicate is the spec's isVirtualSearchField, never a local list. A formula is never JSON-stored, so the two dimension ids never fire on one member.
  • One-line verdict and fix, as the [maintainer] validate: the field-no-consumers warning is one 856-character line, printed by validate, build and dev alike — one-line verdict + rule: id + a pointer to the full reasoning (os explain, which today takes only schema names) #22161 siblings. Verdict: groups by field "FIELD" (formula on object "OBJECT"), a value computed on read and never stored, so no query can group by it. Fix: Store the value in a stored field of "OBJECT" (written when its source changes) and point this dimension at that field, or remove the dimension. The reasoning (which doors refuse it, why a computed value is no group key) is os explain dimension-virtual-field-refused (rule-explanations.ts). The id's constant is exported from the package barrel beside its two siblings.

Measured before the change (on origin/main 2d04cd2b, probes since deleted):

Tests

Package runs
  • At b100c406 (the implementation commit, before the origin/main merge; the commits after it touch only the dogfood pin and the changeset, and the merge brought in no file of either package): @objectstack/service-analytics full suite 211 files / 5015 passed, 300 skipped (lock VERDICT command-exit 0); @objectstack/lint full suite 195 files / 8236 passed (VERDICT 0); typecheck for both packages exit 0.
  • Before the fix, the compile gate alone on the same suite: 1 file red, preview-date-bucket-type.test.ts, 19 cases (the shared fixture declared formula dimensions), which is what the fixture split answers.
  • The dogfood pin with its analytics: a plain groupBy over a formula field answers DATABASE_ERROR 500 on the native composition, INVALID_FIELD 400 on ObjectQL, and a null group on the preview and in-memory engine #29304 sibling, 10/10 at the pre-tightening head 6c77bf99 (the merge commit); the pin alone 5/5 at 0dd6d595, and both inside the full battery below.
Ablations (fix committed first; `scripts/ablation-replace.mjs`, which restores to HEAD and checks `git diff HEAD` is empty)
  • Compile gate: deleted the assertDimensionFieldStored(...) call in compileDataset (anchor 1 → 0, blob 9bf5497fcd8b → 6e7d8fe55a4a). 10 red: the three new request / configuration / bucket door cases in aggregate-nontemporal-measure-refusal.test.ts and the seven [#30773] cases in preview-date-bucket-type.test.ts; 66 green, including the controls, the tiers and every measure pin. Restored: blob == HEAD.
  • Lint dataset leg: replaced if (isVirtualSearchField(shape)) { with a constant-false guard (blob 5f981455daa6 → 5e2fc683fa4f). 7 red: six cases of the new describe and the runtime write-door LIT case; the cube case stayed green (its own leg). Restored: blob == HEAD.
  • Lint cube leg: the same on if (isVirtualSearchField(column.shape)) { (blob → 0e485f1cf802). 1 red, the cube case. Restored: blob == HEAD.
  • Both packages' tests import the subjects from src/ by relative path, so no dist/ rebuild was needed.

Acceptance notes

  • The preview's own virtual arm is now pre-empted for a bare dataset dimension. queryDataset compiles before the draft preview evaluates, and both read the same sourceFieldMeta hook, so the preview's call to assertDatasetGroupTargetsStored no longer sees a direct formula dimension (and its declaredType reads the base object only, so it never judged a dotted one). It is left in place as the date-bucket door's partner; carrier: none (noted, not filed).
  • Docs, skills and the upgrade guide (the seat's rulings on contract review 6677341880): the validating-metadata.mdx paragraph is folded in here at a97ed9f0 as a surface addendum; the skills formula row is follow-up skills: the formula row of objectstack-data field-types should say a formula is no group key either (follow-up to #30773) #30824 (Tier H, the skills lane); an ADR-0087 semantic upgrade-guide entry mirroring 18.dataset-measure-aggregate-field-type-refused is follow-up spec: an upgrade-guide entry for a dataset or cube dimension over a formula field, now refused at authoring (follow-up to #30773) #30822 (the spec lane), to land before the release that ships this change.
  • The WIP commit 098b2b92 carries a Claude-Session: trailer naming the wrong session id (the coordinator's); later commits carry this run's. The branch is a claude/project-thread-* branch, so it is not rewritten; the seat ruled it has no landing effect (squash merge).

Verification

node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at 0dd6d595 (after merging origin/main at 172eebb2, pnpm install --frozen-lockfile and a whole-tree turbo run build, 119/119 tasks) derived 64 commands. All 64 ran and exited 0; --ran reports 64 run, 0 NOT-MEASURED, 0 UNRUN. check-adr-0087-registration reads the changeset as [BREAKING+bang+clause-②-narrowing+metadata-protocol-narrowed] not-required (no-migration-prescription).

After the docs commit a97ed9f0 (content/docs only), the derivation grew to 89 families; the 25 new ones plus seven docs-reading families from the first pass were run at a97ed9f0, all exit 0, and --ran over the combined record reports 89 run, 0 NOT-MEASURED, 0 UNRUN. The other families read no file the docs commit changed and keep their 0dd6d595 readings.

Dogfood battery (title carries !): 0dd6d595 · pnpm --filter @objectstack/dogfood test under the verify lock, VERDICT command-exit 0 · Test Files 424 passed, 3 skipped (427) · Tests 3537 passed, 41 skipped (3578) · no failure.


Generated by Claude Code

@github-actions github-actions Bot added size/l documentation Improvements or additions to documentation tests tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface labels Nov 6, 2026
@github-actions

github-actions Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/lint, @objectstack/service-analytics, touching 8 documentable anchor(s). ⚠️ 1 changed file(s) yielded no anchor (packages/lint/src/index.ts), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

⛔ 1 release-owned page(s) name something this change touched. These are read-only:

  • content/docs/releases/v17/17-6.mdx (via compileDataset (symbol, a top-level function))

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/lint/src/index.ts) — pages documenting those are invisible to this run
  • 3 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 63 of 221 client-bound route-ledger rows — the other 158 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 158: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 55 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 103 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 14 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 9b24f3ca8734b5e0ea77cc3cb282c3f8f55a862b → packageMentionDocs.

Which tree this was computed on

This run read content/docs from 9905b1a4e47b580bb9d695444a7ee8b0704a4703 — the merge of head 43db93dfabc5a2e6da08abb884644d2c69a01263 into base 9b24f3ca8734b5e0ea77cc3cb282c3f8f55a862b, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 9905b1a4e47b580bb9d695444a7ee8b0704a4703 && git checkout 9905b1a4e47b580bb9d695444a7ee8b0704a4703
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 9b24f3ca8734b5e0ea77cc3cb282c3f8f55a862b 43db93dfabc5a2e6da08abb884644d2c69a01263 && git checkout -B drift-repro 9b24f3ca8734b5e0ea77cc3cb282c3f8f55a862b && git merge --no-ff 43db93dfabc5a2e6da08abb884644d2c69a01263

node scripts/docs-audit/affected-docs.mjs --json 9b24f3ca8734b5e0ea77cc3cb282c3f8f55a862b

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs 9b24f3ca8734b5e0ea77cc3cb282c3f8f55a862b → pass the list as
args.docs, on the commit named under Which tree this was computed on.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:server#3 · os-elon-musk · session_016WV4cytQjG9X1CrCgytUM5

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 0dd6d595fb2cb44ab445a1504d331d6c2cbfb59c
Local-runs: none
Scope: packages/services/service-analytics/src/dataset-compiler.ts, packages/services/service-analytics/src/__tests__/aggregate-nontemporal-measure-refusal.test.ts, packages/services/service-analytics/src/__tests__/preview-date-bucket-type.test.ts, packages/lint/src/validate-dataset-measure-aggregates.ts, packages/lint/src/validate-dataset-measure-aggregates.test.ts, packages/lint/src/rule-explanations.ts, packages/lint/src/index.ts, packages/lint/src/runtime-gate.dataset-writes.test.ts, packages/qa/dogfood/test/analytics-formula-dimension-authoring.dogfood.test.ts + cited on main: dataset-compiler.ts (compileDataset's dimension loop, assertDeclared, assertAggregateFieldTypeCompatible and REMEDY_BY_SOURCE_CLASS, the declaredValueShape hook); validate-dataset-measure-aggregates.ts (the dataset leg's four skips, resolveCubeColumn, columnOf, shapeOf, declarerOf, groupKeyClassOf); authoring-rules.ts (the validateDatasetMeasureAggregates registry entry, tier: gating, commands: ALL, runtimeTypes: ['dataset']); packages/spec/src/data/search-fields.ts (isVirtualSearchField); packages/spec/src/migrations/entries/semantic/18.dataset-measure-aggregate-field-type-refused.ts; scripts/check-adr-0087-registration.mjs (breakingDeclaration, the five dispositions); scripts/pm/clause2-line.mjs; scripts/check-commit-card-trailers.mjs; the repo's merge settings; packages/lint/CHANGELOG.md and packages/services/service-analytics/CHANGELOG.md for the sibling precedents; content/docs/deployment/validating-metadata.mdx; .changeset/30773-dataset-dimension-formula-refused.md as the ② input.

Inputs read: card #30773 body and its three comments (triage 6675591690, seat claim 6676304413, os-dev-report 6677212943); #24426 body and its PR #24505's file list; the dispatch order and the dev's PR body, report, gates and reconcile files on the project mount; PR #30815 body, 10-file list, commit list with trailers, and the net diff vs main (merge-base 172eebb2, 5 ahead, main 6 ahead touching none of the 10 paths); the docs-drift comment 6677216592; the check-runs on this head, read twice; records 6674767869 and 6674911226 on PR #30768 (the query-time sibling).

① Derived judgments

② Semver level

Both carriers read Clause-②: no (narrowing) and Metadata-protocol: narrowed through clause2-line.mjs (value: no, arm: narrowing; value: narrowed), one line-initial key each. narrowed is right by AGENTS.md step 3: a dataset or cube dimension field naming a formula is "a value refused", the precedent class above declares the same. The level follows the kind: minor on each package the diff moves, @objectstack/service-analytics and @objectstack/lint, and no other package moves. The ! title is on the PR and the changeset's first line; the BREAKING section reads Before (measured on 2d04cd2b) / Now / Unchanged / Who moves / The remedy; one adr-0087: not-required (no-migration-prescription) marker, which the gate accepted ([BREAKING+bang+clause-②-narrowing+metadata-protocol-narrowed], exit 0 locally per the dev and Check Changeset green on this head).

Ledgers. narrowed moves none here: the authorable-surface and authorable-defaults shards are generated from packages/spec schemas by gen:schema, and this diff touches no spec file, so check:authorable-surface has nothing to project; check:spec-changes and check:upgrade-guide project the migration registries in memory, and no entry is added. Spec property liveness is green. The one ledger question is the ADR-0087 disposition itself, below.

ADR-0087 disposition. The no-migration-prescription exemption is mechanically honest: no key is added, removed, renamed or re-shaped, no conversion can rewrite a formula dimension into a stored one, and the changeset carries no FROM-to-TO rewrite. Five sibling gating rules shipped under the same words. Against that, the compile door's own measure-side precedent registered a semantic entry (dataset-measure-aggregate-field-type-refused, with surface, replacement, reason, acceptanceCriteria, relevantWhen: stack-declares datasets) for a refusal of a stored dataset shape at this same door, and dashboard-filter-binding-unknown registered one for a new gating rule; and this change does more than refuse a shape that never worked: a stored dataset carrying a formula dimension compiled on main and served its stored dimensions, and after this change the whole dataset is refused until an author hand-migrates it, which the Who-moves bullet says. That hand-migration is what the semantic registry projects into the upgrade guide. Not a must-fix (the gate accepts it, the exemption's letter holds, and the order told the dev to ask the seat before writing an entry), but a should-fix the seat decides before the release that ships this.

Check-runs on 0dd6d595 at the second read (about 05:25Z): 21 completed/success, among them Check Changeset, Governed Surface Queue Guard, Dogfood Regression Gate, PR-body guards, Spec property liveness, Build Core, Lint · ESLint, Lint · CI, release & engine gates, Lint · docs & code guards, Lint · scoped (three), Lint · PM dispatch-gates, Type Check · source gates, Type Check · debt ledger, Plan Test Core shards, Flag docs affected by code changes; 9 completed/skipped; 30 in_progress (Test Core 1 to 8 of 8, Test UI 1 to 16 of 16, Type Check UI, Type Check · consumer gates, Type Check · workspace, Lint · repo & tooling gates, Build & E2E UI, Live E2E UI); none failed. The all-green landing precondition is the seat's to read on this head.

③ Boundary flags

  • open_questions: none. The dev's three out-of-scope notes are read and taken up below: the docs page and the skills row (should-fix follow-ups, not this PR), the pre-empted preview arm (nit), the trailer (no effect).
  • validating-metadata.mdx. Hand-written (not under references/), last touched by lint: the dataset filter-key rules refuse a bare dimension or measure name that the dataset door binds at run time #30006 for a lint rule, and it documents dimension-json-stored-field-refused and the cube leg paragraph by paragraph. The new gating id is absent, so the page is drifted by this change. The dispatch's file surface excluded docs and told the dev to report, which they did, and the refusal text, the hint and os explain dimension-virtual-field-refused carry the prescription, so the PR is not held for it; it is owed as a docs-only follow-up PR (a paragraph beside the JSON-stored one and one sentence in the cube paragraph), carrier the seat.
  • skills/objectstack-data/rules/field-types.md line 131 ("virtual: not aggregatable, a dataset measure needs a stored field") could add "nor a group key". Tier H governed surface: a skills seat's follow-up, not this PR; the dev rightly left it. Skills-docs line is honest.
  • WIP commit 098b2b92 carries a Claude-Session trailer naming the coordinator's session; the three later commits carry the dev session's. The repository allows squash merges only (squash_merge_commit_title: PR_TITLE, squash_merge_commit_message: PR_BODY), so no branch commit message reaches main; the pre-push gate check-commit-card-trailers.mjs judges card relations and model identifiers, not session identity; and AGENTS.md forbids rewriting a pushed claude/project-thread-* branch. No effect on landing, no action.
  • objectql-strategy.ts and the engine door are untouched: the query-time refusal of fix(objectql, service-analytics)!: a plain group over a formula field is refused alike on every analytics face, instead of a 500, a driver backstop, one null group or a rendered statement #30768 stands as it landed, and this PR adds the authoring half in front of it.
  • Author is objectstack-fleet[bot]; the PR is a draft; no auto-merge to disarm.
  • Independence: rendered by an isolated contract-review subagent fed the card, lint: the measure-aggregate-field-type-refused hint for a formula total says "aggregate it with count", where the spec's own remedy is "store the value as a number field" (cloud#2861 ruling B item 4) #24426, the dispatch order, the PR, the net diff, the cited code on main, the CHANGELOG precedents, the gate sources and the check-runs, not the seat's conclusions; adopted by the seat named in Reviewed-by:.

④ Design judgment

Findings (none must-fix):

  • should-fix — for the seat before the release that ships this: decide the ADR-0087 disposition on the record. Either register a semantic entry mirroring 18.dataset-measure-aggregate-field-type-refused (surface: a dataset or analyticsCubes dimension over a virtual field; replacement: a stored field written when the source changes, or the dimension removed; reason and acceptance; relevantWhen: stack-declares datasets and analyticsCubes), so the upgrade guide carries the hand-migration a stored dataset now needs, in this PR or a spec follow-up before release; or state in the ACCEPT why the lint-rule precedent (no-migration-prescription, five entries) governs over the compile-door precedent (registered). The marker as written passes the gate either way.
  • should-fix — docs follow-up, carrier the seat: content/docs/deployment/validating-metadata.mdx lists the dataset and cube rules and lacks dimension-virtual-field-refused; a paragraph beside dimension-json-stored-field-refused and a sentence in the cube paragraph, in a docs-only PR.
  • should-fix — skills follow-up, carrier a skills seat: skills/objectstack-data/rules/field-types.md line 131, "nor a group key" on the formula row (governed, Tier H).
  • nit — the draft preview's assertDatasetGroupTargetsStored arm in analytics-service.ts is now unreachable for a bare dataset dimension (the compile precedes it through the same hook) and never judged a dotted one; its pin moved to the compile. Either remove the call or leave a comment saying it is the bucket door's partner only; carrier none.
  • nit — the compile message's clause "every query selecting this dimension is refused" states the query-time fact, while the error now reaches callers whose selection did not name the dimension; "every query on this dataset" would match what the reader just saw.
  • nit — the two GUARD-style pins that assert the cube and dataset legs never fire together rely on "a formula is never JSON-stored"; a one-line sweep asserting groupKeyClassOf is null for every SEARCH_VIRTUAL_TYPES member would pin that premise.

Implemented-by: claude/project-thread-c4pypv
Reviewed-by: session_016WV4cytQjG9X1CrCgytUM5

VERDICT: PASS

…N-stored dimension rule

Claude-Session: https://claude.ai/code/session_016WV4d1SZmabyrNd3YLCq3J
Co-authored-by: Claude <noreply@anthropic.com>
…follow-up #30824

The changeset still said validating-metadata.mdx did not list the id;
a97ed9f moved it, and the skills formula row is follow-up #30824.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WV4d1SZmabyrNd3YLCq3J
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:server#3 · os-elon-musk · session_016WV4cytQjG9X1CrCgytUM5

ACCEPT · #30773 · 2026-11-06T05:35Z · Head-sha: 43db93dfabc5a2e6da08abb884644d2c69a01263

席位核对

  1. Shape: 11 files, +666/−84: compileDataset's dimension loop calls assertDimensionFieldStored (spec isVirtualSearchField), refusing a dataset dimension over a base-object formula with DATASET_INVALID / 400 at every door that compiles (registerDataset, queryDataset on every face, the build probes), with the measure gate's cannot-answer tiers; the lint id dimension-virtual-field-refused sits inside validate-dataset-measure-aggregates.ts beside dimension-json-stored-field-refused, covering dataset and authored-cube dimensions (dotted paths judged on the leaf object), plus rule-explanations.ts, the barrel export, pins, the runtime write-door LIT case and one dogfood pin. The preview-date-bucket-type.test.ts fixture split is a re-homing, not a weakened pin: the query-time refusal stays pinned where no compile fronts it. Ablations red on each leg. Diff read at this head.
  2. Premise, measured: contract review 6677341880 (CONTRACT_REVIEW_TIER, head 0dd6d595): PASS, no must-fix. Clause-②: no (narrowing) and Metadata-protocol: narrowed on both carriers; check-adr-0087-registration reads not-required (no-migration-prescription).
  3. Gates: 64 derived at 0dd6d595, all exit 0 (--ran: 0 NOT-MEASURED, 0 UNRUN); full dogfood 424 files / 3537 tests green (title carries !). The two later commits are docs and changeset only: docs gates 32/32 at a97ed9f0, and at this head check-changeset-no-major, check-empty-changeset, check-adr-0087-registration and check:changeset-gate-self-tests exit 0. CI on this head: 57 success, 8 skipped, 0 failed.
  4. Accepted deviations: the seat's ruling on the review's should-fix items: (b) the content/docs/deployment/validating-metadata.mdx paragraph is folded in here as a surface addendum (a97ed9f0, read by the seat; no new review owed, docs only); (a) the semantic ADR-0087 upgrade-guide entry is follow-up spec: an upgrade-guide entry for a dataset or cube dimension over a formula field, now refused at authoring (follow-up to #30773) #30822, which must land before the release that ships this; (c) the skills field-types.md formula row is follow-up skills: the formula row of objectstack-data field-types should say a formula is no group key either (follow-up to #30773) #30824 (Tier H). The three reviewer nits are left as they are. The 098b2b92 WIP commit's wrong Claude-Session trailer has no landing effect (squash merge).
  5. Out of scope: spec: an upgrade-guide entry for a dataset or cube dimension over a formula field, now refused at authoring (follow-up to #30773) #30822 (spec lane), skills: the formula row of objectstack-data field-types should say a formula is no group key either (follow-up to #30773) #30824 (skills lane); the preview's own virtual arm, now pre-empted for a bare dataset dimension, stays as the date-bucket door's partner (noted in the PR, no carrier).
  6. Landing: check-governed-merges --pr 30815 on the final 11-file list: NOT governed, 750 lines. Ordinary queue landing by this seat: ready + auto-merge.

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

Labels

documentation Improvements or additions to documentation size/l tests tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

analytics: a dataset or cube dimension over a formula field is accepted at authoring, though every query now refuses it (follow-up to #29304)

1 participant