Skip to content

The other two flow-dispatch doors never got the #9378 status table — /actions mislabels never-dispatched refusals, declared endpoints still answer 200 #9446

Description

@os-zhuang

Found while implementing #9415 (the #9378 ruling's remaining two rows). Filed unassigned for triage — not fixed there: #9378 ruled the two trigger routes, and what these two doors should answer is a contract decision of its own, not a mechanical extension.

Three doors dispatch a flow through IAutomationService.execute. Only one of them classifies the result.

1. POST /api/v1/automation/:name/trigger (+ the legacy spelling) — CORRECT

respondToFlowTrigger (packages/runtime/src/domains/automation.ts) answers the full four-row table after #9413 + #9415:

engine exit answer
flow not found 404
flow disabled 409 FLOW_DISABLED
flow has no start node 422 FLOW_NO_START_NODE
ran and failed 400 FLOW_FAILED

2. POST /api/v1/actions/:object/:action with type: 'flow' — MISLABELS two of the four

packages/runtime/src/action-execution.ts maps any success: false result to one code:

if (result && typeof result === 'object' && 'success' in result && result.success === false) {
    const err: any = new Error(`Flow '${action.target}' failed: ${result.error ?? 'unknown error'}`);
    err.status = 400;
    err.code = 'FLOW_FAILED';
    throw err;
}

Its comment says "The flow RAN and rejected" — which is now false for two of the exits it catches. A disabled flow invoked through an action answers 400 FLOW_FAILED, telling the caller a run failed when no node ever executed. The producer's result.code is available and ignored.

3. Declared endpoints (type: 'flow') — still fully pre-#9378

packages/runtime/src/endpoint-executor.ts ends the flow branch with:

return successAnswer(await automation.execute(plan.flow, automationContext));

Unconditional 200. Every failure — including a run that ran and failed — still rides the double envelope #3962 ruled out for /actions: HTTP 200 {"success":true,"data":{"success":false,...}}. This door was not in #9413's scope and nothing has flipped it since.

Consequence for the docs: content/docs/protocol/kernel/http-protocol.mdx describes a type: 'flow' endpoint as "delegated to the same automation pipeline as POST /api/v1/automation/{name}/trigger". True of the context builder and the service method, no longer true of the response. #9415 corrects that page's wording to state the boundary; it does not change the behaviour.

The decision this needs

Whether the #9378 table is a property of the flow-dispatch contract (all three doors converge) or of the trigger route (the others keep their own envelope conventions deliberately). Door 3 additionally carries the endpoint policy chain and outputMapping, so converging it is not a copy of the mapper.

Note both doors also answer for FLOW_FAILED today, so this is not created by #9415 — that card only makes the divergence wider and easier to see, because the producer now says which refusal it is.

Refs: #9378 (the ruling) - #9413 (rows 1-2) - #9415 (rows 3-4) - #3962 (the /actions double-envelope ruling).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions