Skip to content

docs(spec): upgrade-guide entry for a dataset or cube dimension over a formula field - #30925

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/project-thread-5kf1uq
Nov 6, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/project-thread-5kf1uq

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Tesla · project thread

Fixes #30822

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:升级指南(os migrate meta 与协议升级文档)新增一条语义迁移条目 dataset-dimension-virtual-field-refused:数据集或 analyticsCubes 的维度指向公式字段(不落库的虚拟字段)现在在编写时就被拒,条目告诉作者怎么改。
  • 为什么改:analytics: a dataset or cube dimension over a formula field is accepted at authoring, though every query now refuses it (follow-up to #29304) #30773 已让数据集编译(400 DATASET_INVALID)和 lint(dimension-virtual-field-refused)拒绝这种维度,但升级指南没有对应条目,作者升级后只会在数据集突然编译失败时才知道;度量侧的同类收窄早已有条目。
  • 风险与回滚:只加一条指南文字和它的相关性登记,不改任何 schema、导出或接受集;回滚即 revert。
  • 先看:packages/spec/src/migrations/entries/semantic/18.dataset-dimension-virtual-field-refused.ts(条目正文,引用两道拒绝的原文);packages/spec/src/migrations/semantic-relevance.test.ts(相关性登记表 +1)。
  • 两分钟验证:pnpm --filter @objectstack/spec exec tsx scripts/build-upgrade-guide.ts --out /tmp/g.md && grep -n dataset-dimension-virtual-field-refused /tmp/g.md,预期在协议 18 一节看到该条目及其「Why not automatic / Done when」两行。
  • 需要你做的:无,席位落地。

What changes

  • New semantic migration entry dataset-dimension-virtual-field-refused (protocol 18 step), the dimension-side sibling of dataset-measure-aggregate-field-type-refused, for a datasets[].dimensions[].field or an analyticsCubes[].dimensions.KEY.sql naming a formula field (SEARCH_VIRTUAL_TYPES).
    • No automatic rewrite: which stored field should carry the value is the author's judgement.
    • Replacement, as the card words it: store the value in a field of its own on the object (written by a hook or a flow when its source changes) and point the dimension at that field, or remove the dimension.
    • acceptanceCriteria quotes both refusals as PR 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 shipped them: the dataset compile's 400 DATASET_INVALID text from assertDimensionFieldStored (dataset-compiler.ts), and the lint finding's message and hint from virtualDimensionFinding (validate-dataset-measure-aggregates.ts), with placeholders for the names. It also carries the two scope facts from that PR's changeset: the whole dataset stops compiling (not only the member), and the compile does not judge a dotted dimension while lint does.
    • relevantWhen: { kind: 'stack-declares', keys: ['datasets', 'analyticsCubes'] }.
  • semantic-relevance.test.ts: the reviewed ENUMERATION table gains the entry; the count pins move 26 → 27 overall and 21 → 22 for protocol 18.
  • Changeset @objectstack/spec patch with both declaration lines.

Why

The upgrade guide is the only channel that reaches an author upgrading across the release that ships #30773 before their dataset stops compiling. The narrowing PR registered not-required (no-migration-prescription), so no conversion exists to replay; this entry is the prescription. The card asks for it to land before that release.

Verification

All runs on head 012839b6 in a dedicated worktree, base origin/main 6ff27b34 (main has moved since with no change under packages/spec/src/migrations).

Tests
  • pnpm --filter @objectstack/spec build :: exit 0
  • vitest run src/migrations scripts/upgrade-guide-docs.test.ts scripts/upgrade-guide-surface-span.test.ts (spec): Test Files 7 passed (7), Tests 228 passed (228)
  • pnpm --filter @objectstack/spec test: Test Files 818 passed (818), Tests 25838 passed, 1 todo
  • pnpm --filter @objectstack/spec typecheck :: exit 0
  • Rendered guide (build-upgrade-guide.ts --out): the entry appears in protocol 18's section, its surface in one intact code span, with its "Why not automatic" and "Done when" lines.
Derived gates

node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 81 families for the 3-path change set; all 81 ran with exit 0. --ran reconciliation: 81 derived, 81 run, 0 NOT-MEASURED, 0 UNRUN. Four first runs answered exit 3 (prerequisite, nothing measured) and were re-run green after the prerequisite: check-plugin-teardown-shape --self-test (clone deepened), check:doc-formula-expressions, check:lean-entry-closure, check:dual-build-cjs-loads (dependency builds). Record: /mnt/project-files/spec-seat-1/r2026-11-06/out/30822-gates-ran-012839b6.list.

Dogfood: n/a (no ! in the title, no (narrowing) arm).

Acceptance notes

  • relevantWhen names only datasets and analyticsCubes, as the card rules. Measured on packages/spec/src: DatasetSchema is reachable from the stack only through datasets (stack.zod.ts), and CubeSchema only through analyticsCubes, so no third key carries the surface.
  • A dataset stored at runtime (Studio, /meta) is outside the relevance question by its own definition (SemanticRelevance: runtime-stored metadata is not part of the stack it reads), so a deployment whose only datasets are stored rows sees this entry counted as absent under os migrate meta and listed under --all. The entry's sweep is source-first (os validate); it names the runtime save's 422 only as one of the doors that refuse.
  • No ablation: the diff changes no tested behaviour, only registry data and its enumeration pin (the pin itself goes red without the table row, which is the reviewed-edit design).
  • The PR assignee is left to the seat at hand-over.

Human Minimum

  • 1. Schemas start as Zod; packages/spec holds no runtime logic.
  • 2. Every name I added uses the casing for its kind.
  • 3. No formatter ran; pnpm lint passes (CI-owned).
  • 4. One issue, one branch off an up-to-date main, one pull request.
  • 5. A change that publishes carries a changeset, and both declaration lines are filled in here and in the changeset.
  • 6. packages/spec touched: its generated artifacts are regenerated and committed (none committed for an entry: registry.ts and the guide are generated, not tracked).
  • 7. No hand edits to content/docs/references/, packages/*/CHANGELOG.md or content/docs/releases/.
  • 8. Title, body and comments are in English.

🤖 Generated with Claude Code

https://claude.ai/code/session_01L9qibvg2LHxbiRKsqRA6iR


Generated by Claude Code

…a formula field

The dataset compile and the authoring rules now refuse a dataset or
analyticsCubes dimension over a virtual (formula) field. Register the
semantic migration entry that tells an upgrading author what to do:
store the value in a stored field and point the dimension at it, or
remove the dimension. No automatic rewrite; relevant when the stack
declares datasets or analyticsCubes.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L9qibvg2LHxbiRKsqRA6iR
@github-actions github-actions Bot added size/s 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 1 package(s): @objectstack/spec, touching 3 documentable anchor(s).

2 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/deployment/validating-metadata.mdx (via analyticsCubes (literal, a string literal in relevantWhen))
  • content/docs/getting-started/quick-start.mdx (via analyticsCubes (literal, a string literal in relevantWhen))

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

  • content/docs/releases/v17/17-5.mdx (via analyticsCubes (literal, a string literal in relevantWhen))
  • content/docs/releases/v17/17-6.mdx (via analyticsCubes (literal, a string literal in relevantWhen))
  • content/docs/releases/v17/17-7.mdx (via analyticsCubes (literal, a string literal in relevantWhen))

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
  • 3 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 63 of 222 client-bound route-ledger rows — the other 159 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 159: 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; 104 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 — 170 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 0e882086b9d289fdcc18d5c841237a151404f419 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from 9f6e6e1876184130521c0a0850c4043138f08430 — the merge of head 012839b62658f75173cfa3a3e7d2c970f6ad3443 into base 0e882086b9d289fdcc18d5c841237a151404f419, 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 9f6e6e1876184130521c0a0850c4043138f08430 && git checkout 9f6e6e1876184130521c0a0850c4043138f08430
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 0e882086b9d289fdcc18d5c841237a151404f419 012839b62658f75173cfa3a3e7d2c970f6ad3443 && git checkout -B drift-repro 0e882086b9d289fdcc18d5c841237a151404f419 && git merge --no-ff 012839b62658f75173cfa3a3e7d2c970f6ad3443

node scripts/docs-audit/affected-docs.mjs --json 0e882086b9d289fdcc18d5c841237a151404f419

⚠️ 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 0e882086b9d289fdcc18d5c841237a151404f419 → 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:spec#1 · os-tesla · session_01L9qibzzqHZdAVqgBAvxXKB

维护者速读

  • 改了什么:升级指南新增一条语义迁移条目 dataset-dimension-virtual-field-refused:数据集或 analyticsCubes 的维度指向公式字段,现在编写时就被拒(数据集编译 400 DATASET_INVALID,lint dimension-virtual-field-refused)。条目原文引用两道拒绝,并给出改法:把值存进对象上的一个普通字段(由 hook 或 flow 在源变化时写入),维度改指向它,或删掉这个维度。不自动改写。
  • 为什么改:analytics: a dataset or cube dimension over a formula field is accepted at authoring, though every query now refuses it (follow-up to #29304) #30773 已上线这条拒收,但升级指南没有条目,作者升级后只会在数据集突然编译失败时才知道;度量侧的同类收窄早有条目。卡要求赶在发布 analytics: a dataset or cube dimension over a formula field is accepted at authoring, though every query now refuses it (follow-up to #29304) #30773 的版本之前落地。
  • 风险与回滚:只加一条指南条目和它的相关性登记,不改 schema、导出或接受集。回滚即 revert。
  • 先看:packages/spec/src/migrations/entries/semantic/18.dataset-dimension-virtual-field-refused.ts。
  • 两分钟验证:pnpm --filter @objectstack/spec exec tsx scripts/build-upgrade-guide.ts --out /tmp/g.md && grep -n dataset-dimension-virtual-field-refused /tmp/g.md。
  • 需要你做的:在席位线程回一句放行,席位即翻 ready 并挂自动合并。不属受管面。

席位意见:可以落地。

席位核对

ACCEPT · seat domain:spec#1 · head 012839b6 · 2026-11-06T12:29Z

  1. Shape: Fixes #30822, draft, base main, 3 files (.changeset/30822-dataset-dimension-virtual-field-guide-entry.md, packages/spec/src/migrations/entries/semantic/18.dataset-dimension-virtual-field-refused.ts, packages/spec/src/migrations/semantic-relevance.test.ts), +69/−3. @objectstack/spec patch changeset with Clause-②: no and Metadata-protocol: none, matching the claim 6683531934.
  2. Premise: PR 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 (the narrowing) merged; no semantic entry on main covered a dimension over a virtual field.
  3. Contract review: none owed at CONTRACT_REVIEW_TIER. No *.zod.ts, no governed path (check-governed-merges: 0 hits), Clause-②: no, no narrowing arm; the entry is upgrade-guide data, so the accept set is byte-identical. Seat self-read of the whole diff at TIER_DEFAULT: both quoted refusals match main (assertDimensionFieldStored in packages/services/service-analytics/src/dataset-compiler.ts, virtualDimensionFinding + declaredAs in packages/lint/src/validate-dataset-measure-aggregates.ts); relevantWhen keys datasets + analyticsCubes are the only stack keys reaching DatasetSchema / CubeSchema (dev measured); count pins 26→27 / 21→22 match the one added row.
  4. Gates / check-runs: dev: 81 of 81 derived gates exit 0, --ran reconciled, spec suite 818 files green (report 6684313506). On head 012839b6: 64 runs, 55 success, 9 skipped, 0 failed, 0 running; mergeable_state clean.
  5. Accepted deviations: the dev detached the shared checkout (clean) to free the branch for its worktree, and deepened the clone for one self-test fixture; neither reaches the diff.
  6. Landing: not governed, 72 changed lines: the seat readies the PR and arms auto-merge on the maintainer's explicit word in the seat thread, quoted here when given.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:spec#1 · os-tesla · session_01L9qibzzqHZdAVqgBAvxXKB

Landing · seat domain:spec#1 · head 012839b6 · 2026-11-06T14:09Z

  • Maintainer's word (verbatim, seat thread, 2026-11-06T14:09:04Z): 「你应该是使用 pm-dispatch 技能自主审核和落地 pr」.
  • ACCEPT on this head stands; check-governed-merges --pr 30925: no governed path, under 3000 lines; mergeable_state clean; check-runs green.
  • This stroke: relay pr_ready + automerge_enable. The same seat dispatched the card thread that authored this PR.

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review November 6, 2026 14:11
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge November 6, 2026 14:11
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Nov 6, 2026
Merged via the queue into main with commit ebe0a98 Nov 6, 2026
65 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-5kf1uq branch November 6, 2026 14:51
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/s 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.

spec: an upgrade-guide entry for a dataset or cube dimension over a formula field, now refused at authoring (follow-up to #30773)

1 participant