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
The last residual from the #2605 "declared-but-not-wired" family, split out so the umbrella can close. This is a declaration-surfacing gap, not an execution gap: since #2608, a standalone authored action metadata row is registered into the engine by resyncAuthoredActions and its body executes via the REST /actions/... route — but the MCP action surface never sees it, because both MCP resolution paths read declarations exclusively from object.actions:
listActions — packages/runtime/src/http-dispatcher.ts:813 iterates meta.listObjects() and collects obj.actions only.
resolveActionByName (backing run_action) — packages/runtime/src/http-dispatcher.ts:1174 — same source.
So an AI agent calling list_actions will never discover a standalone authored action, and run_action on its name returns "Action not found", even when the row carries ai: { exposed: true }. Actions embedded in an authored object row are fine on both surfaces (they appear in obj.actions via the metadata service).
Scope notes
Same declaration-surfacing family as the Studio-rail listing work (task_8dd7c8a0): the execution layer (engine registry via resyncAuthoredActions, packages/objectql/src/plugin.ts:1330) already merges standalone rows + object-embedded rows with artifact-wins semantics — only the declaration consumers (MCP bridge) don't.
Sketch: have the bridge's declaration source union meta.listObjects().actions with standalone action items (metadata.loadMany('action')), keyed the same way the engine registry keys them (object-scoped vs global), dedup artifact-wins — mirroring resyncAuthoredActionsNow's merge.
Origin
Noted as "Residual (not chased here)" in the #2605 wrap-up comment (#2605 (comment)); re-confirmed still present on main @ 93fd58e (2026-07-16).
Summary
The last residual from the #2605 "declared-but-not-wired" family, split out so the umbrella can close. This is a declaration-surfacing gap, not an execution gap: since #2608, a standalone authored
actionmetadata row is registered into the engine byresyncAuthoredActionsand its body executes via the REST/actions/...route — but the MCP action surface never sees it, because both MCP resolution paths read declarations exclusively fromobject.actions:listActions—packages/runtime/src/http-dispatcher.ts:813iteratesmeta.listObjects()and collectsobj.actionsonly.resolveActionByName(backingrun_action) —packages/runtime/src/http-dispatcher.ts:1174— same source.So an AI agent calling
list_actionswill never discover a standalone authored action, andrun_actionon its name returns "Action not found", even when the row carriesai: { exposed: true }. Actions embedded in an authored object row are fine on both surfaces (they appear inobj.actionsvia the metadata service).Scope notes
task_8dd7c8a0): the execution layer (engine registry viaresyncAuthoredActions,packages/objectql/src/plugin.ts:1330) already merges standalone rows + object-embedded rows with artifact-wins semantics — only the declaration consumers (MCP bridge) don't.ai.exposedfail-closed (Security: MCP action surface must gate onai.exposed— action bodies run trusted (unbounded RLS/FLS), so invoke-time is the only agent boundary (#2849) #2849 / ADR-0011), the ADR-0066 D4 capability gate, andisHeadlessInvokableAction.meta.listObjects().actionswith standaloneactionitems (metadata.loadMany('action')), keyed the same way the engine registry keys them (object-scoped vs global), dedup artifact-wins — mirroringresyncAuthoredActionsNow's merge.Origin
Noted as "Residual (not chased here)" in the #2605 wrap-up comment (#2605 (comment)); re-confirmed still present on
main@93fd58e(2026-07-16).