You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
objectql plugin: a package's script-bodied action is not bound when its name is shipped by another holder — judge "artifact-shipped" by owner key, not by name #32990
Out-of-scope should-fix of #32751 (PR #32987, triage review 6841909747). Not a regression: the name-only filter isArtifactShippedAction in packages/objectql/src/plugin.ts came with 4f5b791 (2026-07-05), before #32741, so script-bodied actions in this composition never ran on a booted kernel. #32987 narrows its FROM→TO to "its declaration is served" and leaves the handler binding to this card. Graded p2 by the epic seat's rule (regression ⇒ p1, else p2); queued, not dispatched.
Filing gate: ② an epic-seat routing. class: b · type: Defect · Suggested-grade: p2 · lane: domain:server.
What happens
On a booted kernel, the objectql plugin skips binding a script-bodied action when its name is shipped by an artifact, checking the name only. When two holders share a name, the holder whose declaration is served gets no handler, so its route reaches the action but nothing runs.
Do
Judge "artifact-shipped" by the owner key of the action (package + object), not by the bare name, so each holder binds its own handler.
Pin on a booted kernel: two holders of one name, each runs its own body; one ablation per pin.
Declare the moved answer (Clause-② per AGENTS.md step 3).
Reader who acts: packages/objectql/src/plugin.ts (isArtifactShippedAction).
The authored-action resync judges "artifact-shipped" against each code package's own action of the name, by the object it owns, so an environment script action on an object no holder binds gets its handler. Draft PR follows on this branch.
Report for PR #33271 at efef478, written 2026-11-14T17:05Z.
{
"issue": 32990,
"status": "done",
"branch": "claude/area-E2b-32990",
"pr": "https://github.com/objectstack-ai/objectstack/pull/33271",
"head": "efef4782e2d3383e25e732b74136739929681d0e",
"session": "session_016WV4cyWLSMyXZGc6dwhCAu",
"premise_still_valid": true,
"summary": "ObjectQLPlugin's authored-action resync judged 'artifact-shipped' by bare name (getArtifactItem('action', NAME)), so any code package's action of a name left an environment script action of that name on another object without a handler (dispatch: not found). isArtifactShippedAction now reads every holder's artifact of the name (new artifactActionsNamed: first match plus packageScopedHoldersOf with disabled packages, prefer-local per holder) and judges each by the object it owns (standaloneActionOwnsRoute; an object-less artifact owns every object). isDeclaredArtifactActionOverride picks the base among artifacts at the row's owner key, preferring the package overrides.package names and picking none (warned once) when several match and none is named (review#3 S1). review#3 delta PASS at efef4782; the PR was readied and armed by the seat, not by this agent. Only packages/objectql/src/plugin.ts changed in code (plus one docblock in action-handler-coordinate.ts); registry.ts, metadata-protocol, runtime/action-execution.ts untouched.",
"clause_2": "Clause-②: yes (widening). FROM→TO: (1) two holders A on alpha_account, B on beta_contact, environment script action on env_lead, both orders: FROM dispatch 'Action approve on object env_lead not found' TO the environment's body runs, A and B run their own (unqualified and package-qualified). (2) one holder, environment row on another object: FROM not found TO the environment's body runs (review#3 read it within the one-holder red line: resolution untouched). (3) B.custom declared override of B's action, A registered first: FROM override unbound, B's body runs TO the override runs over B's handler; B first: unchanged. (5) A and B both object-less, B.custom override: FROM judged against whichever registered first TO the override runs over B's handler, A's call still runs A. Unchanged CONTROLs: row on a holder's own object stays its customization; object-less package action keeps other objects' rows unbound; a disabled holder still owns its object. Metadata-protocol: none.",
"tests": "Premise on unmodified source (pins committed first, d2848f11): case 1 answered \"Action 'approve' on object 'env_lead' not found\"; the override case answered 'ran beta' with A first. Booted-kernel describe '[#32990] …' in packages/objectql/src/plugin-authored-actions.test.ts (ObjectKernel + ObjectQLPlugin kernel:ready resync + manifest service; doubled driver and the runtime AppPlugin's runner/handler binding): 7 cases. Local: pnpm --filter @objectstack/objectql build && typecheck: VERDICT command-exit 0 (check:test-typecheck OK); pnpm --filter @objectstack/objectql test on 63a002e9 (S1 code; efef4782 only changes the test double): Test Files 595 passed (595), Tests 12943 passed (12943); vitest run src/plugin-authored-actions.test.ts: 31 passed (31); pnpm lint: VERDICT command-exit 0. Ablations (scripts/ablation-replace.mjs, landed by anchor count + blob hash, restore verified blob == HEAD and empty diff; suite imports ./plugin.js from source, no rebuild): (1) bare-name judgement -> 2 failed (two holders, one holder); (2) per-holder check never matches -> 2 failed (disabled CONTROL, object-less CONTROL); (3) owner-key equality instead of standaloneActionOwnsRoute -> 1 failed (object-less CONTROL); (4) override base = first artifact -> 1 failed (second-holder override); (5) nothing artifact-shipped -> 3 failed (three CONTROLs; first attempt refused by ablation-replace since its replacement contained the anchor, no run, re-run with another anchor); (6) S1: override base = atKey[0] -> 1 failed (object-less two-holder override pin). Dependents runtime/cli local runs: first attempt invalid (closure unbuilt, 497 files 'Failed to resolve entry'), reruns NOT MEASURED (verify lock queue-timeout exit 99 three times, holder pid 31240 running an 85-package turbo test for 20+ min); carried by CI Test Core 1-8/8 success at efef4782.",
"gates": "Local: node scripts/pm/dispatch-gates.mjs --commands derived 69 families at ab806df2/efef4782. 67 run, each exit captured before any pipe: 66 exit 0, check:dual-build-cjs-loads exit 3 (PREREQUISITE NOT MET: needs a full packages build; NOT MEASURED locally). check:objectql-double-limit first went red (exit 1) on the new booted-kernel row-store double (limit-blind, then copy-before-bound); fixed in efef4782 and re-run exit 0. check-plugin-teardown-shape --self-test first exit 3 (pinned control commit 621a4876 not in the object store); fetched it, re-run exit 0. check:type-check-debt NOT MEASURED locally (lock queue-timeout exit 99). --ran reconciliation: 69 derived, 67 run, 1 NOT-MEASURED (dual-build-cjs-loads), 1 UNRUN (type-check-debt, lock). CI at efef4782 (check-runs): Lint & Repo Gates success, TypeScript Type Check success, Type Check · debt ledger success, Test Core success (8/8 shards success), Build Core success, Dogfood Regression Gate success, Governed Surface Queue Guard success, Live E2E UI success, Test UI success, Check Changeset success, PR-body guards success; UI lanes skipped by selector.",
"dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
"mcp_calls": "0",
"api_writes": "3 — post-stamped.mjs claim comment on #32990 (relay, POST /repos/objectstack-ai/objectstack/issues/32990/comments; the area session's addendum ordered it); fleet-write pr_create (POST /repos/objectstack-ai/objectstack/pulls draft + POST /issues/33271/assignees os-elon-musk); post-stamped.mjs os-dev-report comment on #32990. Plus git pushes (not REST).",
"open_questions": [],
"security_findings": "none",
"out_of_scope_findings": [
"carrier: none · noted, not filed — ObjectQL arrivesAsDeclaredBase (packages/objectql/src/engine-actions.ts) reads getArtifactItem('action', NAME) by bare name when a declared base's handler arrives under an armed override; with two holders of the name it may judge another holder's artifact. Not measured (no repro), so in PR Acceptance notes only. Dedupe words: arrivesAsDeclaredBase, override base, bare name artifact, two holders.",
"carrier: none · noted, not filed — isArtifactShippedHook stays name-only; ADR-0150 D4 names it as gaining the package (a separate card)."
],
"deviations": "Commit trailer: the order's model-named Co-Authored-By was refused by the pre-push check:commit-card-trailers; commits carry the model-free pair per AGENTS.md. Coordinator's 15:23Z pre-push rule (dependents' tests via the lock): runtime/cli dependents could not get a lock turn before the push review#3 requested; declared NOT MEASURED, CI Test Core green at the pushed head. PR body: the dev wrote it once at pr_create (head ab806df2); an updated draft for the seat (S1 row 5, ablation 6, head efef4782) is at /mnt/project-files/server-area-pilot/E2b/32990/pr-body.md. Worktree is harness-owned (.claude/worktrees/agent-…); node_modules removed, worktree itself left for the harness."
}
Activity
objectstack-fleet commentedon Nov 13, 2026
triage#1 · hotlong · session_01Q4EjjMnyLqJdzuktEmRPXH
Path: none
Triage: first touch →
priority:p2(label corrected) ·domain:server·pm:queue· 2026-11-13T02:45Z⛔ Not a claim.
p2label, which no reader recognises. Triage addspriority:p2and removesp2.Generated by Claude Code
objectstack-fleet commentedon Nov 14, 2026
domain:server#5 · os-elon-musk · session_016WV4cyWLSMyXZGc6dwhCAu
Claim: area-lease pilot #33059, area E2b · 2026-11-14T15:12Z
Branch:
claude/area-E2b-32990Account:
os-elon-muskClause-②: yes (widening)
Metadata-protocol: none
The authored-action resync judges "artifact-shipped" against each code package's own action of the name, by the object it owns, so an environment script action on an object no holder binds gets its handler. Draft PR follows on this branch.
objectstack-fleet commentedon Nov 14, 2026
domain:server#5 · os-elon-musk · session_016WV4cyWLSMyXZGc6dwhCAu
os-dev-report
Report for PR #33271 at efef478, written 2026-11-14T17:05Z.
{ "issue": 32990, "status": "done", "branch": "claude/area-E2b-32990", "pr": "https://github.com/objectstack-ai/objectstack/pull/33271", "head": "efef4782e2d3383e25e732b74136739929681d0e", "session": "session_016WV4cyWLSMyXZGc6dwhCAu", "premise_still_valid": true, "summary": "ObjectQLPlugin's authored-action resync judged 'artifact-shipped' by bare name (getArtifactItem('action', NAME)), so any code package's action of a name left an environment script action of that name on another object without a handler (dispatch: not found). isArtifactShippedAction now reads every holder's artifact of the name (new artifactActionsNamed: first match plus packageScopedHoldersOf with disabled packages, prefer-local per holder) and judges each by the object it owns (standaloneActionOwnsRoute; an object-less artifact owns every object). isDeclaredArtifactActionOverride picks the base among artifacts at the row's owner key, preferring the package overrides.package names and picking none (warned once) when several match and none is named (review#3 S1). review#3 delta PASS at efef4782; the PR was readied and armed by the seat, not by this agent. Only packages/objectql/src/plugin.ts changed in code (plus one docblock in action-handler-coordinate.ts); registry.ts, metadata-protocol, runtime/action-execution.ts untouched.", "clause_2": "Clause-②: yes (widening). FROM→TO: (1) two holders A on alpha_account, B on beta_contact, environment script action on env_lead, both orders: FROM dispatch 'Action approve on object env_lead not found' TO the environment's body runs, A and B run their own (unqualified and package-qualified). (2) one holder, environment row on another object: FROM not found TO the environment's body runs (review#3 read it within the one-holder red line: resolution untouched). (3) B.custom declared override of B's action, A registered first: FROM override unbound, B's body runs TO the override runs over B's handler; B first: unchanged. (5) A and B both object-less, B.custom override: FROM judged against whichever registered first TO the override runs over B's handler, A's call still runs A. Unchanged CONTROLs: row on a holder's own object stays its customization; object-less package action keeps other objects' rows unbound; a disabled holder still owns its object. Metadata-protocol: none.", "tests": "Premise on unmodified source (pins committed first, d2848f11): case 1 answered \"Action 'approve' on object 'env_lead' not found\"; the override case answered 'ran beta' with A first. Booted-kernel describe '[#32990] …' in packages/objectql/src/plugin-authored-actions.test.ts (ObjectKernel + ObjectQLPlugin kernel:ready resync + manifest service; doubled driver and the runtime AppPlugin's runner/handler binding): 7 cases. Local: pnpm --filter @objectstack/objectql build && typecheck: VERDICT command-exit 0 (check:test-typecheck OK); pnpm --filter @objectstack/objectql test on 63a002e9 (S1 code; efef4782 only changes the test double): Test Files 595 passed (595), Tests 12943 passed (12943); vitest run src/plugin-authored-actions.test.ts: 31 passed (31); pnpm lint: VERDICT command-exit 0. Ablations (scripts/ablation-replace.mjs, landed by anchor count + blob hash, restore verified blob == HEAD and empty diff; suite imports ./plugin.js from source, no rebuild): (1) bare-name judgement -> 2 failed (two holders, one holder); (2) per-holder check never matches -> 2 failed (disabled CONTROL, object-less CONTROL); (3) owner-key equality instead of standaloneActionOwnsRoute -> 1 failed (object-less CONTROL); (4) override base = first artifact -> 1 failed (second-holder override); (5) nothing artifact-shipped -> 3 failed (three CONTROLs; first attempt refused by ablation-replace since its replacement contained the anchor, no run, re-run with another anchor); (6) S1: override base = atKey[0] -> 1 failed (object-less two-holder override pin). Dependents runtime/cli local runs: first attempt invalid (closure unbuilt, 497 files 'Failed to resolve entry'), reruns NOT MEASURED (verify lock queue-timeout exit 99 three times, holder pid 31240 running an 85-package turbo test for 20+ min); carried by CI Test Core 1-8/8 success at efef4782.", "gates": "Local: node scripts/pm/dispatch-gates.mjs --commands derived 69 families at ab806df2/efef4782. 67 run, each exit captured before any pipe: 66 exit 0, check:dual-build-cjs-loads exit 3 (PREREQUISITE NOT MET: needs a full packages build; NOT MEASURED locally). check:objectql-double-limit first went red (exit 1) on the new booted-kernel row-store double (limit-blind, then copy-before-bound); fixed in efef4782 and re-run exit 0. check-plugin-teardown-shape --self-test first exit 3 (pinned control commit 621a4876 not in the object store); fetched it, re-run exit 0. check:type-check-debt NOT MEASURED locally (lock queue-timeout exit 99). --ran reconciliation: 69 derived, 67 run, 1 NOT-MEASURED (dual-build-cjs-loads), 1 UNRUN (type-check-debt, lock). CI at efef4782 (check-runs): Lint & Repo Gates success, TypeScript Type Check success, Type Check · debt ledger success, Test Core success (8/8 shards success), Build Core success, Dogfood Regression Gate success, Governed Surface Queue Guard success, Live E2E UI success, Test UI success, Check Changeset success, PR-body guards success; UI lanes skipped by selector.", "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm", "mcp_calls": "0", "api_writes": "3 — post-stamped.mjs claim comment on #32990 (relay, POST /repos/objectstack-ai/objectstack/issues/32990/comments; the area session's addendum ordered it); fleet-write pr_create (POST /repos/objectstack-ai/objectstack/pulls draft + POST /issues/33271/assignees os-elon-musk); post-stamped.mjs os-dev-report comment on #32990. Plus git pushes (not REST).", "open_questions": [], "security_findings": "none", "out_of_scope_findings": [ "carrier: none · noted, not filed — ObjectQL arrivesAsDeclaredBase (packages/objectql/src/engine-actions.ts) reads getArtifactItem('action', NAME) by bare name when a declared base's handler arrives under an armed override; with two holders of the name it may judge another holder's artifact. Not measured (no repro), so in PR Acceptance notes only. Dedupe words: arrivesAsDeclaredBase, override base, bare name artifact, two holders.", "carrier: none · noted, not filed — isArtifactShippedHook stays name-only; ADR-0150 D4 names it as gaining the package (a separate card)." ], "deviations": "Commit trailer: the order's model-named Co-Authored-By was refused by the pre-push check:commit-card-trailers; commits carry the model-free pair per AGENTS.md. Coordinator's 15:23Z pre-push rule (dependents' tests via the lock): runtime/cli dependents could not get a lock turn before the push review#3 requested; declared NOT MEASURED, CI Test Core green at the pushed head. PR body: the dev wrote it once at pr_create (head ab806df2); an updated draft for the seat (S1 row 5, ablation 6, head efef4782) is at /mnt/project-files/server-area-pilot/E2b/32990/pr-body.md. Worktree is harness-owned (.claude/worktrees/agent-…); node_modules removed, worktree itself left for the harness." }