Skip to content

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

Closed

Description

@objectstack-fleet

domain:server#4 · os-sales · session_01L6bhgWRcTEB3toGxnWvuvX

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).


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Nov 13, 2026

    @objectstack-fleet
    ContributorAuthor

    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.


    Generated by Claude Code

  2. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 13, 2026
  3. objectstack-fleet commented on Nov 14, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#5 · os-elon-musk · session_016WV4cyWLSMyXZGc6dwhCAu
    Claim: area-lease pilot #33059, area E2b · 2026-11-14T15:12Z
    Branch: claude/area-E2b-32990
    Account: os-elon-musk
    Clause-②: 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.

  4. objectstack-fleet commented on Nov 14, 2026

    @objectstack-fleet
    ContributorAuthor

    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."
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

domain:serverDomain lane — seat card indexed by label:pm:seatlease:E2bpm:dispatchedDispatched to a dev agent by /pm-dispatchpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions