Summary
ConvertLeadAction in src/actions/lead.actions.ts relies on confirmText to make the runtime treat the action as approval-requiring for AI callers. The 17.2.0 runtime does not read confirmText for that purpose; the key it consults is ai.requiresConfirmation. As a result list_actions over MCP reports convert_lead as requiresConfirmation: false, and the comment describing an HITL queue is not what happens.
What the code says
src/actions/lead.actions.ts (lines ~26–36 at 5e08628f):
confirmText: 'Are you sure you want to convert this lead?',
// … `confirmText` makes the runtime treat it as approval-requiring, so an agent
// invocation lands in the HITL queue rather than converting a lead unattended …
ai: {
exposed: true,
What the runtime does
@objectstack/runtime 17.2.0, actionLooksDestructive(_deps, action):
if (action?.ai?.requiresConfirmation !== void 0) return Boolean(action.ai.requiresConfirmation);
return Boolean(action?.mode === "delete" || action?.variant === "danger");
confirmText is not consulted. @objectstack/spec agrees — its action-key aliases map confirm / hitl / humanInTheLoop → requiresConfirmation, and the field doc reads: "requiresConfirmation: true forces a human-in-the-loop gate on the AI call."
Observed
Claude Code → http://localhost:4001/api/v1/mcp (API key, principal = sales.manager), list_actions:
{ "name": "convert_lead", "objectName": "crm_lead", "type": "flow",
"description": "Converts a qualified lead into an account, contact and opportunity. Irreversible — requires human approval before it runs.",
"requiresRecord": true, "requiresConfirmation": false }
The description claims approval; the flag says none is needed.
Suggested fix
ai: {
exposed: true,
requiresConfirmation: true,
description: '…',
},
and rewrite the comment so it does not attribute the gate to confirmText (which remains the console's confirm-dialog string, unrelated to AI).
Two caveats worth recording
Summary
ConvertLeadActioninsrc/actions/lead.actions.tsrelies onconfirmTextto make the runtime treat the action as approval-requiring for AI callers. The 17.2.0 runtime does not readconfirmTextfor that purpose; the key it consults isai.requiresConfirmation. As a resultlist_actionsover MCP reportsconvert_leadasrequiresConfirmation: false, and the comment describing an HITL queue is not what happens.What the code says
src/actions/lead.actions.ts(lines ~26–36 at5e08628f):What the runtime does
@objectstack/runtime17.2.0,actionLooksDestructive(_deps, action):confirmTextis not consulted.@objectstack/specagrees — its action-key aliases mapconfirm/hitl/humanInTheLoop→requiresConfirmation, and the field doc reads: "requiresConfirmation: trueforces a human-in-the-loop gate on the AI call."Observed
Claude Code →
http://localhost:4001/api/v1/mcp(API key, principal = sales.manager),list_actions:{ "name": "convert_lead", "objectName": "crm_lead", "type": "flow", "description": "Converts a qualified lead into an account, contact and opportunity. Irreversible — requires human approval before it runs.", "requiresRecord": true, "requiresConfirmation": false }The description claims approval; the flag says none is needed.
Suggested fix
and rewrite the comment so it does not attribute the gate to
confirmText(which remains the console's confirm-dialog string, unrelated to AI).Two caveats worth recording
requiresConfirmationis only surfaced to the client inlist_actions;run_actiondoes not enforce it server-side. The only confirmation an MCP agent hits today is whatever the client (e.g. Claude Code's permission prompt) chooses to do with thedestructiveHintannotation. So "lands in the HITL queue" is not accurate for MCP regardless of this fix.convert_lead's targetlead_conversionis a screen flow, so via MCP it currently pauses onscreen_1and cannot be resumed at all — see MCPrun_actionon a screen flow dead-ends: the screen pauses even when every input is bound, andlist_actionsnever surfaces flow input variables objectstack#15705. That is a platform issue; this one is only about the misdeclared key and misleading comment.