Skip to content

docs(skills): the data skill's Field Groups section teaches a group's visibleWhen and requiresFeature - #30890

Draft
objectstack-fleet[bot] wants to merge 5 commits into
mainfrom
claude/project-thread-vea7es
Draft

objectstack-fleet[bot] wants to merge 5 commits into
mainfrom
claude/project-thread-vea7es

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Tesla · project thread

domain:skills#2 · os-tesla · session_01L9qibxLYNwSMSVQkj55gA6

Fixes #30812

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:skills/objectstack-data/references/examples-objects.md 的 Field Groups 一节新增一条:整个字段分组(含标题)可以用 visibleWhen(对记录求值的 CEL,为 FALSE 或求值出错即隐藏)或 requiresFeature(取自 PUBLIC_AUTH_FEATURES 的部署特性名,未知名字解析即拒绝;解析时降成该分组的 visibleWhen 并去掉,与作者自写的 visibleWhen 以 AND 合成、作者谓词在前)隐藏,两者都只管界面、字段仍可经 API 读取;示例取真实的 sys_organization「集团结构」分组(requiresFeature: 'multiOrgEnabled')。
  • 为什么改:PR feat(spec): a field group's requiresFeature hides the group where a deployment feature is off; Edit organization hides Parent Organization and Sort Order on one organization #30810 给字段分组加了 requiresFeature,技能文本仍只列 icon、description、collapse,读技能的 agent 写对象时不知道一个分组可以按谓词或按部署特性隐藏,会去改表单页面或者什么都不做。
  • 风险与回滚:只改技能文本、一条 changeset 和 token 棘轮的一行(1756 → 1737,向下重锁到合并后的实测值:本 PR 削 5,已合并的 docs(skills): teach one naming rule, every package-authored metadata name starts with its namespace #30831 削 14 且未重锁);运行时零改动,行文逐词对照 main 上的 object.zod.ts 与 public-auth-features.ts。回滚即 revert。
  • 先看:skills/objectstack-data/references/examples-objects.md 的 Field Groups 段(新增一条 + 四处删减);同文件 Quick-Start 的一行注释与 Metadata Protection 的一句删减;scripts/check-skills-token-ratchet.mjs 的 examples-objects 行。
  • 两分钟验证:node scripts/check-skills-token-ratchet.mjs | grep examples-objects,预期 is 1737 tokens (ceiling 1737; headroom 0);再对照 packages/spec/src/data/object.zod.ts 中 requiresFeature 的 describe 文本,技能句子与之一致。
  • 需要你做的:本 PR 触 skills/**(Tier H),需要受管审批人在 GitHub 上 Approve 一次;之后席位落地。

What changes

skills/objectstack-data/references/examples-objects.md, section "Field Groups (MVP)": one new bullet after the per-group options, stating what main does since PR #30810 (ObjectFieldGroupSchema in packages/spec/src/data/object.zod.ts, lowerRequiresFeature in packages/spec/src/kernel/public-auth-features.ts):

  • a whole group, header included, is hidden by visibleWhen (CEL over record.*; FALSE or a fault hides it — the slot is fail-closed) or by requiresFeature (a deployment feature flag from PUBLIC_AUTH_FEATURES; an unknown flag is refused at parse);
  • requiresFeature is lowered at parse into the group's visibleWhen and stripped from the output, AND-combined after an authored visibleWhen (the author's predicate first);
  • both are presentation only: the fields stay readable through the API;
  • the example is the real one: sys_organization hides Parent Organization and Sort Order on a single-organization deployment with { key: 'group_structure', label: 'Group Structure', requiresFeature: 'multiOrgEnabled' } (packages/platform-objects/src/identity/sys-organization.object.ts).

Not taught, on purpose: the gate's CEL spelling (features.X != false / == true), the four composition refusals (visibleWhen: false, a non-CEL or AST-only predicate, a blank source), the lint's accepted-trailing-gate rule, and the console's empty-features pre-fetch window. The skill names the two keys and the one behaviour an author must know; the rest is the schema's own docblock and refusal text.

Growth paid in the same file, by deletion (no re-wrap):

Deleted Why it was restatement
The section's intro sentence (Organize fields into logical groups (e.g., "Contact Information", "Billing", "System") for forms, detail pages, and editors.) The heading says what the section is; the example right below shows those three labels; the collapse bullet already says groups render on forms, modals and detail pages.
; group labels are human-readable A truism beside the label: 'Contact Information' lines of the example.
— replaces the deprecated \defaultExpanded` flag, ADR-0085` History of the collapse enum, not a rule; the enum's three values stay spelled out.
The "Supported migrations at this layer" paragraph Restates bullets 1 and 2 (edit the fieldGroups array; edit Field.group); its last sentence was a roadmap note.
— see above in the Quick-Start sharingModel comment A dangling pointer: the text it pointed at lives in SKILL.md, not in this file (the block was moved here verbatim). // required in practice stays.
The block is \.strict()`: `reason` is required (min 1 / max 500 chars) and unknown keys are rejected.` (Metadata Protection) The schema block two lines above already says REQUIRED — reason … (1–500 chars); strictness is taught once in SKILL.md (ObjectSchema.create() rejects unknown keys).
// src/objects/sys-user.object.ts (Metadata Protection example) A path comment the other two os:check blocks in this file do not carry.

scripts/check-skills-token-ratchet.mjs: the examples-objects.md row re-locks DOWN at the landed count, 1756 → 1737, zero headroom, with the usual comment: -5 from this PR's cut, -14 from the merged #30831 (its hook-example rename dropped the block's intro line and left the headroom unlocked).

.changeset/30812-field-group-visible-when-requires-feature.md: '@objectstack/skills': patch, both declaration lines.

No eval case: the objectstack-data evals convention (skills/objectstack-data/evals/README.md) lists the two fixtures' topic clusters and binds no taught key to a case; the card asked for one only if the convention asks. The seat may add one if it reads the convention wider.

Readings (os-dev rule for skills/**):

Reading Before (origin/main 8b9cc712) After (62fd849b)
skills/objectstack-data/references/examples-objects.md lines 195 191
skills/objectstack-data/references/examples-objects.md bytes / tokens (check-skills-token-ratchet, ceil(bytes/4)) 6964 / 1741 (ceiling 1756, headroom 15) 6945 / 1737 (ceiling 1737, headroom 0)
Package, all 11 skills/*/SKILL.md, lines 4525 4525
Package, all 11 skills/*/SKILL.md, tokens (gate formula) 56670 56670

Why

#30812, the Skills-docs: follow-up PR #30810 declared (card #30692, ruling 6670372892 row 4 A). The key exists on main since that merge; until the skill names it, an agent reading the Field Groups section learns only icon, description and collapse, and either leaves a feature-bound section visible everywhere or reaches for a page layout to hide it.

Tests

No runtime code changes. Every word of the new bullet was read off main at a2f523aa (unchanged at 8b9cc712): ObjectFieldGroupSchema's visibleWhen / requiresFeature docblocks and .describe() texts, lowerRequiresFeature ('visibleWhen' slot: gate alone when no predicate is authored, (AUTHORED) && GATE otherwise), z.enum(PUBLIC_AUTH_FEATURE_NAMES) (unknown flag refused), and sys_organization.object.ts line 352 (the group_structure entry quoted verbatim). The pins behind them are packages/spec/src/data/field-group-requires-feature.test.ts and packages/platform-objects/src/identity/sys-organization-group-structure-gate.test.ts, unchanged here.

pnpm --filter @objectstack/spec check:skill-examples (the three os:check blocks of this file among the 283 marked blocks) against freshly built @objectstack/spec, @objectstack/client and @objectstack/client-react declarations: ✅ 283 prose examples type-check across 3 surface(s), exit 0 — at 36152cd8 and again at the head 62fd849b.

Acceptance notes

Verification

Derived with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack against the three-file diff (no paths passed; the tool reads the change set off the merge base). Every line run with stdin closed, exit code landed to disk before any pipe (COMMAND :: exit CODE):

  • At 36152cd8 (before any origin/main merge; spec, client, client-react and lint built): 62 derived families, 62 run, 61 exit 0, 1 exit 3 (pnpm check:dual-build-cjs-loads, PREREQUISITE NOT MET: 31 packages had no dist/); --ran: 62 derived, 61 run, 1 NOT-MEASURED (derived from the recorded exit 3), 0 UNRUN.
  • At c5cc868a (after merging origin/main 18870c92 and a declarations build of every ./packages/**): the same 62 families, 62 run, 62 exit 0; --ran: 62 derived, 62 run, 0 NOT-MEASURED, 0 UNRUN.
  • At 62fd849b (the head: origin/main 8b9cc712 merged, the ratchet row re-locked at 1737): the same 62 families, 62 run, 62 exit 0; --ran: 62 derived, 62 run, 0 NOT-MEASURED, 0 UNRUN. Ran lists: skills-seat-2/out/30812-gates-ran-{36152cd8,c5cc868a,62fd849b}.list in the project files.
Gate readings at 62fd849
  • check-skills-token-ratchet: skills/objectstack-data/references/examples-objects.md is 1737 tokens (ceiling 1737; headroom 0), exit 0; --self-test: 97 cases pass, exit 0.
  • check:skill-identifier-liveness: Leg 1: 486 citation(s) over 71 published file(s) … Leg 2: 8 registered exhaustive section(s), 0 ledgered gap(s), exit 0.
  • check:dual-build-cjs-loads: 116 published require entry point(s) across 71 package(s) load; 2456 emitted CommonJS file(s) parse, exit 0 (declarations build of ./packages/**; exit 3 without it).
  • check-empty-changeset --base origin/main: 1 declaring changeset(s) added, no merge-base changeset modified, exit 0. check-adr-0087-registration --base origin/main: no declared-breaking changeset, exit 0. check-changeset-no-major --base origin/main: exit 0.
  • check:doc-authoring: 21232 customer-facing string(s) across 1711 spec sources clean, exit 0.
  • pnpm --filter @objectstack/spec run check:skill-refs, check:skill-compatibility, check:skill-frame-sync, check:pm-skill-id-lint, check:pm-governed-merges, check:lean-entry-closure, check:nul-bytes, check:role-word, check-comment-mask-corpus, check:pm-dispatch-gates and the rest of the 62: exit 0.

Tier: dispatch-gates --tier on the three paths: skills/** clause ①, claude-fable-5-1 mandated, no one-line exit; this thread runs on it. check-governed-merges --test on the three paths: Tier H (skills/objectstack-data/references/examples-objects.md).

CI families (Lint & Repo Gates, Test Core, the rest) are the PR's check-runs, not re-run locally. Dogfood battery: n/a (no ! in the title, no narrowing arm).

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 is CI's run (no source file in the diff).
  • 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 not touched.
  • 7. No hand edits to content/docs/references/, packages/*/CHANGELOG.md or content/docs/releases/.
  • 8. Title, body and comments are in English.
  • The Before Submitting list in CONTRIBUTING.md is done.

🤖 Generated with Claude Code

https://claude.ai/code/session_01L9qibxLYNwSMSVQkj55gA6

… visibleWhen and requiresFeature

examples-objects.md names the two ways a whole field group is hidden:
visibleWhen (CEL over the record; FALSE or a fault hides the group, header
included) and requiresFeature (a PUBLIC_AUTH_FEATURES flag, refused when
unknown, lowered at parse into the group's visibleWhen and stripped,
AND-composed after an authored predicate), with sys_organization's Group
Structure section as the example. Paid by deleting restatement in the same
file; the token ratchet row re-locks at the landed count (1756 -> 1751).

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L9qibxLYNwSMSVQkj55gA6
…anded count (1737)

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L9qibxLYNwSMSVQkj55gA6
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface labels Nov 6, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#2 · os-tesla · session_01L9qibz5RLVEYDFco93jZ7u

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 62fd849b787c6a483cba47e8964a7a1e203d7480
Local-runs: none
Scope: skills/objectstack-data/references/examples-objects.md + scripts/check-skills-token-ratchet.mjs (the ceiling row the hunks move; a rule and its gate read as one), packages/spec/src/data/object.zod.ts (ObjectFieldGroupSchema), packages/spec/src/kernel/public-auth-features.ts (lowerRequiresFeature, featureGatePredicate, PUBLIC_AUTH_FEATURE_NAMES), packages/platform-objects/src/identity/sys-organization.object.ts (fieldGroups, group_structure), packages/spec/src/shared/protection.zod.ts (ProtectionSchema), skills/objectstack-data/SKILL.md, skills/objectstack-data/evals/README.md. The changeset is the lane seat's ACCEPT at TIER_DEFAULT.

Inputs read: card #30812 (body, triage 6677319850, claim 6679873660, os-dev-report 6681485641), PR #30890 (body, 3-file list, compare/main...62fd849b), the head's check-runs. Card open_questions: [].

① Derived judgments

  • Public schema surface: none changed. The diff touches no *.zod.ts, no api-surface/, no liveness/; fieldGroups[].visibleWhen and fieldGroups[].requiresFeature already exist on main (PR feat(spec): a field group's requiresFeature hides the group where a deployment feature is off; Edit organization hides Parent Organization and Sort Order on one organization #30810, merged 677d542a). Right.
  • Accept-set: none changed. No lint rule, no gate predicate, no refusal text moves. Right.
  • Governed register (skills/**): the data skill's Field Groups section gains one bullet naming the two group-hiding keys and loses seven restatements; the Quick-Start and Metadata Protection sections each lose one line of restatement. Tier H applies (governed approver, queue guard whole-PR). Right.
  • Token ratchet: examples-objects.md row 1756 → 1737. Measured at the head: 6945 bytes, ceil(6945/4) = 1737, headroom 0 — the row equals the measurement. On main the file is 6964 bytes = 1741 against an unlocked 1756 (the docs(skills): teach one naming rule, every package-authored metadata name starts with its namespace #30831 headroom the PR body names). A lowering is the one move the gate's shrink-only contract permits ("A ceiling may be LOWERED by any PR that shrinks its file"). Right. Caveat for the merger, not a defect: zero headroom means any further byte landed in this file on main before merge forces one more re-lock.
  • check:skill-examples: the three os:check blocks in the file are unchanged in code; only a path comment and an inline comment tail were removed, neither type-bearing. Right.
  • Check-runs on 62fd849b at read time: 21 success (incl. Check Changeset, Governed Surface Queue Guard, PR-body guards, Type Check · workspace/source/consumer/debt, Lint · ESLint, Lint · docs & code guards, Lint · PM dispatch-gates, Lint · scoped · tooling self-tests, Lint · scoped · query-options erasure, Test Core 3/8, Test UI, Dogfood Regression Gate, Live E2E UI), 14 skipped (UI/docs/opt-in families on a non-UI diff), 6 in_progress (Build Core, Test Core 1/8, Test Core 2/8, Lint · repo & tooling gates, Lint · scoped · slot lookup & corpus, Lint · CI, release & engine gates), 0 failure. The ratchet family is among the in_progress ones; its arithmetic is reproduced above by the gate's own documented convention. This record's verdict is a design verdict; the seat's ACCEPT waits for those six to conclude.

② Semver level

  • .changeset/30812-field-group-visible-when-requires-feature.md: '@objectstack/skills': patch. @objectstack/skills is a real workspace package (packages/skills/package.json), the skill catalog ships in it, and patch is the precedent for a docs-only skill text change (PR docs(skills): teach one naming rule, every package-authored metadata name starts with its namespace #30831's changeset, same package, same level). No other package changes. Matches.
  • Clause-②: no on the PR body and in the changeset, both present and identical; Metadata-protocol: none, correct — no metadata record is touched. Not a narrowing (no (narrowing) arm), so the face is the rules face by path alone: CONTRACT_REVIEW_TIER is owed and served.

③ Boundary flags

  1. No eval case (dev flag; the card said "if the skill's eval convention asks for it"; the dispatch allowed at most one). Judged against the tree, not the dev's account: skills/objectstack-data/evals/README.md is a two-item fixture listing with topic clusters ("naming, field types, relationships, validation, conditional field rules" / "hooks, permission-set scopes, datasources, seeds") and states no rule binding a taught key to a case. The only "Contributing" rule in the catalog is in skills/objectstack-ui/evals/README.md ("Each eval should test a single, specific rule from SKILL.md"), which governs how a case is written, not which keys must have one. The CI step "Skill Eval Token Check — Check every eval must_contain token against the guides" runs in the eval → guide direction (a must_contain token must appear in a guide), never guide → eval; there is no coverage gate. The existing fixture's case 4 covers field-level visibleWhen under "conditional field rules"; field groups fall in no listed cluster. The dev's reading holds: no case is owed by the convention, so none is owed by the card. Not escalated. A seat that still wants one may add it under the dispatch's "at most one" allowance; its must_contain tokens (requiresFeature, visibleWhen, fieldGroups) now all appear in the guides, so the token check would pass.
  2. Overlap with docs(skills): teach one naming rule, every package-authored metadata name starts with its namespace #30831 (acceptance note). docs(skills): teach one naming rule, every package-authored metadata name starts with its namespace #30831 merged as 0e73de82; its hunk is the Lifecycle Hooks block, this PR's hunks are Field Groups, one Quick-Start comment, two Metadata Protection lines. The compare shows a clean 3-file net diff with no conflict residue. Answered.
  3. Title line "(moved verbatim from SKILL.md)" left as is (out-of-scope finding, carrier none). Four reference files share the convention; a catalog decision, correctly not taken here. Answered; not this card's.
  4. check:dual-build-cjs-loads / check:skill-examples prerequisite (exit 3 without a full declarations build). Tooling observation about the local gate harness, no change requested in this diff; the CI families carry those conclusions. Answered.
  5. Deletions as payment (seven items). Each judged under ④ below; none removes a teaching with no other home.

④ Design judgment

skills/objectstack-data/references/examples-objects.md, judged against the scenario the card accepts it against (an agent writing an object learns a group can be hidden by a predicate or by a deployment feature) and the spec it teaches on main:

Every clause of the new bullet read against the cited code:

  • "Hide a whole group, header included, with visibleWhen (CEL over record.*; FALSE or a fault hides it)" — ObjectFieldGroupSchema.visibleWhen docblock: "FALSE (or a faulting predicate — fail-closed) hides the WHOLE group, header included; TRUE (or absent) shows it". Holds. The record.* framing is right for an author: the lint (withoutLoweredFeatureGate, feat(spec): a field group's requiresFeature hides the group where a deployment feature is off; Edit organization hides Parent Organization and Sort Order on one organization #30810) keeps the root verdict on any hand-written features read in a group predicate and points at requiresFeature, so requiresFeature is the author's only route to a feature gate.
  • "requiresFeature (a deployment feature flag from PUBLIC_AUTH_FEATURES; an unknown flag is refused)" — z.enum(PUBLIC_AUTH_FEATURE_NAMES). Holds.
  • "At parse requiresFeature is lowered into the group's visibleWhen and stripped, AND-combined after an authored visibleWhen" — the schema's .transform calls lowerRequiresFeature(group, ctx, 'visibleWhen'); the helper writes (${existing.source}) && ${gate}, author first, gate last, and the key never reaches the output. Holds.
  • "Presentation only: the fields stay readable through the API" — the key's .describe() text verbatim. Holds.
  • The example { key: 'group_structure', label: 'Group Structure', requiresFeature: 'multiOrgEnabled' } is sys-organization.object.ts line 353 verbatim; parent_organization_id and sort_order carry group: 'group_structure' (lines 508, 516) and are labelled Parent Organization and Sort Order. Holds.

Attempts to break it:

  • An author writes visibleWhen: false beside requiresFeature, or an AST-only predicate: refused at parse with the slot named. The skill omits these refusals by design (PR body "Not taught, on purpose"); the schema's own refusal text carries them, and the skill's job is the two keys and the one behaviour. Acceptable.
  • The console's empty-features window hides a default-on group until /auth/config resolves: a renderer timing fact, not an authoring decision; omitting it is correct for this file.
  • The bullet names no visibleWhen spelling for a group. The file's other predicates (SKILL.md line 189, P\record.status == 'paid'`) establish the form, and EvaluatedExpressionInputSchemaaccepts both string and envelope; the card asked for one short example and therequiresFeature` one is the real consumer. Acceptable.

Deletions, each checked for another home:

  • Intro sentence, "labels are human-readable", migrations paragraph, path comment: pure restatement of the heading, the example, bullets 1–2, and nothing respectively. Fine.
  • "replaces the deprecated defaultExpanded flag, ADR-0085": the schema still accepts defaultExpanded / collapsible / collapsed as parse-time aliases with [DEPRECATED → collapse] in each .describe(), so the redirection lives on the key itself. Fine.
  • "— see above" on the Quick-Start sharingModel comment: nothing above in this file explains sharingModel; the explanation is SKILL.md line 65. The pointer was dangling; // required in practice stays. Fine.
  • "The block is .strict(): reason is required (min 1 / max 500 chars) and unknown keys are rejected": ProtectionSchema is a strictObject with reason: z.string().min(1).max(500) — the sentence was true. Its content survives: the typed block two lines above enumerates the three keys and marks reason REQUIRED (1–500 chars), and strictObject's own refusal names the accepted keys ("are lock, reason and docsUrl"). Fine.

Should-fix (does not fail):

  • The bullet names PUBLIC_AUTH_FEATURES as the flag vocabulary without saying where it lives. The schema docblock says @objectstack/spec/kernel; the skill reader has only the bare symbol and has to grep for it before they can pick a legal flag. Naming the module (or the one flag an author is likeliest to want, which the example already does) closes that. At zero headroom it costs a deletion elsewhere; the "Groups render identically on forms, modals, and detail pages; for a bespoke single-page layout assign a custom Page instead" tail of the collapse bullet is the obvious payer, being a layout aside in a Field Groups section.

Must-fix: none.

scripts/check-skills-token-ratchet.mjs (read as the gate the rule is enforced by): the row moves 1756 → 1737 with the required comment naming both cuts; the value is the head measurement; the direction is the permitted one. No finding.

Implemented-by: claude/project-thread-vea7es
Reviewed-by: session_01L9qibz5RLVEYDFco93jZ7u

VERDICT: PASS

…Field Groups bullet

Contract review should-fix: the flag vocabulary is named with its module
(@objectstack/spec/kernel) so a skill reader has more than a bare symbol
to find. Paid in the same file by dropping the custom-Page aside, whose
rule lives in the ui skill; the token row re-locks down at 1728.

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

Copy link
Copy Markdown
Contributor Author

domain:skills#2 · os-tesla · session_01L9qibz5RLVEYDFco93jZ7u

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 2e81ba6a138a69860097d3f1775187119a2ba08b
Local-runs: none
Scope: skills/objectstack-data/references/examples-objects.md + scripts/check-skills-token-ratchet.mjs (the ceiling row the hunk moves), packages/spec/src/kernel/index.ts and packages/spec/package.json (the @objectstack/spec/kernel export the new pointer names), skills/objectstack-ui/SKILL.md (the home the dev names for the cut aside), skills/objectstack-data/SKILL.md (the boundary table). The changeset is unchanged and stays the lane seat's ACCEPT at TIER_DEFAULT.

Delta review: one commit (2e81ba6a) on the reviewed head 62fd849b, two files, addressing the one should-fix of the earlier record on 62fd849b. Only what moved is judged here; every finding of the earlier record that this commit does not touch stands as written there.

① Derived judgments

  • Public schema surface and accept-set: untouched by the delta. Right.
  • Governed register (skills/**): the Field Groups bullet gains the four words "in @objectstack/spec/kernel" and is reflowed with the same words otherwise (verified against the hunk: no other word of the bullet changes); the collapse bullet loses "; for a bespoke single-page layout assign a custom Page instead". Right.
  • Token ratchet: examples-objects.md row 1737 → 1728. Measured at the head: 6912 bytes, ceil(6912/4) = 1728 exactly, headroom 0; the row comment names the payer. A lowering, the permitted direction. Right.
  • Check-runs on 2e81ba6a at read time (fresh push): 3 success (PR-body guards, Governed Surface Queue Guard, Check PR Size), 3 skipped (opt-in and schedule families), 14 in_progress (the four Type Check families, the eight Lint families including repo & tooling gates, Check Changeset, Auto Label), 0 failure. The ratchet arithmetic is reproduced above by the gate's own convention. This record's verdict is a design verdict; the seat's ACCEPT waits for the in_progress families to conclude.

② Semver level

Unchanged by the delta: .changeset/30812-field-group-visible-when-requires-feature.md is not in the commit; '@objectstack/skills': patch, Clause-②: no on body and changeset, Metadata-protocol: none. The delta publishes nothing new. Still matches.

③ Boundary flags

  1. Dev claim: the cut half has a home in skills/objectstack-ui/SKILL.md L62, L88, L190. Read on main: L61–62 "you almost never need a custom page or form config. Prefer, in order:"; L88 "object-master-detail-form page block (bespoke layout). Use a page only for free-form layouts."; L190 (Record pages row) "The object's declarations produce the page … src/pages/*.page.ts only to override a slotted slot or for a kind: 'full' layout". The rule the aside stated (a bespoke layout is a Page, not a field-group arrangement) is taught there, three times, in the skill that owns pages; the data skill's boundary table (SKILL.md L31) hands "Build views, dashboards, or apps" to objectstack-ui, so a reader of the data skill is routed to that home. Holds. The earlier record named this very tail as the payer.
  2. No new dev flags, no open_questions. Earlier flags unchanged and already answered.

④ Design judgment

skills/objectstack-data/references/examples-objects.md, the two moved sentences only:

  • "a deployment feature flag from PUBLIC_AUTH_FEATURES in @objectstack/spec/kernel" — packages/spec/src/kernel/index.ts L156 export * from './public-auth-features', and packages/spec/package.json declares the ./kernel subpath export (browser and node conditions, types included). The pointer names the module an author can import or read the vocabulary from; it is the same path the schema's own requiresFeature docblock gives. Holds; the should-fix is closed.
  • "Groups render identically on forms, modals, and detail pages." — the retained half is a Field Groups fact (the group renders the same on every surface, deriveFieldGroupLayout single-sources it); the removed half was a cross-domain pointer whose rule lives in the ui skill (③.1). Nothing a data-skill reader needs to author a group is lost. Holds.
  • Reflow: line breaks moved; sys_organization example line unchanged and still verbatim from main.

scripts/check-skills-token-ratchet.mjs: row 1737 → 1728 equals the head measurement; the comment names the two cuts and the review payment. No finding.

Must-fix: none. Should-fix: none.

Implemented-by: claude/project-thread-vea7es
Reviewed-by: session_01L9qibz5RLVEYDFco93jZ7u

VERDICT: PASS

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#2 · os-tesla · session_01L9qibz5RLVEYDFco93jZ7u

维护者速读

  • 改了什么:数据技能参考页 examples-objects.md 的「Field Groups (MVP)」一节加一条:字段分组可以用 visibleWhen(分组级谓词)隐藏,也可以用 requiresFeature(取自 @objectstack/spec/kernel 的 PUBLIC_AUTH_FEATURES)按部署特性隐藏;后者在解析时并入 visibleWhen 并从输出里去掉,未知的特性名会被拒绝,和手写的 visibleWhen 以 (手写) && 特性 合并。附 sys_organization 的例子(单组织部署下隐藏上级组织和排序)。
  • 为什么改:PR feat(spec): a field group's requiresFeature hides the group where a deployment feature is off; Edit organization hides Parent Organization and Sort Order on one organization #30810 已上线分组的 requiresFeature,技能只列 icon、description、collapse,AI 写对象时不知道分组能按谓词或特性隐藏,会去改页面或干脆不做。
  • 风险与回滚:只改技能参考文字和 changeset,不碰运行时,不加评测题(数据技能的评测约定没有要求每个键对应一题,复审认可)。篇幅靠同文件七处删除换来,每处在别处有家;token 上限 1756 下调到实测 1728,没有上调。回滚即 revert。
  • 先看:skills/objectstack-data/references/examples-objects.md 的「Field Groups (MVP)」新增条目。
  • 两分钟验证:git grep -n "requiresFeature" skills/objectstack-data/references/examples-objects.md,对照 packages/spec/src/data/object.zod.ts 的 ObjectFieldGroupSchema 和 packages/spec/src/kernel/public-auth-features.ts 的 lowerRequiresFeature。
  • 需要你做的:改的是 skills/**,属于 Tier H,需要 os-zhuang(或 hotlong)批准后才能合并。契约复审 PASS 6681646542,补改后增量复审 PASS 6681761762。

席位意见:契约复审 PASS,一条建议修改(写明 PUBLIC_AUTH_FEATURES 所在模块)已补上,增量复审无发现。可以批准。

席位核对

ACCEPT · seat domain:skills#2 · head 2e81ba6a · 2026-11-06T09:53Z

  1. Shape: Fixes #30812, draft, base main, 3 files (skills/objectstack-data/references/examples-objects.md, scripts/check-skills-token-ratchet.mjs one row 1756 → 1728, .changeset/30812-field-group-visible-when-requires-feature.md '@objectstack/skills': patch), no eval case.
  2. Ruling: filing gate ① on skills(objectstack-data): teach a field group's visibleWhen and requiresFeature in examples-objects.md #30812, the Skills-docs: follow-up PR feat(spec): a field group's requiresFeature hides the group where a deployment feature is off; Edit organization hides Parent Organization and Sort Order on one organization #30810 (card Edit organization: hide Parent Organization and Sort Order on a single-organization deployment with a field-group requiresFeature #30692, ruling 6670372892 row 4 A) named as owed; triage 6677319850; Claim 6679873660. Ceiling moved down only.
  3. Contract review: PASS 6681646542 at 62fd849b (no must-fix, one should-fix: name the module of PUBLIC_AUTH_FEATURES). Delta PASS 6681761762 at 2e81ba6a (same reviewer, no findings): the bullet now names @objectstack/spec/kernel (packages/spec/src/kernel/index.ts exports ./public-auth-features; ./kernel is a declared subpath export), paid by cutting the collapse bullet's custom-Page aside, whose rule skills/objectstack-ui/SKILL.md carries (L61–62, L88, L190). Clause-②: no, Metadata-protocol: none.
  4. Corrected facts (PR body not patched): the body reads head 62fd849b and ceiling 1737; on this head the file is 6912 bytes, 1728 tokens, and the ratchet row is re-locked at 1728, headroom 0.
  5. Gates / check-runs: dev reports 62/62 derived families exit 0 at 62fd849b, --ran clean (report 6681485641); at 2e81ba6a the ratchet (+ --self-test), skill-refs, identifier-liveness, compatibility, frame-sync, doc-authoring, ratchet-remedy-authority, nul-bytes and skill-examples (283 blocks) families exit 0 (list skills-seat-2/out/30812-gates-ran-2e81ba6a-fix.list). On head 2e81ba6a: 42 check-runs, 29 success, 13 skipped, 0 failed; mergeable_state clean.
  6. Accepted deviations: no eval case. The reviewer judged the dev's reading under ③: the objectstack-data evals README binds no taught key to a case, and the eval token check runs eval → guide only. Overlap with PR docs(skills): teach one naming rule, every package-authored metadata name starts with its namespace #30831 (merged) in the same file: the dev merged main with no conflict and the hunks stay apart.
  7. Landing: GOVERNED, Tier H (skills/**). The seat readies the PR and the relay's governed-review leg requests the approvers; no auto-merge is armed by the seat.

This branch has not been deployed

No deployments
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 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.

skills(objectstack-data): teach a field group's visibleWhen and requiresFeature in examples-objects.md

1 participant