From 764d2eff9b4b1440783bf02894fe21fd5453862b Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 18 Aug 2026 20:23:12 +0000 Subject: [PATCH] docs(spec): record the second FLOW_DISABLED / FLOW_NO_START_NODE emitter Since #9446 (PR #9584), POST /api/v1/actions/:object/:action also emits both codes through dispatchFlowAction (packages/runtime/src/action-execution.ts), not just the trigger door's respondToFlowTrigger. Update the ledger's provenance notes to record the second emitter, following the in-file PACKAGE_DELETE_PARTIAL precedent ("Second EMITTER of the code ... Provenance, not identity"). Comment-only: the registration rows themselves are unchanged, so no code is registered or unregistered. Fixes #9586 Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_016D9wdJR14KKCxz1WgdAzcw --- packages/spec/src/api/error-code-ledger.zod.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/spec/src/api/error-code-ledger.zod.ts b/packages/spec/src/api/error-code-ledger.zod.ts index 38119239ce..2672d60664 100644 --- a/packages/spec/src/api/error-code-ledger.zod.ts +++ b/packages/spec/src/api/error-code-ledger.zod.ts @@ -260,6 +260,13 @@ export const ERROR_CODE_LEDGER = { // synonym of `CONFLICT` in the detector's sense and not one in meaning // either — it names WHICH state conflicts, which is what an operator acts // on. Never carries `status`: nothing dispatched (#9378 row 3). + // [#9446] Second EMITTER of the code: `POST /api/v1/actions/:object/:action` + // answers the same 409 through `dispatchFlowAction` + // (`packages/runtime/src/action-execution.ts`), reading the same + // engine `AutomationResult.code` via the shared `classifyFlowRefusal` + // table (`flow-dispatch-status.ts`) and serving the throw through + // `errorFromThrown` — the two doors now state the same refusal the same + // way. Provenance, not identity (see above). 'FLOW_DISABLED', // [#8846] a flow that RAN and rejected — a deliberate business rejection, // served as a 400 (#3962) with the semantic code kept on the wire so @@ -274,6 +281,13 @@ export const ERROR_CODE_LEDGER = { // FLOW_DISABLED — one is reversible operational state, the other an // authoring defect — and from FLOW_FAILED, which means the flow ran // (#9378 row 4). + // [#9446] Second EMITTER of the code: `POST /api/v1/actions/:object/:action` + // answers the same 422 through `dispatchFlowAction` + // (`packages/runtime/src/action-execution.ts`), reading the same + // engine classification via the shared `classifyFlowRefusal` table + // (`flow-dispatch-status.ts`) and serving the throw through + // `errorFromThrown` — the two doors now state the same refusal the same + // way. Provenance, not identity (see above). 'FLOW_NO_START_NODE', 'INVALID_OR_EXPIRED', // share-link token 'NEEDS_PASSWORD', // share link requires a password