Skip to content

In-process ScopedRepo.execute() bypasses the packaged-action activation consult (ADR-0126 §8) #12349

Description

@claude

The ADR-0126 §8 action activation ledger is consulted at the two doors that dispatch a DECLARED action — the REST /actions/:object/:action route and the MCP run_action bridge (both call disabledActionRefusal, landed in #12348). A third caller of engine.executeAction is not covered, and this issue records it rather than leaving it to be discovered.

The path

ScopedRepo.execute(actionName, params) (packages/objectql/src/engine.ts) — what a hook body or an action body reaches through ctx.api.object('x').execute('some_action'). It calls engine.executeAction(objectName, actionName, ctx) directly.

A packaged action switched off in sys_metadata_activation still runs through this path.

Why it was left out of #12160, deliberately

  1. It has no declaration in hand. It dispatches by HANDLER KEY, and ADR-0110 D2 is explicit that a registration key is not an action's identity: a body action registers under name, a target-bound script action under target. The ledger addresses the declarative name, so a check at that seam would silently miss every target-bound action while appearing to gate them — a gate that looks present and is not is worse than none.
  2. It carries no caller identity (ScopedRepo.execute passes neither user nor session), so it is not a wire surface: it is package code calling package code — the class ADR-0126 §2 keeps outside the customization model for hook, on the maintainer's amendment ruling 1.

What a fix would need (not chartered here)

The engine can answer "which declaration is addressable by this (object, key) pair" — collectEngineActionDeclarations + resolveActionHandlerKeys already build exactly that map for the ADR-0110 D5 boot inventory. A consult at executeAction would have to resolve through that map rather than treating actionName as an identity, and would then need its own per-path pin. Whether an in-process body SHOULD be refused at all is the product question underneath, and it is the same one ruling 1 answered for hooks.

Filed from the #12160 leg; the consult points that DO exist are documented in packages/runtime/src/action-execution.ts (disabledActionRefusal) and pinned per door in packages/runtime/src/domains/action-activation-dispatch.test.ts.

Refs: #12160 · PR #12348 · ADR-0126 §8 item 2 · ADR-0110 D2


Generated by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions