Skip to content

docs(skills): the platform skill teaches the package customizations read's contributions - #30071

Merged
os-zhuang merged 1 commit into
mainfrom
claude/project-thread-li956g
Nov 4, 2026
Merged

os-zhuang merged 1 commit into
mainfrom
claude/project-thread-li956g

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Irene · project thread

Fixes #29411

Clause-②: no
Metadata-protocol: none

The Fable mandate was waived by the maintainer; this PR was developed on Opus.

维护者速读

  • 改了什么:objectstack-platform 技能的「定制已安装包」一节,在 GET /packages/<id>/customizations 段后新增一段,教读取结果的 contributions 成员:每个其他包加到基础包上的条目一条,带 packageId;field / flow 条目给出所在的基础包 object,nav 条目给出基础包的 app、目标 group(有则给)和条目 id(name);counts.contributions 数的是条目而非包。另加一个 '@objectstack/skills': patch changeset。
  • 为什么改:spec 的 GetPackageCustomizationsResponseSchema 早已声明 contributions(runtime: a served read naming which package contributes to an installed base — extension fields, flows on its objects, navigation entries — so Studio can draw contributed items greyed with their source (ADR-0029 D7, ADR-0146 D3) #28722 已在 main 上产出 nav 条目),技能只说该读取列出 overrides、extensions 和 switched-off,AI 读不到第四个列表。
  • 风险与回滚:纯技能文本 + changeset。token 天花板就地付账:删了同文件三处复述(每处的规则在文件内另有归宿),6004 → 6000 / 6011,上限行未动,无 re-wrap。回滚即 revert。
  • 先看:skills/objectstack-platform/SKILL.md 新段(L132)与三处删除;对照 packages/spec/src/api/package-lifecycle.zod.ts 的 contributions 与 counts.contributions。
  • 两分钟验证:node scripts/check-skills-token-ratchet.mjs,预期 platform SKILL.md 6000/6011。
  • 需要你做的:Tier H 受管面(skills/**),需要 GOVERNED_APPROVERS 的批准;PR 保持 draft。

What changes

skills/objectstack-platform/SKILL.md, "Customizing an installed package (ADR-0146)". A new paragraph after the one that introduces GET /packages/hotcrm/customizations (that paragraph is byte-identical):

That read's `contributions` lists what other packages add to the base, one entry per item with its `packageId`: a `field` or `flow` names the base's `object` it is on, a `nav` item the base's `app`, its `group` if any, and its id as `name`; `counts.contributions` counts items, not packages.

Each fact is read off main at c23501b2:

  • GetPackageCustomizationsResponseSchema.contributions (packages/spec/src/api/package-lifecycle.zod.ts): a discriminated union on kind; the field / flow arm carries object, name, packageId; the nav arm carries app, optional group, name (the nav item's id), packageId. packageId is never the base nor its pair.
  • counts.contributions: "contributions.length: items, not packages."
  • nav is served on main. readBaseContributions in packages/runtime/src/domains/packages.ts pushes { kind: 'nav', app, group?, name: id, packageId } from registry.getAppNavContributions(app) for each app the base owns (runtime: a served read naming which package contributes to an installed base — extension fields, flows on its objects, navigation entries — so Studio can draw contributed items greyed with their source (ADR-0029 D7, ADR-0146 D3) #28722 closed; packages-customizations.test.ts pins it). So the paragraph teaches it plainly, with no "not yet served" mark.
  • Not taught, on purpose: "a disabled package's items are not listed". The runtime applies isPackageDisabled only to the nav loop (a disabled package's flow is simply not registered; fields are not filtered), so a general sentence would overstate it, and the card did not ask for it.

.changeset/29411-platform-skill-package-contributions.md: '@objectstack/skills': patch, with Clause-②: no and Metadata-protocol: none. @objectstack/skills ships this catalog, so the change publishes and takes a changeset, never skip-changeset.

Token ratchet, paid in place (no ceiling row moved, no re-wrap)

file tokens before / after / ceiling bytes before / after lines before / after
skills/objectstack-platform/SKILL.md 6004 / 6000 / 6011 (headroom 7 → 11) 24036 / 24019 429 / 426

The new paragraph is paid for by three deletions in the same file, each a restatement whose rule keeps a home there. The lines around each cut are byte-identical; nothing was rewrapped.

  1. "Exact shape: ObjectStackDefinitionSchema in node_modules/@objectstack/spec/src/stack.zod.ts; each collection's item schema sits in its domain folder (…)." (3 lines and the blank line, 201 bytes). Home: the References section ("Always Read the source for exact field shapes") and references/_index.md, which lists stack.zod.ts and every domain schema file. check:skill-top-level-keys reads the enumeration paragraph above it by its own anchor, not this line.
  2. "Raise it there; do not compensate for it here." (the tail of the "fix is upstream" bullet). Home: the "A platform defect means waiting for the platform fix" bullet two items below ("No defensive coding, no shape tolerance …", "Record the block against the platform issue").
  3. "Pick demoStaff whenever the demo needs an account to exist." (the last sentence of Demo accounts). Home: the section's opening, which says a seed cannot create an account and to "Declare the people in demoStaff", and the sentence before it, which says devLogins creates nothing.

Why

The skill told an author that the customizations read lists overrides, extensions and switched-off items, and stopped there. The schema has served a fourth list, contributions, plus its count, since #28722; an AI reading only the skill would not know other packages' fields, flows and nav items come back on the same read, or would read counts.contributions as a package count.

Verification

Head 21e8aa1a (one commit on c23501b2).

Local gates on 21e8aa1: 45 derived, 45 run with exit 0, 0 NOT MEASURED (`dispatch-gates --ran`)
  • node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 45 commands for the two changed files. All 45 ran after pnpm install --frozen-lockfile and a full pnpm build (exit 0), each with a 900 s timeout and its exit code captured before any pipe.
  • All 45 exited 0, among them check-skills-token-ratchet.mjs (and --self-test), check-changeset-no-major.mjs, check-empty-changeset.mjs, check:changeset-gate-self-tests, check-comment-mask-corpus.mjs, check:skill-docs, check:skill-top-level-keys, check:skill-identifier-liveness, check:skill-frame-sync, check:skill-compatibility, check:role-word, check:dts-closure, check:dual-build-cjs-loads and check:lean-entry-closure.
  • --ran printed: 45 derived famil(ies) accounted for — 45 run, 0 NOT-MEASURED.
  • node scripts/check-commit-card-trailers.mjs --range origin/main..HEAD: exit 0 (one commit, no card relation, model-free trailer pair).
  • Writes: one git push (the branch, 21e8aa1); one relay pr_create; no GitHub MCP write.
  • Evals: no case in skills/objectstack-platform/evals/config-plugins-ops.json covers the customizations read, so none is run or added for the new paragraph. Two cases (L116, L134) cover the Demo accounts section that cut 3 touches; their expected outputs rest on the sentences that stay (demoStaff creates the accounts, devLogins creates nothing), so they read the same.

Human Minimum

  • 1. Schemas start as Zod; packages/spec holds no runtime logic. (No schema touched.)
  • 2. Every name I added uses the casing for its kind.
  • 3. No formatter ran; pnpm lint is CI's repo-wide run.
  • 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 维护者速读 block is the repo's own Chinese reading aid).

🤖 Generated with Claude Code

https://claude.ai/code/session_01J8VVAjMvCpqNhHkd2m3T5A

…ead's contributions

Names `contributions` and `counts.contributions` beside the overrides,
extensions and switched-off items, paid for by deleting three
restatements in the same file.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J8VVAjMvCpqNhHkd2m3T5A
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation tooling labels Nov 4, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#1 · huangyiirene · session_01J8VVAnMUWA9rufXzFaEh4J

Contract-review-claim: session_01J8VVAnMUWA9rufXzFaEh4J · head 21e8aa1 · 2026-11-04T12:36Z

The seat review runs at CONTRACT_REVIEW_TIER in an isolated subagent (the seat session is not at that tier). No review seat (lanes/review.md) is seated.


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#1 · huangyiirene · session_01J8VVAnMUWA9rufXzFaEh4J

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 21e8aa1a923f840b344ec2cb04b381021e82869f
Local-runs: probe — on a detached worktree of the head (merge-base with origin/main c23501b; origin/main at d79eecf when fetched; neither skills/objectstack-platform/**, packages/spec/src/api/package-lifecycle.zod.ts, packages/runtime/src/domains/packages.ts, packages/runtime/src/domains/packages-customizations.test.ts nor scripts/check-skills-token-ratchet.mjs is in the two commits main gained since the merge-base, whose diff is .changeset/30018-page-header-placed-actions.md, .changeset/connect-agent-work-assistants.md and skills/objectstack-ui/rules/pages.md only): node scripts/check-skills-token-ratchet.mjs on the head (exit 0: objectstack-platform/SKILL.md 6000 / 6011, headroom 11; 57 authored files within ceiling) and its --self-test (exit 0, 97 cases); wc -c on the head file (24019 bytes, 426 lines) and on the merge-base blob (24036 bytes, 429 lines); node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (45 commands, the same set as the 45 lines of the dev record, diff empty); node scripts/pm/check-skill-id-lint.mjs (self-test 23 cases; 110 files clean, exit 0); node scripts/check-skill-identifier-liveness.mjs (self-test OK; 486 citations over 71 published files, exit 0); check-skill-top-level-keys.mjs (self-test 14 cases; live: SKILL.md:33 enumerates all 53 authorable keys, exit 0), check-skill-frame-sync.mjs, check-skill-compatibility-version.mjs, check-role-word.mjs (self-test and live, all exit 0); node scripts/check-empty-changeset.mjs --base c23501b2 (exit 0, 1 declaring changeset added, none from the merge-base modified) and --self-test (exit 0, 165 assertions); node scripts/check-changeset-no-major.mjs --base c23501b2 (exit 0, no major); node scripts/check-commit-card-trailers.mjs --range origin/main..HEAD and --range c23501b2..HEAD (exit 0, one commit, no card relation, model-free trailer pair); node scripts/pm/check-governed-merges.mjs --branch HEAD (exit 3, GOVERNED, Tier H, 1 of 2 paths hits skills/**, 21 changed lines); check-doc-authoring.mjs (exit 3 PREREQUISITE NOT MET in this container: no node_modules, read from CI); pnpm --filter @objectstack/spec run check:skill-docs not run (no tsx in the worktree; read from CI); sed-applied cuts on the merge-base blob cmp'd against the head with its two new lines removed (byte-identical remainder, no re-wrap); git diff --word-diff=porcelain (9 changed-token lines, every one inside the touched lines); node -e require(...) over skills/objectstack-platform/evals/config-plugins-ops.json (parses; the two demoStaff cases 7 and 8 read); gh api REST reads of the PR, its files, commits and comments, its reviews (none), card #29411 and its two comments, and the head's check-runs three times. The worktree was removed after the runs and the main checkout was not touched.
Scope: skills/objectstack-platform/SKILL.md (the governed hit: the new paragraph L132; the three cuts — merge-base L71–74 "Exact shape", the L147 tail "Raise it there; do not compensate for it here.", merge-base L406–407 "Pick demoStaff whenever…"), .changeset/29411-platform-skill-package-contributions.md + read, not reviewed: packages/spec/src/api/package-lifecycle.zod.ts on main (the GetPackageCustomizationsResponseSchema docblock L476–517, contributions L563–611, counts.contributions L616), packages/runtime/src/domains/packages.ts on main (readPackageCustomizations L3264–3278, the readBaseContributions docblock L3281–3322 and body L3323–3405), packages/runtime/src/domains/packages-customizations.test.ts L641–725 (the field/flow, nav, disabled-package and other-base pins), packages/objectql/src/registry.ts (getObjectContributors L6318, listItems L7711–7731, isPackageDisabled L7740, disablePackage L8250, applyNavContributions L8372–8388, the object fold resolveObjectLeavingExtensionsOut / foldExtenders L4723–4760), skills/objectstack-platform/references/_index.md L21 and L27, skills/objectstack-platform/SKILL.md L33 (the enumeration anchor), L150–156 (the platform-defect bullet), L383–386 and L403–404 (Demo accounts), L420–424 (References), scripts/check-skill-top-level-keys.mjs L41–109, scripts/check-skills-token-ratchet.mjs L552–584 (the CEILINGS row), packages/skills/package.json, card #29411 body, comments 6580159482 (triage) and 6630191176 (claim), PR #30071 body and its one comment (the seat's review claim on this head), the dev gate record pr-29411/gates-21e8aa1a.txt (read as input)

Reviewer: an isolated contract reviewer at CONTRACT_REVIEW_TIER, read-only on GitHub (REST reads only; nothing written, pushed or commented), fed the card body and comments, the PR body, the net diff against the merge-base, the head's check-runs, AGENTS.md, the pm-dispatch SKILL.md 路径分叉 section, contract-review.md, review-checklist.md, lanes/skills.md and lanes/review.md. The dev gate record was read as input, not as conclusions; every count and every claim about the schema and the runtime below is this review's own reading of the trees named. No environment variable value is printed anywhere in this record.

① Derived judgments

  1. File surface. One commit (21e8aa1, commit author Claude, PR author objectstack-fleet[bot], head repo = base repo, draft, base main, head ref claude/project-thread-li956g = the claim's branch, trailers Co-Authored-By: Claude + Claude-Session:, no model identifier). git diff --stat c23501b2 21e8aa1a, the REST file listing (+14 / −7, 2 files) and the PR body agree on exactly two paths: skills/objectstack-platform/SKILL.md +4/−7 (429 → 426 lines, 24036 → 24019 bytes) and .changeset/29411-platform-skill-package-contributions.md +10/−0 (new). The claim (6630191176) named the paragraph around L134 "plus its evals if the edited lines are covered, and one '@objectstack/skills': patch changeset"; no eval covers the edited lines (①.7), so none rides. Nothing outside those two paths; the ratchet script is not in the diff. Correct, and on surface.
  2. The new paragraph against the schema on main. Head L132: "That read's contributions lists what other packages add to the base, one entry per item with its packageId: a field or flow names the base's object it is on, a nav item the base's app, its group if any, and its id as name; counts.contributions counts items, not packages." Clause by clause against package-lifecycle.zod.ts: contributions is a discriminatedUnion('kind', …) of two arms (L563); the field/flow arm carries kind, object ("The base-owned object the item is on"), name, packageId ("Never the base and never its <base>.custom pair"), .strict() (L564–575); the nav arm carries kind: 'nav', app ("The base-owned app the item is contributed to"), optional group ("Absent when the contribution targets the app's top level"), name ("The nav item's id, as the contribution's items declare it"), packageId, .strict() (L576–598); the array describe opens "Every field, flow and navigation item another installed package contributes to the base, one entry per item and contributing package" (L600–601); counts.contributions is "contributions.length: items, not packages." (L616). "What other packages add to the base" is the docblock's "what OTHER packages bring to X's surface" (L496–497), and "one entry per item with its packageId" is "one entry per item, each stamped with the package that contributes it" (L498). Every clause has a line in the schema; no clause names a member the schema lacks (object is absent from the nav arm and the text does not give nav one). Correct.
  3. The producer on main, and whether nav is really served. readPackageCustomizations (packages.ts L3264) calls readBaseContributions(baseId, pair…, registry) and returns its array as contributions with counts.contributions: contributions.length (L3271, L3276). readBaseContributions (L3323–3405) pushes { kind: 'field', object, name, packageId } for each fields key of each extend contributor of a base-owned object (L3347–3356), { kind: 'flow', object, name, packageId } for each listItems('flow') whose start node's config.objectName is base-owned (L3359–3370), and — the question the card left open — { kind: 'nav', app, group?, name: id, packageId } for each id-carrying item of each registry.getAppNavContributions(app) entry over listItems('app', baseId) (L3372–3392), then sorts field/flow first and nav after (L3394–3404). packages-customizations.test.ts L667–672 pins four nav entries through the dispatcher (partner_home, partner_tools, partner_help with group: 'showcase_missing', acme_sync_log with group: 'showcase_work'), that the field and flow entries come first (L675), and that the whole answer parses through GetPackageCustomizationsResponseSchema (L676–677). So nav is produced on main, runtime: a served read naming which package contributes to an installed base — extension fields, flows on its objects, navigation entries — so Studio can draw contributed items greyed with their source (ADR-0029 D7, ADR-0146 D3) #28722 is closed (card comment 6630191176 and the PR body agree), and the card's "Mark nav as not yet served until runtime: a served read naming which package contributes to an installed base — extension fields, flows on its objects, navigation entries — so Studio can draw contributed items greyed with their source (ADR-0029 D7, ADR-0146 D3) #28722 Wanted 3 lands, or write it after that lands" is met by the second arm: the paragraph teaches nav plainly with no "not yet served" mark, which is the true state of main. Correct.
  4. The deliberate omission ("a disabled package's items are not listed"). The runtime applies isPackageDisabled only in the nav loop (packages.ts L3380); the flow loop relies on listItems('flow'), which does filter a disabled package's items (registry.ts L7729–7731, options.includeDisabledPackages !== true); the field loop reads getObjectContributors (registry.ts L6318, the raw objectContributors map) with no disabled check, and the object fold it mirrors (resolveObjectLeavingExtensionsOut → foldExtenders, L4723–4760) applies no isPackageDisabled to extenders either, so a disabled package's extension fields stay on the served object AND stay listed. The one test on the subject (L693–712) disables a package that contributes only a nav item and pins the list against the served navigation. So on main: a disabled package's nav and flow contributions are not listed, its field contributions are. A general sentence "a disabled package's items are not listed" would be false for field; the dev's decision not to write it is the right one, and the card did not ask for it. The skill text as written is correct: it says nothing about disabled packages and teaches nothing false. The spec's own words split: the array .describe() (L600–605) excludes only "a flow of a disabled package" and a disabled package's navigation items, consistent with main; the docblock paragraph at L512–516 ("a disabled package's contributions MUST NOT be listed, as the fold drops them", written of the nav entry under ruling letter E) and the nav arm's describe (L597, "A disabled package's contributions are not listed") read generally. Spec docblock vs .describe() vs runtime disagree for the field kind: an out-of-scope finding, recorded in ③, not this PR's. Correct as written.
  5. Cut 1, merge-base L71–74 ("Exact shape: ObjectStackDefinitionSchema in node_modules/@objectstack/spec/src/stack.zod.ts; each collection's item schema sits in its domain folder (data/object.zod.ts, ui/view.zod.ts, …)." plus its blank line; measured 201 bytes). Its three facts and their homes on the head: the schema name ObjectStackDefinitionSchema is in the enumeration paragraph that check-skill-top-level-keys.mjs anchors (head L33, "enumerates all 53 authorable top-level keys of ObjectStackDefinitionSchema", exit 0 on the head, so the gate reads L33 and not the cut, as the body says); the file path stack.zod.ts is references/_index.md L21 ("node_modules/@objectstack/spec/src/stack.zod.ts — Exports: …"); the domain-folder placement is _index.md L27 (data/object.zod.ts) and the index's per-domain listing, which SKILL.md's References section (head L420–424) routes to: "See [references/_index.md] for the full list of Zod schemas … pointers into node_modules/@objectstack/spec/src/. Always Read the source for exact field shapes". No other file in skills/, .claude/ or content/docs reads "Exact shape" or an anchor of it (grep). Nothing taught only there. Survives.
  6. Cut 2, the L147 tail "Raise it there; do not compensate for it here." (47 bytes). The bullet keeps "A missing default, a wrong diagnostic, a shape the spec refuses — the fix is upstream." (head L144–145), which is the "raise it there" half; the "do not compensate" half is the third bullet of the same list, head L150–156: "A platform defect means waiting for the platform fix. No defensive coding, no shape tolerance, no hand-written predicate re-implementing a platform rule, and never 'land the half we can' … Record the block against the platform issue". The surviving bullet is the stronger statement (it names the four compensations and the record to leave). Nothing taught only there. Survives.
  7. Cut 3, merge-base L406–407 "Pick demoStaff whenever the demo needs an account to exist." (63 bytes with its line break; the preceding sentence "devLogins creates and grants nothing — it only prints an existing account on the boot banner." is kept byte-for-byte, head L403–404). Homes: the section's opening, head L383–386 — "A seed deals records to people … but cannot create one … so nobody can sign in as it. Declare the people in demoStaff; os dev creates each account" — states the rule positively (an account exists only through demoStaff), and the kept devLogins sentence states the negative. Evals: config-plugins-ops.json cases 7 (L116, must_contain demoStaff, position, permissionSets, os dev; must_not_contain role:, admin_full_access) and 8 (L134, must_contain demoStaff, manager: ', os dev; must_not_contain manager_id:, reportsTo:) rest on L383–401, not on the cut sentence; no case names customizations, contributions, ObjectStackDefinitionSchema, stack.zod or "compensate" (grep over the fixture), so no eval covers the new paragraph or cuts 1–2, and the two that cover the Demo accounts section read the same. Nothing taught only there. Survives.
  8. Token ratchet. Head file 24019 bytes → ceil((24019 − 20) / 4) = 6000 tokens against the CEILINGS row ['skills/objectstack-platform/SKILL.md', 6011] (ratchet script L584, unchanged in the diff; the gate itself prints 6000 / 6011, headroom 11); merge-base 24036 bytes → 6004 (headroom 7). Exit 0 and the self-test's 97 cases pass on the head. No ceiling row moved. No re-wrap: the merge-base blob with the three cuts applied by sed (L71–74 deleted, the L147 tail removed, the L406 tail and L407 removed) is byte-identical to the head with L132–133 (the new paragraph and its blank line) removed; the word-diff's 9 changed-token lines all fall inside those lines. Paid line by line, 311 bytes cut for 293 added. Correct.
  9. Changeset. .changeset/29411-platform-skill-package-contributions.md: frontmatter '@objectstack/skills': patch; body carries line-initial Clause-②: no and Metadata-protocol: none; prose names contributions beside the three lists, the per-kind members (packageId; object for field/flow; app, group when targeted, item id as name for nav), counts.contributions as items not packages, and the three same-file deletions with an unchanged ceiling — each sentence reproduces against ①.2, ①.3 and ①.8. @objectstack/skills (packages/skills/package.json) is not private, has publishConfig.access: public and ships the skills/** tree through sync-catalog.mjs into dist, so a skills/** edit publishes and takes a patch changeset, never skip-changeset; the PR carries no skip-changeset label (labels documentation, size/s, tooling) and Check Changeset is success. check-empty-changeset and check-changeset-no-major exit 0 on the head. Correct.
  10. Gates re-run here. The 45 commands dispatch-gates.mjs --commands derives on the head are the same 45 lines as the dev record. Of those re-run: token ratchet and self-test, skill-id-lint, skill-identifier-liveness, skill-top-level-keys, skill-frame-sync, skill-compatibility, role-word, empty-changeset, changeset-no-major, commit-card-trailers, governed-merges all pass (governed-merges exit 3 by design: GOVERNED, Tier H, skills/objectstack-platform/SKILL.md on the register, the changeset not, 21 changed lines under the 3000 threshold). check-doc-authoring exits 3 PREREQUISITE NOT MET in this container (no node_modules) and check:skill-docs needs tsx; both read from CI: Lint · docs & code guards, Lint · repo & tooling gates, Lint & Repo Gates and TypeScript Type Check are success on the head. Correct.
  11. PR body against the head. First content line Fixes #29411: the card's Wanted is one paragraph naming contributions, each kind's members and the item count, with nav written after runtime: a served read naming which package contributes to an installed base — extension fields, flows on its objects, navigation entries — so Studio can draw contributed items greyed with their source (ADR-0029 D7, ADR-0146 D3) #28722 landed; all done, so Fixes is the right verb; the other numbers in the body (runtime: a served read naming which package contributes to an installed base — extension fields, flows on its objects, navigation entries — so Studio can draw contributed items greyed with their source (ADR-0029 D7, ADR-0146 D3) #28722, feat(runtime): the per-base customizations read names the package behind each field and flow another package contributes #28749, feat(spec): the customizations read's contributions declare a nav kind, with an entry shape per kind #29401) sit beside no closing keyword and PR-body guards is success. Clause-②: no and Metadata-protocol: none are right (no spec, no authorable key). The model note is "The Fable mandate was waived by the maintainer; this PR was developed on Opus." — a tier word, not a model id (check-commit-card-trailers exit 0; the claim 6630191176 records the same waiver and its maintainer quotation). The body's facts reproduce: the byte-identical introducing paragraph (head L130), the per-arm members, "nav is served on main" with readBaseContributions and the test as its evidence, the token row 6004 / 6000 / 6011 (headroom 7 → 11), bytes 24036 / 24019, lines 429 / 426, the three cuts with their homes (①.5–7), cut 1's 201 bytes, "45 derived, 45 run with exit 0, 0 NOT MEASURED", the evals note (no case covers the read; L116 and L134 cover Demo accounts and read the same). Correct.
  12. Governance. Tier H (skills/**); draft, auto_merge null, no reviews, no assignee, no requested reviewer, mergeable_state blocked. Landing is the maintainer's hand or an authorized GOVERNED_APPROVERS approval; this record does not lift it.

② Semver level

patch on @objectstack/skills, as declared. No packages/spec/src/**, no TypeScript, no authorable key: one paragraph added and three restatements removed in a published skill file, which the catalog package ships. Clause-②: no, Metadata-protocol: none in the PR body and the changeset agree with the diff; Check Changeset is success on the head.

③ Boundary flags

  • Dev open_questions: none in the body. The body's one deliberate omission — not teaching "a disabled package's items are not listed" because the runtime filters only nav (and, through listItems, flow) — is confirmed against the code (①.4) and accepted: the skill teaches nothing false.
  • Out-of-scope finding, for the seat to file (not this PR's): packages/spec/src/api/package-lifecycle.zod.ts L512–516 (the docblock: "a disabled package's contributions MUST NOT be listed, as the fold drops them") and L597 (the nav arm's describe: "A disabled package's contributions are not listed") read as every kind; the array .describe() at L600–605 excludes only a disabled package's flows and navigation items; the runtime (packages/runtime/src/domains/packages.ts L3347–3356, the field loop over getObjectContributors with no isPackageDisabled) lists a disabled package's extension fields, and the object fold (packages/objectql/src/registry.ts L4723–4760) serves them, so the list and the served object agree with each other and with the array describe, and disagree with the docblock sentence. Governing text is the spec, so domain:spec owns the first move (decide whether the docblock's "contributions" means every kind, and if so the .describe() at L600–605 must say so and domain:server owes the field filter plus a test beside L693; if not, the docblock sentence narrows to nav); no test on main pins either reading for field. Reference ①.4.
  • Independence: PR author objectstack-fleet[bot], commit author Claude; no off-relay author note is owed. The PR thread carries the seat's Contract-review-claim: for this head (its one comment) and no other record; no review seat is seated (the claim says so). No assignee or requested reviewer on the PR.
  • Tier H: this record does not lift the landing; the maintainer's hand or an authorized approval does. Draft, auto_merge null, so no disarm is owed in either verdict.

④ Design judgment

Per hits file, against the card's scenario (an AI reading the skill must learn that the customizations read answers a fourth list, what each entry carries per kind, and that the count is of items) and the code on main:

  • skills/objectstack-platform/SKILL.md, the new paragraph L132: placed directly after the paragraph that introduces GET /packages/hotcrm/customizations and its three lists, so "That read's contributions" has its referent one line above; the paragraph is one sentence with the per-kind members in the schema's own words (object, app, group, name, packageId) and ends on the one misreading an author would make (counts.contributions as a package count). It does not copy the schema's ordering, the "never the base nor its pair" rule or the separator/id detail — all of which references/_index.md and "Always Read the source" route to — which is the right altitude for a 6011-token SKILL.md with 11 tokens of headroom. The reader who acts on this line is named (an author reading the customizations answer, the card's own evidence); it is not a token tax. Holds.
  • skills/objectstack-platform/SKILL.md, cut 1 (Exact shape): the sentence pointed at files the References section and _index.md already list, and the gate that could have read it reads the enumeration paragraph by its own anchor (verified, exit 0). A same-file restatement with two homes. Holds.
  • skills/objectstack-platform/SKILL.md, cut 2 (Raise it there; do not compensate): the kept bullet still says the fix is upstream, and the third bullet of the same list says what "do not compensate" means in four named forms plus the record to leave. The list is tighter, not thinner. Holds.
  • skills/objectstack-platform/SKILL.md, cut 3 (Pick demoStaff…): the section opens by saying a seed cannot create an account and to declare the people in demoStaff, and the kept sentence before the cut says devLogins creates nothing; the cut sentence was the conclusion of those two, and both demoStaff evals assert the premises, not the conclusion. Holds.
  • .changeset/29411-platform-skill-package-contributions.md: patch on the package that ships the file, both declaration lines, prose that reproduces against the diff and the schema. Holds.

Must-fix: none. Should-fix: none. The out-of-scope spec/runtime disagreement on a disabled package's field contributions (③) is the seat's to file, not this PR's; the skill text neither states nor contradicts it.

Check-runs at record time: 40 check-runs on 21e8aa1, 26 success, 13 skipped, 0 failure, 1 in progress on the third read (Test Core 1/8); three reads went 15 → 25 → 26 success with no non-success completion at any read (the first read, at 40 runs, had nine in progress: Lint · CI, release & engine gates, Lint · ESLint, Lint · docs & code guards, Lint · repo & tooling gates, Live E2E UI, Test Core 1/8 and 2/8, Type Check · consumer gates, Type Check · source gates; all but Test Core 1/8 completed success). Success: Lint & Repo Gates, Lint · repo & tooling gates, Lint · CI, release & engine gates, Lint · PM dispatch-gates, Lint · docs & code guards, Lint · ESLint, Lint · scoped · tooling self-tests, Lint · scoped · slot lookup & corpus, Lint · scoped · query-options erasure, TypeScript Type Check, Type Check · workspace / source gates / debt ledger / consumer gates, Build Core, Governed Surface Queue Guard, Dogfood Regression Gate, Test UI, Test Core (2/8), Plan Test Core shards, Live E2E UI, PR-body guards, Check Changeset, Check PR Size, Auto Label, filter. Skipped by path filter or opt-in: Build Docs, Build UI Deps, Build & E2E UI, Lint UI, Type Check UI, UI Published Artifacts, Dogfood Verify CLI, Temporal Conformance, Schedule gate, 18.x upgrade harness, Packed-tarball smoke, and the matrix-templated placeholder rows for Test UI and the Dogfood shards. Combined status pending (statuses API, 0 statuses). The one in-progress shard is a full-battery test lane on a diff that touches no package source; the landing pre-check still owes a read of it green before any Tier H act. PR updated_at 2026-11-04T12:37:19Z; draft, auto_merge null, mergeable_state blocked, labels documentation, size/s, tooling; Tier H (skills/**), landing by the maintainer's hand or an authorized approval, not by this record.

Implemented-by: claude/project-thread-li956g
Reviewed-by: session_01J8VVAnMUWA9rufXzFaEh4J

VERDICT: PASS


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#1 · huangyiirene · session_01J8VVAnMUWA9rufXzFaEh4J

维护者速读

席位核对 — ACCEPT · domain:skills#1 · head 21e8aa1a923f840b344ec2cb04b381021e82869f

  1. 形态: draft → main,Fixes #29411;作者 objectstack-fleet[bot];文件在认领面内,附 @objectstack/skills patch changeset(⛔ 不挂 skip-changeset)。
  2. 前提实测: 复核逐条对过 spec 与 readBaseContributions(runtime packages.ts);nav 在 main 上已产出,所以照常教。
  3. 门禁(钉 head 21e8aa1a): check-runs success 26 / skipped 13 / 进行中 1(Test Core 1/8),无失败;落地前检须读到全绿。派生门禁 45 条全过。
  4. 接受的偏差: 开发在 Opus 上进行,依维护者原话(无 fable 额度时豁免)。
  5. 范围外去向: spec 说停用包的 contributions 不列出,运行时只对 flow 和 nav 过滤,字段照列;本席另立卡交 domain:spec。
  6. 落地条款: Tier H。保持 draft,挂 needs-user-decision,同轮请 os-zhuang、hotlong 审批;获批后本席过落地前检、清标、ready、auto-merge;维护者直合亦可。

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/s tooling

Projects

None yet

2 participants