Skip to content

fix(spec): check:variant-docs reads a z.enum discriminator arm's members into the union key - #29531

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/project-thread-azun9f
Nov 2, 2026
Merged

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

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Warren · project thread
Fixes #29412

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:check:variant-docs 现在把 z.enum 判别臂的全部成员读进联合的台账键;唯一受影响的条目从 kind:nav 改键为 kind:field|flow|nav,并在 api/metadata-api.mdx 补一句点名 field / flow 两个 kind。
  • 为什么改:旧的遍历只读字面量臂,枚举臂整个不进键,枚举增删成员时键不动,门禁就不会把作者送回文档。
  • 风险与回滚:只动门禁脚本、它的台账和一句文档,不发布任何包;回滚即 revert 本 PR。
  • 先看:packages/spec/scripts/check-variant-docs.mts 的 armVariants();再看 packages/spec/scripts/check-variant-docs.test.ts;最后 packages/spec/variant-docs.json 的改键。
  • 两分钟验证:pnpm --filter @objectstack/spec check:variant-docs,预期打印 24 个联合全部通过;--list 里 contributions 的键是 kind:field|flow|nav。
  • 需要你做的:无,席位落地。

What changes

  • packages/spec/scripts/check-variant-docs.mts: a new exported armVariants() reads the values one arm's discriminator matches. A literal keeps them in the def's values; a zod 4 z.enum keeps its members in entries, and the walker never read that field, so an enum arm was left out of the key entirely. armVariants() now reads zod's own parse set (_zod.values, which drops a numeric TypeScript enum's reverse-mapping keys) and falls back to the entries' values. The per-union key building moved into an exported unionKey(). The sweep moved into main() and runs only when the file is invoked as a script, so the test can import the two helpers without sweeping src/ or setting OS_EAGER_SCHEMAS in its worker.
  • packages/spec/variant-docs.json: re-keyed the one entry this moves, kind:nav to kind:field|flow|nav (GetPackageCustomizationsResponseSchema contributions). Its note is kept, with the sentence saying the walker cannot read the enum arm replaced by one saying it now does.
  • content/docs/api/metadata-api.mdx (bounded in-place fix, file surface amended in Claim amendment 6582783172): once re-keyed, the gate found that the bound doc never mentions field, and that flow passed only through an unrelated row (the type column at line 33). That is the doc owing a re-read, which this change is what surfaces. One sentence now names the kinds: "the fields (kind field) and flows (kind flow) other installed packages contribute to hotcrm's objects".
  • packages/spec/scripts/check-variant-docs.test.ts (new): pins a fixture union with one enum arm and one literal arm, keyed on all three members; adding a member to the enum arm moves the key; a literal-only control keys as before; non-discriminated schemas answer null; an object-built enum reads its values, not its keys.

Why

A discriminated union's ledger key exists so that adding or dropping a variant changes the key and sends the author back to the bound doc. An enum arm's members were never in the key, so a page kind added to the field / flow enum would have left the key at kind:nav and the gate green.

Tests

  • check:variant-docs --list on origin/main 94d3e25 vs this head: 24 discriminated unions both times; exactly one key differs (kind:nav became kind:field|flow|nav). Measured, not assumed: no other union in src/ has an enum arm.
  • New scripts/check-variant-docs.test.ts: 7/7 pass.
  • pnpm --filter @objectstack/spec test (local project) at 314f4b3: Test Files 793 passed (793), Tests 23526 passed, 1 todo.
  • pnpm --filter @objectstack/spec typecheck at 314f4b3 (tsc, check:scripts-typecheck, check:test-typecheck): exit 0.
  • No ablation: the diff changes a gate script, which os-dev does not ablate. The before/after --list reading above is the evidence that the reading changed.

Acceptance notes

  • No changeset, skip-changeset: @objectstack/spec's files[] ships dist, json-schema, src/**/*.zod.ts and others, not scripts/ or variant-docs.json; content/docs/ is no package.
  • No packages/spec/src/**/*.zod.ts file and no strictness-ledger file is touched.
  • The match for a variant in a doc stays as loose as before; the gate still proves only that the page says the word.

Verification

dispatch-gates at 314f4b3: 86 derived, 86 run, all exit 0

node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 86 families. 76 exited 0 on the first run; 10 exited 3 (PREREQUISITE NOT MET) on the fresh worktree, the one check:docs exit 1 being the missing json-schema tree, a prerequisite and not a finding. After git fetch origin 621a4876 and turbo run build --filter='@objectstack/lint...' --filter=@objectstack/objectql --filter=@objectstack/formula --filter='@objectstack/client-react...' --filter=@objectstack/spec, all ten re-ran to exit 0, check:variant-docs among them on the first run. Reconciliation: "dispatch-gates --ran: 86 derived famil(ies) accounted for — 86 run, 0 NOT-MEASURED".

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 (eslint on the two changed scripts files: exit 0; the repo-wide run is CI's).
  • 4. One issue, one branch off an up-to-date main, one pull request.
  • 5. A change that publishes carries a changeset (nothing publishes here).
  • 6. packages/spec touched: no generated artifact moves (check:docs green).
  • 7. No hand edits to content/docs/references/, packages/*/CHANGELOG.md or content/docs/releases/.
  • 8. Title, body and comments are in English.

Dispatched by domain:spec#3 · os-warren · session_01JQwxbahe4v7GBD94QeSnir; dev = card thread session_01JQwxbZYuv4NM4LDCUNP3cK.

🤖 Generated with Claude Code

https://claude.ai/code/session_01JQwxbZYuv4NM4LDCUNP3cK


Generated by Claude Code

…ers into the union key

Claude-Session: https://claude.ai/code/session_01JQwxbZYuv4NM4LDCUNP3cK
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Nov 2, 2026
@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tests tooling labels Nov 2, 2026
@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️ 1 changed file(s) yielded no anchor (packages/spec/variant-docs.json), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)).

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/spec/variant-docs.json) — pages documenting those are invisible to this run
  • 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 — 168 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 5651647d82dea5ce18ad537d629c18e3dd27f613 → packageMentionDocs.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:spec#3 · os-warren · session_01JQwxbahe4v7GBD94QeSnir

维护者速读

  • 改了什么:check:variant-docs 门禁现在把 z.enum 形式的判别臂也读进账本键;账本里唯一受影响的一行从 kind:nav 改成 kind:field|flow|nav,metadata-api.mdx 一句话补上 field / flow 两个 kind;加了一个夹具测试。
  • 为什么改:原来只读字面量臂,枚举臂增减成员时键不动,门禁就不会提醒去复读文档。
  • 风险与回滚:只动门禁脚本、账本一行和一句文档,不发包(skip-changeset);回滚即 revert。
  • 先看:packages/spec/scripts/check-variant-docs.mts 新增的 armVariants() / unionKey()。
  • 两分钟验证:pnpm --filter @objectstack/spec check:variant-docs,预期绿;夹具测试 check-variant-docs.test.ts 7 例全过。
  • 需要你做的:无,CI 全绿,席位落地。
  • 席位意见:改前改后都是 24 个判别联合,只有这一个键移动;文档那句是门禁变严后立刻抓到的真缺口,已在认领修订 6582783172 里纳入范围。

席位核对

ACCEPT · domain:spec#3 · head 314f4b3419e77c5661e7318663f88ef19c77c2d8 · 2026-11-02T18:17Z

  1. Shape: four files: packages/spec/scripts/check-variant-docs.mts (+139 / -102: armVariants() and unionKey() extracted and exported, the sweep moved into main() behind an invoked-directly guard so the test import does not sweep), packages/spec/scripts/check-variant-docs.test.ts (new, fixture unions), packages/spec/variant-docs.json (one key re-keyed, its note rewritten), content/docs/api/metadata-api.mdx (one sentence). Inside the amended file surface (6582783172).
  2. Premise, measured: on 94d3e254 the seat read walk() building keys from dd.values / dd.value only and the ledger holding kind:nav for the contributions union. The dev measured the key move with --list before/after: 24 unions both ways, one key moved.
  3. Gates: local 86 derived / 86 run / 0 NOT-MEASURED, all exit 0 after prerequisite builds (report 6584253114). On this head 70 check-runs, every one success or skipped; mergeable_state clean. The fixture test is collected by packages/spec/vitest.config.ts (scripts/**/*.test.ts).
  4. Accepted deviations: the OS_EAGER_SCHEMAS default moved from module top level into main(), so the CLI path is unchanged and the test import leaves the variable unset. Seat read the doc sentence against the union's arms: field and flow are the enum arm's members, nav keeps its "declared and not yet served" clause.
  5. Out of scope: none found by the dev or the seat. Skills-docs: n/a (Metadata-protocol: none).
  6. Landing: not governed (check-governed-merges --pr 29531: NOT governed, 322 changed lines), Clause-②: no, no contract-review face hit (spec tooling scripts, a ledger JSON and docs prose; no packages/spec/src/**), skip-changeset (publishes nothing). Seat lands it: pr_ready + automerge_enable.

Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review November 2, 2026 18:19
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge November 2, 2026 18:19
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Nov 2, 2026
Merged via the queue into main with commit 32907ae Nov 2, 2026
71 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-azun9f branch November 2, 2026 18:46
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:spec#3 · os-warren · session_01JQwxbahe4v7GBD94QeSnir

Landed · 2026-11-02T19:06Z

Reading Value
PR #29531 MERGED 2026-11-02 18:46:56Z via merge queue, merge commit 32907ae9 on main
Card #29412 closed completed by Fixes #29412; no other closing keyword in the body

State change: pm:dispatched removed from #29412. Delivered: check:variant-docs reads a z.enum discriminator arm's members into the union keys. Remaining: none on this card.


Generated by Claude Code

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/m skip-changeset PR has no user-facing published change; bypasses the changeset gate tests tooling

Projects

None yet

1 participant