Repository navigation
feat(runtime): the per-base customizations read names the package behind each field and flow another package contributes - #28749
Conversation
…d to an installed base GET /packages/:id/customizations gains a contributions list: every field another package's object extension adds to one of the base's objects and every flow such a package ships whose trigger object the base owns, each stamped with its package. The base and its .custom pair are never listed. Co-Authored-By: Claude <noreply@anthropic.com>
…answers Regenerate the spec docs and strictness ledger for the new member, and add the changeset. Co-Authored-By: Claude <noreply@anthropic.com>
…ibutions list Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 2 package(s): 28 hand-written doc(s) name something this change touched — list omitted above 15 rows. Re-derive on the tree named below: ⛔ 7 release-owned page(s) also affected — read-only, see AGENTS.md Documentation Guardrails. What this run could not see
Coarse fallback — 173 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin ede30e99a53cb36bfc452fb1a7d24430c89a6af5 && git checkout ede30e99a53cb36bfc452fb1a7d24430c89a6af5
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 8afaf12d7c302072871f7e975e9dff5be5541d90 fb7fafd3d3e4b4c49b15955ce00c5f17323bdcb5 && git checkout -B drift-repro 8afaf12d7c302072871f7e975e9dff5be5541d90 && git merge --no-ff fb7fafd3d3e4b4c49b15955ce00c5f17323bdcb5
node scripts/docs-audit/affected-docs.mjs --json 8afaf12d7c302072871f7e975e9dff5be5541d90
|
…ol added, minor The new member moves the spec's authorable-surface shard, so the kind is added and spec and runtime take minor. Co-Authored-By: Claude <noreply@anthropic.com>
|
domain:server#3 · os-project-manager · session_01FEkQ5kE5BrPUPNMMyv6oCH Contract reviewServed-tier: Head The remainder of the diff — content/docs/references/api/package-lifecycle.mdx and docs/audits/2026-07-unknown-key-strictness-ledger.counts/api.md (regenerated), packages/runtime/src/dispatcher-plugin.package-customizations-mount.test.ts and the three ui fixtures (the required member added to hand-built answers) — is the lane seat's ACCEPT at ① Derived judgments
② Semver levelChangeset
③ Boundary flagsFrom the os-dev-report
④ Design judgment
Holds — tried and not broken:
Findings:
No must-fix. The schema change holds against ADR-0029 D7 / ADR-0146 D3, the card's fixture is the test's fixture, the reader reads two registries that already record the contributor, and the first consumer parses the answer it is given. Implemented-by: VERDICT: PASS |
|
domain:server#3 · os-project-manager · session_01FEkQ5kE5BrPUPNMMyv6oCH 席位核对 · ACCEPT · PR #28749 · 2026-11-01T17:58ZHead-sha: 维护者速读(席位终稿)
核对六项
|
…shard on the merged tree Co-Authored-By: Claude <noreply@anthropic.com>
|
domain:server#3 · os-project-manager · session_01FEkQ5kE5BrPUPNMMyv6oCH Contract reviewServed-tier: Re-confirm of the record posted as comment 6561256710 (verdict PASS on head ① The net diff, read, not taken on trust
② The two regenerated files: main's entries kept, only this PR's additions on top
③ Check-runs on
|
|
domain:server#3 · os-project-manager · session_01FEkQ5kE5BrPUPNMMyv6oCH 席位核对 · ACCEPT(head 续认)· PR #28749 · 2026-11-01T18:28ZHead-sha: 续认
对 main 的净差异仍是同样 12 个文件、+254/−17;两个生成文件以外的部分与原 head 逐字节相同。 |
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 41338791986 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 分类: 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
…stomization answers Co-Authored-By: Claude <noreply@anthropic.com>
|
domain:server#3 · os-project-manager · session_01FEkQ5kE5BrPUPNMMyv6oCH Contract reviewServed-tier: Second re-confirm — of the record posted as comment 6562066799 (re-confirm of 6561256710, verdict PASS, head ① The delta vs the last re-confirm, read
② Generated files on the new merged tree
③ Every hand-written customizations answer on
|
|
domain:server#3 · os-project-manager · session_01FEkQ5kE5BrPUPNMMyv6oCH 席位核对 · ACCEPT(第二次 head 续认)· PR #28749 · 2026-11-01T19:48ZHead-sha: 本条续认 为何出队:队列构建 41338791986 的 修法:head 前进两个提交,没有 force-push。
核对:
落地:重新开启 auto-merge 进队列。其余各项同 |
domain:server#3 · os-project-manager · session_01FEkQ5kE5BrPUPNMMyv6oCH
Requested by Leehom · project thread
Part of #28722
Clause-②: yes (widening)
Metadata-protocol: added
Skills-docs: none — the member is on a REST answer that no published skill teaches, and no metadata author writes it
维护者速读
GET /packages/:id/customizations) 多返回一张contributions清单:别的包给这个基础包的对象加的字段,以及别的包挂在这些对象上的流程,每一条都写明是哪个包贡献的。基础包自己的东西和它的.custom配对包不在里面。packages/spec/src/api/package-lifecycle.zod.ts新增的contributions与counts.contributions(契约);②packages/runtime/src/domains/packages.ts的readBaseContributions(排除基础包、配对包和本环境自己写的流程的三处判断);③packages/runtime/src/domains/packages-customizations.test.ts新增的 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 一组测试。pnpm --filter @objectstack/runtime exec vitest run src/domains/packages-customizations.test.ts,预期 17 个测试全绿。What changes
packages/spec/src/api/package-lifecycle.zod.ts:GetPackageCustomizationsResponseSchemagainscontributions, an array of strict entries{ kind: 'field' | 'flow', object, name, packageId }, andcounts.contributions. Strict like the rest of the answer, and required: the door always serves it.packageCustomizations-io.ts), with the read gate, the closed query set, the pair-id refusal and the 404 wording this answer also needs. A newGET /packages/:id/contributionswould duplicate all four and add a route-ledger row, a dispatcher mount, a typed client method and the dogfood route census pins.extensionsstays the pair's members only, and Studio's "customized" count (overrides + extensions) is unchanged.packages/runtime/src/domains/packages.ts#readBaseContributions, called byreadPackageCustomizations. Two sources, each the registry that already records the contributor:extendcontributors of each object the base owns (getObjectOwner), the same walk theextensionslist makes for the pair. Each contributor'sdefinitionis its extension body as declared, so itsfieldskeys are the fields it adds and itspackageIdis the package that declared them.registry.listItems('flow')(which already drops a disabled package's flows), kept when thestartnode'sconfig.objectNameis a base-owned object and the body is a code package's (isCodeArtifactBody: not thesys_metadatasentinel and not a tenant-authored overlay). The package is the stamp the registration put on the flow..custompair (the pair's members stay inextensions). One entry per item and package, so two packages adding a field of one name are two entries. Ordered by object, kind, name and package.getObjectContributorsalready knows the extenders: holds. Read here exactly as N-15 reads it.mergeObjectDefinitions): not taken. The fold is shared by every object read and the write door, and objectql: an object extension's display patch is carried and applied by mergeObjectDefinitions; a patch naming a missing field or option is refused at install and validate #28565 edits it. Reading the declaredextendbodies needs no change to the served object._packageId, stamped byregisterItem). The trigger object is thestartnode'sconfig.objectName.packages/runtime/src/route-ledger.ts: the row's note names the new list (check-route-ledger-censusgreen).content/docs/references/api/package-lifecycle.mdx(gen:docs) anddocs/audits/2026-07-unknown-key-strictness-ledger.counts/api.md(gen:strictness-ledger), the two artifactscheck:generatednamed stale, andpackages/spec/authorable-surface/api.json(the spec build writes it: one line,api/GetPackageCustomizationsResponse:contributions). No export was added or removed (check:api-surfaceunchanged)..changeset/28722-customizations-contributions.md:minoron@objectstack/specand@objectstack/runtime. The kind isadded: the new member moves the spec's authorable-surface shard (packages/spec/authorable-surface/api.json), and a kind takes at leastminoron every package the diff moves (AGENTS.md Post-Task Checklist step 3). The ui fixture edits are test files, which no package ships.Tests
packages/runtime/src/domains/packages-customizations.test.ts(17)packages.tsat base4bf48a8c: 7 red (the 4 new tests and the 3 whole-answer equalities)isCodeArtifactBodyguard removed (environment flows listed)The new tests (#28722 describe block) use the card's fixture: a base with its own flow on its object, the pair extending that object and carrying a flow, and a third code package registered through
ObjectQL.registerApp(the real manifest path) with anobjectExtensionsfield and two flows, one on the base's object and one on another package's object.sys_metadatasentinel, and a tenant-authored overlay wearing a package id) is not listed.Each ablation ran through
scripts/ablation-replace.mjs(anchor hit, run, restore), and each restore was proven: blob equal to HEAD andgit diff HEADempty. The runtime test importspackages.tsfromsrc, so no rebuild was needed between legs.Suites:
pnpm --filter @objectstack/runtime testBuilderLanding.customizationCounts-28566,customizationMarks,metadataAreaHost.customizations-28568pnpm --filter @objectstack/runtime typecheck,pnpm --filter @objectstack/spec typecheckpnpm build(whole repo)Acceptance notes
Part of #28722.main. Drawing it here would edit the same Studio surfaces that PR is changing, so the reader is N-19's (or its follow-up card's) to wire, now that a served source exists for fields and flows.type-checkneeds everyui/package built; it was not run locally. CI'sType Check UIcovers it.Verification
All readings at head
b4a36765unless named. Head7edbf44bchanges only the changeset (kindadded,minor);check-adr-0087-registration --base origin/mainandcheck-empty-changeset --base origin/mainexit 0 there.pnpm --filter @objectstack/runtime exec vitest run src/domains/packages-customizations.test.ts: 17/17. Withpackages.tsrestored to base4bf48a8c: 7 red.Derived gates: 109 derived, 109 run, 0 NOT-MEASURED, 0 UNRUN
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, re-derived atb4a36765: the same 109 commands as at274f09f9, where the loop ran.--ranverdict: "109 derived famil(ies) accounted for — 109 run, 0 NOT-MEASURED", exit 0.274f09f9: 105 exit 0, and four that did not:check:doc-authoringexit 1: a real finding. The route-ledger note carried the tracker id. It is removed inb4a36765, and the gate is green there.check-plugin-teardown-shape --self-testexit 3: shallow clone. After fetching its pinned fixture commit, 48 cases pass.check:skill-examplesandcheck:dual-build-cjs-loadsexit 3 (PREREQUISITE NOT MET: no built output). After a whole-repopnpm build(exit 0), both exit 0.b4a36765after the note edit:check:doc-authoring,check:route-envelope,check:issue-citations,check:nul-bytes,check:published-files,check:type-check-coverage,check:durability-log-leveland the four above, all exit 0.node scripts/check-route-ledger-census.mjs: exit 0 (115 rows).pnpm --filter @objectstack/spec check:generated --fix: two artifacts were stale (docs, strictness ledger). Both were regenerated and re-checked green.--no-inline-configover the 5 changedpackages/TS files: exit 0. ui eslint over the 3 changed test files: exit 0.ui fixtures were needed
BuilderLanding.customizationCounts-28566.test.tsxrestored to base: 3 of 6 red against the new schema, because its served answer lacks the now-requiredcontributions. With the fixture carrying it: 6/6 green.Generated by Claude Code