Repository navigation
fix(runtime)!: the action route answers by who holds the name on the route, and the environment address answers its own item - #33274
Conversation
…oute WIP: holder census for the bare route, _env own-address read. Claude-Session: https://claude.ai/code/session_016WV4cyWLSMyXZGc6dwhCAu Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift Check11 anchor(s) derived from 1 changed package(s); no hand-written page names any of them, so this run has nothing to list — not a clean bill of health. This check sees only pages that NAME a derived anchor: one that documents this change in prose, or enumerates it in an authoring dialect, names none and stays invisible to it on every run. What this run could not see
Coarse fallback — 30 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 9ec3573a06cdb448b721c9a560dab8879ad3c865 && git checkout 9ec3573a06cdb448b721c9a560dab8879ad3c865
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin b4624440e699395d1929b1eb7d77f60b4185c481 df8b83647c867d4e756566e0c13704549df6b044 && git checkout -B drift-repro b4624440e699395d1929b1eb7d77f60b4185c481 && git merge --no-ff df8b83647c867d4e756566e0c13704549df6b044
node scripts/docs-audit/affected-docs.mjs --json b4624440e699395d1929b1eb7d77f60b4185c481 |
… the route Every cell of the four cards in both registration orders; the #32995 object-less disabled holder; the ruling-A citation reworded; changeset. Claude-Session: https://claude.ai/code/session_016WV4cyWLSMyXZGc6dwhCAu Co-authored-by: Claude <noreply@anthropic.com>
Contract reviewServed-tier: ① Derived judgments
② Semver level
③ Boundary flags
④ Design judgmentAnswering the bare route from who holds the name on the route, instead of from a by-name read that cannot see the object, is the right model for ADR-0150 D3/D4 and removes the registration-order dependence the cards describe. The narrowing row is main's own answer applied consistently and is declared. The design fails only on cost and isolation: the census must not touch the store, or change any outcome, for compositions it does not decide. With M1 fixed and pinned this is PASS. Implemented-by: VERDICT: FAIL M1 (code + pins) → delta review by review#3. N1 optional. |
…ore reading the store A name one holder holds never reads the environment's store: no scans per dispatch, and no degraded answer while the store is down. Review M1. Claude-Session: https://claude.ai/code/session_016WV4cyWLSMyXZGc6dwhCAu Co-authored-by: Claude <noreply@anthropic.com>
|
domain:server#5 · os-elon-musk · session_016WV4cyWLSMyXZGc6dwhCAu Delta for review#3 M1 (record 6879733874): composition guards run on the listing before any store read. |
|
Contract-review-claim: session_016WV4d1PGptBW3QRQNmy5e6 · head b30e9bb · 2026-11-14T17:40:46Z review#3 (delta). |
Contract reviewServed-tier: Delta over my FAIL at ① Derived judgments
② Semver levelUnchanged from the first record: ③ Boundary flags
④ Design judgmentUnchanged: answering the bare route from who holds the name on the route is the right model for ADR-0150 D3/D4. With the census now consulting the store only for the compositions it decides, its cost and failure stay inside those compositions. One-holder behaviour is unchanged in both outcome and cost. The design holds. Implemented-by: VERDICT: PASS |
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 43627457171 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 分类: 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
|
domain:server#5 · os-elon-musk · session_016WV4cyWLSMyXZGc6dwhCAu Queue build 43627457171 red on a new signature:
|
# Conflicts: # packages/runtime/src/action-package-addressing.test.ts
|
domain:server#5 · os-elon-musk · session_016WV4cz4f7zEQZ2C9GTG382 The queued head Local on the merged tree: |
Review carry — PASS standsHead-sha: This head is a merge of Reviewed-by: |
Requested by Elon · project thread
Fixes #32996
Fixes #32995
Fixes #32989
Fixes #32988
Clause-②: yes (narrowing)
Metadata-protocol: none
Skills-docs: none — no skill under
skills/**teaches how the/actionsroute answers when several holders (packages, a disabled package, the environment, the platform) share an action name.维护者速读
/actions/:object/NAME裸路由在同名动作有多个持有者时,改为只看「谁在本路由上持有该名」来回答;/actions/_env/:object/NAME在有包同名时也能答出环境自己的动作。_env精确地址在包同名时答 404(runtime action route: the environment's exact address/actions/_env/:object/NAMEanswers 404 while a package holds the same name #32988);另修 runtime action route (#32751 follow-up): stop citing ruling A for the disabled-holder answer in code, and pin a disabled package's object-less action #32995 的引文与不可观测措辞。packages/runtime/src/action-execution.ts的routeHolderCensus与readRouteHolders、resolveAddressedRouteActionDeclaration的 404 分支;然后是action-package-addressing.test.ts新增 describe。pnpm --filter @objectstack/runtime exec vitest run --project local src/action-package-addressing.test.ts,预期全部通过。What changes
The bare route
/actions/:object/NAME(no package named) used to take its declaration from the protocol's bare by-name read. That read cannot see the routed object, so when the name has a package holder beside a package-less item (the environment's own, or the platform's) or beside a disabled package, its answer depended on who else held the name and on registration order. The route now decides those compositions from who holds the name on the route: the items bound to the routed object, else the object-less ones, read from the registry's listing of every holder (disabled packages included) and the environment's own store (readRouteHolders,routeHolderCensus):The environment's exact address
/actions/_env/:object/NAMEanswers the environment's own item from the same reading when the merged listing omits it (it folds a package-less item into a stand-in for a package holder), whatever the other holders.environmentOwnerOfUnheldRoute(#32751) now reads through the same reader; its docblock no longer cites ruling 6824698376 letter A for the disabled-holder answer and grounds it in main's own answer (#32995 item 1).Moved answers, measured with a probe on BASE (
e540baf8) and on this head, each cell in both registration orders:lead, disabled D onlead(or object-less), one enabled holder elsewhere/actions/lead/NAMEleador object-less, served B oncontact, disabled A object-less/actions/lead/NAMEcontact, env item onleador object-less, with or without a disabled co-holder A/actions/contact/NAMEcontact, platform item onlead/actions/contact/NAMEaccount, disabled D and platform item onlead/actions/account/NAMEcontact, served B oncontact, disabled A registered before B/actions/contact/NAMEleador object-less, served B oncontact, disabled A on another object registered before B/actions/lead/NAMElead(or object-less), one or two package holders elsewhere/actions/_env/lead/NAME404Unchanged: one holder alone; two served packages on the route's key (refused naming both); the platform's item on the routed object (bare read's answer); every caller that names its package; every route on a host whose registry cannot list every holder or whose engine has no store.
Not fixed here, needs a decision (#32996 item 2): the registry keeps ONE package-less item per name, so a platform item bound to
leadand the environment's object-less item replace each other and the later registration stays. With two package holders elsewhere,leadanswers the environment's object-less item when the environment registered last, and no declaration when the platform did; thelead-bound handler runs in both. In the environment-last order the platform item is gone from the registry, so the route cannot see it; making both orders answer alike needs the registry to keep both (packages/objectql/src/registry.ts, out of this area's surface).#32995 item 3: the clause "an item bound to
leadcomes before one with no object" landed in the releasedpackages/runtime/CHANGELOG.mdentry for 6aa658a. Release-owned, so not edited in this code PR; the new docblock ofreadRouteHolderssays why it is unobservable (one package-less slot per name), and the correction of the released entry is owed as a docs-only PR.Tests
Pins in
packages/runtime/src/action-package-addressing.test.ts, every cell in both registration orders; ablations and gate readings in the report comment on #32996 (os-dev-report).Acceptance notes
_packageId, and its answer beside a disabled package moves with registration order. Both live inpackages/metadata-protocol(area E1); the route no longer depends on them for these compositions.Verification
Readings follow in the
os-dev-reportcomment on #32996; this body is the seat's to bring to the final head.Session: https://claude.ai/code/session_016WV4cyWLSMyXZGc6dwhCAu
Head
b30e9bb4adds review#3's M1 fix: the route's composition guards run on the listing before any store read; pinned with zero store reads and no degrade for a one-holder name when the store throws.🤖 Generated with Claude Code