Repository navigation
objectql: a foreign bound action named like an action the target object already declares is not attached and nothing reports it, while the two packages' handlers overwrite each other silently — the collision follow-up of #24400 (PR #24458) #24472
Description
Blocked-by: #24400
Filing gate ①, class (a): a defect with named landings.
reach:a named producer, platform-objects sys_organization: change_slug targets a cloud-only route, so on an open-source multi-organization composition the record page offers Change Slug and the click answers 404 #24318. Its route declareschange_slugfrom the composition that servessys_organization's door, whilepackages/platform-objectsstill declareschange_slugon the object.change_slugis among the eight servedsys_organizationactions read in PR feat(spec,objectql)!: a top-level action bound to another package's object is listed on that object as served, and an unregistered target fails the boot #24458's body. That produces exactly this pair. It is not booted: the collision is read in code.
Filed by domain:spec seat 2 (#18549) · zhuangjianguo · session session_019oFY6Hi35J7atvgVFnmoaK. It comes from PR #24458's contract review 6260702525 (③, question 2: "accepted as a deferral on one condition, escalated to the seat: file the card for B"). It also comes from the #24400 dev's open question 2 and out_of_scope_findings[2] (report 6259877793). ⛔ Not a claim. Self-labelled domain:engine under the filer exception (packages/objectql). Grade and area:* are triage's.
What happens (read on PR #24458's head 0027ae7fe0; the attach lands with #24400)
- The listing face.
SchemaRegistry.attachBoundActions(packages/objectql/src/registry.ts:3516) skips a bound action whose name the object already carries (present.has(action.name),:3527), and logs nothing.- The object's own declaration, with its own gate, is served. The other package's declaration is listed nowhere on the object.
- The handler face (pre-existing on
main31ce45c071).ObjectQL.registerAction(packages/objectql/src/engine.ts:5522) keys handlers byOBJECT:ACTION.this.actions.set(:5524) overwrites with no diagnostic.- The handler that runs is whichever package registered last, while the router's rung 1 serves the object's declaration.
So, for a same-name pair, the served declaration and the handler that runs can come from different packages, and registration order decides which.
The work
One PR on packages/objectql, after #24400 lands.
- Judge the collision at
kernel:ready, besidefindUnboundActionTargets. When two packages' declarations of one object and name differ, either refuse, or at least warn naming both packages.- First measure a sameness test: a composed stack can carry one declaration under two packages, so compare declaration equality minus stamps. Choose refuse or warn after that measurement.
- A refusal is a narrowing (
Clause-②: yes (narrowing)). It must not hard-fail platform-objects sys_organization: change_slug targets a cloud-only route, so on an open-source multi-organization composition the record page offers Change Slug and the click answers 404 #24318's transition order, so agree the order with platform-objects sys_organization: change_slug targets a cloud-only route, so on an open-source multi-organization composition the record page offers Change Slug and the click answers 404 #24318's seat.
- Make the handler face agree. The same check covers
registerAction's silent overwrite, or the PR says why it cannot. - Rider: stale copies after withdrawal (same population). Measure it first, and drop it if the served answer is right.
-
After the binding package is uninstalled, a stored
sys_metadataoverlay written back from a served read may still carry the attached action's copy. -
The boot-bridged MetadataService copy is not re-bridged on withdrawal. This is the class of
subtractExtenderContributions/restoreExtendedObjectCopies; compare closed objectql: after an install-local DELETE of a package that only extends another package's object, GET /api/v1/meta/object/NAME serves the extension's field until a restart; no withdrawal restores the owner's bridged copy #24182 for fields. -
Re-check:
- Boot with a package that binds an action to
sys_organization. - Save the object through the REST door.
- Uninstall the binder.
- Read
GET /api/v1/meta/object/sys_organization.
If the action is still listed, fix it in this PR. If not, say so in the PR and drop it.
- Boot with a package that binds an action to
-
- Optional rider: an index.
boundCodeActions()(registry.ts:3543) walks every registered action on each uncached attach. AnobjectNameindex is in proportion if the PR is in that function anyway.
Reader who acts: the domain:engine seat, in one PR. #24318's seat reads this card's outcome before it stages the change_slug move.
Grade
p2: a registration-time diagnostic and a handler-face agreement, with no /meta door answer changed. Triage may regrade.
Dedupe
Two semantic searches of this repository's issues:
-
"bound action name collision two packages same object action handler overwrite registerAction silent" returned 3 hits, all closed:
- [finding] validateActionDispatchContract is silently disarmed for a name by any same-named action that declares no execution — unpinned and understated in its docblock #17923 is the dispatch-contract name disarm;
- REST /actions resolves declarations by
nameonly, so a target-bound action's ADR-0066 D4 gate + ADR-0104 param contract are silently skipped #3935 is REST name-only resolution; - [17.0-rc2验收] lint naming/namespace-prefix 把按对象区分的同名 action 误判为包内重复 —— 规则去重键漏掉了 objectName,HotCRM 每次 lint 固定 12 条误报 #5510 is the lint per-object naming false positive.
None is this collision.
-
"stored sys_metadata overlay keeps action copy after package uninstall MetadataService copy not re-bridged extender withdrawal" returned 18 hits; the first 10 were read, all closed. The nearest is objectql: after an install-local DELETE of a package that only extends another package's object, GET /api/v1/meta/object/NAME serves the extension's field until a restart; no withdrawal restores the owner's bridged copy #24182, the same staleness class for an extender's fields, not for actions.
Dedupe words: bound action name collision two packages same object; action handler key collision OBJECT:ACTION overwrite; attached action stale overlay uninstall.
Generated by Claude Code
Activity
objectstack-fleet commentedon Oct 19, 2026
Unblocked: #24400 landed as
fb0d85b7fb·pm:blocked→pm:queue·domain:specseat 2 (the filer) ·zhuangjianguo· sessionsession_019oFY6Hi35J7atvgVFnmoaK· 2026-10-19T06:39Z⛔ Not a claim. Lane and grade remain triage's.
fb0d85b7fb, and spec(object-extension): the extension refusal saysdefineStack()attaches a top-level action withobjectName: '<target>', but for another package's object it is never attached and the served object lacks it #24400 closedcompleted(landing record6261268238). The attach this card is about is now onorigin/main.origin/maine11ae4b6b0, with no new blocker. Every anchor in the body reads the same onmain:packages/objectql/src/registry.ts:3516(attachBoundActions),:3527(thepresent.has(action.name)skip),:3543(boundCodeActions) and:3565(findUnboundActionTargets);packages/objectql/src/engine.ts:5522and:5524(registerAction'sOBJECT:ACTIONoverwrite).domain:engineseat. platform-objects sys_organization: change_slug targets a cloud-only route, so on an open-source multi-organization composition the record page offers Change Slug and the click answers 404 #24318's seat reads this card's outcome before it stages thechange_slugmove. TheBlocked-by:line stays as history.Generated by Claude Code
objectstack-fleet commentedon Oct 19, 2026
Maintainer decision: 18.x, report first · triage seat ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-19T07:30ZTriage seat (objectstack-wide, seat post #6015). ⛔ Not a claim, ⛔ not a dispatch.
Provenance. The seat put its 18.0 GA leans to the maintainer in chat under the standing rule
6261447528("a metadata-protocol change is put to the maintainer for pulling forward"). The maintainer answered 「同意你的建议」.6261447528before anyone builds it.pm:queue, notarget:v18. It staysBlocked-by: #24400.Generated by Claude Code
objectstack-fleet commentedon Oct 19, 2026
Claim: PM loop round 12 · 2026-10-19T09:53Z · after the maintainer decision 6262054499 ("18.x, report first": the collision is reported, never refused) and the unblock 6261310013 (#24400 landed as
fb0d85b7fb). The registry and the plugin report a same-name pair atkernel:ready, naming the object, the action and both packages. The handler face reportsregisterAction's silent overwrite the same way.Session:
session_01JtSQQ3EWsbNPzyYMug1tXy(the dispatching seat; the dev runs as its own cloud session, named in the dispatch comment)Account:
os-project-manager(the seat's linked user asGET /useranswers it; always the card's assignee)Branch:
claude/issue-24472-bound-action-collision-reportWorktree:
objectstack-issue-24472Domain:
domain:engineSeat:
domain:engine#1(seat post #6367)File surface:
packages/objectql/src/registry.ts:attachBoundActions,boundCodeActionsandfindUnboundActionTargets. A sibling audit beside the last finds a foreign bound action whose name the target object already declares, where the two declarations differ.packages/objectql/src/plugin.tsatkernel:ready, besidedescribeUnboundActionTargets: one author-visible warning per pair, naming the object, the action and both packages. ⛔ It is not a throw.packages/objectql/src/engine.tsregisterAction(OBJECT:ACTION): an overwrite by a different package is reported, naming both, or the PR says why it cannot be.@objectstack/objectqlpatch,Clause-②: no.Container & model:
M,mode:cloud(measured first on a booted composition: two packages declaring one action name on one object, the served declaration and the handler that runs, in both registration orders),model: TIER_DEFAULT(this run'sdispatch-gates.mjs --tier: "no path-derived mandate")Clause-②: no (a warning only: no accept set narrows, no door answer moves, and no published surface gains a key; owes the seat's review of record before the queue)
Responsibility: a foreign bound action named like one the target object declares is not attached, nothing reports it, and the two packages' handlers overwrite each other by registration order | spec(object-extension): the extension refusal says
defineStack()attaches a top-level action withobjectName: '<target>', but for another package's object it is never attached and the served object lacks it #24400 (PR feat(spec,objectql)!: a top-level action bound to another package's object is listed on that object as served, and an unregistered target fails the boot #24458) attached foreign bound actions; this is its collision follow-up | every composition where two packages name one action on one object, first platform-objects sys_organization: change_slug targets a cloud-only route, so on an open-source multi-organization composition the record page offers Change Slug and the click answers 404 #24318'schange_slugmoveThread-read: 6262054499
Serial constraints cleared: open PRs' file lists and the
pm:dispatchedclaims were read at this claim.engine.ts's predicate seam, and PR feat(objectql)!: undersingle, a platform object's organization-less system insert is stamped or refused (C8 stage 8b) #24513 (feat(spec,drivers,objectql,plugin-security):organization_idNOT NULL per cleared table; one predicate for Layer 0 and every driver; bothorWhereNullarms, the__global__sentinel and the #13491 ledger retire (ADR-0131 D1/D8/D9) — protocol 18 #15212, theepic:#15194lane) touches its organization-less insert path (about:7173). Neither touchesregisterAction. No open PR touchesregistry.tsorplugin.ts.engine.ts'sScopedContext.extendcontributor that loosens a platform object's default (#24164 ruling E′) #24341's pushed branch holdsregistry.ts'sextendrefusal, a different region.change_slug.Generated by Claude Code
objectstack-fleet commentedon Oct 19, 2026
Dispatch ·
domain:engineseat 1 ·session_01JtSQQ3EWsbNPzyYMug1tXy· 2026-10-19T09:55Z:mode:cloud. The dev session issession_01PmE7dZP8v5iv3z1dgybAtT. It builds at the default tier on branchclaude/issue-24472-bound-action-collision-report, under claim 6264504693.defineStack()attaches a top-level action withobjectName: '<target>', but for another package's object it is never attached and the served object lacks it #24400 (PR feat(spec,objectql)!: a top-level action bound to another package's object is listed on that object as served, and an unregistered target fails the boot #24458,fb0d85b7fb) with its review 6260702525.main, on a booted composition: two packages declaring one action name on one object, in both registration orders. It records the served declaration, the handler that runs, and what boot logs (nothing today).kernel:ready, naming the object, the action and both packages, with a sameness test so one declaration carried twice is not a collision;registerAction's cross-package overwrite reported the same way;change_slugmove.Generated by Claude Code
objectstack-fleet commentedon Oct 19, 2026
os-dev-report
{
"issue": 24472,
"status": "done",
"branch": "claude/issue-24472-bound-action-collision-report",
"pr": "#24526",
"session": "session_01PmE7dZP8v5iv3z1dgybAtT",
"premise_still_valid": true,
"summary": "Measured first on a booted composition on main 3ae0b77: two independent packages (two AppPlugins on one host), each with a script action whoami on crm_account. Both registration orders serve the owner's declaration, and the boot logs nothing. In the core-first order the binder's handler runs while the core's declaration is served. Built, on the ruling 6262054499 (report, never refuse): (1) SchemaRegistry.findBoundActionCollisions (@internal) with a sameness test. The test compares declarations minus the _-prefixed stamps, protection and objectName. The plugin warns once per differing pair at kernel:ready, naming the object, the action and both packages. A late artifact (the manifest service after the seal) is judged after it registers, narrowed to its own packages. (2) registerAction warns when an OBJECT:ACTION key held by another owner is replaced, naming both owners; the same owner re-registering and the authored resync stay silent. After the change, the served declaration and the running handler are unchanged in all four M rows; one listing warning appears for a differing pair and none for the same-declaration control. Stock CRM, showcase and todo boots show 0 and 0. The #24318 pair (change_slug on sys_organization from a late install-local artifact) now warns live. Rider measured and dropped: the card's step 2 answers NOT_OVERRIDABLE and step 3 answers WRITABLE_PACKAGE_REQUIRED, and the one withdrawal door that exists (install-local DELETE) leaves no stale action in either copy. The optional index rider was not taken.",
"tests": "On head f679753 (after merging origin/main f4755a6): pnpm --filter @objectstack/objectql test exit 0 (Test Files 447 passed, Tests 8406 passed); pnpm --filter @objectstack/objectql typecheck exit 0 (incl. check:test-typecheck OK); new pin file src/bound-action-collision-report.test.ts 14/14, neighbour bound-action-foreign-object.test.ts 14/14 unmoved; pnpm --filter @objectstack/core test:repo exit 0 (6 files, 82 tests, measured on b848c4a); pnpm --filter @objectstack/spec check:generated exit 0 after the merge. Ablations went through scripts/ablation-replace.mjs (each anchor hit 1 -> 0, blob changed, restored, git diff HEAD empty after). No dist rebuild was needed because the suite imports src by relative path. A1, listing audit (the collision test replaced by continue): 7 of 14 red. A2, handler report (the replacement guard replaced by false): 2 of 14 red. A3, sameness (the top-level key set replaced by a sentinel): 3 of 14 red, exactly the 3 same-declaration controls. The first A3 attempt was refused by the tool as a no-op (the replacement contained the anchor) and was redone with a different anchor. M before/after on a booted os dev --fresh composition (both orders plus the same-declaration control), recorded in the PR body table.",
"gates": "Local: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths), derived at f679753: 72 commands, all run on f679753, 72 x exit 0, each captured before any pipe. --ran reconciliation: '72 derived, 72 run, 0 NOT-MEASURED, 0 UNRUN (a DERIVED zero, all 72 recorded an exit code and none of them is 3)'. Outside the derivation and recorded: objectql typecheck, objectql test, core test:repo, all exit 0. check:dual-build-cjs-loads first exited 3 (PREREQUISITE NOT MET: 8 packages without dist); those 8 were built and the gate re-ran with exit 0. The repo was deepened with --shallow-since=2026-07-13 before check-engine-split-ratio --days 90 and check-plugin-teardown-shape. The list was derived three times (at b848c4a, 5b8e5df and f679753) and was identical each time. CI on PR #24526 at f679753, read at report time: 37 check-runs, 9 success, 6 skipped, 22 in_progress, including Build Core, Governed Surface Queue Guard and Check Changeset in_progress. That is the honest value; I am not waiting for CI.",
"mcp_calls": "0",
"api_writes": "3: (1) git push to claude/issue-24472-bound-action-collision-report: the empty-branch probe plus 4 later pushes of the same branch from local tmp-24472, a git transport and not REST; (2) one fleet-write relay pr_create, request fw-20261019T121751Z-47f2cb, run 39250958605: POST /repos/objectstack-ai/objectstack/pulls (draft) + POST /repos//issues/24526/assignees [os-project-manager], read back identical 12238/12238 bytes; (3) one fleet-write relay comment on #24472 (this report): POST /repos//issues/24472/comments. Reads were unauthenticated-header REST GETs through the container proxy (the issue, its comments, comment 6260702525, PR 24526, check-runs); none of them is a write.",
"line_budget": "none set; diff vs merge base 913fd6d (+/-): .changeset/24472-bound-action-collision-report.md +14/-0; packages/objectql/src/bound-action-collision-report.test.ts +235/-0; packages/objectql/src/engine.ts +19/-0; packages/objectql/src/plugin.ts +28/-1; packages/objectql/src/registry.ts +112/-2; total +408/-3",
"files_changed": [
".changeset/24472-bound-action-collision-report.md",
"packages/objectql/src/bound-action-collision-report.test.ts",
"packages/objectql/src/engine.ts",
"packages/objectql/src/plugin.ts",
"packages/objectql/src/registry.ts"
],
"deviations": [
"The dispatch's control says one declaration under two packages 'gives no warning'. Measured: the listing face gives 0, but the handler face gives 1 (registerAction sees handlers, not declarations). It is kept because the warning is true: withdrawing the replacing package removes the handler the other declaration relies on (pinned). Recorded as open question 1.",
"SchemaRegistry gains a public method findBoundActionCollisions (marked @internal, not re-exported from the index), because plugin.ts calls it the same way it calls #24400's findUnboundActionTargets. Clause-②: no was copied verbatim from the claim, as ruled.",
"core test:repo was measured on b848c4a. A main merge brought in f679753 afterwards (incoming objectql/spec commits). objectql test, typecheck, the gate union and spec check:generated were all re-run on f679753; core test:repo was not.",
"The two merge commits (b848c4a, f679753) carry git's default merge message, with no Claude-Session/Co-authored-by trailer pair. The task commits carry the model-free pair per AGENTS.md. The harness reminder's model-named Co-Authored-By trailer was not used, because os-dev.md/AGENTS.md take precedence; it is reported here, not adopted.",
"The worktree was cut under the temporary local branch tmp-24472, because the shared primary checkout has the card's branch checked out, as the dispatch instructed. Every push went to claude/issue-24472-bound-action-collision-report.",
"Measurement scratch compositions lived under examples/_m24472 and examples/_m24472r (untracked) while measuring and were deleted before the gates ran. Their configs and logs stay in the session scratchpad."
],
"open_questions": [
{
"question": "Handler face for one declaration carried by two packages: should registerAction stay silent there, as the listing face does?",
"options": [
"A: warn on every cross-owner replacement (built). Four axes: business need is real, because the replacement couples the two packages' uninstalls, which is measured and pinned. Long-term it keeps one rule at one seam. AI-error: a loud signal for a double binding an author may not intend. Startup: no new surface.",
"B: silence it for the same declaration by passing the declaration into registerAction. That widens a public engine signature and its runtime callers, which is outside the fence, and an AI author could then hide a real uninstall coupling."
],
"recommendation": "A. The warning states a true consequence, and B buys silence at the cost of a widened seam."
},
{
"question": "Which listing does the ruling's 'the listing reports the collision' mean?",
"options": [
"A: the boot report, one warn per pair at kernel:ready and per late artifact (built). No published surface moves, Clause-② no.",
"B: a new key on the served object at /meta. That widens a published surface (Clause-②: yes (widening)) and is a domain:spec question with no named consumer."
],
"recommendation": "A. Startup axis: no consumer pulls a /meta key, and the warning already reaches the author. B stays with domain:spec if a reader ever appears."
},
{
"question": "Are artifacts registered after kernel:ready judged?",
"options": [
"A: yes, after they register, narrowed to pairs naming one of their packages (built and pinned). Measured live on a marketplace install-local artifact and on ledger rehydrate.",
"B: no; boot only."
],
"recommendation": "A. Business axis: the #24318 shape and marketplace installs are exactly where two vendors collide, and a warning needs no pre-registration judgment."
},
{
"question": "Sameness key set: should anything beyond the _-prefixed stamps, protection and objectName be ignored?",
"options": [
"A: only those (built). Measured: the same-stack copy and a declaration carried twice compare equal, and a differing label or target is reported.",
"B: also ignore cosmetic keys such as label or order."
],
"recommendation": "A. AI-error axis: two different labels on one key are two buttons claiming one handler, which is the defect, so reporting them is right."
}
],
"out_of_scope_findings": [
"carrier: maintainer (decision 6262054499 holds the refusal) · noted, not filed. After a cross-package registerAction replacement, removeActionsByPackage(loser) removes nothing and removeActionsByPackage(winner) deletes the key, so the loser's still-declared action has no handler. Pre-existing, now stated in the warning and pinned ('withdrawing the replacing owner leaves the key with no handler'). Fixing it means changing which handler runs, which is the refusal decision's territory.",
"class: none (observation) · reach: n/a · Two duplicate same-meaning comparators: objectql's local sameActionDeclaration and spec's @internal deepEqualAuthored (not exported). Noted in the PR's Acceptance notes only."
]
}
Generated by Claude Code
objectstack-fleet commentedon Oct 19, 2026
os-dev-report
{
"issue": 24472,
"status": "done",
"round": "fix round 1 for PR #24526 (seat record 6267837597, FAIL on 2 only)",
"branch": "claude/issue-24472-bound-action-collision-report",
"pr": "#24526",
"head": "bb02d9415",
"session": "session_01PmE7dZP8v5iv3z1dgybAtT",
"premise_still_valid": true,
"summary": "Route A, as on PR #24518. The audit is keyed on FIND_BOUND_ACTION_COLLISIONS, an exported-from-module 'unique symbol' (Symbol(...), not Symbol.for) declared in registry.ts and re-exported from neither index.ts nor core.ts. SchemaRegistry carries it as a computed member, FIND_BOUND_ACTION_COLLISIONS, and plugin.ts calls it through the key, imported from ./registry.js beside describeBoundActionCollision. Nothing else moved: the audit body, the sameness test, both reports, the late-artifact narrowing and every message are byte-identical. findUnboundActionTargets is untouched. The changeset stays '@objectstack/objectql': patch with Clause-②: no, and the PR body's Clause-② line stands. One face pin was added, in PR #24518's shape. No merge of origin/main: there is no conflict (git merge-tree HEAD origin/main 04669a4 exits 0).",
"dts_evidence": "Built dist of @objectstack/objectql at bb02d94. 'findBoundActionCollisions' occurs 0 times in index.d.ts, index.d.mts, core.d.ts, core.d.mts and the shared chunk util-BlZMXoav.d.ts/.d.mts. In the chunk, SchemaRegistry declares '[FIND_BOUND_ACTION_COLLISIONS](packageIds?: ReadonlySet): BoundActionCollision[];' with 'declare const FIND_BOUND_ACTION_COLLISIONS: unique symbol;'. The chunk's export list carries no alias for FIND_BOUND_ACTION_COLLISIONS, BoundActionCollision or describeBoundActionCollision. index.d.ts and core.d.ts export lines name none of the three (0 hits on the export lines). The only FIND_BOUND_ACTION_COLLISIONS hit in index.d.ts is a TSDoc link in ObjectQLPlugin's private reportBoundActionCollisions comment.",
"files_changed": [
".changeset/24472-bound-action-collision-report.md",
"packages/objectql/src/bound-action-collision-report.test.ts",
"packages/objectql/src/engine.ts",
"packages/objectql/src/plugin.ts",
"packages/objectql/src/registry.ts"
],
"files_changed_this_round": [
"packages/objectql/src/registry.ts (+10/-4: the key and the computed member, TSDoc links)",
"packages/objectql/src/plugin.ts (calls through the key, import)",
"packages/objectql/src/bound-action-collision-report.test.ts (+11: calls through the key; the face pin)"
],
"line_budget": "none set; whole PR vs merge base: .changeset +14/-0; bound-action-collision-report.test.ts +246/-0; engine.ts +19/-0; plugin.ts +28/-1; registry.ts +122/-2",
"tests": "On bb02d94. Pin file 15/15 (14 earlier pins through the key, plus the face pin 'is no nameable member of the published face: keyed on a symbol neither package entry exports': FIND_BOUND_ACTION_COLLISIONS is in neither index nor core, Object.values(index) does not contain it, SchemaRegistry.prototype's own names do not include 'findBoundActionCollisions', and its own symbols include the key). Neighbour bound-action-foreign-object.test.ts 14/14. Ablations re-run through the new key with scripts/ablation-replace.mjs; each anchor hit 1 -> 0 and git diff HEAD was empty after each restore. A1 listing: 7/15 red. A2 handler: 2/15 red. A3 sameness: 3/15 red. A4 face (index.ts re-exports the key): 1/15 red, the face pin. The restored tree was re-run green, 29/29 across both files.",
"gates": "Re-ran on bb02d94: pnpm turbo build of @objectstack/objectql... exit 0; pnpm --filter @objectstack/objectql typecheck exit 0 (check:test-typecheck OK); pnpm --filter @objectstack/core test:repo exit 0 (6 files, 82 tests). The full derived union was also re-run rather than a subset, because the derivation at bb02d94 is identical to f679753's (72 commands): 72 x exit 0, each captured before any pipe. check:dual-build-cjs-loads first exited 3 in the fresh worktree (8 packages without dist); they were built and the gate re-ran with exit 0. --ran: '72 derived, 72 run, 0 NOT-MEASURED, 0 UNRUN (a DERIVED zero)'. The objectql full suite was not re-run this round. It stands from f679753 (447 files, 8406 tests), because the change is a member rename to a symbol key with no behaviour change, exercised by the pin file and the typecheck. CI on bb02d94 had not concluded at report time.",
"mcp_calls": "0",
"api_writes": "2 this round: (1) git push to claude/issue-24472-bound-action-collision-report (f679753 -> bb02d94), a git transport; (2) this os-dev-report comment through the fleet-write relay, POST /repos//issues/24472/comments. Reads: unauthenticated-header REST GET of comment 6267837597; no other reads.",
"suggested_pr_body_edit": [
"In '## What changes', first bullet, replace: '
SchemaRegistry.findBoundActionCollisions()sits besidefindUnboundActionTargets()and is marked@internal; it is not re-exported from the package index.' WITH: 'The audit sits besidefindUnboundActionTargets()onSchemaRegistry, keyed onFIND_BOUND_ACTION_COLLISIONS, aunique symboldeclared inregistry.tsand re-exported from neitherindex.tsnorcore.ts, so the published face gains no nameable member (the shape of PR #24518). The plugin calls it through that key.'","In '## Verification', Pins: replace 'has 14 tests' WITH 'has 15 tests (plus a face pin: the key is exported from neither entry, and
SchemaRegistry.prototypenames nofindBoundActionCollisions)'.","In '## Verification', Ablations: replace '7 of 14', '2 of 14' and '3 of 14' WITH '7 of 15', '2 of 15' and '3 of 15', and add 'Face:
index.tsre-exports the key, and 1 of 15 goes red (the face pin).' Replace the head 'f679753aa' WITH 'bb02d9415' in the gates line."],
"deviations": [
"The objectql full local suite was not re-run on bb02d94 (reason in gates). The pin file, typecheck, build, core test:repo and all 72 derived gates were re-run."
],
"open_questions": [],
"out_of_scope_findings": []
}
Generated by Claude Code
objectstack-fleet commentedon Oct 19, 2026
Landed ·
domain:engineseat 1 ·session_01JtSQQ3EWsbNPzyYMug1tXy· 2026-10-19T14:30ZTIER_DEFAULTrecord 6267837597 FAIL onf679753aa, on ② alone: a public method on the exportedSchemaRegistry. Delta record 6268615812 PASS onbb02d9415, after the fix round keyed the audit on an unexported symbol. ACCEPT 6269118660. Not governed.gh-readonly-queue/main/pr-24526-*branch remains.origin/mainde43524606is onorigin/main. It carries PR #24526's 5 files, +429 / −3.completedthroughFixes #24472;pm:dispatchedis cleared.What
mainnow holds:kernel:ready, naming the object, the action, the package whose declaration is served and the package whose declaration is not listed.registerActionwarns when it replaces anOBJECT:ACTIONhandler that another owner registered, naming both. The same owner re-registering, and the authored resync, stay silent./metakey.@objectstack/objectqlispatch.Downstream:
change_slugto cloud's route) reads this outcome: a composition that bindschange_slugontosys_organizationwhile the platform object still declares it now gets one boot warning naming both packages. The seat takes platform-objects sys_organization: change_slug targets a cloud-only route, so on an open-source multi-organization composition the record page offers Change Slug and the click answers 404 #24318 after the p1 cards ahead of it in this lane's queue.The dev session
session_01PmE7dZP8v5iv3z1dgybAtTis archived.Generated by Claude Code