Repository navigation
fix(objectql)!: the registry fold judges an option patch against the options the owner declares, as the install door and os validate do (#28809) - #28836
Conversation
…d options in the registry fold, as at the install door and os validate (#28809) Co-Authored-By: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 2 package(s): 5 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 1 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 22 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 c35191804fa72cb4e44681d2876b4d07c6d62ec3 && git checkout c35191804fa72cb4e44681d2876b4d07c6d62ec3
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 6ea8342ac1cf3c8742313eee38c1c9cc268bae7e 301b4e3d8f13bae733c2cc5d3c9e4a516c0ef55a && git checkout -B drift-repro 6ea8342ac1cf3c8742313eee38c1c9cc268bae7e && git merge --no-ff 301b4e3d8f13bae733c2cc5d3c9e4a516c0ef55a
node scripts/docs-audit/affected-docs.mjs --json 6ea8342ac1cf3c8742313eee38c1c9cc268bae7e
|
…ases for the test typecheck (#28809) Co-Authored-By: Claude <noreply@anthropic.com>
|
domain:server#1 · os-project-manager · session_01R1q2xdtYgU6FKrZ7LgjPCC Contract-review-claim: Taken by the dispatching seat. Face Generated by Claude Code |
|
domain:server#1 · os-project-manager · session_01R1q2xdtYgU6FKrZ7LgjPCC Contract reviewServed-tier: Reviewed at 2026-11-01T23:59Z, read-only: card #28809 (body and both comments: the claim 6564158975 and the os-dev-report 6565322781), PR #28836 (body, 7-file list, net diff Check-runs on ① Derived judgmentsThe diff implies these accept-set and public-surface changes; each named right or wrong against the published spec (
② Semver levelChangeset
③ Boundary flags
④ Design judgmentThe narrowing, read against the published spec on Does it take a declared capability away at the consumer? No. The spec declares Breaking attempts, read in the tree:
The residual (card ruling 4 / dev's open question). An earlier layer (an extension's Judged should-fix S1, not a must-fix, for these reasons:
Findings:
Implemented-by: Rendered by the seat's subagent. VERDICT: PASS Generated by Claude Code |
|
domain:server#1 · os-project-manager · session_01R1q2xdtYgU6FKrZ7LgjPCC Contract-review-claim: Taken by the dispatching seat. Face Generated by Claude Code |
|
domain:server#1 · os-project-manager · session_01R1q2xdtYgU6FKrZ7LgjPCC Contract reviewServed-tier: Reviewed at 2026-11-02T00:39Z, read-only: card #28809 (body and both comments: the claim 6564158975 and the os-dev-report 6565322781), PR #28836 (body, 7-file list, net diff DELTA round. The prior record on Check-runs on ① Derived judgmentsJudgments 1 to 9 of the record on
4 (amended). Naming is the union of the two verdicts. What the owner-judge misses is named (the doors' refusal, the narrowing) and what the merged-judge misses among the admitted is named ( Pinned in the tree: the residual case now expects exactly one ② Semver levelUnchanged from the record on The prose now states the narrowing truly (S1 and S2 of the prior record):
③ Boundary flags
④ Design judgmentThe narrowing itself, read against the published spec on The delta, tried against the tree:
Findings: none. S1 and S2 of the record on Implemented-by: Rendered by the seat's subagent. VERDICT: PASS Generated by Claude Code |
|
domain:server#1 · os-project-manager · session_01R1q2xdtYgU6FKrZ7LgjPCC 席位核对 · ACCEPT ·
|
| item | reading |
|---|---|
| Shape | Draft, base main, Fixes #28809. 7 files: the field-patch fold in objectql/src/registry.ts judges each extension's option patches against the owner's declaration before the merge (the target the install door and os validate read), and merges only what it admits. A naming-only second pass over the merged fields names the residual once, as main did. Plus tests in objectql, cloud-connection and cli, a metadata-core docblock sentence, one docs bullet, and an objectql minor changeset with the BREAKING banner. No door source, no packages/spec/**, no export, no gate. |
| Should-fix | S1 (the residual named once) and S2 (the tenant overlay base named as a second source) are both in the tree and the prose at 301b4e3d, judged by the delta record. |
| Evidence | CI on head 301b4e3d (filter=latest): 14 skipped, 40 success, 0 failed. The report and the round-2 note show red on main (3 of 17), the ablations restored clean, the objectql suite (9996) and its typecheck in full, and 95/95 derived gates on the first head. |
| Serial | #28811 has landed since. git merge-tree of this head onto current origin/main is clean, and the merge queue tests the merged tree. |
| Landing | 「按照 pm-dispatch 规则复核过的都授权」 (Leehom, 2026-10-25T11:35Z): ready and auto-merge through the relay, with every check green or an expected skip. |
Generated by Claude Code
domain:server#1 · os-project-manager · session_01R1q2xdtYgU6FKrZ7LgjPCC
domain:server#1 · os-project-manager · session_01R1q2xdtYgU6FKrZ7LgjPCC
Fixes #28809
Clause-②: yes (narrowing)
Metadata-protocol: narrowed
Skills-docs: none —
skills/**never namesfieldPatches(git grep: 0); the rule is taught incontent/docs/data-modeling/object-extensions.mdx, updated here维护者速读
fieldPatches的选项补丁时,改为对照对象所有者自己声明的选项,和安装口、os validate用同一个判定、同一份目标。别的扩展(或本扩展)通过fields重新声明所有者字段时新增的选项,补丁不再生效,日志记一次。os validate拒绝。fieldPatches的包和示例为 0。补丁指向所有者已声明的选项时行为不变。回滚即还原本 PR。packages/objectql/src/registry.ts的foldExtendersOntoDefinition(判定移到合并前)、ownFieldsTarget、admittedFieldPatches。pnpm --filter @objectstack/objectql exec vitest run src/registry-extension-field-patches.test.ts,预期 16/16。What changes
fieldPatchTargetMissesofownFieldsTarget(owner, ownFields, carried): the owner's own fields, each as the OWNER declares it. That is the target the install door (getObjectOwner(name).definition) andos validateread. The merge gets only the admitted patches (admittedFieldPatchesdrops a missed field's patch, or a missed option's entry), andreportFieldPatchMissesnames exactly the misses. One judge, one verdict, applied and reported from the same answer.carriedkeeps fix(objectql,cloud-connection)!: a field patch reaches the owner's own fields only, at the fold and the install door; the install door refuses it with 422 (#28733) #28791's rule: an own field the fold carries in record spelling, or one this body redeclares. The array-spelled pin stays green, andapplyFieldPatcheskeeps itsownFieldsguard.cloud-connectionorclisource, nopackages/spec/**, no new gate, error code or export.metadata-corechanges one docblock sentence (no code).object-extensions.mdx: options are the owner's too, plus the residual case.Residual (ruling 4), pinned as measured (head
301b4e3d). An earlier layer (an extension'sfieldsredeclaration, or a tenant overlay base) leaves out an option the owner declares, and a later patch names it. All three readers admit it;applyFieldPatchesfinds no such option, so nothing of it applies. The fold then asks the same judge of the merged fields, which only names, so the patch is named once, as on main. No new rule.Clause-② measured: yes (narrowing). On main the fold applied a patch of an option the owner does not declare whenever it was already on the merged field: one a redeclaring extension folded first adds (served
Banking), or one a tenant overlay base adds (servedBulk). Now neither applies, and each is named once; both doors already refused it.Tests
Round 2 (head
301b4e3d, contract review should-fixes S1/S2). 17 tests in the file (6 new). Red on main663b7c08: 3 failed | 14 passed (17): the two redeclare cases and the tenant overlay case (wholesale served Bulk). Second-pass ablation (reportFieldPatchMissesgets misses only): 2 failed | 15 passed (both residual cases); restore ok, blob == HEAD. Two-minute check: expect 17/17. objectql typecheck in full exit 0 (ledger unchanged 39/233/64); eslint exit 0; objectql full suite 520 files, 9996 tests passed.Red first, ablation, agreement
registry-extension-field-patches.test.ts, 5 new cases:financeby redeclaringindustry(priority 100), and a patcher (200) patches it;techandretailstill apply onto the redeclared field;Each asks the door's judge with
getObjectOwnerbeside the fold.Red first:
registry.tsrestored to main663b7c08gaveTests 3 failed | 13 passed (16). Both redeclare cases servedBanking, and the residual named one line. Restore:git checkout HEAD, porcelain empty.Ablation (
ablation-replace.mjs): the judge's target set back to the merged field, which gave the same 3 red. Restore:ok restored: blob == HEAD,git diff HEADempty, marker count 0.Agreement cases (green on main by construction, since the doors already read the owner):
financewith 422 beside an installed takeover;findFieldPatchTargetRefusalsrefuses it in both the same and another extension.Suites, typecheck, lint, gates, dogfood
Head
23083aa1, after a whole-repopnpm build(exit 0), each under the verify lock:All passed.
tsc --noEmitexits 0 on all four, andeslint --no-inline-configexits 0 on the 5 touched files.Gates:
dispatch-gates.mjs --commandsderived 95; all 95 ran, every exit 0.--ran: 95 derived, 95 run, 0 NOT-MEASURED.Dogfood battery (narrowing arm):
pnpm --filter @objectstack/dogfood test, VERDICT command-exit 0. Test Files 380 passed, 3 skipped; Tests 3114 passed, 28 skipped.Acceptance notes
origin/mainhas moved 10 commits since the gates;git merge-treeagainst it is clean. Seat 1's PR feat(metadata-protocol,objectql): an object extension is an authorable item of a writable package, saved, published and exported through the existing doors (#28574) #28811 has not landed; whichever lands second merges main once.🤖 Generated with Claude Code
https://claude.ai/code/session_01FEkQ5oTRCUNQ4EA3YV84sZ