Repository navigation
refactor(metadata-protocol): move getDiscovery's body into its facet, and settle the card's last facade-gate rows - #31177
Conversation
…obe reads a parameter The codemod's members pass refuses getDiscovery on main: its body reads the instance method searchAll as a value (`typeof this.searchAll`), and a host entry forwards a method through a closure that is always a function. This intermediate makes the probe read a parameter, searchAllOnInstance, so the members pass can move the body; the next commit is the pass's output on this tree and the commit after it the hand edits that remove the parameter from the public signature again (the stub passes this.searchAll, read on the instance). `node scripts/codemod-split-protocol.mjs --members --verify --base X` proves the generated commit against this one. Not a landing state on its own: getDiscovery's public signature carries the parameter here. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ihL2ebbZkr2QAEG1x7UC8
…(codemod output on X) `node scripts/codemod-split-protocol.mjs --members getDiscovery --write` run on the intermediate X (the previous commit), unedited. The body goes to ProtocolDiscoveryAndBasesFacet in protocol-discovery-and-bases.ts by the E1 form; the stub forwards protocolHost(this) and the parameter. `--members --verify --base X` exits 0: 1 moved member, host-split 1/1 E1, undoing the move rebuilds X's protocol.ts, protocol-host.ts and section modules byte for byte (15 import bindings pruned). The next commit is the hand edit that takes the parameter off the public signature again. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ihL2ebbZkr2QAEG1x7UC8
…he instance (hand edits) The hand edits on top of the codemod output: - protocol.ts: getDiscovery takes no parameter again (its public signature is main's), and the stub hands the facet `this.searchAll`, read on the instance. The facet keeps `typeof searchAllOnInstance === 'function'`, so capabilities.search still answers whether this instance serves search; a host entry would have forwarded the method through a closure that is always a function. - facade-delegation-registry.json, per ruling 6687801899: the getDiscovery row goes; triggerAutomation, sql-driver `get supports` and `static DIALECT_CONNECT_TIMEOUT` stay on #30147 as accepted terminal exceptions, each reason prefixed with the ruling; the four engine.ts rows are re-pointed to #30975. - A patch changeset for @objectstack/metadata-protocol. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ihL2ebbZkr2QAEG1x7UC8
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ihL2ebbZkr2QAEG1x7UC8
📓 Docs Drift CheckThis PR changes 1 package(s): 27 hand-written doc(s) name something this change touched — list omitted above 15 rows. Re-derive on the tree named below: ⛔ 12 release-owned page(s) also affected — read-only, see AGENTS.md Documentation Guardrails. What this run could not see
Coarse fallback — 10 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 21afdaa800c09005db431ab989580144053a1cda && git checkout 21afdaa800c09005db431ab989580144053a1cda
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 21c1f74850eade99b4cb30b86b271d6a9dbd71c7 1a84657c25aa12f010b0174281a43fd51420eb37 && git checkout -B drift-repro 21c1f74850eade99b4cb30b86b271d6a9dbd71c7 && git merge --no-ff 1a84657c25aa12f010b0174281a43fd51420eb37
node scripts/docs-audit/affected-docs.mjs --json 21c1f74850eade99b4cb30b86b271d6a9dbd71c7
|
|
domain:devx#2 · marchtian · session_017ihL2ebbZkr2QAEG1x7UC8 Contract reviewServed-tier: Round 1 was judged at Read: ① Derived judgments1. Behaviour preserved — holds.
2. Codemod honesty — holds, by reading.
3. Registry against ruling 6687801899 — holds.
4. Public surface — unchanged, by reading. 5. Landing.
Check-runs at head (polled 2026-11-07T16:12Z):
Must-fix: none. Should-fix:
② Semver level
③ Boundary flags
④ Design judgmentThe move holds against the code it cites and its scenario. The hazard the registry row recorded was real: a host entry forwards a method through a closure that is always a function, so The registry edits implement ruling 6687801899 as written. The three terminal rows are justified on their own reasons: a one-statement facet, a public declaration change, and a class-evaluation-order hazard. #30975 holds the engine rows with its plan. The should-fix items are hygiene. None changes what the code does. Round 2 delta (
|
…t to the facet; name accepted terminal rows in the facade gate header - protocol.ts kept the commit 376c70f comment that annotated its resolveDiscoveryVersion import after the members pass moved that import to the facet, so the comment sat above an unrelated import. It now annotates the facet's import of resolveDiscoveryVersion and names the facet. - check-facade-delegation-only.mjs's header said every exception row names the card that will move it; it now also says a row may be an accepted terminal exception that cites the maintainer ruling which accepted it and stays after its card closes. Comment only, no gate logic change. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ihL2ebbZkr2QAEG1x7UC8
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ihL2ebbZkr2QAEG1x7UC8
|
domain:devx#2 · marchtian · session_017ihL2ebbZkr2QAEG1x7UC8 维护者速读
席位意见:可以落地。行为不变的证据完整,包括函数体逐行对照、公开类型逐字节一致、反向对照。第一轮的 3 项应改已在第 2 轮全部修好,增量复审通过。 席位核对 — ACCEPT ·
|
Requested by 田騏 · project thread
Fixes #30147
Clause-②: no
Metadata-protocol: none
维护者速读
getDiscovery的方法体从protocol.ts搬进所在分区的 facet(ProtocolDiscoveryAndBasesFacet),类上只留签名和一行委托;并按裁决 6687801899 收尾 facade 门禁登记表里这张卡名下剩下的行。getDiscovery靠typeof this.searchAll === 'function'决定是否对外宣告"支持搜索",codemod 的 host 转发会让这个判断恒为真,所以手工搬:类上读实例自己的searchAll再交给 facet 判断。index.d.ts/index.d.cts与 main 逐字节相同;回滚即 revert 本 PR。packages/metadata-protocol/src/protocol.ts中getDiscovery的存根(传this.searchAll那一行);protocol-discovery-and-bases.ts中 facet 的search: typeof searchAllOnInstance === 'function';scripts/facade-delegation-registry.json的 8 处改动。pnpm check:facade-delegation-only,预期末行5 facade class(es) in 3 file(s) hold delegations only, 15 named exception(s).,退出码 0。What changes
getDiscovery, a hand move in three commits. The codemod's members passrefuses this member on
main: its body reads the instance methodsearchAllas a value to set
capabilities.search, and a host entry forwards a methodthrough a closure that is always a function, so a moved probe would advertise
search on every host. The route the card records (dev report 6686885545,
phase_3b):43df6766ffis the intermediate X: the probe reads a parameter,searchAllOnInstance, instead ofthis.searchAll. Not a landing state onits own (the public signature carries the parameter there).
4a2e27e428isnode scripts/codemod-split-protocol.mjs --members getDiscovery --writerun on X, unedited: the body goes to
ProtocolDiscoveryAndBasesFacetbythe E1 form (460 body lines), and the stub forwards
protocolHost(this)and the parameter.
e87a512b0eis the hand edit:getDiscovery()takes no parameter again,so its signature is
main's byte for byte, and the stub hands the facetthis.searchAll, read on the instance. The facet keepstypeof searchAllOnInstance === 'function'. The stub also gains atwo-line comment that says why.
host-split.mjs's refusal of a method read as a value is unchanged.The registry (
scripts/facade-delegation-registry.json), per ruling6687801899:
getDiscoveryrow is deleted (16 to 15 exceptions, onmainafter refactor(objectql): move the ObjectQL constructor body into the hooks-and-functions facet (E3) #31151);triggerAutomation, sql-driverget supportsandstatic DIALECT_CONNECT_TIMEOUTkeepcard: "#30147"(the gate requires acard number) and each reason is prefixed with
accepted terminal exception (ruling 6687801899):, the reason alreadywritten kept after it;
engine.tsrows (homeAmountServing,projectHomeAmountsOntoPatch,ScopedContext#derive,[APP_AUTHORED_HOOK_API]) point at objectql engine.ts: retire the four facade-gate exception rows #30147 hands over #30975.engine.tsandsql-driver.tsare not touched.A patch changeset for
@objectstack/metadata-protocol: the package'sbuilt JavaScript changes (the body now runs from the facet module) while its
public
.d.tsdoes not, andMetadata-protocol: nonetakespatch.Tests
No test file changes. Measured on the final head
56dbba9841(this branchmerged with
main56baf78e0c; the merge touched neither package):@objectstack/metadata-protocolvitest: 321 files passed, 4 skipped;22,525 tests passed, 26 skipped.
typecheckexit 0,buildexit 0.packages/restvitest (it loads@objectstack/metadata-protocolthrough the built
dist/, rebuilt from this head): 398 files, 7,782 testspassed, 354 skipped.
discovery-search-capability-agreement.test.ts4/4.e87a512b0e(before the merge) gave the same counts.instead of
this.searchAll; the package rebuilt and the closure confirmedin
dist/index.jsanddist/index.cjs(ablation-dist-preflight.mjs);discovery-search-capability-agreement.test.tsfailed 2 of 4 ("agrees on aprotocol that cannot search" and the anti-vacuity case). Restored from
HEAD(blob hash equal,git diff HEADempty), rebuilt, the closureabsent from
dist/: 4/4 again.Acceptance notes
.d.tsbar.dist/index.d.tsanddist/index.d.ctsbuilt frommainaf3451b08b's two source files and from this branch's are byte-equal(sha256
1b94b057e16e19b5…on all four).getDiscoveryis public with awritten return type and no docblock, so nothing moved out of the printed
declaration.
git checkout 4a2e27e428andnode scripts/codemod-split-protocol.mjs --members --verify --base 43df6766ffexits 0. On the head the same command exits 1, naming exactly the
hand-edited stub and signature (expected; that is the third commit).
triggerAutomation's reason now reads "accepted terminal exception(ruling 6687801899): accepted exception (Facade codemods: retire the codemod-limit exception rows in the facade gate registry (protocol.ts, engine.ts, sql-driver.ts) #30147 phase 3): …": the order was
to prefix and keep the reason already written, and that reason already
opened with its own label. A one-word tidy is the seat's call.
packages/metadata-protocol/src/protocol*.tsor the registry that this branch could collide with; fix(objectql)!: a non-system write may name, in a lookup or user field, only a record the caller can read #30747 (engine.ts) is
untouched here.
Verification
Suites on the final head
One locked run at
56dbba9841:pnpm --filter @objectstack/metadata-protocol buildexit 0,typecheckexit 0,exec vitest run --maxWorkers=2exit 0 (Test Files 321 passed, 4 skipped; Tests 22,525 passed, 26 skipped);pnpm --filter @objectstack/rest exec vitest run --maxWorkers=2exit 0 (Test Files 398 passed; Tests 7,782 passed, 354 skipped);discovery-search-capability-agreement.test.tsverbose: 4 passed (the ordinary host, a host that does not mount the route, a protocol that cannot search, anti-vacuity).Undo proof against X
node scripts/codemod-split-protocol.mjs --members --verify --base 43df6766ffon the tree of4a2e27e428: exit 0.Facade gate
pnpm check:facade-delegation-onlyat1a84657c25: exit 0,5 facade class(es) in 3 file(s) hold delegations only, 15 named exception(s).dispatch-gates
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackat56dbba9841: 65 families derived, all 65 run after a fullpnpm build(plus a rebuild of the packages themainmerge touched), every oneexit 0, codes captured before any pipe.--ran: 65 derived, 65 run, 0 NOT-MEASURED (a derived zero: all 65 recorded an exit code), 0 UNRUN.pnpm --filter @objectstack/spec check:generated: all 14 artifacts up to date (a first run reportedcheck:test-typecheckastsc failed without diagnosticson a contended box; the gate alone and the re-run both pass). eslint on the two changed source files: exit 0.Changed lines
1,033 changed lines (+554 / -479, 4 files, changeset included), under the 3,000 budget.
Session: https://claude.ai/code/session_017ihL2ebbZkr2QAEG1x7UC8
🤖 Generated with Claude Code