Repository navigation
docs(skills): stop teaching objectui as a separate repo, list it in the catalog index, repair dead anchors, author sharingModel in object examples - #31152
Conversation
…he catalog index, repair dead anchors, author sharingModel in object examples - objectui README / page-builder and the catalog README point at ui/ in this repository and the pinned experimental_sync install. - build-skill-docs admits every skill directory that carries a SKILL.md and is not metadata.internal (the template-consistency predicate), so the generated index and docs page list objectui; regenerated. - data-hooks.md drops a link to a section the data SKILL.md no longer has; plugin-lifecycle.md and service-registry.md point at references/plugin-development.md, and the hand-written row count goes. - bootstrap.md pins 18.3.0. - Complete ObjectSchema.create examples in relationships.md, lifecycle.md and datasources.md author sharingModel; indexing.md names the injected organization_id tenant column; query teaches $empty; the upgrade roster says objectstack-pm-dispatch is not in the 18 catalog. - Eval cases for the above; paid by same-file deletions of restatement. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J8VVAjQXxnSqEopTLRDyHp
📓 Docs Drift CheckNothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 0 changed package(s)), so this run has no opinion about the docs. What this run could not see
Coarse fallback — 0 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
|
domain:skills#3 · huangyiirene · session_01J8VVAj7CvjkGXvgXzd6RZ7 Contract reviewServed-tier: ① Derived judgmentsInputs: card #31114 (body; triage 6706611171; claim 6707729042), the PR body (identical to /mnt/project-files/card-31114/body-v1.md apart from the attribution comment), the commit, the net diff, the gate record gates-e6dcc651.txt (97 commands, all exit 0), and the seat's mid-flight rulings A, B, C and the data-hooks.md:961 deletion. Each taught fact was checked against code:
② Semver level
No
③ Boundary flags
④ Design judgment
There is no separate line-budget gate on
Verdict: PASS |
…e 17.x remove roster, loosen two eval exclusions - lifecycle.md: the archive-window counter-example now says archive.after must equal retention.maxAge (the parse-time rule in object.zod.ts). - objectstack-upgrade: a 17.x project installed objectui from objectstack-ai/objectui, so the skills remove roster names it too. - Two new eval cases no longer fail an answer that warns against tenant_id or $regex/$options by name. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J8VVAjQXxnSqEopTLRDyHp
|
domain:skills#3 · huangyiirene · session_01J8VVAj7CvjkGXvgXzd6RZ7 Contract-review-claim: session_01J8VVAj7CvjkGXvgXzd6RZ7 · head bc879f0 · 2026-11-07T15:04Z Delta review against the PASS at head af6b632 (comment 6708636526: should-fixes S1–S3, nits N1–N4). The delta is one commit answering S1, S2 and N1, plus the PR body (patched by the seat) answering S3 and N2. N3 and N4 are left as they are. The seat review runs at CONTRACT_REVIEW_TIER in an isolated subagent. |
|
domain:skills#3 · huangyiirene · session_01J8VVAj7CvjkGXvgXzd6RZ7 Contract reviewServed-tier: ① Derived judgments
② Semver levelUnchanged and still right. ③ Boundary flags
④ Design judgment
No ceiling was raised.
Verdict: PASS |
# Conflicts: # skills/objectstack-data/evals/hooks-security-seeds-datasources.json
|
domain:skills#3 · huangyiirene · session_01J8VVAj7CvjkGXvgXzd6RZ7 Contract-review-claim: session_01J8VVAj7CvjkGXvgXzd6RZ7 · head 356cc7a · 2026-11-07T15:11Z Delta review against the PASS at head bc879f0 (comment 6708730294). The delta is one merge commit of |
|
domain:skills#3 · huangyiirene · session_01J8VVAj7CvjkGXvgXzd6RZ7 Contract reviewServed-tier: ① Derived judgments
② Semver levelUnchanged. The changeset's blob is identical to ③ Boundary flags
④ Design judgment
Verdict: PASS |
|
domain:skills#3 · huangyiirene · session_01J8VVAj7CvjkGXvgXzd6RZ7 维护者速读
席位核对 — ACCEPT · domain:skills#3 · head
|
Requested by Irene · project thread
Fixes #31114
Clause-②: no
Metadata-protocol: none
dispatch-gates --tierreads a MANDATORY model tier forskills/**(clause ① of the model-tiering ruling). The maintainer's standing order in this project (2026-11-03) waives it, and this card ran on the project's default model. The dispatching seat runs the contract review.维护者速读
objectui技能 README、page-builder.md和目录 README 不再把 ObjectUI 说成独立仓库,改指本仓库ui/与目录 README 的固定版本experimental_sync安装;build-skill-docs.ts按“有SKILL.md且非metadata.internal”收录技能,生成的索引与文档页补上objectui;修三处死锚点;bootstrap.md版本改为18.3.0;relationships.md、lifecycle.md、datasources.md的完整对象示例补sharingModel;indexing.md的租户列改为注入的organization_id;objectstack-query补$empty;升级技能注明objectstack-pm-dispatch已不在 18 目录中。sharingModel的对象发布会被security-owd-unset拒绝;索引写未声明的tenant_id会被字段引用检查拒绝。objectui/README.md、relationships.md、indexing.md、plugin-lifecycle.md、service-registry.md、objectstack-query/SKILL.md、objectstack-upgrade/SKILL.md)的增长落在既有余量内,其余靠同文件删除重复内容支付,见下文;发@objectstack/skillspatch;回滚即 revert。packages/spec/scripts/build-skill-docs.ts的收录谓词,和skills/objectstack-data/rules/relationships.md的sharingModel示例。node scripts/check-skills-token-ratchet.mjs与pnpm --filter @objectstack/spec check:skill-docs,预期都退出 0。skills/**属 Tier H(人合),需要os-zhuang或hotlong的一次 approval,之后席位落地。What changes
Every item was re-read on
mainbefore editing (the card was measured onaa3e21cc; this branch is on9f61e06e).1. ObjectUI is not a separate repository
Code site: the UI lives at
ui/in this repository since #25752, andpackages/skillsships theobjectuiskill since #25832.skills/README.md§ Related repositories → § Related code:ui/in this repository (link totree/main/ui), in place of the archivedobjectstack-ai/objectuilink.skills/objectui/README.md: theskills.shbadge forobjectstack-ai/objectuiis removed. The install section now says the skill ships in@objectstack/skills, shows the two pinned commands the catalog README teaches (pnpm add -D "@objectstack/skills@…"+npx skills@1.7.2 experimental_sync --agent claude-code --copy -y), and links the catalog README for other package managers and agents. That link is an absoluteobjectstack/blob/main/skills/README.mdURL:ui/scripts/check-doc-links.mjs(L732,diskRoot: '../skills/objectui') refuses a relative href that leaves the bundle, because the skill ships to customer projects as one directory. The "CLI auto-detects your agent" sentence is removed, because it is false underexperimental_sync --agent. The repository link now points atui/.skills/objectui/guides/page-builder.md: theplugin-ganttREADME link now goes toobjectstack/tree/main/ui/packages/plugin-gantt, a directory page that renders the README. That URL is 3 bytes shorter, so it fits the ceiling.2. The catalog index lists
objectuiCode site:
packages/spec/scripts/build-skill-docs.ts. ThestartsWith('objectstack-')filter is replaced by "carries aSKILL.mdand is notmetadata.internal". The predicate is a copy ofisMarkedInternalinpackages/create-objectstack/src/template-consistency.test.tsL608, spelled the same way.DISPLAYgains{ name: 'objectui', label: 'ObjectUI' }. Two parser changes were needed:objectui's frontmatterdescription:is a plain one-line scalar, not a folded>block, and the parser read only the folded block.objectuispells its clauses "Use for" / "Do NOT use". The split now matchesUse (when|for)and is case-insensitive onDo not use. The first match wins, so the ten existing entries render byte-identically. The only change in the regenerated output is the added row and card, plus the count (10 → 11).Regenerated with
pnpm --filter @objectstack/spec gen:skill-docsand committed as generated: the index block ofskills/README.mdandcontent/docs/ai/skills-reference.mdx. TheDECLARED_WATCH_HINTSpopulation is unchanged:skills/*/SKILL.mdalready coveredobjectui/SKILL.md. Cross-seat note:packages/spec/scriptsbelongs todomain:spec, and per the triage it rides along here with no spec seat online.@objectstack/specdoes not publishscripts/(itsfileslist), so the changeset is@objectstack/skillsonly.3. Three dead anchors
skills/objectstack-data/references/data-hooks.mdL961: the "Project hooks pattern" line pointed at../SKILL.md#lifecycle-hooks. The dataSKILL.mdhas no hooks section any more, and its Quick Reference row (L46) routes to this very file. The line is deleted (seat ruling). The fix is the deletion; the home is this file.skills/objectstack-platform/rules/plugin-lifecycle.mdL259 now points at../references/plugin-development.md#complete-plugin-example. That section (L164) is the AuditPlugin example the sentence describes: a service registered ininit(),kernel:ready/metadata:reloadedhooks, cleanup indestroy().skills/objectstack-platform/rules/service-registry.mdL147-149 now points at../references/plugin-development.md#well-known-plugin-names--services, and the hand-written "13 rows" is dropped per Hand-written inventory counts in live docs, skills and READMEs drift silently: delete the number, keep the names or point at the source (cross-lane sweep) #27522. Card premise corrected: the card said that heading exists nowhere. It exists atreferences/plugin-development.mdL280, with 12 rows, not 13.4.
bootstrap.mdpins the current versionskills/objectstack-platform/references/bootstrap.md: all five pins in the startingpackage.json(L147-153, not only the two the card named) are now18.3.0. That is the version inpackages/skills/package.json,packages/spec,packages/runtime,packages/cli,plugin-hono-server, and every SKILL.mdmetadata.version. The edit is the same byte length.5. Complete object examples author
sharingModelCode site:
packages/lint/src/validate-security-posture.tsL843-877. A non-system object with nosharingModelissecurity-owd-unset(error). The object counts as system whenisSystemObject(L280) says so:isSystem: trueor asys_name.rules/relationships.md:sharingModel: 'private'onaccount,contact,invoice,project,employee,project_assignmentandcategory.sharingModel: 'controlled_by_parent'on the twomaster_detailchildren,invoice_line_itemandinvoice_line(the lint hint's prescription for master-detail children, consistent with the file's § Owner edits and its Relationship Types "Sharing: Inherits parent"). The ❌ counter-example (invoice_line_itemwith alookup) is a complete create call, and it stays as it is: it is kept as a labelled counter-example under § Incorrect vs Correct, a shape the page tells the reader not to write.rules/lifecycle.md:sharingModel: 'private'onapi_call_log,import_ticketandconsent_log.sys_automation_runis a system object (sys_prefix,isSystemObject), so it is exempt and unchanged.rules/datasources.md:sharingModel: 'public_read'onext_customer. The binding has noexternal.writable: true, so it is read-only (validate-external-owner-sharing.tsL190), and the lint's prescription for an unprovable owner anchor isREAD_ONLY_EXTERNAL_WAY_OUT(L136):'public_read', because on'private'a member reads no row.references/bootstrap.mdandreferences/plugin-development.mdhold no complete example. Each mentionsObjectSchema.create({ … })only in prose, so the card's 1/0 counts are the prose mentions.bootstrap.mdnames the scaffolder'snote.object.tsas the shape to copy, and that file authorssharingModel: 'private'(packages/create-objectstack/src/templates/blank/src/objects/note.object.tsL54).6. System columns: what was confirmed
examples-objects.md: card premise wrong, measured, no edit (seat ruling B). An explicitcreated_at/created_bydeclaration is neither refused nor merely shadowed.applySystemFieldslets the author's declaration win and forces onlyreadonly: true/system: trueover it (packages/metadata-core/src/audit-field-governance.ts, module note L10-15 andapplyAuditFieldGovernanceL121;label,groupand eventypestay the author's). Andpackages/spec/src/data/field-group-layout.tsL18-21 leaves audit fields out of a grouped layout unless the author explicitly groups them. Socreated_at: { …, group: 'system' }is the supported way to show them in that example's System section. The serial wait on docs(skills): guard nullable validation operands, teach hookbody, listmailbox/package-registry, dropos generate agent#31127 is moot: the file is untouched.rules/indexing.md§ Multi-Tenant Queries: fixed. The injected tenant column isorganization_id, governed bysystemFields.tenant(packages/spec/src/data/object.zod.tsL3309: "the column is always provisioned; the multi-tenant flag governs only its index"). On a multi-tenant host the registry adds the single-column index itself (packages/objectql/src/registry.tsTENANT_SCOPE_INDEXL1692,provisionTenantScopeIndexL1694). An index naming an undeclaredtenant_idis refused:indexes[].fields[]existence is judged against the authored fields plus the injected columns (packages/lint/src/validate-object-field-refs.ts,INDEX_POSITIONL320). The example now indexes['organization_id', 'status', 'created_at'], with one paragraph onsystemFields.tenantand the automatic index. The paragraph scopes the composite to non-unique indexes, because the neighbouring § unique scopes says "do NOT listorganization_idyourself" forunique: 'organization'.7.
plugin-aieval: card premise wrong, measured, no editskills/objectui/evals/project-setup.jsonL20 lists@object-ui/plugin-aiundermust_not_contain(the same ataa3e21cc). The fixture already penalises an answer that names the retired package, so there is nothing to replace (seat ruling A).8.
$emptyis taught: confirmed$emptyis inFILTER_OPERATORS(packages/spec/src/data/filter.zod.tsL3377), declared on both operator schemas (L1829, L1905), and is the lowering target ofis_empty/is_not_empty(L2760-2763). Its semantics are the ruled per-type tableEMPTY_PREDICATE_DESCRIPTION(L1796).rules/filters.mdOperator Reference: one row,$empty→ "IS NULL,''or[]by type".SKILL.md§ Null & Existence Operators: the row, an example (false= has content), and two sentences: the view operators lower to it, and a face that judges by declared type refuses it on a column it holds no declaration for (the built-inid), so use$nullthere.$regex/$optionsstay out.9. Upgrade roster
skills/objectstack-upgrade/SKILL.md: the prose before theskills removeblock saysobjectstack-pm-dispatchis not in the 18 catalog and that only an older install has it (#17311). The prose carries the note, not the command, so the command stays copy-pasteable. The roster also gainsobjectui(seat review S2): a 17.x project installed it fromobjectstack-ai/objectui, so it has a github-sourcedskills-lock.jsonentry that the sync skips, like theobjectstack-*ones.Token readings (
node scripts/check-skills-token-ratchet.mjs, exit 0)mainskills/objectui/README.mdskills/objectui/guides/page-builder.mdskills/objectstack-data/references/data-hooks.mdskills/objectstack-data/rules/relationships.mdskills/objectstack-data/rules/lifecycle.mdskills/objectstack-data/rules/datasources.mdskills/objectstack-data/rules/indexing.mdskills/objectstack-platform/references/bootstrap.mdskills/objectstack-platform/rules/plugin-lifecycle.mdskills/objectstack-platform/rules/service-registry.mdskills/objectstack-query/SKILL.mdskills/objectstack-query/rules/filters.mdskills/objectstack-upgrade/SKILL.mdskills/README.mdis outside every skill directory and is not ratcheted. No ceiling is raised, so the ruling path was not used. No line was re-wrapped. Every deletion, with the facts it held and where each survives:objectui/README.md: theskills.shbadge (a pointer to the archived repo's listing; no surviving home needed). The "CLI auto-detects your agent… (e.g..claude/skills/objectui/…) See skills.sh/docs" sentence. Facts: auto-detection is false under the taught--agentinstall; the landing directory and the other agents are in the catalog README (§ install: "the skills land as real files in.claude/skills/", "Name your own runtime after--agent"), which the new text links.data-hooks.md: the dead "Project hooks pattern" reference line (item 3). Its home is this file, which the dataSKILL.mdQuick Reference routes to.relationships.md:post_tagblock is replaced by "The junction object pattern above.", mirroring the master_detail Correct entry. Facts: a junction is an explicit object with twolookups, bothrequired: true. Home: § Many-to-Many: Junction Object (project_assignment, same shape, plus its unique pair index).// Contact can exist without accountcomment onrequired: false. Homes: the example's own// Child: Contact (independent lifecycle)and the Relationship Types rowlookup | Independent | Optional by default.lifecycle.md:SKILL.mdQuick Reference row.// must: after === maxAgeon the ConsentLogarchiveline. It was the page's only statement of the equality thatobject.zod.tsL1067 enforces at parse, so the follow-up commit restates it at its home (seat review S1). The § Validation Rules counter-example's comment now reads// ❌ archive.after must equal retention.maxAge, in place of "❌ Archive window detached from the hot window".datasources.md: ", not only on a federated object" in thecolumnNamebullet. Home: the same bullet's "on ANY object" and "everywhere".query/rules/filters.md:$null: falseisIS NOT NULL" in § Prefer$null. Home: the Operator Reference$nullrow (IS NULL/IS NOT NULL) andSKILL.md's Null table.// Records created in the last 7 days (compute date in application code)comment. Its first half did not match the code below it (a fixednew Date('2025-01-01')), and its second half is the section's lead sentence ("For ad-hoc queries in application code, compute the date yourself").Link walk
/mnt/project-files/card-31114/linkwalk.py(project folder) walks everyskills/**/*.mdoutside code fences and inline code. It checks that relative links resolve to a file, that#anchorsmatch a GitHub heading slug or an<a id>in the target, and thatgithub.com/objectstack-ai/objectstack/(tree|blob)/main/<path>links name a path that exists in the checkout.main(98583cd6): 243 links, 3 broken (exactly item 3's three).ui/scripts/check-doc-links.mjs(inpnpm --dir ui exec vitest run scripts/, a derived gate) also coversskills/objectuiand is green.Eval cases
objectstack-data/evals/objects-fields-relationships.jsoncase 8 (new, item 5):project+ ownedmilestone. Must containObjectSchema.create,sharingModel: 'private',sharingModel: 'controlled_by_parent',master_detail,deleteBehavior: 'cascade'; must not containmany_to_many,deleteBehavior: 'set_null'.objectstack-data/evals/objects-fields-relationships.jsoncase 9 (new, item 6): a multi-tenant index for an organization's open tickets. Must containindexes,organization_id;must_not_containis empty, because a careful answer warns againsttenant_idby name, as the case's ownexpected_outputdoes (seat review N1).objectstack-data/evals/hooks-security-seeds-datasources.jsoncase 11 (new, item 5; renumbered from 10 when docs(skills): guard nullable validation operands, teach hookbody, listmailbox/package-registry, dropos generate agent#31127's case 10 landed onmain): a read-only externalext_supplier. Must containObjectSchema.create,remoteName,sharingModel: 'public_read'; must not containcolumnName:.objectstack-query/evals/filters-pagination-search.jsoncase 7 (new, item 8): tasks with no notes, where a blank string counts as none. Must contain$empty: true;must_not_containis empty, because an answer that warns against the retired$regex/$optionsby name must not fail (seat review N1).evals/fortenant_id,objectstack-ai/objectui,18.1.0and the three dead anchors, with no hits.Other sites found (not changed: outside this card's file surface)
content/docs/releases/v12.mdxL204 andv14.mdxL298 link the archivedobjectuiCHANGELOG. These are release notes, which Human Minimum item 7 says not to hand-edit. The otherobjectstack-ai/objectuihits undercontent/docs/frontend/**are historical issue links, which are correct as they are.ObjectSchema.createexample withoutsharingModel(swept: everyskills/**/*.mdwith a create call).Verification
Local gates: 97 derived, 97 exit 0, 0 NOT MEASURED
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 97 commands for the 20 changed paths. Each one ran undertimeout 900withNODE_OPTIONS=--max-old-space-size=8192, and its exit code was captured before any pipe. The full list with exit codes is in the project folder,card-31114/gates-e6dcc651.txt.check-plugin-teardown-shape --self-testexited 3 because this shallow clone lacks its pinned fixture commit; fixed withgit fetch origin 621a4876….check:skill-examples(exit 3),check:dts-closure(exit 1) andcheck:dual-build-cjs-loads(exit 3) failed with nodist/, beforepnpm build(exit 0) had finished.pnpm --dir ui exec vitest run scripts/(exit 1) caught a real defect:check-doc-linksrefused the relative../README.mdinskills/objectui/README.md, which now uses an absolute URL (see § 1). The rest of that file's reds were build-dependent.e6dcc651): 97 exit 0. That includescheck:skill-identifier-liveness,check:skill-top-level-keys,check:skill-compatibility,check:skill-frame-sync,check:skill-docs,check:skill-refs,check:skill-examples(283 blocks),check:doc-authoring,check:corpus-claim-drift, the uiscripts/suite (4996 tests) and the token ratchet.origin/main9f61e06ebefore the first push. Those 5 newmaincommits touch no file in this diff. The token ratchet,check:skill-docs --check, the commit-trailer check and the link walk were re-run on the rebased head, all exit 0.bc879f05(seat review S1, S2, N1; 4 skill files plus the changeset bullet):node scripts/check-skills-token-ratchet.mjs,check:skill-docs --check,check:skill-refs,check:skill-compatibility,check:skill-identifier-liveness,check:corpus-claim-drift,check:doc-authoringandcheck-empty-changeset --base origin/mainall exit 0, and all three touched eval files parse as JSON.356cc7ae(origin/maininto the branch, no rebase): the one conflict washooks-security-seeds-datasources.json, where docs(skills): guard nullable validation operands, teach hookbody, listmailbox/package-registry, dropos generate agent#31127 also appended a case 10. Both cases are kept, and this PR's case is renumbered to 11, so the ids run 1-11. Nothing else in this PR's diff againstmainchanged. The token ratchet,check:skill-docs --check, the JSON parse of all three eval files and the link walk (249 links, 0 broken) all exit 0.node scripts/check-commit-card-trailers.mjs --range origin/main..HEAD: exit 0 before each push.Human Minimum
packages/specholds no runtime logic. (No schema touched; only a build script underpackages/spec/scripts.)main, one pull request.'@objectstack/skills': patch), and both declaration lines are filled in here and in the changeset.packages/spectouched (scripts/build-skill-docs.ts): its generated artifacts (skills/README.mdindex,content/docs/ai/skills-reference.mdx) are regenerated and committed;check:skill-docsis green.content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.🤖 Generated with Claude Code
https://claude.ai/code/session_01J8VVAjQXxnSqEopTLRDyHp