Skip to content

docs(spec): wrong-layer guidance for group/hideFields/rowColor on object userActions - #12606

Merged
os-zhuang merged 2 commits into
mainfrom
claude/issue-11459-object-useractions-guidance
Aug 27, 2026
Merged

docs(spec): wrong-layer guidance for group/hideFields/rowColor on object userActions#12606
os-zhuang merged 2 commits into
mainfrom
claude/issue-11459-object-useractions-guidance

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes #11459

What

Adds three curated guidance entries to the object-level userActions strictObject in packages/spec/src/data/object.zod.tsgroup, hideFields, rowColor — mirroring the existing sort/search/filter/editInline wrong-layer wording convention.

Why

ui/view.zod.ts's UserActionsConfigSchema adopted group/hideFields/rowColor at #11195 (merged via #11458). Those three keys share a name-collision trap with the object block's own userActions (disjoint vocabulary, same key names elsewhere): an author who learned them on the view writes them on the object and, until this PR, got only the generic unknown-key rejection with an edit-distance suggestion — which has nothing useful to offer over the object block's create/import/edit/delete/exportCsv shape.

Acceptance is byte-identical. All three keys were already rejected by name on the object block before this change (measured on origin/main pre-PR) and are rejected after it; only the refusal's message gains the same curated pointer the other four wrong-layer keys already carry. Clause-② does not apply — the accept/reject set does not move.

Changes

  • packages/spec/src/data/object.zod.ts — three guidance entries (group, hideFields, rowColor), placed after editInline; updated the block's leading comment to note the three keys now carry curated pointers too.
  • packages/spec/src/data/object-strictness-batch20.test.ts — new test userActions.group / .hideFields / .rowColor name the VIEW block, same as sort (#11459), asserting the "VIEW" pointer for all three, mirroring the existing sort pin. The pre-existing disjoint-vocabulary test (which already asserted these three are rejected by name) is untouched.
  • .changeset/object-useractions-view-key-guidance.md — patch changeset, following the precedent set by the prior pure-guidance-text change (visible-when-alias-guidance.md, docs(spec): alias guidance for visible/showWhen/disabled on the visibleWhen shapes (#7832) #7884): guidance/describe-text changes on @objectstack/spec get a real changeset, not skip-changeset.

Verification

Local commands run under scripts/pm/os-verify-lock.sh, on merge commit a413af29c (merge base 23d52f99c of origin/main):

  • pnpm --filter @objectstack/spec build — clean, 34/34 declared .d.ts present.
  • pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2 src/data/object-strictness-batch20.test.ts src/shared/alias-integrity.test.ts src/data/object.test.ts253 passed (253), including the ReportSchema 的 filter 别名指向 filters —— 一个 ReportSchema 同样拒绝的键(#4001 战役自己的假处方,第 5 例) #5013 alias-integrity audit (no guidance key is itself a declared key — the three new entries are keys the object shape rejects, so they pass automatically) and the new pin.
  • pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2 (full package) — 432 test files / 11499 tests passed.
  • pnpm --filter @objectstack/spec check:generated — all 14 generated artifacts up to date, no regeneration needed (guidance prose is not a .describe()/authorable key).
  • pnpm --filter @objectstack/spec run typecheck — clean (tsc --noEmit, check:scripts-typecheck, check:test-typecheck).
  • Full pnpm build (needed as a prerequisite for check:dev-prereqs / check:type-check-debt) — 71/71 tasks successful.
  • node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack derivation, and every gate it named for this diff — all green: check:authorable-surface, check:cross-package-test-inputs (both the pnpm script and the raw script invocation), check:doc-authoring, check:doc-formula-expressions, check:empty-state, check:liveness, check:merge-driver, check:objectql-double-limit, check:page-declaration-shape, check:published-files, check:slot-lookup, check:spec-parsed-alias, check:strictness-ledger, check:test-source-alias, check:type-source-resolution, check:variant-docs, check:ci-filter-parity, check:comment-mask-adoption, check:dev-prereqs, check:plugin-teardown-shape, docs-audit/check-affected-docs, docs-audit/check-drift-comment.
  • Convention-triggered gates for the edited test file: check:type-check-coverage (OK), check:type-check-debt --re-measure (31 ledger entries re-measured, none above their recorded ceiling), check:query-options-erasure, check:engine-double-contract (689 pinned / 134 debt / 3 exempt, unchanged), check:where-matcher (303/303) — all green.
  • Changeset-triggered family: check:changeset-gate-self-tests, check:objectui-changeset, check-adr-0087-registration.mjs, check-changeset-no-major.mjs, check-empty-changeset.mjs, release-rehearsal-clone.mjs --self-test — all green.
  • Scoped eslint --no-inline-config over the two touched source files (object.zod.ts, object-strictness-batch20.test.ts): 0 errors / 0 warnings, 2 files (per --format json). Collapse to this scope is a measured, not assumed, safe narrowing: eslint --print-config on the touched file confirms no parserOptions.project is set for this tree (no type-aware linting), so the diff cannot move any judgment on an untouched file.
  • Self-scanned both touched source files and the changeset for control-byte contamination (grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]') — clean.

Per this batch's constraints, packages/spec/src/api/** and packages/rest (sibling PR #12605's surface) are untouched, and content/docs/releases/** is untouched.


Generated by Claude Code

claude added 2 commits August 26, 2026 18:30
…ect userActions (#11459)

Add three curated `guidance` entries to the object-level `userActions`
strictObject in packages/spec/src/data/object.zod.ts, mirroring the existing
sort/search/filter/editInline wrong-layer wording convention: group,
hideFields and rowColor are VIEW `userActions` keys (adopted at #11195) that
share a name with nothing on the object block, so an author who learned them
on the view writes them here and previously got only the generic
unknown-key rejection.

Nothing changes about what parses — all three keys were already refused by
name on the object block; only the refusal's message gains the same curated
pointer the other four wrong-layer keys already carry.

Mirrors the existing pin for `sort` with a new test asserting the "VIEW"
pointer for all three keys, alongside the pre-existing disjoint-vocabulary
check. The #5013 alias-integrity audit judges the three new entries
automatically (each is a key the object shape rejects).
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/spec, touching 1 documentable anchor(s).

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

  • content/docs/data-modeling/objects.mdx (via userActions (symbol))
  • content/docs/protocol/objectui/index.mdx (via userActions (symbol))

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

  • content/docs/releases/v14.mdx (via userActions (symbol))
  • content/docs/releases/v16.mdx (via userActions (symbol))
  • content/docs/releases/v17.mdx (via userActions (symbol))

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
  • the SDK route bridge reached 47 of 219 client-bound route-ledger rows — the other 172 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 172: 14 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 56 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 102 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.

Coarse fallback — 126 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 23d52f99c728d3af6acb14594726993be515de36packageMentionDocs.

Which tree this was computed on

This run read content/docs from 36b8799dd04d06ec620746aa9672ad953928632d — the merge of head a413af29ca951b819a2cb611fc59069884cd3afd into base 23d52f99c728d3af6acb14594726993be515de36, 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 36b8799dd04d06ec620746aa9672ad953928632d && git checkout 36b8799dd04d06ec620746aa9672ad953928632d
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 23d52f99c728d3af6acb14594726993be515de36 a413af29ca951b819a2cb611fc59069884cd3afd && git checkout -B drift-repro 23d52f99c728d3af6acb14594726993be515de36 && git merge --no-ff a413af29ca951b819a2cb611fc59069884cd3afd

node scripts/docs-audit/affected-docs.mjs --json 23d52f99c728d3af6acb14594726993be515de36

⚠️ 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 23d52f99c728d3af6acb14594726993be515de36 → pass the list as
args.docs, on the commit named under Which tree this was computed on.

This was referenced Aug 26, 2026
@os-zhuang
os-zhuang marked this pull request as ready for review August 27, 2026 04:05

Copy link
Copy Markdown
Contributor Author

Contract review released by the maintainer (2026-08-27, in-session, verbatim 「12606 绿了」) — needs:contract-review stripped from both carriers (this PR and card #11459) on that authority; this seat did not self-release. Flipping ready and entering the merge queue; the spec seat (session session_012xGvxcwPRTJfA7RfjXEYA4) watches to MERGED.


Generated by Claude Code

@os-zhuang
os-zhuang added this pull request to the merge queue Aug 27, 2026
Merged via the queue into main with commit 0c77ea4 Aug 27, 2026
44 checks passed
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 protocol:data tests tooling

Projects

None yet

2 participants