@cadraos/sdk 0.3.9 → 0.3.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/kanban/config-client.ts","../../../src/kanban/engine/handlers.ts","../../../src/kanban/adapters/in-memory-adapter.ts","../../../src/kanban/adapters/http-adapter.ts","../../../src/kanban/adapters/example-host.ts","../../../src/kanban/adapters/conformance.ts","../../../src/kanban/engine/index.ts"],"names":["run","cards"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * BoardConfigClient — fetch + cache + pin board configs from Cadra.\n *\n * The control-plane half of an agentic board lives in Cadra (Plan 1):\n * versioned, immutable-on-publish board-config definitions exposed at\n * `GET /api/v1/board-configs/:uuid[?version=]`. This client fetches a config,\n * maps the wire `definition` (stages/transitions/handlers, snake-cased) to the\n * SDK's `KanbanBoard` lane/transition contract, and caches by `(uuid, version)`.\n *\n * Graceful degradation (design.md §6/§11 R-cache): if the config API blips on a\n * refetch, the last cached copy is served so existing boards keep working —\n * only brand-new fetches (no cache) hard-fail.\n *\n * Server-safe: NO DOM imports. The engine (server) and the board UI (client)\n * both consume this.\n *\n * @module @cadraos/sdk/kanban\n */\n\nimport type {\n DueRule,\n KanbanBoard,\n KanbanLane,\n KanbanLaneDispatch,\n KanbanLaneTrigger,\n KanbanTransition,\n} from \"./types.js\";\nimport type {\n LifecycleSource,\n ResolvedLifecycle,\n} from \"./lifecycle/types.js\";\n\n// =============================================================================\n// HTTP DEPENDENCY\n// =============================================================================\n\n/**\n * Minimal HTTP surface this client needs — a `get(path, query)` that returns\n * the (already envelope-unwrapped) JSON body. The SDK's `HttpClient` and any\n * `CadraClient`-backed transport satisfy this.\n */\nexport interface BoardConfigHttp {\n get<T>(\n path: string,\n query?: Record<string, string | number | boolean | undefined>\n ): Promise<T>;\n}\n\n// =============================================================================\n// WIRE TYPES (Plan 1 §3 definition shape)\n// =============================================================================\n\ninterface WireHandler {\n type?: string;\n agent_uuid?: string;\n team_uuid?: string;\n /**\n * remote_agent → the `remote_agents.uuid` for a `remote_agent` lane (§5.3).\n * Snake-cased on the wire (published JSONB); mapped to `remoteAgentUuid`.\n * WITHOUT this the binding is silently dropped at parse and every published\n * remote_agent lane fails dispatch with \"missing remoteAgentUuid\" (FINDING-6).\n */\n remote_agent_uuid?: string;\n /** Legacy p28 slug ref. */\n agent_ref?: string;\n webhook?: {\n url: string;\n headers?: Record<string, string>;\n timeout_ms?: number;\n retry?: number;\n } | null;\n}\n\nexport interface WireStage {\n id: string;\n key: string;\n name: string;\n color?: string;\n is_initial?: boolean;\n is_terminal?: boolean;\n is_pushback_target?: boolean;\n handler?: WireHandler | null;\n /**\n * Conductor-mode metadata (design §4). `trigger` defaults to `event` when\n * absent; `due_rule`/`cap` apply only to `scheduled` lanes. Snake-cased on\n * the wire; mapped to `KanbanLane.trigger`/`dueRule`/`cap`.\n */\n trigger?: KanbanLaneTrigger;\n due_rule?: DueRule | null;\n cap?: number | null;\n /**\n * Batched-dispatch metadata (design §7). `dispatch` defaults to `per-card`\n * when absent; `chunk_size` applies only to `dispatch: batch` lanes.\n * Snake-cased on the wire; mapped to `KanbanLane.dispatch`/`chunkSize`.\n */\n dispatch?: KanbanLaneDispatch;\n chunk_size?: number | null;\n}\n\ninterface WireTransition {\n id: string;\n from_stage_id: string;\n to_stage_id: string;\n manual_allowed?: boolean;\n auto_on_complete?: boolean;\n kind?: \"forward\" | \"pushback\";\n}\n\ninterface WireDefinition {\n stages: WireStage[];\n transitions?: WireTransition[];\n reserved_keys?: string[];\n shared_context_caps?: Record<string, unknown>;\n card_types?: string[];\n}\n\ninterface WireConfigMeta {\n uuid: string;\n slug?: string;\n name?: string;\n activeVersion?: number | null;\n orgId?: number;\n}\n\n/**\n * A board-config VERSION ROW as Cadra returns it (the `board_config_version`\n * record): the version number + status + the nested flat `definition`. Cadra\n * returns this row both for an active fetch (under `definition`) and a pinned\n * fetch (under `version`).\n */\ninterface WireVersionRow {\n version: number;\n status?: string;\n definition: WireDefinition;\n}\n\n/**\n * Wire envelope returned by `GET /api/v1/board-configs/:uuid`.\n *\n * Cadra (Plan 1) returns a version ROW, not a flat definition:\n * - Active fetch: `{ config, definition: WireVersionRow }` (`getActiveDefinition`).\n * - Pinned fetch (`?version=`): `{ config, version: WireVersionRow }` (`getVersion`).\n *\n * `definition` is also accepted as a flat `WireDefinition` for forward-compat /\n * simpler producers — `parse()` unwraps whichever shape it gets.\n */\ninterface WireConfigResponse {\n config: WireConfigMeta;\n /** Active fetch: Cadra's version row, or a flat definition. */\n definition?: WireDefinition | WireVersionRow;\n /** A number (legacy) or the version row (pinned fetch). */\n version?: number | WireVersionRow;\n}\n\n/** Type guard: a version ROW (has a nested `.definition`) vs a flat definition. */\nfunction isVersionRow(\n d: WireDefinition | WireVersionRow | undefined\n): d is WireVersionRow {\n return (\n !!d &&\n typeof d === \"object\" &&\n \"definition\" in d &&\n !!(d as WireVersionRow).definition\n );\n}\n\n// =============================================================================\n// RESOLVED CONFIG\n// =============================================================================\n\n/**\n * A resolved board config: stable uuid + version + the mapped `KanbanBoard`\n * (lanes + transitions) ready to drive the UI and engine.\n */\nexport interface ResolvedBoardConfig {\n /** Stable config uuid (cards pin this). */\n uuid: string;\n /** Resolved version (cards pin this). */\n version: number;\n /** Config metadata. */\n name?: string;\n slug?: string;\n /** The mapped board (lanes in declared order + transitions). */\n board: KanbanBoard;\n /** The raw mapped definition (stages == lanes, transitions). */\n definition: { stages: KanbanLane[]; transitions: KanbanTransition[] };\n}\n\n// =============================================================================\n// MAPPERS (wire → SDK)\n// =============================================================================\n\nfunction mapHandler(h: WireHandler | null | undefined): KanbanLane[\"handler\"] {\n if (!h || !h.type || h.type === \"none\") {\n // `none`/absent → no handler binding (plain lane).\n return undefined;\n }\n return {\n type: h.type,\n agentUuid: h.agent_uuid,\n teamUuid: h.team_uuid,\n // FINDING-6: carry the remote_agent binding through the wire parse. The\n // engine's remote_agent dispatch reads `remoteAgentUuid`; dropping it here\n // made every published remote_agent lane dispatch-dead.\n remoteAgentUuid: h.remote_agent_uuid,\n agentRef: h.agent_ref,\n webhook: h.webhook\n ? {\n url: h.webhook.url,\n headers: h.webhook.headers,\n timeoutMs: h.webhook.timeout_ms,\n retry: h.webhook.retry,\n }\n : undefined,\n };\n}\n\nfunction mapStage(s: WireStage, index: number): KanbanLane {\n const lane: KanbanLane = {\n // Carry the IMMUTABLE stage id through (p33 §10.2). It is what the\n // webhook-secret fetch + the stage-run idemKey + the UI columns key off —\n // a `key`/`label` rename never breaks dispatch or keying. `key` stays the\n // editable display/slug.\n id: s.id,\n key: s.key,\n label: s.name,\n order: index,\n handler: mapHandler(s.handler),\n terminal: s.is_terminal ?? false,\n initial: s.is_initial ?? false,\n };\n // Conductor-mode metadata (design §4) — carry it through so the resolved\n // config the engine reads knows a lane is `scheduled` + its dueRule/cap.\n // `event` is the default; only thread non-default/present values so existing\n // single-mode boards map identically.\n if (s.trigger) lane.trigger = s.trigger;\n if (s.due_rule != null) lane.dueRule = s.due_rule;\n if (s.cap != null) lane.cap = s.cap;\n // Batched-dispatch (design §7). Only thread non-default/present values so an\n // existing `per-card` lane maps identically (no `dispatch` key).\n if (s.dispatch) lane.dispatch = s.dispatch;\n if (s.chunk_size != null) lane.chunkSize = s.chunk_size;\n return lane;\n}\n\n/**\n * Map a wire transition. Stages reference each other by `*_stage_id`, which in\n * the Plan 1 definition equals the stage `key`/`id` (they are 1:1 in the seed).\n * The SDK board speaks in lane KEYS, so we resolve ids → keys via the stage map.\n */\nfunction mapTransition(\n t: WireTransition,\n idToKey: Map<string, string>\n): KanbanTransition {\n return {\n id: t.id,\n fromLane: idToKey.get(t.from_stage_id) ?? t.from_stage_id,\n toLane: idToKey.get(t.to_stage_id) ?? t.to_stage_id,\n manualAllowed: t.manual_allowed ?? false,\n autoOnComplete: t.auto_on_complete ?? false,\n kind: t.kind,\n };\n}\n\n/**\n * Map a wire definition (+ config meta) → a resolved board config.\n */\nexport function mapDefinitionToBoard(\n config: WireConfigMeta,\n definition: WireDefinition,\n version: number\n): ResolvedBoardConfig {\n const lanes = (definition.stages ?? []).map(mapStage);\n const idToKey = new Map(\n (definition.stages ?? []).map((s) => [s.id, s.key] as const)\n );\n const transitions = (definition.transitions ?? []).map((t) =>\n mapTransition(t, idToKey)\n );\n\n const board: KanbanBoard = {\n id: config.uuid,\n orgId: config.orgId ?? 0,\n lifecycleId: config.uuid,\n lifecycleVersion: version,\n name: config.name,\n lanes,\n transitions,\n };\n\n return {\n uuid: config.uuid,\n version,\n name: config.name,\n slug: config.slug,\n board,\n definition: { stages: lanes, transitions },\n };\n}\n\n// =============================================================================\n// CLIENT\n// =============================================================================\n\nexport interface BoardConfigClientOptions {\n /** HTTP transport (the SDK's HttpClient or a CadraClient-backed get()). */\n http: BoardConfigHttp;\n /** Override the base path (default `/api/v1/board-configs`). */\n basePath?: string;\n}\n\nconst DEFAULT_BASE_PATH = \"/api/v1/board-configs\";\n\n/**\n * Fetch + cache + pin board configs.\n *\n * - `getActive(uuid)` — fetch the config's ACTIVE version (re-validates each\n * call so newly published versions are picked up); falls back to the cached\n * copy when the fetch fails.\n * - `getPinned(uuid, version)` — fetch a SPECIFIC frozen version; cached\n * permanently (published versions are immutable, so a cache hit short-circuits\n * the network entirely).\n */\nexport class BoardConfigClient {\n private readonly http: BoardConfigHttp;\n private readonly basePath: string;\n\n /** Cache keyed by `${uuid}:${version}`. */\n private readonly cache = new Map<string, ResolvedBoardConfig>();\n /** Last-known active version per uuid (for degraded active fetch). */\n private readonly activeVersions = new Map<string, number>();\n\n constructor(options: BoardConfigClientOptions) {\n this.http = options.http;\n this.basePath = options.basePath ?? DEFAULT_BASE_PATH;\n }\n\n /**\n * Fetch a config's ACTIVE version and map it. Re-validates against Cadra each\n * call (a newly published version supersedes the old active one). On a fetch\n * failure, serves the last cached copy for that config (graceful degradation,\n * design.md §11 R-cache); if nothing is cached, the error propagates.\n */\n async getActive(uuid: string): Promise<ResolvedBoardConfig> {\n try {\n const res = await this.http.get<WireConfigResponse>(\n `${this.basePath}/${uuid}`\n );\n const resolved = this.parse(res);\n this.put(resolved);\n this.activeVersions.set(uuid, resolved.version);\n return resolved;\n } catch (err) {\n const cached = this.cachedActive(uuid);\n if (cached) return cached;\n throw err;\n }\n }\n\n /**\n * Fetch a SPECIFIC frozen version and map it. Published versions are\n * immutable, so a cache hit skips the network. On a fetch miss + failure,\n * serves the cached version if present.\n */\n async getPinned(uuid: string, version: number): Promise<ResolvedBoardConfig> {\n const cached = this.cache.get(this.key(uuid, version));\n if (cached) return cached;\n\n try {\n const res = await this.http.get<WireConfigResponse>(\n `${this.basePath}/${uuid}`,\n { version }\n );\n const resolved = this.parse(res, version);\n this.put(resolved);\n return resolved;\n } catch (err) {\n const fallback = this.cache.get(this.key(uuid, version));\n if (fallback) return fallback;\n throw err;\n }\n }\n\n /** Drop all cached configs (e.g. after a known publish). */\n clearCache(): void {\n this.cache.clear();\n this.activeVersions.clear();\n }\n\n // -------------------------------------------------------------------------\n // internals\n // -------------------------------------------------------------------------\n\n private key(uuid: string, version: number): string {\n return `${uuid}:${version}`;\n }\n\n private put(resolved: ResolvedBoardConfig): void {\n this.cache.set(this.key(resolved.uuid, resolved.version), resolved);\n }\n\n private cachedActive(uuid: string): ResolvedBoardConfig | undefined {\n const v = this.activeVersions.get(uuid);\n if (v === undefined) return undefined;\n return this.cache.get(this.key(uuid, v));\n }\n\n /**\n * Normalize the wire envelope (active `{ config, definition, version }` OR\n * pinned `{ config, version: { version, definition } }`) into a resolved\n * config.\n */\n private parse(\n res: WireConfigResponse,\n requestedVersion?: number\n ): ResolvedBoardConfig {\n if (!res?.config?.uuid) {\n throw new Error(\"Invalid board-config response: missing config.uuid\");\n }\n\n let definition: WireDefinition | undefined;\n let version: number | undefined;\n\n if (res.version && typeof res.version === \"object\") {\n // Pinned envelope: `version` is the version row.\n definition = res.version.definition;\n version = res.version.version;\n } else if (isVersionRow(res.definition)) {\n // Active envelope from Cadra: `definition` is the version ROW\n // ({ version, status, definition }), not the flat definition.\n definition = res.definition.definition;\n version = res.definition.version ?? res.config.activeVersion ?? undefined;\n } else {\n // Flat active envelope: `definition` IS the WireDefinition.\n definition = res.definition;\n version =\n typeof res.version === \"number\"\n ? res.version\n : res.config.activeVersion ?? undefined;\n }\n\n if (!definition) {\n throw new Error(\"Invalid board-config response: missing definition\");\n }\n const resolvedVersion = version ?? requestedVersion ?? 1;\n\n return mapDefinitionToBoard(res.config, definition, resolvedVersion);\n }\n}\n\n// =============================================================================\n// CADRA LIFECYCLE SOURCE (LifecycleSource over read-through board-configs)\n// =============================================================================\n\n/**\n * Project a `ResolvedBoardConfig` (the board-config-client's resolved shape)\n * into the source-agnostic `ResolvedLifecycle` the engine + renderer consume\n * (p33 §3). `source` is always `cadra` here — this is the read-through Cadra\n * board-config source. The lane/transition shapes are identical, so this is a\n * thin re-shape (stages/transitions == the board's lanes/transitions).\n */\nexport function toResolvedLifecycle(\n cfg: ResolvedBoardConfig\n): ResolvedLifecycle {\n return {\n uuid: cfg.uuid,\n version: cfg.version,\n source: \"cadra\",\n name: cfg.name,\n slug: cfg.slug,\n stages: cfg.board.lanes,\n transitions: cfg.board.transitions ?? [],\n board: cfg.board,\n };\n}\n\n/**\n * `CadraLifecycleSource` — a `LifecycleSource` backed by read-through Cadra\n * board-configs (p33 §3). The promotion of `BoardConfigClient` to a first-class\n * lifecycle source: same fetch + cache-by-`(uuid, version)` + version-pin +\n * graceful-degradation machinery (it IS a `BoardConfigClient` internally), but\n * `getActive`/`getPinned` return the source-agnostic `ResolvedLifecycle`\n * (`source: 'cadra'`) the engine + renderer consume.\n *\n * - immutable-per-version cache keyed by `(uuid, version)`;\n * - short TTL applies to `getActive` only (re-validate to pick up a fresh\n * publish for NEW cards), inherited from the underlying client's per-call\n * active re-fetch;\n * - on a fetch failure, the last cached copy is served (stale-cache read) so\n * in-flight boards keep operating (NFR Resilience / design §4).\n */\nexport class CadraLifecycleSource implements LifecycleSource {\n private readonly client: BoardConfigClient;\n\n constructor(options: BoardConfigClientOptions);\n /** Wrap an existing `BoardConfigClient` (shares its cache). */\n constructor(client: BoardConfigClient);\n constructor(arg: BoardConfigClientOptions | BoardConfigClient) {\n this.client =\n arg instanceof BoardConfigClient ? arg : new BoardConfigClient(arg);\n }\n\n /** The ACTIVE version, projected to a `ResolvedLifecycle` (`source: cadra`). */\n async getActive(uuid: string): Promise<ResolvedLifecycle> {\n return toResolvedLifecycle(await this.client.getActive(uuid));\n }\n\n /** A PINNED version, projected to a `ResolvedLifecycle` (`source: cadra`). */\n async getPinned(uuid: string, version: number): Promise<ResolvedLifecycle> {\n return toResolvedLifecycle(await this.client.getPinned(uuid, version));\n }\n\n /** Drop the underlying cache (e.g. after a known publish). */\n clearCache(): void {\n this.client.clearCache();\n }\n}\n","/**\n * Stage handlers — dispatch a stage's automated handler (cadra_agent /\n * cadra_team / webhook) from the server engine.\n *\n * The engine owns the state machine; this module owns the OUTBOUND invocation\n * (run an agent/team by reference, or POST a signed webhook). Completion is\n * NOT awaited here — it arrives later via the run stream / a host callback,\n * which the engine turns into `completeStageRun`.\n *\n * Server-only (no DOM imports): uses `fetch` + `crypto` (Web Crypto / Node 18+\n * global `crypto.subtle`).\n *\n * @module @cadraos/sdk/kanban\n */\n\nimport type { KanbanLane } from \"../types.js\";\n\n// =============================================================================\n// CADRA RUN CLIENT (the host's seam to Cadra)\n// =============================================================================\n\nexport interface RunAgentInput {\n /** Concrete Cadra agent uuid. */\n agentUuid: string;\n /** Tenant/org id the run executes under. */\n orgId?: number;\n /** Card context passed to the agent (task + kanban context). */\n input: Record<string, unknown>;\n /** Idempotency key (= cardId:stageId:version). */\n idemKey: string;\n /**\n * Board/headless dispatch forces allowAskUser=false (spec §6.5 / FINDING-5).\n * The engine only ever dispatches cadra_agent stages from board surfaces,\n * which have NO ask_user UI — an ask attempt must FAIL the execution (→ failed\n * callback → completion bridge → §10 reclaim), never pause it. Pinned `false`\n * at the type boundary, matching RunRemoteAgentInput.\n */\n allowAskUser: false;\n /** A host callback reference the run can advance through (optional). */\n callbackRef?: string;\n}\n\nexport interface RunTeamInput {\n /** Concrete Cadra team uuid. */\n teamUuid: string;\n orgId?: number;\n input: Record<string, unknown>;\n idemKey: string;\n /** Board/headless dispatch forces allowAskUser=false (spec §6.5 / FINDING-5). */\n allowAskUser: false;\n callbackRef?: string;\n}\n\nexport interface RunRemoteAgentInput {\n /** Cadra remote_agents registry uuid (§5.3). */\n remoteAgentUuid: string;\n orgId?: number;\n input: Record<string, unknown>;\n idemKey: string;\n /**\n * Board dispatch forces allowAskUser=false (spec §6.5). The engine only ever\n * dispatches remote_agent stages from board/headless surfaces, so this is\n * pinned to `false` at the type boundary — a remote ask_user must fail with\n * ask_user_not_supported, never pause/hang a card.\n */\n allowAskUser: false;\n callbackRef?: string;\n}\n\nexport interface RunResult {\n /** The execution UUID driving the live run stream. */\n executionUuid: string;\n}\n\n/**\n * Per-stage webhook secret material, fetched from Cadra's MUTABLE\n * `board_config_secret` store (NOT from the immutable definition — design §11\n * R4). Rotation updates this row with a grace window; the engine always asks\n * for the current secret at dispatch.\n */\nexport interface WebhookSecret {\n /** Current HMAC signing secret. */\n secret: string;\n /** Scoped callback token the target echoes back to advance the card. */\n callbackToken?: string;\n}\n\n/**\n * The host's seam to Cadra: run an agent/team/remote-agent by reference (reusing\n * the p28 enqueue contract) and fetch webhook secrets. The engine calls only this.\n */\nexport interface CadraRunClient {\n /** Enqueue an agent run; returns the executionUuid for streaming. */\n runAgent(input: RunAgentInput): Promise<RunResult>;\n /** Enqueue a team run; returns the executionUuid for streaming. */\n runTeam(input: RunTeamInput): Promise<RunResult>;\n /**\n * Enqueue a remote_agent run (spec §10.2 / STORY-008).\n * Board dispatch sets allowAskUser=false; the remote runner maps ask_user\n * to run.failed with code='ask_user_not_supported'.\n */\n runRemoteAgent(input: RunRemoteAgentInput): Promise<RunResult>;\n /**\n * Fetch the per-stage webhook secret + callback token from Cadra's mutable\n * secret store (keyed by configUuid + stageId).\n */\n getWebhookSecret(input: {\n boardConfigUuid: string;\n stageId: string;\n }): Promise<WebhookSecret | null>;\n}\n\n// =============================================================================\n// HANDLER DISPATCH\n// =============================================================================\n\nexport interface HandlerContext {\n cardId: string;\n boardConfigUuid: string;\n configVersion: number;\n stage: KanbanLane;\n idemKey: string;\n /** Card context (task + shared context) passed to the handler. */\n input: Record<string, unknown>;\n orgId?: number;\n /** Host callback URL base for webhook completions (design §11 R4). */\n callbackUrl?: string;\n /**\n * BATCH dispatch metadata (design §7). Present only for a `dispatch: \"batch\"`\n * lane's chunk dispatch. When set, this is ONE handler run over MANY cards:\n * `cardId` is the chunk's lead/representative card and `input` carries the\n * full card LIST under `context.kanban.batch`, so a handler/agent can process\n * all N at once. The completion fans out per-card via the chunk's batch key\n * (see `BatchDispatchMeta`). Absent ⇒ a normal per-card dispatch.\n */\n batch?: BatchDispatchMeta;\n}\n\n/**\n * Per-card context inside a batch chunk — the unit a batch handler iterates.\n */\nexport interface BatchCardContext {\n /** Card UUID. */\n cardId: string;\n /** The card's per-card stage-run idempotency key (`cardId:stageId:version`). */\n idemKey: string;\n /** Card title (the agent task line). */\n task: string;\n /** Card shared context (host/GTM fields). */\n sharedContext: Record<string, unknown>;\n}\n\n/**\n * Metadata identifying a batch chunk dispatch (design §7). One handler run\n * processes the whole `cards` list; completion resolves each card's stage-run\n * (`cards[i].idemKey`) and advances it along the lane's single\n * `auto_on_complete` edge (advance-all-on-success; a failed card stays put).\n */\nexport interface BatchDispatchMeta {\n /** The chunk's batch key (`batch:stageId:version:<chunk-token>`). */\n batchKey: string;\n /** Every card in this chunk (each with its own per-card stage-run idemKey). */\n cards: BatchCardContext[];\n}\n\nexport interface HandlerDispatchResult {\n /** Execution UUID (cadra_agent/team) — undefined for fire-and-forget webhooks. */\n executionUuid?: string;\n /** True when the handler dispatched (vs a passive `none`/`human` stage). */\n dispatched: boolean;\n}\n\n/**\n * Options controlling webhook delivery (bounded retry/backoff).\n */\nexport interface WebhookDeliveryOptions {\n /** Injected fetch (defaults to global fetch). */\n fetchImpl?: typeof fetch;\n /** Max attempts on transient (5xx/network) failure (default from binding/3). */\n maxAttempts?: number;\n /** Base backoff ms (default 200). Exponential. */\n baseBackoffMs?: number;\n /** Sleep impl (injectable for tests). */\n sleep?: (ms: number) => Promise<void>;\n /** Clock for the signed timestamp (injectable for tests). */\n now?: () => number;\n}\n\n/** A 4xx is permanent (don't retry); a 5xx / network error is transient. */\nexport class WebhookDeliveryError extends Error {\n constructor(\n message: string,\n readonly status: number | undefined,\n readonly retryable: boolean\n ) {\n super(message);\n this.name = \"WebhookDeliveryError\";\n }\n}\n\n/**\n * Compute the hex HMAC-SHA256 signature of `payload` with `secret`.\n *\n * Uses Web Crypto (`crypto.subtle`) — available as a global in Node 18+ and\n * the edge/worker runtimes a host backend might use. No node:crypto import, so\n * the module stays portable.\n */\nexport async function hmacSign(secret: string, payload: string): Promise<string> {\n const enc = new TextEncoder();\n const key = await crypto.subtle.importKey(\n \"raw\",\n enc.encode(secret),\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"sign\"]\n );\n const sig = await crypto.subtle.sign(\"HMAC\", key, enc.encode(payload));\n return [...new Uint8Array(sig)]\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\nconst sleepDefault = (ms: number) => new Promise<void>((r) => setTimeout(r, ms));\n\n/**\n * Deliver a signed webhook with bounded exponential backoff.\n *\n * - 2xx → resolves.\n * - 4xx → throws a non-retryable `WebhookDeliveryError` immediately.\n * - 5xx / network → retries up to `maxAttempts`, then throws retryable.\n */\nexport async function deliverWebhook(\n ctx: HandlerContext,\n cadra: CadraRunClient,\n opts: WebhookDeliveryOptions = {}\n): Promise<void> {\n const binding = ctx.stage.handler?.webhook;\n if (!binding) throw new Error(`Stage ${ctx.stage.key} has no webhook binding`);\n\n const doFetch = opts.fetchImpl ?? fetch;\n const maxAttempts = opts.maxAttempts ?? binding.retry ?? 3;\n const baseBackoff = opts.baseBackoffMs ?? 200;\n const sleep = opts.sleep ?? sleepDefault;\n const now = opts.now ?? Date.now;\n\n // Secret is fetched from Cadra (NOT the definition), keyed by the IMMUTABLE\n // stage `id` (p33 §10.2 — rename-proof) — falling back to `key` for a lane\n // authored before the stage-identity contract.\n const stageId = ctx.stage.id ?? ctx.stage.key;\n const secretMaterial = await cadra.getWebhookSecret({\n boardConfigUuid: ctx.boardConfigUuid,\n stageId,\n });\n\n const timestamp = now();\n const body = {\n idemKey: ctx.idemKey,\n cardId: ctx.cardId,\n boardConfigUuid: ctx.boardConfigUuid,\n configVersion: ctx.configVersion,\n stageId,\n input: ctx.input,\n callbackUrl: ctx.callbackUrl,\n callbackToken: secretMaterial?.callbackToken,\n timestamp,\n };\n const payload = JSON.stringify(body);\n const signature = secretMaterial?.secret\n ? await hmacSign(secretMaterial.secret, `${timestamp}.${payload}`)\n : undefined;\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"Idempotency-Key\": ctx.idemKey,\n ...(binding.headers ?? {}),\n };\n if (signature) {\n headers[\"X-Cadra-Signature\"] = `t=${timestamp},v1=${signature}`;\n }\n\n let attempt = 0;\n // eslint-disable-next-line no-constant-condition\n while (true) {\n attempt += 1;\n try {\n const res = await doFetch(binding.url, {\n method: \"POST\",\n headers,\n body: payload,\n ...(binding.timeoutMs\n ? { signal: AbortSignal.timeout(binding.timeoutMs) }\n : {}),\n });\n if (res.ok) return;\n if (res.status >= 400 && res.status < 500) {\n // Permanent — bad request / auth. Do not retry.\n throw new WebhookDeliveryError(\n `Webhook ${binding.url} returned ${res.status}`,\n res.status,\n false\n );\n }\n // 5xx — transient.\n throw new WebhookDeliveryError(\n `Webhook ${binding.url} returned ${res.status}`,\n res.status,\n true\n );\n } catch (err) {\n const retryable =\n err instanceof WebhookDeliveryError ? err.retryable : true; // network errors are transient\n if (!retryable || attempt >= maxAttempts) {\n if (err instanceof WebhookDeliveryError) throw err;\n throw new WebhookDeliveryError(\n err instanceof Error ? err.message : String(err),\n undefined,\n true\n );\n }\n await sleep(baseBackoff * 2 ** (attempt - 1));\n }\n }\n}\n\n/**\n * Dispatch a stage's handler. Returns the executionUuid for streamable\n * handlers (cadra_agent/team); webhooks are fire-and-forget (completion lands\n * via the host callback). `human`/`none` stages do not dispatch.\n */\nexport async function dispatchStageHandler(\n ctx: HandlerContext,\n cadra: CadraRunClient,\n webhookOpts?: WebhookDeliveryOptions\n): Promise<HandlerDispatchResult> {\n const handler = ctx.stage.handler;\n if (!handler || handler.type === \"none\" || handler.type === \"human\") {\n return { dispatched: false };\n }\n\n // For a batch chunk, the OUTBOUND run's idempotency key is the chunk's\n // `batchKey` (ONE execution per chunk), not a per-card key — `ctx.input`\n // already carries the full card list under `context.kanban.batch`. Per-card\n // idempotency is enforced separately by the engine's per-card `beginStageRun`\n // CAS before this dispatch is ever issued.\n const runIdemKey = ctx.batch?.batchKey ?? ctx.idemKey;\n\n switch (handler.type) {\n case \"cadra_agent\": {\n if (!handler.agentUuid) {\n throw new Error(`Stage ${ctx.stage.key} (cadra_agent) missing agentUuid`);\n }\n const { executionUuid } = await cadra.runAgent({\n agentUuid: handler.agentUuid,\n orgId: ctx.orgId,\n input: ctx.input,\n idemKey: runIdemKey,\n // Board/headless dispatch always disables ask_user (spec §6.5 / FINDING-5).\n allowAskUser: false,\n callbackRef: ctx.callbackUrl,\n });\n return { dispatched: true, executionUuid };\n }\n case \"cadra_team\": {\n if (!handler.teamUuid) {\n throw new Error(`Stage ${ctx.stage.key} (cadra_team) missing teamUuid`);\n }\n const { executionUuid } = await cadra.runTeam({\n teamUuid: handler.teamUuid,\n orgId: ctx.orgId,\n input: ctx.input,\n idemKey: runIdemKey,\n // Board/headless dispatch always disables ask_user (spec §6.5 / FINDING-5).\n allowAskUser: false,\n callbackRef: ctx.callbackUrl,\n });\n return { dispatched: true, executionUuid };\n }\n case \"webhook\": {\n await deliverWebhook(ctx, cadra, webhookOpts);\n return { dispatched: true };\n }\n case \"remote_agent\": {\n // handler.remoteAgentUuid is the cadra remote_agents registry uuid (§5.3).\n // Cast to any to handle the cadra-web boardDefinition union shape which uses\n // remote_agent_uuid (snake_case from JSONB) while the SDK type uses remoteAgentUuid.\n const h = handler as unknown as Record<string, unknown>;\n const remoteAgentUuid =\n (h[\"remoteAgentUuid\"] as string | undefined) ??\n (h[\"remote_agent_uuid\"] as string | undefined);\n if (!remoteAgentUuid) {\n throw new Error(`Stage ${ctx.stage.key} (remote_agent) missing remoteAgentUuid`);\n }\n const { executionUuid } = await cadra.runRemoteAgent({\n remoteAgentUuid,\n orgId: ctx.orgId,\n input: ctx.input,\n idemKey: runIdemKey,\n // Board/headless dispatch always disables ask_user (spec §6.5).\n allowAskUser: false,\n callbackRef: ctx.callbackUrl,\n });\n return { dispatched: true, executionUuid };\n }\n default:\n // Unknown handler type — treat as passive (forward-compatible).\n return { dispatched: false };\n }\n}\n","/**\n * InMemoryStorageAdapter — a reference KanbanStorageAdapter.\n *\n * Single-threaded JS gives us free atomicity (no real row locks needed): each\n * adapter method runs to completion before the next starts. We still model the\n * CONTRACT faithfully:\n * - `applyTransition` is a CAS on `fromLane` (a stale `fromLane` throws a\n * conflict — the loser of a concurrent race).\n * - `beginStageRun` is a CAS insert on `idemKey` (UNIQUE).\n * - `completeStageRun` is idempotent: a second completion returns\n * `{ applied: false }` and does not re-advance.\n *\n * Used by the engine tests and the Task-6 conformance suite as the proof that\n * the contract is implementable. Hosts use it as a worked example.\n *\n * Server-safe (no DOM imports).\n *\n * @module @cadraos/sdk/kanban\n */\n\nimport type {\n AdapterCapabilities,\n KanbanStorageAdapter,\n} from \"./storage-types.js\";\nimport type {\n Actor,\n ApplyTransitionInput,\n CreateCardServerInput,\n DueRule,\n KanbanCard,\n KanbanHandlerType,\n StageRun,\n TransitionLogEntry,\n} from \"../types.js\";\n\n/**\n * Thrown by `applyTransition` when the CAS `fromLane` guard fails (the card has\n * already moved — a concurrent transition won the race).\n */\nexport class TransitionConflictError extends Error {\n readonly code = \"transition_conflict\";\n constructor(message = \"Card lane changed since the move was computed\") {\n super(message);\n this.name = \"TransitionConflictError\";\n }\n}\n\n/**\n * Thrown by `listDueCards` when a `DueRule.kind` is not in the closed\n * vocabulary (design §6 — fail closed; never silently return everything).\n */\nexport class UnknownDueRuleError extends Error {\n readonly code = \"unknown_due_rule_kind\";\n constructor(kind: string) {\n super(`Unknown DueRule.kind: ${JSON.stringify(kind)}`);\n this.name = \"UnknownDueRuleError\";\n }\n}\n\nlet idSeq = 0;\nfunction nextId(prefix: string): string {\n idSeq += 1;\n return `${prefix}-${idSeq}`;\n}\n\n/** Default stale-`queued` horizon (design §10): 15 minutes. */\nconst DEFAULT_STALE_QUEUED_MS = 15 * 60_000;\n\nexport class InMemoryStorageAdapter implements KanbanStorageAdapter {\n private cards = new Map<string, KanbanCard & { boardConfigUuid: string }>();\n private logs = new Map<string, TransitionLogEntry[]>();\n private runs = new Map<string, StageRun>();\n\n /**\n * A `queued` stage-run older than this (ms) is STALE and re-claimable by\n * `beginStageRun` (design §10) — it models a run whose process died between\n * `beginStageRun` and dispatch, so `failStageRun` never ran. A `failed` run is\n * re-claimable regardless of age. Must comfortably exceed the dispatch time so\n * a genuinely in-flight `queued` run is never re-claimed out from under it.\n */\n private readonly staleQueuedMs: number;\n /** Injectable clock (ms) — real hosts use `Date.now`; tests pin it. */\n private readonly now: () => number;\n\n constructor(opts?: { staleQueuedMs?: number; now?: () => number }) {\n this.staleQueuedMs = opts?.staleQueuedMs ?? DEFAULT_STALE_QUEUED_MS;\n this.now = opts?.now ?? (() => Date.now());\n }\n\n // ----- Cards -----\n\n async listCards(boardConfigUuid: string): Promise<KanbanCard[]> {\n return [...this.cards.values()]\n .filter((c) => c.boardConfigUuid === boardConfigUuid)\n .map((c) => this.publicCard(c));\n }\n\n async getCard(cardId: string): Promise<KanbanCard | null> {\n const c = this.cards.get(cardId);\n return c ? this.publicCard(c) : null;\n }\n\n async createCard(input: CreateCardServerInput): Promise<KanbanCard> {\n const id = nextId(\"card\");\n const now = new Date().toISOString();\n const card = {\n id,\n boardId: input.boardConfigUuid,\n boardConfigUuid: input.boardConfigUuid,\n // Persist BOTH halves of the lifecycle pin as first-class card fields\n // (p33 §10.5): the Cadra lifecycle uuid + version the card was created\n // under. These are surfaced on the public card so the engine's\n // `resolveLifecycleRef` reads a restart-safe, re-link-proof pin.\n cadraLifecycleUuid: input.boardConfigUuid,\n configVersion: input.configVersion,\n lane: input.initialLane,\n title: input.title,\n description: input.description,\n type: input.type,\n sharedContext: input.sharedContext,\n createdAt: now,\n updatedAt: now,\n };\n this.cards.set(id, card);\n this.logs.set(id, []);\n return this.publicCard(card);\n }\n\n async updateCard(\n cardId: string,\n patch: { title?: string; description?: string; sharedContext?: Record<string, unknown> }\n ): Promise<KanbanCard> {\n const c = this.requireCard(cardId);\n if (patch.title !== undefined) c.title = patch.title;\n if (patch.description !== undefined) c.description = patch.description;\n if (patch.sharedContext !== undefined) {\n c.sharedContext = { ...(c.sharedContext ?? {}), ...patch.sharedContext };\n }\n c.updatedAt = new Date().toISOString();\n return this.publicCard(c);\n }\n\n async applyTransition(cardId: string, move: ApplyTransitionInput): Promise<KanbanCard> {\n const c = this.requireCard(cardId);\n // CAS guard: the card must still be in `fromLane`.\n if (c.lane !== move.fromLane) {\n throw new TransitionConflictError(\n `Expected lane ${move.fromLane}, card is in ${c.lane}`\n );\n }\n c.lane = move.toLane;\n if (move.contextPatch) {\n c.sharedContext = { ...(c.sharedContext ?? {}), ...move.contextPatch };\n }\n if (move.executionUuid) c.executionId = move.executionUuid;\n c.updatedAt = new Date().toISOString();\n this.appendLog(cardId, {\n fromLane: move.fromLane,\n toLane: move.toLane,\n transitionId: move.transitionId,\n actor: move.actor,\n executionUuid: move.executionUuid,\n });\n return this.publicCard(c);\n }\n\n async listTransitions(cardId: string): Promise<TransitionLogEntry[]> {\n return [...(this.logs.get(cardId) ?? [])];\n }\n\n // ----- Conductor mode: due queries + counts + capabilities -----\n\n async listDueCards(\n boardConfigUuid: string,\n laneKey: string,\n dueRule: DueRule,\n opts?: { limit?: number }\n ): Promise<KanbanCard[]> {\n // Fail-closed: reject an unknown kind BEFORE touching any card, so a bad\n // rule never silently returns the whole lane (design §6, §14.4).\n this.assertKnownKind(dueRule);\n\n const now = Date.now();\n const due = [...this.cards.values()]\n .filter(\n (c) => c.boardConfigUuid === boardConfigUuid && c.lane === laneKey\n )\n .filter((c) => this.isDue(c, dueRule, now))\n .map((c) => this.publicCard(c));\n\n const limit = opts?.limit;\n if (limit !== undefined && limit >= 0 && due.length > limit) {\n return due.slice(0, limit);\n }\n return due;\n }\n\n async countsByLane(\n boardConfigUuid: string\n ): Promise<Record<string, number>> {\n const counts: Record<string, number> = {};\n for (const c of this.cards.values()) {\n if (c.boardConfigUuid !== boardConfigUuid) continue;\n counts[c.lane] = (counts[c.lane] ?? 0) + 1;\n }\n return counts;\n }\n\n capabilities(): AdapterCapabilities {\n // The reference adapter resolves `field_due`/`predicate` against a card's\n // `sharedContext`, so any key is translatable. `[\"*\"]` advertises \"any\n // field/predicate\" for the worked-example adapter (real hosts enumerate\n // their concrete columns/predicates).\n return {\n dueRuleFields: [\"*\"],\n dueRulePredicates: [\"*\"],\n membership: \"adapter-resolved\",\n };\n }\n\n // ----- Stage runs -----\n\n async beginStageRun(\n cardId: string,\n r: { stageId: string; idemKey: string; handlerType: KanbanHandlerType }\n ): Promise<{ created: boolean; run: StageRun }> {\n const existing = this.runs.get(r.idemKey);\n if (existing) {\n // Re-claim a STRANDED run so a transient dispatch failure self-heals on\n // the next sweep (design §10): a `failed` run (a prior dispatch threw →\n // failStageRun), or a stale `queued` run (a process died before dispatch\n // could flip it to running/failed). A `running` (mid-flight) or\n // `completed` run is NEVER re-claimed — that is the acyclic guarantee\n // (a completed stage is never re-run under the same idemKey). On re-claim\n // we reset to a fresh `queued` intent (dropping the stale\n // error/executionUuid) and bump `attempts`, then return created:true so\n // the engine dispatches again.\n if (this.isReclaimable(existing)) {\n const run: StageRun = {\n idemKey: r.idemKey,\n cardId,\n stageId: r.stageId,\n handlerType: r.handlerType,\n status: \"queued\",\n attempts: (existing.attempts ?? 1) + 1,\n createdAt: new Date(this.now()).toISOString(),\n };\n this.runs.set(r.idemKey, run);\n return { created: true, run: { ...run } };\n }\n return { created: false, run: { ...existing } };\n }\n const run: StageRun = {\n idemKey: r.idemKey,\n cardId,\n stageId: r.stageId,\n handlerType: r.handlerType,\n status: \"queued\",\n attempts: 1,\n createdAt: new Date(this.now()).toISOString(),\n };\n this.runs.set(r.idemKey, run);\n return { created: true, run: { ...run } };\n }\n\n /**\n * A stranded stage-run the next `beginStageRun` may re-claim (design §10): a\n * `failed` run (dispatch threw), or a `queued` run older than `staleQueuedMs`\n * (a process died before dispatch flipped it). `running`/`completed` runs are\n * never re-claimed.\n */\n private isReclaimable(run: StageRun): boolean {\n if (run.status === \"failed\") return true;\n if (run.status === \"queued\") {\n const age = this.now() - Date.parse(run.createdAt);\n return Number.isFinite(age) && age >= this.staleQueuedMs;\n }\n return false;\n }\n\n async completeStageRun(\n idemKey: string,\n c: {\n executionUuid?: string;\n toLane?: string;\n contextPatch?: Record<string, unknown>;\n actor: Actor;\n }\n ): Promise<{ applied: boolean }> {\n const run = this.runs.get(idemKey);\n if (!run) throw new Error(`No stage run for idemKey ${idemKey}`);\n // Idempotent: a duplicate/retried completion is a no-op.\n if (run.status === \"completed\") return { applied: false };\n\n run.status = \"completed\";\n if (c.executionUuid) run.executionUuid = c.executionUuid;\n\n // One \"transaction\": mark complete + advance.\n if (c.toLane) {\n const card = this.requireCard(run.cardId);\n // Advance from the card's CURRENT lane (a lane KEY). The engine resolved\n // `toLane` for a card sitting in this run's stage, so the card's lane is\n // that stage's key — using it as `fromLane` is the CAS and is robust to a\n // stage `id` that differs from its `key` (p33 §10.2: `run.stageId` is the\n // immutable id, not necessarily the lane key). Skip the advance only if\n // the card already moved on (already at the target).\n if (card.lane !== c.toLane) {\n await this.applyTransition(run.cardId, {\n fromLane: card.lane,\n toLane: c.toLane,\n actor: c.actor,\n contextPatch: c.contextPatch,\n executionUuid: c.executionUuid ?? run.executionUuid,\n });\n }\n }\n return { applied: true };\n }\n\n async failStageRun(idemKey: string, f: { error: string }): Promise<void> {\n const run = this.runs.get(idemKey);\n if (!run) throw new Error(`No stage run for idemKey ${idemKey}`);\n if (run.status === \"completed\") return; // don't clobber a completed run\n run.status = \"failed\";\n run.error = f.error;\n }\n\n async getStageRun(idemKey: string): Promise<StageRun | null> {\n const r = this.runs.get(idemKey);\n return r ? { ...r } : null;\n }\n\n async markStageRunDispatched(\n idemKey: string,\n d: { executionUuid?: string }\n ): Promise<void> {\n const run = this.runs.get(idemKey);\n if (!run) return;\n if (run.status === \"queued\") run.status = \"running\";\n if (d.executionUuid) {\n run.executionUuid = d.executionUuid;\n // Mirror the execution uuid onto the card so the UI can stream it.\n const card = this.cards.get(run.cardId);\n if (card) card.executionId = d.executionUuid;\n }\n }\n\n // ----- internals -----\n\n /**\n * Reject (throw) if any node in the rule tree is not a known `kind` — checked\n * up front so a bad rule fails closed before we ever inspect a card.\n */\n private assertKnownKind(rule: DueRule): void {\n switch (rule.kind) {\n case \"always\":\n case \"backlog\":\n case \"field_due\":\n case \"predicate\":\n return;\n case \"and\":\n for (const r of rule.rules) this.assertKnownKind(r);\n return;\n default:\n throw new UnknownDueRuleError(\n (rule as { kind?: string }).kind ?? \"<missing>\"\n );\n }\n }\n\n /**\n * Evaluate a (validated) `DueRule` against an in-memory card. `field_due` /\n * `predicate` read the card's `sharedContext` (the reference adapter's only\n * \"host data\"); a real host pushes these down to SQL over its own columns.\n */\n private isDue(\n card: KanbanCard,\n rule: DueRule,\n now: number\n ): boolean {\n switch (rule.kind) {\n case \"always\":\n // Every card in the lane is due.\n return true;\n case \"backlog\":\n // The card is IN the lane (the caller already filtered to it), so any\n // card in a non-empty lane is due — the \"process the backlog\" rule.\n return true;\n case \"field_due\": {\n const v = card.sharedContext?.[rule.field];\n if (v == null) return false; // no value → not due (fail closed)\n const left = this.toComparable(v);\n const right =\n rule.value === \"now\"\n ? now\n : this.toComparable(rule.value);\n if (left == null || right == null) return false;\n // op is fixed to \"<=\".\n return left <= right;\n }\n case \"predicate\": {\n const v = card.sharedContext?.[rule.ref];\n if (v == null) return false;\n // op is fixed to \"=\".\n return String(v) === String(rule.value);\n }\n case \"and\":\n return rule.rules.every((r) => this.isDue(card, r, now));\n default:\n // Unreachable — assertKnownKind already rejected unknown kinds.\n throw new UnknownDueRuleError(\n (rule as { kind?: string }).kind ?? \"<missing>\"\n );\n }\n }\n\n /**\n * Coerce a value to a comparable primitive for `field_due` (`<=`): dates →\n * epoch ms, numeric strings → numbers, else the raw number/string.\n */\n private toComparable(v: unknown): number | string | null {\n if (typeof v === \"number\") return v;\n if (v instanceof Date) return v.getTime();\n if (typeof v === \"string\") {\n const t = Date.parse(v);\n if (!Number.isNaN(t)) return t; // ISO date-ish string → epoch ms\n const n = Number(v);\n if (!Number.isNaN(n) && v.trim() !== \"\") return n;\n return v;\n }\n return null;\n }\n\n private requireCard(cardId: string) {\n const c = this.cards.get(cardId);\n if (!c) throw new Error(`Card not found: ${cardId}`);\n return c;\n }\n\n private appendLog(cardId: string, entry: Omit<TransitionLogEntry, \"id\" | \"cardId\" | \"createdAt\">) {\n const list = this.logs.get(cardId) ?? [];\n list.push({\n id: nextId(\"log\"),\n cardId,\n createdAt: new Date().toISOString(),\n ...entry,\n });\n this.logs.set(cardId, list);\n }\n\n private publicCard(\n c: KanbanCard & { boardConfigUuid: string }\n ): KanbanCard {\n // Strip only the internal duplicate `boardConfigUuid` (the public card\n // exposes the pin via `boardId` + the first-class `cadraLifecycleUuid` /\n // `configVersion` fields the engine's `resolveLifecycleRef` reads).\n const { boardConfigUuid: _b, ...pub } = c;\n void _b;\n return { ...pub };\n }\n}\n","/**\n * HttpStorageAdapter — the GENERIC, cross-system KanbanStorageAdapter.\n *\n * The second adapter flavor (design.md §10). Where the in-process adapter\n * (crm/yobo) implements `KanbanStorageAdapter` directly over the host's own\n * tables, the `HttpStorageAdapter` satisfies the SAME contract by calling a\n * small, fixed REST contract that a FOREIGN (non-TS) system exposes over its\n * own data. No SDK link, no TypeScript, is required of the foreign host — it\n * just answers HTTP. This is the cross-system drop-in lever: an HRIS, an\n * accounting SaaS, a fulfillment system, or a video pipeline becomes a Cadra\n * board host by answering ~3-4 endpoints.\n *\n * THE HTTP CONTRACT (design.md §10 — the small but NON-trivial endpoint set;\n * read + transition + counts + stage-run durability/idempotency):\n *\n * | Method + path | Adapter method |\n * |--------------------------------------------------------|---------------------------|\n * | GET /boards/:uuid/cards?lane=&dueRule=&limit= | listCards / listDueCards |\n * | GET /boards/:uuid/cards/:cardId | getCard |\n * | POST /boards/:uuid/cards | createCard |\n * | PATCH /boards/:uuid/cards/:cardId | updateCard |\n * | POST /boards/:uuid/cards/:cardId/transition | applyTransition |\n * | GET /boards/:uuid/cards/:cardId/transitions | listTransitions |\n * | GET /boards/:uuid/counts | countsByLane |\n * | GET /capabilities | capabilities (prefetched) |\n * | POST /boards/:uuid/stage-runs | beginStageRun (CAS) |\n * | POST /boards/:uuid/stage-runs/:idemKey/complete | completeStageRun (CAS) |\n * | POST /boards/:uuid/stage-runs/:idemKey/fail | failStageRun |\n * | POST /boards/:uuid/stage-runs/:idemKey/dispatched | markStageRunDispatched |\n * | GET /boards/:uuid/stage-runs/:idemKey | getStageRun |\n *\n * WHO OWNS WHAT (design.md §10, §15 open-question 1 — RESOLVED):\n * - The FOREIGN HOST owns the `idemKey` CAS ledger (a unique-keyed `stage_run`\n * table in its own world). `beginStageRun` / `completeStageRun` are CAS over\n * the host's ledger; a replayed POST is a no-op the HOST enforces. v1 ships\n * NO Cadra-hosted-ledger mode — the realism bar is \"one small adapter\" that\n * includes a unique-keyed ledger, not zero code.\n * - The FOREIGN HOST owns `applyTransition` atomicity (one row-locked tx, CAS\n * on `fromLane`) and the `dueRule` → its-own-WHERE-clause translation. The\n * engine never sees host columns; the declared `dueRule` is PUSHED DOWN on\n * the read as a query param the host evaluates.\n *\n * AUTH / TRANSPORT (design.md §10 — no new auth model):\n * - Bearer key (`Authorization: Bearer <apiKey>`), the same key family as the\n * rest of Cadra.\n * - OPTIONAL HMAC-SHA256 over the request: `X-Cadra-Signature: t=<ts>,v1=<hex>`\n * signed over `${timestamp}.${method} ${path}.${body}` with `hmacSecret`,\n * the SAME scheme as `kanban.*` webhook channels + `board_config_secret`\n * (`hmacSign` is reused verbatim from the webhook handler).\n *\n * Server-safe (no DOM imports): uses global `fetch` + `crypto.subtle` (Node\n * 18+ / edge / worker runtimes). No `node:*` imports, so it stays portable.\n *\n * @module @cadraos/sdk/kanban\n */\n\nimport type {\n AdapterCapabilities,\n KanbanStorageAdapter,\n} from \"./storage-types.js\";\nimport type {\n Actor,\n ApplyTransitionInput,\n CreateCardServerInput,\n DueRule,\n KanbanCard,\n KanbanHandlerType,\n StageRun,\n TransitionLogEntry,\n} from \"../types.js\";\nimport { hmacSign } from \"../engine/handlers.js\";\n\n/**\n * Thrown when a foreign host returns a non-2xx response (other than the 404\n * that `getCard`/`getStageRun` map to `null`). Carries the status + the host's\n * response body for the cron/engine to surface (design §6, §14.4).\n */\nexport class HttpAdapterError extends Error {\n readonly code = \"http_adapter_error\";\n constructor(\n readonly status: number,\n readonly method: string,\n readonly path: string,\n readonly body: string\n ) {\n super(\n `HTTP ${status} from ${method} ${path}${\n body ? `: ${body.slice(0, 500)}` : \"\"\n }`\n );\n this.name = \"HttpAdapterError\";\n }\n}\n\n/**\n * Thrown by `capabilities()` when the manifest has not been prefetched. The\n * `KanbanStorageAdapter.capabilities()` method is SYNCHRONOUS (Cadra caches it\n * into its board-config registry, design §6), but HTTP is async — so the\n * caller MUST call `loadCapabilities()` once (or pass `capabilities` to the\n * constructor) before `capabilities()` is read.\n */\nexport class CapabilitiesNotLoadedError extends Error {\n readonly code = \"capabilities_not_loaded\";\n constructor() {\n super(\n \"HttpStorageAdapter.capabilities() called before the manifest was \" +\n \"fetched — call `await adapter.loadCapabilities()` once (or pass \" +\n \"`capabilities` to the constructor).\"\n );\n this.name = \"CapabilitiesNotLoadedError\";\n }\n}\n\n/** A minimal `fetch` shape (so a host may inject a custom transport / test loopback). */\nexport type FetchLike = (\n input: string,\n init?: {\n method?: string;\n headers?: Record<string, string>;\n body?: string;\n }\n) => Promise<{\n status: number;\n ok: boolean;\n text(): Promise<string>;\n}>;\n\n/**\n * Configuration for the {@link HttpStorageAdapter}.\n */\nexport interface HttpStorageAdapterConfig {\n /**\n * Base URL of the foreign host's board API (no trailing slash), e.g.\n * `https://hris.acme.com/cadra`. All contract paths are appended to this.\n */\n baseUrl: string;\n /**\n * The board config uuid this adapter is bound to (cards/counts/stage-runs all\n * key on it). One adapter instance = one board.\n */\n boardConfigUuid: string;\n /** Bearer key sent as `Authorization: Bearer <apiKey>` (no new auth model). */\n apiKey: string;\n /**\n * OPTIONAL HMAC-SHA256 signing secret. When present, every request carries\n * `X-Cadra-Signature: t=<ts>,v1=<hex>` over `${ts}.${method} ${path}.${body}`\n * — the SAME scheme as the `kanban.*` webhook channels + `board_config_secret`.\n * When absent, requests are bearer-only.\n */\n hmacSecret?: string;\n /**\n * OPTIONAL pre-supplied capability manifest. When provided, `capabilities()`\n * returns it without a network call (Cadra typically already cached it).\n * When omitted, call `await loadCapabilities()` once before `capabilities()`.\n */\n capabilities?: AdapterCapabilities;\n /** Inject a custom `fetch` (default: the global `fetch`). */\n fetchImpl?: FetchLike;\n /** Inject a clock for deterministic HMAC timestamps in tests. */\n now?: () => number;\n}\n\n/**\n * The generic HTTP-backed `KanbanStorageAdapter`. One instance is bound to one\n * `boardConfigUuid`; it maps each adapter method to the §10 REST contract.\n *\n * The Conductor-mode methods (`listDueCards` / `countsByLane` / `capabilities`)\n * are implemented — `HttpStorageAdapter` is a Conductor-capable adapter,\n * because the foreign host owns the due-query + counts (a foreign SOP host that\n * cannot answer them simply does not expose those routes, but then it is not a\n * scheduled-lane host).\n */\nexport class HttpStorageAdapter implements KanbanStorageAdapter {\n private readonly baseUrl: string;\n private readonly boardConfigUuid: string;\n private readonly apiKey: string;\n private readonly hmacSecret?: string;\n private readonly fetchImpl: FetchLike;\n private readonly now: () => number;\n private caps?: AdapterCapabilities;\n\n constructor(config: HttpStorageAdapterConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/+$/, \"\");\n this.boardConfigUuid = config.boardConfigUuid;\n this.apiKey = config.apiKey;\n this.hmacSecret = config.hmacSecret;\n this.fetchImpl = (config.fetchImpl ?? (fetch as unknown as FetchLike));\n this.now = config.now ?? Date.now;\n this.caps = config.capabilities;\n }\n\n private get board(): string {\n return encodeURIComponent(this.boardConfigUuid);\n }\n\n // ----- Cards -----\n\n async listCards(boardConfigUuid: string): Promise<KanbanCard[]> {\n const res = await this.request<{ cards: KanbanCard[] }>(\n \"GET\",\n `/boards/${encodeURIComponent(boardConfigUuid)}/cards`\n );\n return res.cards ?? [];\n }\n\n async getCard(cardId: string): Promise<KanbanCard | null> {\n return this.request<KanbanCard | null>(\n \"GET\",\n `/boards/${this.board}/cards/${encodeURIComponent(cardId)}`,\n undefined,\n { nullOn404: true }\n );\n }\n\n async createCard(input: CreateCardServerInput): Promise<KanbanCard> {\n return this.request<KanbanCard>(\n \"POST\",\n `/boards/${encodeURIComponent(input.boardConfigUuid)}/cards`,\n input\n );\n }\n\n async updateCard(\n cardId: string,\n patch: {\n title?: string;\n description?: string;\n sharedContext?: Record<string, unknown>;\n }\n ): Promise<KanbanCard> {\n return this.request<KanbanCard>(\n \"PATCH\",\n `/boards/${this.board}/cards/${encodeURIComponent(cardId)}`,\n patch\n );\n }\n\n async applyTransition(\n cardId: string,\n move: ApplyTransitionInput\n ): Promise<KanbanCard> {\n // The host runs its OWN transition atomically (row-locked, CAS on fromLane)\n // and is the source of truth for the conflict. A stale fromLane → the host\n // returns 409 → we surface it as an `HttpAdapterError` the engine maps to a\n // conflict (the loser of a concurrent race).\n return this.request<KanbanCard>(\n \"POST\",\n `/boards/${this.board}/cards/${encodeURIComponent(cardId)}/transition`,\n move\n );\n }\n\n async listTransitions(cardId: string): Promise<TransitionLogEntry[]> {\n const res = await this.request<{ transitions: TransitionLogEntry[] }>(\n \"GET\",\n `/boards/${this.board}/cards/${encodeURIComponent(cardId)}/transitions`\n );\n return res.transitions ?? [];\n }\n\n // ----- Conductor mode: due queries + counts + capabilities -----\n\n async listDueCards(\n boardConfigUuid: string,\n laneKey: string,\n dueRule: DueRule,\n opts?: { limit?: number }\n ): Promise<KanbanCard[]> {\n // PUSH THE RULE DOWN: the declared `dueRule` rides as a JSON query param the\n // FOREIGN HOST evaluates over its own data. The engine never sees host\n // columns; the host owns the translation + the fail-closed-on-unknown-kind\n // contract (an unknown kind → the host rejects → we surface its error).\n const qs = new URLSearchParams();\n qs.set(\"lane\", laneKey);\n qs.set(\"dueRule\", JSON.stringify(dueRule));\n if (opts?.limit !== undefined) qs.set(\"limit\", String(opts.limit));\n const res = await this.request<{ cards: KanbanCard[] }>(\n \"GET\",\n `/boards/${encodeURIComponent(boardConfigUuid)}/cards?${qs.toString()}`\n );\n return res.cards ?? [];\n }\n\n async countsByLane(\n boardConfigUuid: string\n ): Promise<Record<string, number>> {\n return this.request<Record<string, number>>(\n \"GET\",\n `/boards/${encodeURIComponent(boardConfigUuid)}/counts`\n );\n }\n\n /**\n * Fetch the host's capability manifest once and cache it, so the SYNCHRONOUS\n * `capabilities()` (which Cadra calls at publish/import, design §6) can return\n * it without a network round-trip. Idempotent — re-call to refresh.\n */\n async loadCapabilities(): Promise<AdapterCapabilities> {\n this.caps = await this.request<AdapterCapabilities>(\"GET\", `/capabilities`);\n return this.caps;\n }\n\n capabilities(): AdapterCapabilities {\n if (!this.caps) throw new CapabilitiesNotLoadedError();\n return this.caps;\n }\n\n // ----- Stage runs (durable + idempotent — host owns the CAS ledger) -----\n\n async beginStageRun(\n cardId: string,\n r: { stageId: string; idemKey: string; handlerType: KanbanHandlerType }\n ): Promise<{ created: boolean; run: StageRun }> {\n // CAS on idemKey at the HOST. A first insert → `{ created: true }`; a replay\n // of the same idemKey → `{ created: false }` (no-op). The host's unique\n // constraint is the source of truth — a retried dispatch never double-fires.\n return this.request<{ created: boolean; run: StageRun }>(\n \"POST\",\n `/boards/${this.board}/stage-runs`,\n { cardId, ...r }\n );\n }\n\n async completeStageRun(\n idemKey: string,\n c: {\n executionUuid?: string;\n toLane?: string;\n contextPatch?: Record<string, unknown>;\n actor: Actor;\n }\n ): Promise<{ applied: boolean }> {\n // Idempotent at the HOST: a duplicate/retried completion returns\n // `{ applied: false }` and does NOT double-advance the card.\n return this.request<{ applied: boolean }>(\n \"POST\",\n `/boards/${this.board}/stage-runs/${encodeURIComponent(idemKey)}/complete`,\n c\n );\n }\n\n async failStageRun(idemKey: string, f: { error: string }): Promise<void> {\n await this.request<{ ok?: boolean }>(\n \"POST\",\n `/boards/${this.board}/stage-runs/${encodeURIComponent(idemKey)}/fail`,\n f\n );\n }\n\n async markStageRunDispatched(\n idemKey: string,\n d: { executionUuid?: string }\n ): Promise<void> {\n await this.request<{ ok?: boolean }>(\n \"POST\",\n `/boards/${this.board}/stage-runs/${encodeURIComponent(\n idemKey\n )}/dispatched`,\n d\n );\n }\n\n async getStageRun(idemKey: string): Promise<StageRun | null> {\n return this.request<StageRun | null>(\n \"GET\",\n `/boards/${this.board}/stage-runs/${encodeURIComponent(idemKey)}`,\n undefined,\n { nullOn404: true }\n );\n }\n\n // ----- transport -----\n\n /**\n * One signed request to the foreign host. Adds bearer auth + (optional) HMAC,\n * parses JSON, maps 404 → `null` for the two getters, and throws\n * `HttpAdapterError` on any other non-2xx.\n */\n private async request<T>(\n method: string,\n path: string,\n body?: unknown,\n opts?: { nullOn404?: boolean }\n ): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const serialized = body === undefined ? \"\" : JSON.stringify(body);\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.apiKey}`,\n };\n if (body !== undefined) headers[\"Content-Type\"] = \"application/json\";\n\n // OPTIONAL HMAC — same scheme as the webhook channels: sign over\n // `${ts}.${method} ${path}.${body}` so the signature binds method+path+body.\n if (this.hmacSecret) {\n const ts = this.now();\n const signature = await hmacSign(\n this.hmacSecret,\n `${ts}.${method} ${path}.${serialized}`\n );\n headers[\"X-Cadra-Signature\"] = `t=${ts},v1=${signature}`;\n }\n\n const res = await this.fetchImpl(url, {\n method,\n headers,\n ...(body === undefined ? {} : { body: serialized }),\n });\n\n if (res.status === 404 && opts?.nullOn404) {\n return null as T;\n }\n\n const text = await res.text();\n if (!res.ok) {\n throw new HttpAdapterError(res.status, method, path, text);\n }\n if (text === \"\") return undefined as T;\n return JSON.parse(text) as T;\n }\n}\n","/**\n * exampleHostHandler — a minimal, NON-crm example host implementing the §10\n * HTTP contract (the documented starter template, design.md §10).\n *\n * This is the \"ONE small adapter, not zero code\" realism bar: a brand-new SOP\n * host (an HRIS, an accounting SaaS, a fulfillment system, a video pipeline)\n * becomes a Cadra board host by answering ~3-4 routes over ITS OWN data. Here\n * the \"own data\" is an in-process `KanbanStorageAdapter` (the reference\n * `InMemoryStorageAdapter`) standing in for the foreign host's real tables — a\n * real host swaps that for its own SQL, owning:\n * - the `applyTransition` atomicity (row-locked, CAS on fromLane),\n * - the `dueRule` → its-own-WHERE-clause translation,\n * - the `idemKey` CAS stage-run ledger (a unique-keyed table),\n * - the `capabilities` manifest.\n *\n * The auth boundary (bearer key + optional HMAC-SHA256 over\n * `${ts}.${method} ${path}.${body}`) is enforced here exactly as the\n * `HttpStorageAdapter` signs it — the same scheme as the `kanban.*` webhook\n * channels + `board_config_secret`. NO new auth model.\n *\n * `exampleHostHandler` is transport-agnostic: it takes a parsed\n * `{ method, path, headers, body }` and returns `{ status, body }`. Wrap it in\n * a `node:http` server (see `startExampleHost`), a Fastify route, a Lambda, a\n * Cloudflare Worker — anything. A real foreign host re-implements this surface\n * in its own language; this TS version is the executable specification + the\n * loopback the conformance suite runs against (design §10, STORY-008).\n *\n * Server-safe (no DOM imports). `node:http` is only imported inside the\n * OPTIONAL `startExampleHost` convenience (a lazy dynamic import) so this module\n * stays portable to edge/worker runtimes.\n *\n * @module @cadraos/sdk/kanban\n */\n\nimport type { KanbanStorageAdapter } from \"./storage-types.js\";\nimport { InMemoryStorageAdapter, TransitionConflictError } from \"./in-memory-adapter.js\";\nimport type {\n Actor,\n ApplyTransitionInput,\n CreateCardServerInput,\n DueRule,\n KanbanHandlerType,\n} from \"../types.js\";\nimport { hmacSign } from \"../engine/handlers.js\";\n\n/** A transport-neutral request the host handler consumes. */\nexport interface HostRequest {\n method: string;\n /** Path + query string, e.g. `/boards/cfg-1/cards?lane=scheduled`. */\n path: string;\n headers: Record<string, string | undefined>;\n /** Parsed JSON body (undefined for GET / empty bodies). */\n body?: unknown;\n}\n\n/** A transport-neutral response the handler returns. */\nexport interface HostResponse {\n status: number;\n /** JSON-serializable body (undefined → empty 204-ish reply). */\n body?: unknown;\n}\n\n/** Options for {@link exampleHostHandler}. */\nexport interface ExampleHostOptions {\n /**\n * The backing storage adapter (the foreign host's \"own data\"). Defaults to a\n * fresh `InMemoryStorageAdapter`. A real host passes an adapter over its own\n * tables.\n */\n adapter?: KanbanStorageAdapter;\n /** The bearer key the host accepts (`Authorization: Bearer <apiKey>`). */\n apiKey: string;\n /**\n * OPTIONAL HMAC secret. When set, every request MUST carry a valid\n * `X-Cadra-Signature: t=<ts>,v1=<hex>` over `${ts}.${method} ${path}.${body}`\n * or the host replies 401.\n */\n hmacSecret?: string;\n}\n\n/**\n * Build a §10-contract host handler backed by `opts.adapter`. The returned\n * function is `async (req) => res` — wire it into any transport.\n */\nexport function exampleHostHandler(\n opts: ExampleHostOptions\n): (req: HostRequest) => Promise<HostResponse> {\n const adapter = opts.adapter ?? new InMemoryStorageAdapter();\n\n return async function handle(req: HostRequest): Promise<HostResponse> {\n // --- auth: bearer + optional HMAC (same scheme as kanban.* webhooks) ---\n const authFail = await checkAuth(req, opts);\n if (authFail) return authFail;\n\n const { pathname, query } = splitPath(req.path);\n const segs = pathname.split(\"/\").filter(Boolean);\n\n try {\n // GET /capabilities\n if (req.method === \"GET\" && segs.length === 1 && segs[0] === \"capabilities\") {\n const caps = adapter.capabilities?.() ?? {\n dueRuleFields: [\"*\"],\n dueRulePredicates: [\"*\"],\n membership: \"adapter-resolved\" as const,\n };\n return { status: 200, body: caps };\n }\n\n // Everything else is /boards/:uuid/...\n if (segs[0] !== \"boards\" || segs.length < 2) {\n return { status: 404, body: { error: \"not_found\" } };\n }\n const boardUuid = decodeURIComponent(segs[1]!);\n const rest = segs.slice(2);\n\n // GET /boards/:uuid/counts\n if (req.method === \"GET\" && rest.length === 1 && rest[0] === \"counts\") {\n const counts = (await adapter.countsByLane?.(boardUuid)) ?? {};\n return { status: 200, body: counts };\n }\n\n // ---- cards ----\n if (rest[0] === \"cards\") {\n // GET /boards/:uuid/cards?lane=&dueRule=&limit=\n if (req.method === \"GET\" && rest.length === 1) {\n const lane = query.get(\"lane\") ?? undefined;\n const dueRuleRaw = query.get(\"dueRule\");\n const limitRaw = query.get(\"limit\");\n const limit = limitRaw != null ? Number(limitRaw) : undefined;\n\n // dueRule present → push it down to listDueCards (the host owns the\n // translation + the fail-closed-on-unknown-kind contract).\n if (dueRuleRaw != null && lane) {\n let dueRule: DueRule;\n try {\n dueRule = JSON.parse(dueRuleRaw) as DueRule;\n } catch {\n return { status: 400, body: { error: \"bad_due_rule_json\" } };\n }\n if (!adapter.listDueCards) {\n return { status: 501, body: { error: \"due_query_unsupported\" } };\n }\n try {\n const cards = await adapter.listDueCards(boardUuid, lane, dueRule, {\n ...(limit !== undefined ? { limit } : {}),\n });\n return { status: 200, body: { cards } };\n } catch (e) {\n // Fail closed: an unknown DueRule.kind rejects here (the host),\n // surfaced to the adapter as a 422 — never a silent \"return all\".\n return {\n status: 422,\n body: { error: \"unknown_due_rule\", message: errMsg(e) },\n };\n }\n }\n\n // plain listing\n const cards = await adapter.listCards(boardUuid);\n return { status: 200, body: { cards } };\n }\n\n // POST /boards/:uuid/cards\n if (req.method === \"POST\" && rest.length === 1) {\n const input = req.body as CreateCardServerInput;\n const card = await adapter.createCard({\n ...input,\n boardConfigUuid: boardUuid,\n });\n return { status: 201, body: card };\n }\n\n const cardId = rest[1] != null ? decodeURIComponent(rest[1]) : undefined;\n if (!cardId) return { status: 404, body: { error: \"not_found\" } };\n\n // GET /boards/:uuid/cards/:cardId\n if (req.method === \"GET\" && rest.length === 2) {\n const card = await adapter.getCard(cardId);\n if (!card) return { status: 404, body: { error: \"card_not_found\" } };\n return { status: 200, body: card };\n }\n\n // PATCH /boards/:uuid/cards/:cardId\n if (req.method === \"PATCH\" && rest.length === 2) {\n const card = await adapter.updateCard(\n cardId,\n req.body as {\n title?: string;\n description?: string;\n sharedContext?: Record<string, unknown>;\n }\n );\n return { status: 200, body: card };\n }\n\n // GET /boards/:uuid/cards/:cardId/transitions\n if (req.method === \"GET\" && rest.length === 3 && rest[2] === \"transitions\") {\n const transitions = await adapter.listTransitions(cardId);\n return { status: 200, body: { transitions } };\n }\n\n // POST /boards/:uuid/cards/:cardId/transition\n if (req.method === \"POST\" && rest.length === 3 && rest[2] === \"transition\") {\n try {\n const card = await adapter.applyTransition(\n cardId,\n req.body as ApplyTransitionInput\n );\n return { status: 200, body: card };\n } catch (e) {\n // A stale fromLane (the loser of a concurrent race) → 409 Conflict.\n if (e instanceof TransitionConflictError) {\n return { status: 409, body: { error: \"transition_conflict\", message: e.message } };\n }\n throw e;\n }\n }\n }\n\n // ---- stage runs (the durable, idempotent CAS ledger) ----\n if (rest[0] === \"stage-runs\") {\n // POST /boards/:uuid/stage-runs\n if (req.method === \"POST\" && rest.length === 1) {\n const b = req.body as {\n cardId: string;\n stageId: string;\n idemKey: string;\n handlerType: KanbanHandlerType;\n };\n const out = await adapter.beginStageRun(b.cardId, {\n stageId: b.stageId,\n idemKey: b.idemKey,\n handlerType: b.handlerType,\n });\n return { status: 200, body: out };\n }\n\n const idemKey = rest[1] != null ? decodeURIComponent(rest[1]) : undefined;\n if (!idemKey) return { status: 404, body: { error: \"not_found\" } };\n\n // GET /boards/:uuid/stage-runs/:idemKey\n if (req.method === \"GET\" && rest.length === 2) {\n const run = await adapter.getStageRun(idemKey);\n if (!run) return { status: 404, body: { error: \"run_not_found\" } };\n return { status: 200, body: run };\n }\n\n // POST /boards/:uuid/stage-runs/:idemKey/complete\n if (req.method === \"POST\" && rest.length === 3 && rest[2] === \"complete\") {\n const out = await adapter.completeStageRun(\n idemKey,\n req.body as {\n executionUuid?: string;\n toLane?: string;\n contextPatch?: Record<string, unknown>;\n actor: Actor;\n }\n );\n return { status: 200, body: out };\n }\n\n // POST /boards/:uuid/stage-runs/:idemKey/fail\n if (req.method === \"POST\" && rest.length === 3 && rest[2] === \"fail\") {\n await adapter.failStageRun(idemKey, req.body as { error: string });\n return { status: 200, body: { ok: true } };\n }\n\n // POST /boards/:uuid/stage-runs/:idemKey/dispatched\n if (req.method === \"POST\" && rest.length === 3 && rest[2] === \"dispatched\") {\n await adapter.markStageRunDispatched?.(\n idemKey,\n req.body as { executionUuid?: string }\n );\n return { status: 200, body: { ok: true } };\n }\n }\n\n return { status: 404, body: { error: \"not_found\", path: pathname } };\n } catch (e) {\n // Any host-side error surfaces as a 500 with a message (the adapter turns\n // it into an HttpAdapterError the engine/cron surfaces — design §14.4).\n return { status: 500, body: { error: \"host_error\", message: errMsg(e) } };\n }\n };\n}\n\n/**\n * Verify bearer + (optional) HMAC. Returns a 401 `HostResponse` on failure, or\n * `null` when the request is authorized.\n */\nasync function checkAuth(\n req: HostRequest,\n opts: ExampleHostOptions\n): Promise<HostResponse | null> {\n const auth = header(req.headers, \"authorization\");\n if (auth !== `Bearer ${opts.apiKey}`) {\n return { status: 401, body: { error: \"unauthorized\" } };\n }\n if (opts.hmacSecret) {\n const sigHeader = header(req.headers, \"x-cadra-signature\");\n if (!sigHeader) return { status: 401, body: { error: \"missing_signature\" } };\n const m = /^t=(\\d+),v1=([0-9a-f]+)$/.exec(sigHeader);\n if (!m) return { status: 401, body: { error: \"bad_signature_format\" } };\n const ts = m[1]!;\n const provided = m[2]!;\n const serialized =\n req.body === undefined ? \"\" : JSON.stringify(req.body);\n const expected = await hmacSign(\n opts.hmacSecret,\n `${ts}.${req.method} ${req.path}.${serialized}`\n );\n if (expected !== provided) {\n return { status: 401, body: { error: \"bad_signature\" } };\n }\n }\n return null;\n}\n\nfunction header(\n headers: Record<string, string | undefined>,\n name: string\n): string | undefined {\n const lower = name.toLowerCase();\n for (const k of Object.keys(headers)) {\n if (k.toLowerCase() === lower) return headers[k];\n }\n return undefined;\n}\n\nfunction splitPath(path: string): { pathname: string; query: URLSearchParams } {\n const qIdx = path.indexOf(\"?\");\n if (qIdx === -1) return { pathname: path, query: new URLSearchParams() };\n return {\n pathname: path.slice(0, qIdx),\n query: new URLSearchParams(path.slice(qIdx + 1)),\n };\n}\n\nfunction errMsg(e: unknown): string {\n return e instanceof Error ? e.message : String(e);\n}\n\n/**\n * OPTIONAL convenience: start the example host on a real `node:http` server.\n * Returns the bound `{ url, close }`. Used by the conformance loopback test so\n * the `HttpStorageAdapter` is exercised over REAL HTTP (real serialization, a\n * real socket), not a stubbed transport.\n *\n * `node:http` is imported lazily so the rest of this module stays edge-portable.\n */\nexport async function startExampleHost(\n opts: ExampleHostOptions\n): Promise<{ url: string; port: number; close: () => Promise<void> }> {\n const http = await import(\"node:http\");\n const handle = exampleHostHandler(opts);\n\n const server = http.createServer((req, res) => {\n const chunks: Buffer[] = [];\n req.on(\"data\", (c) => chunks.push(c as Buffer));\n req.on(\"end\", () => {\n void (async () => {\n const raw = Buffer.concat(chunks).toString(\"utf8\");\n let body: unknown;\n if (raw !== \"\") {\n try {\n body = JSON.parse(raw);\n } catch {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"bad_json\" }));\n return;\n }\n }\n const result = await handle({\n method: req.method ?? \"GET\",\n path: req.url ?? \"/\",\n headers: req.headers as Record<string, string | undefined>,\n body,\n });\n const payload =\n result.body === undefined ? \"\" : JSON.stringify(result.body);\n res.writeHead(result.status, { \"Content-Type\": \"application/json\" });\n res.end(payload);\n })();\n });\n });\n\n await new Promise<void>((resolve) => server.listen(0, \"127.0.0.1\", resolve));\n const addr = server.address();\n const port =\n typeof addr === \"object\" && addr ? addr.port : 0;\n\n return {\n url: `http://127.0.0.1:${port}`,\n port,\n close: () =>\n new Promise<void>((resolve, reject) =>\n server.close((err) => (err ? reject(err) : resolve()))\n ),\n };\n}\n","/**\n * KanbanStorageAdapter conformance test-kit.\n *\n * A reusable suite hosts run against THEIR adapter to prove it honors the\n * durability / idempotency / atomicity contract (design §4/§5/§11 R2). The host\n * imports `runAdapterConformance` and passes a factory that returns a FRESH,\n * empty adapter per case + the test-runner primitives (so this module doesn't\n * hard-depend on vitest at the SDK's runtime entry — the host injects its own\n * `describe`/`it`/`expect`).\n *\n * @example\n * ```ts\n * import { describe, it, expect } from 'vitest';\n * import { runAdapterConformance } from '@cadraos/sdk/kanban/engine';\n * import { MyHostAdapter } from './my-adapter';\n *\n * runAdapterConformance(() => new MyHostAdapter(testDb), { describe, it, expect });\n * ```\n *\n * Server-safe (no DOM imports).\n *\n * @module @cadraos/sdk/kanban\n */\n\nimport type { DueRule, KanbanStorageAdapter } from \"./storage-types.js\";\n\n// =============================================================================\n// INJECTED TEST-RUNNER PRIMITIVES\n// =============================================================================\n\n/** Minimal `expect` surface the suite uses (vitest/jest compatible). */\nexport interface ConformanceExpect {\n (actual: unknown): {\n toBe(expected: unknown): void;\n toEqual(expected: unknown): void;\n toBeNull(): void;\n toBeTruthy(): void;\n toBeGreaterThanOrEqual(n: number): void;\n toContain(item: unknown): void;\n };\n}\n\n/** Minimal describe/it surface (vitest/jest compatible). */\nexport interface ConformanceRunner {\n describe(name: string, fn: () => void): void;\n it(name: string, fn: () => void | Promise<void>): void;\n expect: ConformanceExpect;\n}\n\n/**\n * Factory returning a FRESH, empty adapter for each test (so cases are\n * isolated). May be async (e.g. to truncate a test DB).\n */\nexport type AdapterFactory = () => KanbanStorageAdapter | Promise<KanbanStorageAdapter>;\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\nconst BOARD = \"cfg-conformance\";\n\nasync function seedCard(\n adapter: KanbanStorageAdapter,\n lane: string,\n title = \"Card\",\n sharedContext?: Record<string, unknown>\n) {\n return adapter.createCard({\n title,\n boardConfigUuid: BOARD,\n configVersion: 1,\n initialLane: lane,\n sharedContext,\n });\n}\n\n// =============================================================================\n// SUITE\n// =============================================================================\n\n/**\n * Run the adapter conformance suite. Call inside a host test file.\n *\n * @param makeAdapter - Factory returning a fresh empty adapter per case.\n * @param runner - The injected `{ describe, it, expect }` from the host's\n * test framework.\n */\nexport function runAdapterConformance(\n makeAdapter: AdapterFactory,\n runner: ConformanceRunner\n): void {\n const { describe, it, expect } = runner;\n\n describe(\"KanbanStorageAdapter conformance\", () => {\n it(\"create → list → get round-trips a card at its initial lane\", async () => {\n const adapter = await makeAdapter();\n const card = await seedCard(adapter, \"scheduled\", \"My card\");\n expect(card.lane).toBe(\"scheduled\");\n expect(card.title).toBe(\"My card\");\n\n const list = await adapter.listCards(BOARD);\n expect(list.length).toBe(1);\n expect(list[0]!.id).toBe(card.id);\n\n const got = await adapter.getCard(card.id);\n expect(got).toBeTruthy();\n expect(got!.id).toBe(card.id);\n\n const missing = await adapter.getCard(\"nope\");\n expect(missing).toBeNull();\n });\n\n it(\"createCard persists BOTH halves of the lifecycle pin as first-class card fields (p33 §10.5)\", async () => {\n const adapter = await makeAdapter();\n const card = await adapter.createCard({\n title: \"Pinned card\",\n boardConfigUuid: BOARD,\n configVersion: 3,\n initialLane: \"scheduled\",\n });\n\n // The created card surfaces the pin (uuid + version) so the engine's\n // `resolveLifecycleRef` reads a restart-safe, re-link-proof pin — NOT an\n // in-process map. Both round-trip through get/list.\n expect(card.cadraLifecycleUuid).toBe(BOARD);\n expect(card.configVersion).toBe(3);\n\n const got = await adapter.getCard(card.id);\n expect(got!.cadraLifecycleUuid).toBe(BOARD);\n expect(got!.configVersion).toBe(3);\n });\n\n it(\"applyTransition advances the card + appends a transition-log entry\", async () => {\n const adapter = await makeAdapter();\n const card = await seedCard(adapter, \"scheduled\");\n\n const moved = await adapter.applyTransition(card.id, {\n fromLane: \"scheduled\",\n toLane: \"generate\",\n transitionId: \"t1\",\n actor: { type: \"user\", id: \"u1\" },\n });\n expect(moved.lane).toBe(\"generate\");\n\n const log = await adapter.listTransitions(card.id);\n expect(log.length).toBeGreaterThanOrEqual(1);\n const last = log[log.length - 1]!;\n expect(last.fromLane).toBe(\"scheduled\");\n expect(last.toLane).toBe(\"generate\");\n });\n\n it(\"applyTransition is atomic under a concurrent race: exactly one wins (fromLane guard)\", async () => {\n const adapter = await makeAdapter();\n const card = await seedCard(adapter, \"scheduled\");\n\n // Two transitions computed against the SAME fromLane=scheduled race.\n const results = await Promise.allSettled([\n adapter.applyTransition(card.id, {\n fromLane: \"scheduled\",\n toLane: \"generate\",\n actor: { type: \"user\", id: \"a\" },\n }),\n adapter.applyTransition(card.id, {\n fromLane: \"scheduled\",\n toLane: \"ready\",\n actor: { type: \"user\", id: \"b\" },\n }),\n ]);\n\n const fulfilled = results.filter((r) => r.status === \"fulfilled\");\n const rejected = results.filter((r) => r.status === \"rejected\");\n // Exactly one move wins; the loser observes the stale fromLane and fails.\n expect(fulfilled.length).toBe(1);\n expect(rejected.length).toBe(1);\n\n const final = await adapter.getCard(card.id);\n // The card sits in whichever lane the winner moved it to.\n expect([\"generate\", \"ready\"].includes(final!.lane)).toBe(true);\n });\n\n it(\"beginStageRun dedups on idemKey (CAS)\", async () => {\n const adapter = await makeAdapter();\n const card = await seedCard(adapter, \"generate\");\n const idemKey = `${card.id}:generate:1`;\n\n const first = await adapter.beginStageRun(card.id, {\n stageId: \"generate\",\n idemKey,\n handlerType: \"cadra_agent\",\n });\n expect(first.created).toBe(true);\n\n const second = await adapter.beginStageRun(card.id, {\n stageId: \"generate\",\n idemKey,\n handlerType: \"cadra_agent\",\n });\n expect(second.created).toBe(false);\n\n const run = await adapter.getStageRun(idemKey);\n expect(run).toBeTruthy();\n expect(run!.idemKey).toBe(idemKey);\n });\n\n it(\"completeStageRun is idempotent: second call returns applied=false + no double-advance\", async () => {\n const adapter = await makeAdapter();\n const card = await seedCard(adapter, \"generate\");\n const idemKey = `${card.id}:generate:1`;\n\n await adapter.beginStageRun(card.id, {\n stageId: \"generate\",\n idemKey,\n handlerType: \"cadra_agent\",\n });\n\n const first = await adapter.completeStageRun(idemKey, {\n executionUuid: \"exec-1\",\n toLane: \"ready\",\n actor: { type: \"agent\", id: \"exec-1\" },\n });\n expect(first.applied).toBe(true);\n\n const afterFirst = await adapter.getCard(card.id);\n expect(afterFirst!.lane).toBe(\"ready\");\n\n // Duplicate completion is a no-op.\n const second = await adapter.completeStageRun(idemKey, {\n executionUuid: \"exec-1\",\n toLane: \"ready\",\n actor: { type: \"agent\", id: \"exec-1\" },\n });\n expect(second.applied).toBe(false);\n\n // Only ONE advance happened (the log has a single generate→ready entry).\n const log = await adapter.listTransitions(card.id);\n const toReady = log.filter((l) => l.toLane === \"ready\");\n expect(toReady.length).toBe(1);\n });\n\n it(\"failStageRun marks the run failed without advancing\", async () => {\n const adapter = await makeAdapter();\n const card = await seedCard(adapter, \"generate\");\n const idemKey = `${card.id}:generate:1`;\n await adapter.beginStageRun(card.id, {\n stageId: \"generate\",\n idemKey,\n handlerType: \"cadra_agent\",\n });\n\n await adapter.failStageRun(idemKey, { error: \"boom\" });\n const run = await adapter.getStageRun(idemKey);\n expect(run!.status).toBe(\"failed\");\n expect(run!.error).toBe(\"boom\");\n\n const still = await adapter.getCard(card.id);\n expect(still!.lane).toBe(\"generate\"); // not advanced\n });\n\n // -----------------------------------------------------------------------\n // Conductor mode: listDueCards / countsByLane / capabilities (design §6)\n //\n // OPT-IN per host. These cases run ONLY when the adapter implements all\n // three Conductor methods. An event-only host (cadra-web, yobo) omits them\n // and the cases are SKIPPED — the base suite above still runs for ALL\n // adapters. A Conductor host (in-memory reference, crm) implements them, so\n // the cases run + assert the full due-query / counts / capabilities\n // contract.\n //\n // `makeAdapter` may be async, so we can't synchronously probe the adapter\n // at `it()`-registration time. Instead each Conductor case constructs the\n // adapter first, then no-ops (passes) when the methods are absent — the net\n // effect is \"skip on an event-only host, run on a Conductor host\". A typed\n // local guard narrows the optional methods so the rest of the case is\n // type-safe.\n // -----------------------------------------------------------------------\n\n /**\n * Narrow the adapter to one that implements all three Conductor methods, or\n * return null when the host opted out (event-only). When it returns null\n * the calling case simply returns — registered, but a no-op pass.\n */\n type ConductorAdapter = KanbanStorageAdapter &\n Required<\n Pick<\n KanbanStorageAdapter,\n \"listDueCards\" | \"countsByLane\" | \"capabilities\"\n >\n >;\n const asConductor = (\n adapter: KanbanStorageAdapter\n ): ConductorAdapter | null =>\n adapter.listDueCards && adapter.countsByLane && adapter.capabilities\n ? (adapter as ConductorAdapter)\n : null;\n\n /**\n * Does the adapter DECLARE it can translate `field_due` on `field`? The\n * conformance suite drives concrete field/ref names (`next_touch_at`,\n * `status`); a FAIL-CLOSED host (design §6) only supports the fields it\n * enumerates in `capabilities()` and throws on the rest — that rejection is\n * CORRECT contract behavior, not a conformance failure. So a case that drives\n * a field/ref the adapter doesn't advertise is SKIPPED (the adapter's own\n * `listDueCards` matrix tests its real vocabulary). The reference in-memory\n * adapter advertises `[\"*\"]` (any), so it still runs every case.\n */\n const supportsField = (adapter: ConductorAdapter, field: string): boolean => {\n const fields = adapter.capabilities().dueRuleFields;\n return fields.includes(\"*\") || fields.includes(field);\n };\n const supportsPredicate = (\n adapter: ConductorAdapter,\n ref: string\n ): boolean => {\n const preds = adapter.capabilities().dueRulePredicates;\n return preds.includes(\"*\") || preds.includes(ref);\n };\n\n it(\"listDueCards {kind:'always'} returns every card in the lane\", async () => {\n const base = await makeAdapter();\n const adapter = asConductor(base);\n if (!adapter) return; // event-only host: skip Conductor case\n await seedCard(adapter, \"scheduled\", \"a\");\n await seedCard(adapter, \"scheduled\", \"b\");\n await seedCard(adapter, \"other\", \"c\"); // different lane — excluded\n\n const due = await adapter.listDueCards(BOARD, \"scheduled\", {\n kind: \"always\",\n });\n expect(due.length).toBe(2);\n // All returned cards are in the swept lane.\n expect(due.every((c) => c.lane === \"scheduled\")).toBe(true);\n });\n\n it(\"listDueCards {kind:'backlog'} returns cards when the lane has any\", async () => {\n const base = await makeAdapter();\n const adapter = asConductor(base);\n if (!adapter) return;\n const empty = await adapter.listDueCards(BOARD, \"scheduled\", {\n kind: \"backlog\",\n });\n expect(empty.length).toBe(0);\n\n await seedCard(adapter, \"scheduled\", \"a\");\n const full = await adapter.listDueCards(BOARD, \"scheduled\", {\n kind: \"backlog\",\n });\n expect(full.length).toBe(1);\n });\n\n it(\"listDueCards {kind:'field_due'} selects only cards whose field is due (<= now)\", async () => {\n const base = await makeAdapter();\n const adapter = asConductor(base);\n if (!adapter) return;\n // Fail-closed host that doesn't declare `next_touch_at` → skip (correct\n // rejection is proven by the host's own capabilities/listDueCards tests).\n if (!supportsField(adapter, \"next_touch_at\")) return;\n const past = new Date(Date.now() - 60_000).toISOString();\n const future = new Date(Date.now() + 60_000).toISOString();\n await seedCard(adapter, \"scheduled\", \"due\", { next_touch_at: past });\n await seedCard(adapter, \"scheduled\", \"not-due\", {\n next_touch_at: future,\n });\n await seedCard(adapter, \"scheduled\", \"no-field\"); // missing → not due\n\n const rule: DueRule = {\n kind: \"field_due\",\n field: \"next_touch_at\",\n op: \"<=\",\n value: \"now\",\n };\n const due = await adapter.listDueCards(BOARD, \"scheduled\", rule);\n expect(due.length).toBe(1);\n expect(due[0]!.title).toBe(\"due\");\n });\n\n it(\"listDueCards {kind:'predicate'} matches an equality predicate\", async () => {\n const base = await makeAdapter();\n const adapter = asConductor(base);\n if (!adapter) return;\n if (!supportsPredicate(adapter, \"status\")) return;\n await seedCard(adapter, \"queued\", \"approved\", { status: \"approved\" });\n await seedCard(adapter, \"queued\", \"draft\", { status: \"draft\" });\n\n const rule: DueRule = {\n kind: \"predicate\",\n ref: \"status\",\n op: \"=\",\n value: \"approved\",\n };\n const due = await adapter.listDueCards(BOARD, \"queued\", rule);\n expect(due.length).toBe(1);\n expect(due[0]!.title).toBe(\"approved\");\n });\n\n it(\"listDueCards {kind:'and'} requires every nested rule (the Approve gate)\", async () => {\n const base = await makeAdapter();\n const adapter = asConductor(base);\n if (!adapter) return;\n // The Approve gate combines a field_due + a predicate; skip unless the host\n // declares BOTH targets (a fail-closed host that lacks either rejects — its\n // own tests cover that).\n if (\n !supportsField(adapter, \"next_touch_at\") ||\n !supportsPredicate(adapter, \"status\")\n )\n return;\n const past = new Date(Date.now() - 60_000).toISOString();\n const future = new Date(Date.now() + 60_000).toISOString();\n // due + approved → in\n await seedCard(adapter, \"queued\", \"send-me\", {\n next_touch_at: past,\n status: \"approved\",\n });\n // due but NOT approved → out (un-approved is simply not due, §9)\n await seedCard(adapter, \"queued\", \"unapproved\", {\n next_touch_at: past,\n status: \"draft\",\n });\n // approved but NOT due → out\n await seedCard(adapter, \"queued\", \"too-early\", {\n next_touch_at: future,\n status: \"approved\",\n });\n\n const rule: DueRule = {\n kind: \"and\",\n rules: [\n { kind: \"field_due\", field: \"next_touch_at\", op: \"<=\", value: \"now\" },\n { kind: \"predicate\", ref: \"status\", op: \"=\", value: \"approved\" },\n ],\n };\n const due = await adapter.listDueCards(BOARD, \"queued\", rule);\n expect(due.length).toBe(1);\n expect(due[0]!.title).toBe(\"send-me\");\n });\n\n it(\"listDueCards honors opts.limit (caps the sweep)\", async () => {\n const base = await makeAdapter();\n const adapter = asConductor(base);\n if (!adapter) return;\n for (let i = 0; i < 5; i++) await seedCard(adapter, \"scheduled\", `c${i}`);\n\n const due = await adapter.listDueCards(\n BOARD,\n \"scheduled\",\n { kind: \"always\" },\n { limit: 2 }\n );\n expect(due.length).toBe(2);\n });\n\n it(\"listDueCards FAILS CLOSED on an unknown DueRule.kind (rejects, never returns all)\", async () => {\n const base = await makeAdapter();\n const adapter = asConductor(base);\n if (!adapter) return;\n await seedCard(adapter, \"scheduled\", \"a\");\n await seedCard(adapter, \"scheduled\", \"b\");\n\n // A kind outside the closed vocabulary must reject, not silently return\n // every card in the lane (design §6, §14.4).\n const bogus = { kind: \"everything\" } as unknown as DueRule;\n let rejected = false;\n try {\n await adapter.listDueCards(BOARD, \"scheduled\", bogus);\n } catch {\n rejected = true;\n }\n expect(rejected).toBe(true);\n });\n\n it(\"listDueCards fails closed when an unknown kind is nested inside 'and'\", async () => {\n const base = await makeAdapter();\n const adapter = asConductor(base);\n if (!adapter) return;\n await seedCard(adapter, \"scheduled\", \"a\", { status: \"approved\" });\n\n const nested = {\n kind: \"and\",\n rules: [\n { kind: \"predicate\", ref: \"status\", op: \"=\", value: \"approved\" },\n { kind: \"wat\" },\n ],\n } as unknown as DueRule;\n let rejected = false;\n try {\n await adapter.listDueCards(BOARD, \"scheduled\", nested);\n } catch {\n rejected = true;\n }\n expect(rejected).toBe(true);\n });\n\n it(\"countsByLane returns a per-lane card count for the board\", async () => {\n const base = await makeAdapter();\n const adapter = asConductor(base);\n if (!adapter) return;\n await seedCard(adapter, \"sourced\", \"a\");\n await seedCard(adapter, \"sourced\", \"b\");\n await seedCard(adapter, \"scored\", \"c\");\n\n const counts = await adapter.countsByLane(BOARD);\n expect(counts.sourced).toBe(2);\n expect(counts.scored).toBe(1);\n });\n\n it(\"capabilities() advertises dueRule fields/predicates + adapter-resolved membership\", async () => {\n const base = await makeAdapter();\n const adapter = asConductor(base);\n if (!adapter) return;\n const caps = adapter.capabilities();\n expect(caps.membership).toBe(\"adapter-resolved\");\n expect(Array.isArray(caps.dueRuleFields)).toBe(true);\n expect(Array.isArray(caps.dueRulePredicates)).toBe(true);\n });\n });\n}\n","/**\n * @cadraos/sdk/kanban/engine — the SERVER-SIDE board engine.\n *\n * Runs in the HOST BACKEND (route/worker), never the browser (design §11 R1).\n * Drives the state machine and calls exactly two things: the host\n * `KanbanStorageAdapter` for persistence, and Cadra (or a webhook) for stage\n * execution. The host writes only the adapter.\n *\n * Operations:\n * - `createCard(boardConfigUuid, input)` — resolve the ACTIVE config → insert\n * at the initial stage (pinning the version) → run the stage if it has a\n * handler.\n * - `transition(cardId, toLane?)` — load the card + its PINNED config → resolve\n * a `manual_allowed` edge (single outgoing edge when `toLane` omitted; reject\n * ambiguous) → `applyTransition` → run the new stage's handler if any.\n * - `runStage(cardId, stageId)` — `idemKey = cardId:stageId:version` →\n * `beginStageRun` (CAS; no-op if already dispatched) → dispatch the handler →\n * stamp the executionUuid on the run.\n * - `onStageComplete(idemKey, …)` — invoked by the host when a run/webhook\n * reports terminal → resolve the single `auto_on_complete` edge →\n * `completeStageRun` (idempotent advance).\n *\n * Server-safe: NO DOM / React imports.\n *\n * @module @cadraos/sdk/kanban\n */\n\nimport type { KanbanStorageAdapter } from \"../adapters/storage-types.js\";\nimport type { BoardConfigClient } from \"../config-client.js\";\nimport { toResolvedLifecycle } from \"../config-client.js\";\nimport type {\n LifecycleSource,\n ResolveLifecycleRef,\n ResolvedLifecycle,\n} from \"../lifecycle/types.js\";\nimport type { Actor, CreateCardInput, KanbanCard, KanbanLane, KanbanTransition } from \"../types.js\";\nimport {\n dispatchStageHandler,\n type BatchCardContext,\n type CadraRunClient,\n type HandlerDispatchResult,\n type WebhookDeliveryOptions,\n} from \"./handlers.js\";\n\n// Re-export the host-facing engine surface from the `@cadraos/sdk/kanban/engine`\n// entry: the storage contract, config client, handler seams, and the reference\n// in-memory adapter.\nexport type {\n AdapterCapabilities,\n KanbanStorageAdapter,\n} from \"../adapters/storage-types.js\";\nexport {\n InMemoryStorageAdapter,\n TransitionConflictError,\n UnknownDueRuleError,\n} from \"../adapters/in-memory-adapter.js\";\n// The generic HTTP-backed adapter (the cross-system drop-in, design §10) + the\n// §10-contract example host that doubles as the documented starter template.\nexport {\n HttpStorageAdapter,\n HttpAdapterError,\n CapabilitiesNotLoadedError,\n} from \"../adapters/http-adapter.js\";\nexport type {\n HttpStorageAdapterConfig,\n FetchLike,\n} from \"../adapters/http-adapter.js\";\nexport {\n exampleHostHandler,\n startExampleHost,\n} from \"../adapters/example-host.js\";\nexport type {\n ExampleHostOptions,\n HostRequest,\n HostResponse,\n} from \"../adapters/example-host.js\";\nexport { runAdapterConformance } from \"../adapters/conformance.js\";\nexport type {\n AdapterFactory,\n ConformanceExpect,\n ConformanceRunner,\n} from \"../adapters/conformance.js\";\nexport {\n BoardConfigClient,\n CadraLifecycleSource,\n mapDefinitionToBoard,\n toResolvedLifecycle,\n} from \"../config-client.js\";\nexport type {\n BoardConfigClientOptions,\n BoardConfigHttp,\n ResolvedBoardConfig,\n} from \"../config-client.js\";\n// Lifecycle source contract (p33 §3) — the pluggable read-through definition\n// the engine consumes.\nexport type {\n LifecycleRef,\n LifecycleSource,\n LifecycleSourceKind,\n ResolveLifecycleRef,\n ResolvedLifecycle,\n Stage,\n Transition,\n} from \"../lifecycle/types.js\";\nexport {\n dispatchStageHandler,\n deliverWebhook,\n hmacSign,\n WebhookDeliveryError,\n} from \"./handlers.js\";\nexport type {\n BatchCardContext,\n BatchDispatchMeta,\n CadraRunClient,\n HandlerContext,\n HandlerDispatchResult,\n RunAgentInput,\n RunRemoteAgentInput,\n RunResult,\n RunTeamInput,\n WebhookDeliveryOptions,\n WebhookSecret,\n} from \"./handlers.js\";\nexport type {\n Actor,\n ApplyTransitionInput,\n CreateCardServerInput,\n DueRule,\n KanbanLaneDispatch,\n KanbanLaneTrigger,\n StageRun,\n StageRunStatus,\n TransitionLogEntry,\n} from \"../types.js\";\n\n// =============================================================================\n// TRIGGER GATING (design §5 — Conductor mode)\n// =============================================================================\n\n/**\n * Is a lane dispatched on ENTRY (card arriving in the lane fires its handler)?\n *\n * `event` (or absent — `event` is the default) → yes, dispatch on entry exactly\n * as today. `scheduled` → no; the card waits in the lane for the timed sweep\n * (`runDueStages`). This gate is applied at every entry point — `createCard`,\n * `transition`, and `onStageComplete`'s auto-advance — so a `scheduled` lane is\n * never event-driven (design §5). Event lanes are byte-identical to today.\n */\nfunction dispatchesOnEntry(lane: KanbanLane | undefined): boolean {\n return (lane?.trigger ?? \"event\") === \"event\";\n}\n\n/**\n * Does a lane have an automated handler the engine can dispatch? (A `none` /\n * `human` / absent handler is a passive lane — nothing to run.)\n */\nfunction hasAutomatedHandler(lane: KanbanLane | undefined): boolean {\n const h = lane?.handler;\n return !!h && h.type !== \"none\" && h.type !== \"human\";\n}\n\n/**\n * Thrown by `runDueStages` when the target lane is not `scheduled` (an `event`\n * lane is never swept — it is event-driven, design §5 step 1).\n */\nexport class NotScheduledLaneError extends Error {\n readonly code = \"not_scheduled_lane\";\n constructor(laneKey: string, trigger: string) {\n super(\n `Lane \"${laneKey}\" is not scheduled (trigger=\"${trigger}\") — runDueStages only sweeps scheduled lanes`\n );\n this.name = \"NotScheduledLaneError\";\n }\n}\n\n/**\n * Thrown by `runDueStages` when the host adapter does not implement the\n * OPTIONAL Conductor-mode methods (`listDueCards` / `countsByLane` /\n * `capabilities`). Conductor mode (scheduled-lane sweeps) is OPT-IN per host\n * (design §6); an event-only host never needs them and never sweeps a\n * scheduled lane. The event/entry-dispatch path is unaffected — only the\n * scheduled sweep requires these methods.\n */\nexport class ConductorUnsupportedError extends Error {\n readonly code = \"conductor_unsupported\";\n constructor(laneKey: string) {\n super(\n `Host adapter does not implement Conductor-mode methods (listDueCards); scheduled lanes require them (lane \"${laneKey}\")`\n );\n this.name = \"ConductorUnsupportedError\";\n }\n}\n\n/**\n * The per-tick summary `runDueStages` returns for the cron/digest (design §5\n * step 5).\n */\nexport interface RunDueStagesSummary {\n /** Due cards the sweep examined this tick (after the cap). */\n swept: number;\n /**\n * Due CARDS whose handler was dispatched this tick (each created a stage-run\n * CAS). This is always counted per-CARD — in `batch` mode it is the number of\n * cards across all chunks that got dispatched, NOT the number of chunks (see\n * `batches`). So `dispatched` has the SAME meaning in both modes: how many\n * cards the sweep put in flight.\n */\n dispatched: number;\n /** Due cards already mid-run (beginStageRun CAS `created === false`). */\n skipped: number;\n /** Due cards whose dispatch threw (surfaced; the sweep continues). */\n failed: number;\n /**\n * Number of HANDLER RUNS dispatched this tick. In `per-card` mode this equals\n * `dispatched` (one run per card). In `batch` mode this is the number of\n * CHUNKS dispatched (⌈eligible / chunkSize⌉) — the no-LLM-per-lead win: many\n * cards, far fewer runs. A chunk whose dispatch throws is NOT counted here\n * (its cards are counted in `failed`).\n */\n batches: number;\n}\n\n// =============================================================================\n// EDGE RESOLUTION (pinned definition)\n// =============================================================================\n\n/**\n * The minimal resolved-definition shape the engine reads. Both\n * `ResolvedLifecycle` (the source-agnostic p33 shape) AND the legacy\n * `ResolvedBoardConfig` structurally satisfy it (`{ uuid, version, board }`),\n * so the engine helpers work with either source.\n */\ntype EngineConfig = Pick<ResolvedLifecycle, \"uuid\" | \"version\" | \"board\">;\n\n/** The immutable stage identity for a lane (p33 §10.2): `id`, falling back to `key`. */\nfunction stageIdOf(lane: KanbanLane): string {\n return lane.id ?? lane.key;\n}\n\n/** Find a lane by key in a resolved config. */\nfunction laneByKey(cfg: EngineConfig, key: string): KanbanLane | undefined {\n return cfg.board.lanes.find((l) => l.key === key);\n}\n\n/**\n * Find a lane by its immutable stage `id` (p33 §10.2) — falling back to `key`\n * for a lane authored before the stage-identity contract. Used to recover the\n * lane from an idemKey's `stageId` (which is now the immutable id).\n */\nfunction laneById(cfg: EngineConfig, stageId: string): KanbanLane | undefined {\n return cfg.board.lanes.find((l) => stageIdOf(l) === stageId);\n}\n\n/** All outgoing transitions from a lane. */\nfunction outgoing(cfg: EngineConfig, fromLane: string): KanbanTransition[] {\n return (cfg.board.transitions ?? []).filter((t) => t.fromLane === fromLane);\n}\n\n/**\n * Resolve the manual edge to take from `fromLane`.\n *\n * - `toLane` given → require a `manual_allowed` edge to that lane.\n * - `toLane` omitted → require EXACTLY ONE outgoing `manual_allowed` edge;\n * reject ambiguous (multiple) or absent.\n */\nexport function resolveManualEdge(\n cfg: EngineConfig,\n fromLane: string,\n toLane?: string\n): KanbanTransition {\n const manual = outgoing(cfg, fromLane).filter((t) => t.manualAllowed);\n if (toLane) {\n const edge = manual.find((t) => t.toLane === toLane);\n if (!edge) {\n throw new Error(\n `No manual_allowed edge from \"${fromLane}\" to \"${toLane}\"`\n );\n }\n return edge;\n }\n if (manual.length === 0) {\n throw new Error(`No manual_allowed edge from \"${fromLane}\"`);\n }\n if (manual.length > 1) {\n throw new Error(\n `Ambiguous manual transition from \"${fromLane}\": ${manual.length} outgoing edges — specify a target lane`\n );\n }\n return manual[0]!;\n}\n\n/**\n * Resolve the single `auto_on_complete` edge from `fromLane`.\n *\n * Automated stages MUST have exactly one (design §11 R5). Enforced at runtime:\n * zero → null (nothing to advance, e.g. a human stage); more than one → throw.\n */\nexport function resolveAutoEdge(\n cfg: EngineConfig,\n fromLane: string\n): KanbanTransition | null {\n const auto = outgoing(cfg, fromLane).filter((t) => t.autoOnComplete);\n if (auto.length === 0) return null;\n if (auto.length > 1) {\n throw new Error(\n `Stage \"${fromLane}\" has ${auto.length} auto_on_complete edges (expected exactly one)`\n );\n }\n return auto[0]!;\n}\n\n// =============================================================================\n// ENGINE\n// =============================================================================\n\nexport interface CreateEngineOptions {\n /** Host persistence adapter (durable cards + stage runs). */\n adapter: KanbanStorageAdapter;\n /**\n * The pluggable lifecycle source (p33 §3) — `getActive` (new cards) /\n * `getPinned` (in-flight cards). A `CadraLifecycleSource` (read-through\n * board-configs) or a `NativeLifecycleSource` (host tables). Preferred over\n * `configClient`; supply EITHER this OR `configClient` (this wins when both\n * are given).\n */\n lifecycleSource?: LifecycleSource;\n /**\n * @deprecated Prefer `lifecycleSource`. The legacy board-config client\n * (fetch/cache/pin board configs from Cadra). A `BoardConfigClient` satisfies\n * this; the engine adapts it to a `LifecycleSource` internally. Kept for\n * backward compatibility — existing callers passing `configClient` keep\n * working unchanged.\n */\n configClient?: Pick<BoardConfigClient, \"getActive\" | \"getPinned\">;\n /** Cadra run client (run agents/teams by uuid + webhook secrets). */\n cadraClient: CadraRunClient;\n /**\n * Resolve a card's PERSISTED lifecycle pin — BOTH halves (p33 §10.5 / Codex\n * R5): `(card) => ({ uuid: card.cadraLifecycleUuid, version: card.configVersion })`.\n * This is the REQUIRED host wiring for restart-safe pinning: it reads the\n * first-class persisted fields so an in-flight card keeps resolving its\n * ORIGINAL `(uuid, version)` even across an engine restart AND after the host\n * lifecycle is later re-linked to a different Cadra lifecycle — the engine\n * never repoints in-flight cards. Preferred over `resolveConfigVersion`.\n */\n resolveLifecycleRef?: ResolveLifecycleRef;\n /**\n * @deprecated Prefer `resolveLifecycleRef` (pins BOTH halves). Resolve only\n * the per-card config VERSION (the uuid is assumed to be `card.boardId`).\n * Kept for backward compatibility.\n */\n resolveConfigVersion?: (card: KanbanCard) => number | undefined;\n /** Host callback URL base for webhook completions (design §11 R4). */\n callbackUrl?: string;\n /** The default org id threaded into runs (host may override per card). */\n orgId?: number;\n /** Webhook delivery tuning (retry/backoff/fetch) — passed to handlers. */\n webhookOptions?: WebhookDeliveryOptions;\n /** Actor stamped on engine-driven (auto) transitions. Default system/engine. */\n systemActor?: Actor;\n /**\n * Board-wide ceiling on how many due cards a single `runDueStages` tick may\n * dispatch when neither `opts.limit` nor `lane.cap` is set (design §7 — caps\n * are load-bearing; a sweep never fans out to thousands). The effective cap\n * is `opts.limit ?? lane.cap ?? boardCeiling`. Defaults to\n * `DEFAULT_BOARD_CEILING` when omitted.\n */\n boardCeiling?: number;\n}\n\n/**\n * The default board ceiling applied when a scheduled lane declares no `cap` and\n * the caller passes no `opts.limit` (design §7). A finite ceiling keeps an\n * unconfigured sweep bounded rather than fanning out across the whole lane.\n */\nexport const DEFAULT_BOARD_CEILING = 200;\n\n/**\n * One card's outcome inside a batch completion (design §7). The host reports\n * the per-card result of a chunk's handler run; the engine resolves each card's\n * stage-run + advance accordingly (advance-all-on-success; a `failed` card\n * stays put).\n */\nexport interface BatchCardCompletion {\n /** The card's per-card stage-run idempotency key (`cardId:stageId:version`). */\n idemKey: string;\n /** `completed` ⇒ advance the card; `failed` ⇒ leave it + mark the run failed. */\n status: \"completed\" | \"failed\";\n /** Context patch merged on advance (completed cards only). */\n contextPatch?: Record<string, unknown>;\n /** Error message (failed cards only). */\n error?: string;\n}\n\n/** The aggregate result of fanning out a batch completion. */\nexport interface BatchCompleteResult {\n /** Cards advanced along the auto edge (status completed + applied). */\n advanced: number;\n /** Cards left in place + marked failed. */\n failed: number;\n /**\n * Cards whose completion was a no-op (already completed — a duplicate/retried\n * batch callback; idempotent, not re-advanced).\n */\n noop: number;\n}\n\nexport interface KanbanEngine {\n createCard(boardConfigUuid: string, input: CreateCardInput): Promise<KanbanCard>;\n transition(cardId: string, toLane?: string, actor?: Actor): Promise<KanbanCard>;\n runStage(cardId: string, stageId: string): Promise<{ dispatched: boolean; executionUuid?: string }>;\n onStageComplete(\n idemKey: string,\n completion: { executionUuid?: string; contextPatch?: Record<string, unknown>; actor?: Actor }\n ): Promise<{ applied: boolean }>;\n /**\n * Sweep a `scheduled` lane: ask the adapter for due cards (bounded by the\n * effective cap) and dispatch them. A `per-card` lane (default) dispatches one\n * handler run PER due card through the SAME idempotent `runStage` machinery\n * the event path uses. A `dispatch: \"batch\"` lane CHUNKS the due cards (by\n * `chunkSize ?? cap`) and dispatches ONE handler run per chunk over the card\n * LIST (design §7 — the no-LLM-per-lead routine path); per-card idempotency\n * (a stage-run CAS per card) still holds. Refuses an `event` lane\n * (`NotScheduledLaneError`). Returns a\n * `{ swept, dispatched, skipped, failed, batches }` summary (design §5/§7).\n */\n runDueStages(\n boardConfigUuid: string,\n laneKey: string,\n opts?: { limit?: number }\n ): Promise<RunDueStagesSummary>;\n /**\n * Complete a BATCH chunk's handler run (design §7): fan the per-card results\n * out across the chunk — each `completed` card advances along the lane's\n * single `auto_on_complete` edge (via the SAME idempotent\n * `completeStageRun`/`applyTransition` machinery `onStageComplete` uses), each\n * `failed` card stays put and its stage-run is marked failed. Idempotent: a\n * duplicate batch callback re-resolves already-completed cards as `noop`.\n *\n * The host calls this when the chunk's single execution reaches a terminal\n * state, passing the per-card outcomes its handler produced. `batchKey` is the\n * chunk's batch key surfaced at dispatch.\n */\n onBatchComplete(\n batchKey: string,\n completion: {\n executionUuid?: string;\n actor?: Actor;\n cards: BatchCardCompletion[];\n }\n ): Promise<BatchCompleteResult>;\n}\n\n/**\n * The engine carries the card's pinned config version through `runStage` /\n * `onStageComplete` via the stage run's `idemKey` (`cardId:stageId:version`),\n * so completions resolve the SAME pinned config the dispatch used.\n */\nfunction parseIdemKey(idemKey: string): { cardId: string; stageId: string; version: number } {\n // idemKey = cardId:stageId:version. cardId / stageId never contain ':' in\n // our id scheme; version is the trailing integer.\n const lastColon = idemKey.lastIndexOf(\":\");\n const version = Number(idemKey.slice(lastColon + 1));\n const rest = idemKey.slice(0, lastColon);\n const midColon = rest.indexOf(\":\");\n return {\n cardId: rest.slice(0, midColon),\n stageId: rest.slice(midColon + 1),\n version,\n };\n}\n\nexport function createEngine(options: CreateEngineOptions): KanbanEngine {\n const {\n adapter,\n cadraClient,\n callbackUrl,\n webhookOptions,\n } = options;\n const systemActor: Actor = options.systemActor ?? { type: \"system\", id: \"engine\" };\n\n // The pluggable lifecycle source (p33 §3). Prefer `lifecycleSource`; fall back\n // to adapting the legacy `configClient` (which returns `ResolvedBoardConfig`,\n // structurally an `EngineConfig`). Exactly one MUST be supplied.\n const source: LifecycleSource | undefined =\n options.lifecycleSource ??\n (options.configClient\n ? {\n getActive: async (uuid) =>\n toResolvedLifecycle(await options.configClient!.getActive(uuid)),\n getPinned: async (uuid, version) =>\n toResolvedLifecycle(\n await options.configClient!.getPinned(uuid, version)\n ),\n }\n : undefined);\n if (!source) {\n throw new Error(\n \"createEngine requires a `lifecycleSource` (or the deprecated `configClient`)\"\n );\n }\n\n // Per-card pinned version, recorded at createCard, kept ONLY as a within-process\n // convenience for cards created in this same process when the host has not yet\n // wired the persisted pin. It is NEVER the restart-safe pin — `resolveLifecycleRef`\n // (the persisted card fields) is. A card with a persisted ref always resolves\n // through it and never touches this map (so a re-link elsewhere can't repoint it).\n const pinnedVersions = new Map<string, number>();\n\n // batchKey → the per-card idemKeys in that chunk, so `onBatchComplete` can fan\n // the completion out over the right cards even if the host only echoes back\n // the batchKey + a subset of results. Recorded at batch dispatch. (A host that\n // persists its own chunk membership can ignore this and pass full `cards[]`.)\n const batchMembers = new Map<string, string[]>();\n\n function idemKeyFor(cardId: string, stageId: string, version: number): string {\n return `${cardId}:${stageId}:${version}`;\n }\n\n // A monotonic per-engine token so two chunks of the same (stage, version) in\n // one tick (or across ticks) get DISTINCT batch keys — the chunk is the\n // retry/partial-failure boundary, so its key must be unique to the chunk.\n let batchSeq = 0;\n function batchKeyFor(stageId: string, version: number): string {\n batchSeq += 1;\n return `batch:${stageId}:${version}:${batchSeq}`;\n }\n\n async function pinnedConfigFor(card: KanbanCard): Promise<ResolvedLifecycle> {\n // 1) PERSISTED PIN — both halves (p33 §10.5). This is the restart-safe,\n // re-link-proof path: the card's own first-class `(cadraLifecycleUuid,\n // configVersion)` fields, surfaced via `resolveLifecycleRef`. When both\n // halves are present we pin to the card's ORIGINAL lifecycle+version and\n // NEVER fall through to `getActive` — so a re-link of the host lifecycle\n // elsewhere can never repoint this in-flight card.\n const ref = options.resolveLifecycleRef?.(card);\n if (ref?.uuid && ref.version) {\n return source!.getPinned(ref.uuid, ref.version);\n }\n\n // 2) Legacy/back-compat: version-only resolver or the in-process map,\n // pinned against the card's board uuid.\n const boardConfigUuid = card.boardId;\n const version =\n options.resolveConfigVersion?.(card) ?? pinnedVersions.get(card.id);\n if (boardConfigUuid && version) {\n return source!.getPinned(boardConfigUuid, version);\n }\n if (!boardConfigUuid) {\n throw new Error(`Card ${card.id} has no boardConfigUuid to pin its config`);\n }\n // Last resort — active, when the host recorded no pin at all (a card\n // created outside the engine with no persisted ref). A card with a\n // persisted ref never reaches here.\n return source!.getActive(boardConfigUuid);\n }\n\n function cardContext(card: KanbanCard, stage: KanbanLane): Record<string, unknown> {\n return {\n task: card.title,\n context: {\n // Thread the host/tenant org as `tenantOrgId` so cadra-api scopes tool\n // calls to the tenant (X-Org-Id + per-tenant credential resolution),\n // never to the Cadra API-key org. Mirrors the chat adapter\n // (`chat/adapters/default-adapter.ts` → `context: { tenantOrgId }`).\n // When host == platform (single-org harness) this equals the Cadra org\n // and is inert; it only changes behaviour for a distinct-org tenant host.\n ...(options.orgId != null ? { tenantOrgId: options.orgId } : {}),\n kanban: {\n cardId: card.id,\n boardConfigUuid: card.boardId,\n // The IMMUTABLE stage id (p33 §10.2), falling back to `key`.\n stageId: stageIdOf(stage),\n sharedContext: card.sharedContext ?? {},\n },\n },\n };\n }\n\n /**\n * Run a stage's handler idempotently: begin the stage run (CAS), and only\n * dispatch when this call created the run. Stamps the executionUuid.\n *\n * `laneKey` addresses the lane in the engine's lane-key space (the renderer +\n * card.lane speak keys); the stage-run idemKey + the adapter's `stageId` are\n * keyed off the lane's IMMUTABLE `id` (p33 §10.2) so a `key` rename never\n * collides with a prior run.\n *\n * ★ Stranded-run recovery (design §10): if the DISPATCH throws (a transient\n * cadra-api blip), the stage-run must NOT be left `queued` — the idemKey CAS\n * (`cardId:stageId:version`) would then skip it forever, silently parking the\n * card. We `failStageRun(idemKey)` on throw so the next sweep's\n * `beginStageRun` RE-CLAIMS the failed run and re-dispatches, then re-throw so\n * the caller (the `runDueStages` per-card loop, or the event path) surfaces\n * the failure exactly as before. v1 is acyclic-only: same-lane re-entry is\n * impossible under the versioned idemKey, so a re-claim only re-runs a FAILED\n * attempt of THIS stage, never a completed one.\n */\n async function runStage(\n cardId: string,\n laneKey: string\n ): Promise<{ dispatched: boolean; executionUuid?: string }> {\n const card = await adapter.getCard(cardId);\n if (!card) throw new Error(`Card not found: ${cardId}`);\n const cfg = await pinnedConfigFor(card);\n const stage = laneByKey(cfg, laneKey);\n if (!stage) throw new Error(`Stage \"${laneKey}\" not in config ${cfg.uuid}`);\n\n const handler = stage.handler;\n if (!handler || handler.type === \"none\" || handler.type === \"human\") {\n // Passive stage — nothing to dispatch.\n return { dispatched: false };\n }\n\n // idemKey + the persisted stageId key off the IMMUTABLE stage id (p33 §10.2).\n const stageId = stageIdOf(stage);\n const idemKey = idemKeyFor(cardId, stageId, cfg.version);\n const begin = await adapter.beginStageRun(cardId, {\n stageId,\n idemKey,\n handlerType: handler.type,\n });\n if (!begin.created) {\n // Already dispatched (a retry / duplicate) — no-op.\n return { dispatched: false, executionUuid: begin.run.executionUuid };\n }\n\n let result: HandlerDispatchResult;\n try {\n result = await dispatchStageHandler(\n {\n cardId,\n boardConfigUuid: card.boardId,\n configVersion: cfg.version,\n stage,\n idemKey,\n input: cardContext(card, stage),\n orgId: options.orgId,\n callbackUrl,\n },\n cadraClient,\n webhookOptions\n );\n } catch (err) {\n // ★ Stranded-run recovery (design §10): fail the just-claimed run so the\n // next sweep re-claims + re-dispatches it (rather than leaving a `queued`\n // row the CAS skips forever), then re-throw to preserve the caller's\n // error signal.\n await adapter.failStageRun(idemKey, {\n error: err instanceof Error ? err.message : String(err),\n });\n throw err;\n }\n\n // Stamp the executionUuid on the run (status → running) so the UI can\n // stream the live run before completion. Optional adapter hook; when the\n // host doesn't implement it, the executionUuid is surfaced to the caller.\n if (result.executionUuid && adapter.markStageRunDispatched) {\n await adapter.markStageRunDispatched(idemKey, {\n executionUuid: result.executionUuid,\n });\n }\n return { dispatched: result.dispatched, executionUuid: result.executionUuid };\n }\n\n /**\n * The batch handler input: the same `task`/`context` envelope as a single\n * card, but `context.kanban.batch` carries the FULL card list so a handler /\n * agent can process all N at once (design §7). `cardId`/`task` mirror the\n * chunk's lead card for handlers that only read the top-level shape.\n */\n function batchContext(\n lead: KanbanCard,\n stage: KanbanLane,\n cards: BatchCardContext[]\n ): Record<string, unknown> {\n return {\n task: `Batch (${cards.length}) — ${stage.label}`,\n context: {\n ...(options.orgId != null ? { tenantOrgId: options.orgId } : {}),\n kanban: {\n // Lead card (representative) — keeps the single-card shape readable.\n cardId: lead.id,\n boardConfigUuid: lead.boardId,\n // The IMMUTABLE stage id (p33 §10.2), falling back to `key`.\n stageId: stageIdOf(stage),\n sharedContext: lead.sharedContext ?? {},\n // The batch payload: every card in the chunk, each with its task +\n // shared context. THIS is what a batch handler iterates.\n batch: cards.map((c) => ({\n cardId: c.cardId,\n task: c.task,\n sharedContext: c.sharedContext,\n })),\n },\n },\n };\n }\n\n /**\n * Dispatch ONE handler run over a CHUNK of cards (design §7 — batch mode).\n *\n * Per-card idempotency first: `beginStageRun` (CAS) for each card; cards\n * already mid-run (`created === false`) are EXCLUDED from the chunk, so\n * overlapping ticks never double-process a card. If every card was excluded,\n * the chunk is empty and nothing is dispatched. Otherwise ONE\n * `dispatchStageHandler` call carries the eligible card list. The chunk's\n * single `executionUuid` is stamped on every included card's stage-run, and\n * the batchKey → member idemKeys mapping is recorded for `onBatchComplete`.\n *\n * @returns the eligible card idemKeys (the ones actually dispatched) + the\n * skipped count (in-flight cards) + whether a run was dispatched.\n */\n async function runStageBatch(\n cardIds: string[],\n cfg: EngineConfig,\n stage: KanbanLane\n ): Promise<{ dispatchedKeys: string[]; skipped: number; dispatched: boolean }> {\n const handler = stage.handler;\n if (!handler || handler.type === \"none\" || handler.type === \"human\") {\n return { dispatchedKeys: [], skipped: 0, dispatched: false };\n }\n\n // idemKeys + the persisted stageId key off the IMMUTABLE stage id (p33 §10.2).\n const stageId = stageIdOf(stage);\n\n // Per-card CAS: claim each card's stage-run; exclude in-flight cards.\n const eligible: { card: KanbanCard; idemKey: string }[] = [];\n let skipped = 0;\n for (const cardId of cardIds) {\n const card = await adapter.getCard(cardId);\n if (!card) {\n // Card vanished between listDueCards and now — treat as skipped.\n skipped += 1;\n continue;\n }\n const idemKey = idemKeyFor(cardId, stageId, cfg.version);\n const begin = await adapter.beginStageRun(cardId, {\n stageId,\n idemKey,\n handlerType: handler.type,\n });\n if (!begin.created) {\n // Already mid-run — excluded from this chunk (no double-process).\n skipped += 1;\n continue;\n }\n eligible.push({ card, idemKey });\n }\n\n if (eligible.length === 0) {\n return { dispatchedKeys: [], skipped, dispatched: false };\n }\n\n const batchKey = batchKeyFor(stageId, cfg.version);\n const batchCards: BatchCardContext[] = eligible.map(({ card, idemKey }) => ({\n cardId: card.id,\n idemKey,\n task: card.title,\n sharedContext: card.sharedContext ?? {},\n }));\n batchMembers.set(batchKey, batchCards.map((c) => c.idemKey));\n\n const lead = eligible[0]!.card;\n let result: HandlerDispatchResult;\n try {\n result = await dispatchStageHandler(\n {\n cardId: lead.id,\n boardConfigUuid: lead.boardId,\n configVersion: cfg.version,\n stage,\n idemKey: eligible[0]!.idemKey,\n input: batchContext(lead, stage, batchCards),\n orgId: options.orgId,\n callbackUrl,\n batch: { batchKey, cards: batchCards },\n },\n cadraClient,\n webhookOptions\n );\n } catch (err) {\n // ★ Stranded-run recovery (design §10) for the batch path: the chunk's\n // per-card stage-runs were already CAS-claimed (`queued`) above; a chunk\n // dispatch throw must FAIL them so the next sweep re-claims + re-dispatches\n // — not leave them stranded. Then re-throw: `runDueStages`' per-chunk catch\n // counts the group as failed exactly as before.\n const msg = err instanceof Error ? err.message : String(err);\n for (const { idemKey } of eligible) {\n await adapter.failStageRun(idemKey, { error: msg });\n }\n throw err;\n }\n\n // Stamp the chunk's single executionUuid on EVERY included card's stage-run\n // so each card streams the same live run.\n if (result.executionUuid && adapter.markStageRunDispatched) {\n for (const { idemKey } of eligible) {\n await adapter.markStageRunDispatched(idemKey, {\n executionUuid: result.executionUuid,\n });\n }\n }\n\n return {\n dispatchedKeys: eligible.map((e) => e.idemKey),\n skipped,\n dispatched: result.dispatched,\n };\n }\n\n async function transition(\n cardId: string,\n toLane?: string,\n actor: Actor = { type: \"user\" }\n ): Promise<KanbanCard> {\n const card = await adapter.getCard(cardId);\n if (!card) throw new Error(`Card not found: ${cardId}`);\n const cfg = await pinnedConfigFor(card);\n\n const edge = resolveManualEdge(cfg, card.lane, toLane);\n const moved = await adapter.applyTransition(cardId, {\n fromLane: card.lane,\n toLane: edge.toLane,\n transitionId: edge.id,\n actor,\n });\n\n // If the new stage has an automated handler AND is event-triggered, run it\n // on entry. A `scheduled` destination lane is NOT dispatched here — the card\n // waits for the next sweep (`runDueStages`) (design §5 entry-dispatch gating).\n const newStage = laneByKey(cfg, moved.lane);\n if (hasAutomatedHandler(newStage) && dispatchesOnEntry(newStage)) {\n await runStage(cardId, moved.lane);\n }\n return moved;\n }\n\n async function createCard(\n boardConfigUuid: string,\n input: CreateCardInput\n ): Promise<KanbanCard> {\n const cfg = await source!.getActive(boardConfigUuid);\n const initialLane =\n input.lane ??\n cfg.board.lanes.find((l) => l.initial)?.key ??\n cfg.board.lanes[0]?.key;\n if (!initialLane) {\n throw new Error(`Config ${boardConfigUuid} has no lanes`);\n }\n\n const card = await adapter.createCard({\n ...input,\n boardConfigUuid,\n configVersion: cfg.version,\n initialLane,\n });\n pinnedVersions.set(card.id, cfg.version);\n\n // If the initial stage has an automated handler AND is event-triggered, fire\n // it on entry. A `scheduled` initial lane is NOT dispatched here — the card\n // waits for the next sweep (`runDueStages`) (design §5 entry-dispatch gating).\n const initialStage = laneByKey(cfg, initialLane);\n if (hasAutomatedHandler(initialStage) && dispatchesOnEntry(initialStage)) {\n await runStage(card.id, initialLane);\n }\n return (await adapter.getCard(card.id)) ?? card;\n }\n\n async function onStageComplete(\n idemKey: string,\n completion: { executionUuid?: string; contextPatch?: Record<string, unknown>; actor?: Actor }\n ): Promise<{ applied: boolean }> {\n const { cardId, stageId, version } = parseIdemKey(idemKey);\n const card = await adapter.getCard(cardId);\n if (!card) throw new Error(`Card not found: ${cardId}`);\n\n // Resolve the SAME pinned config the dispatch used. Prefer the card's\n // persisted ref (re-link-proof), else the idemKey's (uuid:version) pin.\n const ref = options.resolveLifecycleRef?.(card);\n const boardConfigUuid = card.boardId;\n const cfg = ref?.uuid && ref.version\n ? await source!.getPinned(ref.uuid, ref.version)\n : boardConfigUuid && version\n ? await source!.getPinned(boardConfigUuid, version)\n : await pinnedConfigFor(card);\n\n // The idemKey's `stageId` is the IMMUTABLE stage id (p33 §10.2); recover the\n // lane to resolve its auto edge in the engine's lane-KEY space (transitions\n // + card.lane speak keys). Falls back to treating `stageId` as a key.\n const stageLane = laneById(cfg, stageId);\n const autoEdge = resolveAutoEdge(cfg, stageLane?.key ?? stageId);\n const applied = await adapter.completeStageRun(idemKey, {\n executionUuid: completion.executionUuid,\n toLane: autoEdge?.toLane,\n contextPatch: completion.contextPatch,\n actor: completion.actor ?? systemActor,\n });\n\n // Entry-dispatch gating (design §5): the auto-advance just landed the card\n // in `autoEdge.toLane`. The engine does NOT chain-dispatch the downstream\n // lane's handler here — and it especially MUST NOT for a `scheduled`\n // downstream lane (that card waits for the next sweep). This is made\n // explicit so any future chaining respects `dispatchesOnEntry`: only an\n // `event` lane would ever be a candidate for chain-dispatch; a `scheduled`\n // lane is always picked up by `runDueStages`, never on completion.\n void dispatchesOnEntry; // gate reference — see the rule above.\n return applied;\n }\n\n /**\n * Complete a BATCH chunk's run (design §7): fan the per-card outcomes out over\n * the chunk's cards. Each `completed` card advances along its single\n * `auto_on_complete` edge via the SAME idempotent `onStageComplete` path; each\n * `failed` card is left in place and its stage-run marked failed. Idempotent —\n * a re-delivered batch callback re-resolves already-completed cards as `noop`\n * (the stage-run CAS in `completeStageRun` does not re-advance).\n *\n * The host passes the per-card results its handler produced. If it omits\n * `cards` (or passes a partial list) the engine falls back to the recorded\n * chunk membership and treats any unreported member as `completed` (the\n * advance-all default) — so a host that only signals \"the batch finished\" gets\n * advance-all for free.\n */\n async function onBatchComplete(\n batchKey: string,\n completion: {\n executionUuid?: string;\n actor?: Actor;\n cards: BatchCardCompletion[];\n }\n ): Promise<BatchCompleteResult> {\n const reported = new Map(completion.cards.map((c) => [c.idemKey, c]));\n const members = batchMembers.get(batchKey) ?? [];\n\n // The set of cards to resolve = the recorded chunk members ∪ any explicitly\n // reported idemKeys (a host that tracks its own membership may report cards\n // the engine didn't record, e.g. after a restart).\n const allKeys = new Set<string>([...members, ...reported.keys()]);\n\n let advanced = 0;\n let failed = 0;\n let noop = 0;\n\n for (const idemKey of allKeys) {\n // Default unreported members to `completed` — advance-all-on-success.\n const outcome = reported.get(idemKey) ?? { idemKey, status: \"completed\" as const };\n if (outcome.status === \"failed\") {\n await adapter.failStageRun(idemKey, {\n error: outcome.error ?? \"batch card failed\",\n });\n failed += 1;\n continue;\n }\n const res = await onStageComplete(idemKey, {\n executionUuid: completion.executionUuid,\n contextPatch: outcome.contextPatch,\n actor: completion.actor,\n });\n if (res.applied) advanced += 1;\n else noop += 1;\n }\n\n // Chunk is fully resolved — drop the membership record.\n batchMembers.delete(batchKey);\n return { advanced, failed, noop };\n }\n\n /**\n * Sweep one `scheduled` (board, lane): ask the adapter for the DUE cards\n * (bounded by the effective cap) and dispatch each through the SAME idempotent\n * `runStage` machinery the event path uses. The engine owns: resolve lane →\n * ask adapter for due cards → drive the idempotent dispatch. It does NOT own\n * the clock (host cron), the due SQL (adapter), or judgment (design §5).\n */\n async function runDueStages(\n boardConfigUuid: string,\n laneKey: string,\n opts?: { limit?: number }\n ): Promise<RunDueStagesSummary> {\n // Conductor mode is OPT-IN per host (design §6). Guard up-front: if the\n // adapter doesn't implement the Conductor-mode methods, a scheduled sweep\n // is impossible — fail with a clear typed error rather than a `not a\n // function` TypeError. The event/entry-dispatch path never reaches here.\n if (!adapter.listDueCards) {\n throw new ConductorUnsupportedError(laneKey);\n }\n\n const cfg = await source!.getActive(boardConfigUuid);\n const lane = laneByKey(cfg, laneKey);\n if (!lane) {\n throw new Error(`Lane \"${laneKey}\" not in config ${cfg.uuid}`);\n }\n\n // §5 step 1 — event lanes are NEVER swept; refuse with a typed error.\n const trigger = lane.trigger ?? \"event\";\n if (trigger !== \"scheduled\") {\n throw new NotScheduledLaneError(laneKey, trigger);\n }\n\n // §5 step 3 — caps are load-bearing: opts.limit ?? lane.cap ?? boardCeiling.\n const effectiveCap =\n opts?.limit ?? lane.cap ?? options.boardCeiling ?? DEFAULT_BOARD_CEILING;\n\n // A scheduled lane MUST carry a dueRule; without one there is nothing to\n // push down — treat as a misconfiguration (publish-time validation in\n // STORY-003 prevents this, but the engine fails closed rather than sweep\n // the whole lane).\n if (!lane.dueRule) {\n throw new Error(\n `Scheduled lane \"${laneKey}\" has no dueRule — nothing to push down (config ${cfg.uuid})`\n );\n }\n\n // §5 step 2 — push the declared dueRule down to the adapter; honor the cap\n // as the query LIMIT so the read is bounded. `listDueCards` is guaranteed\n // present (guarded at the top of this function).\n const dueCards = await adapter.listDueCards!(\n boardConfigUuid,\n laneKey,\n lane.dueRule,\n { limit: effectiveCap }\n );\n\n let dispatched = 0;\n let skipped = 0;\n let failed = 0;\n let batches = 0;\n\n const mode = lane.dispatch ?? \"per-card\";\n\n if (mode === \"batch\") {\n // §7 — BATCHED dispatch: chunk the due cards (by `chunkSize ?? cap`) and\n // dispatch ONE handler run per chunk over the card LIST. Per-card\n // idempotency is preserved INSIDE the chunk (a stage-run CAS per card;\n // in-flight cards are excluded), so overlapping ticks never double-process\n // a card — only far fewer handler runs (the no-LLM-per-lead win). A whole\n // chunk's dispatch failing is isolated: those cards count as `failed` and\n // the sweep continues with the next chunk.\n const stage = lane; // `lane` is the resolved scheduled stage.\n const chunkSize = Math.max(1, lane.chunkSize ?? effectiveCap);\n for (const group of chunk(dueCards, chunkSize)) {\n try {\n const res = await runStageBatch(\n group.map((c) => c.id),\n cfg,\n stage\n );\n dispatched += res.dispatchedKeys.length;\n skipped += res.skipped;\n if (res.dispatched) batches += 1;\n } catch {\n // The whole chunk's dispatch threw — count every card in it as failed.\n failed += group.length;\n }\n }\n } else {\n // §5 step 4 — per-card dispatch (default): each due card through the\n // existing runStage flow (idemKey CAS → already-running cards skipped, so\n // overlapping/back-to-back ticks never double-dispatch). Per-card failures\n // are isolated: the sweep continues and surfaces the count. `batches`\n // tracks runs and equals `dispatched` here (one run per card).\n for (const card of dueCards) {\n try {\n const res = await runStage(card.id, laneKey);\n if (res.dispatched) {\n dispatched += 1;\n batches += 1;\n } else {\n // Not dispatched = a CAS skip (already mid-run) for an automated lane.\n skipped += 1;\n }\n } catch {\n failed += 1;\n }\n }\n }\n\n // §5 step 5 / §7 — summary for the cron/digest. `swept` is what we examined\n // this tick (post-cap); dispatched + skipped + failed partition it by CARD.\n // `batches` is the number of handler RUNS (chunks in batch mode; == dispatched\n // in per-card mode).\n return { swept: dueCards.length, dispatched, skipped, failed, batches };\n }\n\n return {\n createCard,\n transition,\n runStage,\n onStageComplete,\n onBatchComplete,\n runDueStages,\n };\n}\n\n/**\n * Split `items` into chunks of at most `size` (the last chunk may be smaller).\n * `size` is assumed ≥ 1 (the caller clamps it).\n */\nfunction chunk<T>(items: T[], size: number): T[][] {\n const out: T[][] = [];\n for (let i = 0; i < items.length; i += size) {\n out.push(items.slice(i, i + size));\n }\n return out;\n}\n"]}
1
+ {"version":3,"sources":["../../../src/kanban/config-client.ts","../../../src/kanban/engine/handlers.ts","../../../src/kanban/adapters/in-memory-adapter.ts","../../../src/kanban/adapters/http-adapter.ts","../../../src/kanban/adapters/example-host.ts","../../../src/kanban/adapters/conformance.ts","../../../src/kanban/engine/index.ts"],"names":["run","cards"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * BoardConfigClient — fetch + cache + pin board configs from Cadra.\n *\n * The control-plane half of an agentic board lives in Cadra (Plan 1):\n * versioned, immutable-on-publish board-config definitions exposed at\n * `GET /api/v1/board-configs/:uuid[?version=]`. This client fetches a config,\n * maps the wire `definition` (stages/transitions/handlers, snake-cased) to the\n * SDK's `KanbanBoard` lane/transition contract, and caches by `(uuid, version)`.\n *\n * Graceful degradation (design.md §6/§11 R-cache): if the config API blips on a\n * refetch, the last cached copy is served so existing boards keep working —\n * only brand-new fetches (no cache) hard-fail.\n *\n * Server-safe: NO DOM imports. The engine (server) and the board UI (client)\n * both consume this.\n *\n * @module @cadraos/sdk/kanban\n */\n\nimport type {\n DueRule,\n KanbanBoard,\n KanbanLane,\n KanbanLaneDispatch,\n KanbanLaneTrigger,\n KanbanTransition,\n} from \"./types.js\";\nimport type {\n LifecycleSource,\n ResolvedLifecycle,\n} from \"./lifecycle/types.js\";\n\n// =============================================================================\n// HTTP DEPENDENCY\n// =============================================================================\n\n/**\n * Minimal HTTP surface this client needs — a `get(path, query)` that returns\n * the (already envelope-unwrapped) JSON body. The SDK's `HttpClient` and any\n * `CadraClient`-backed transport satisfy this.\n */\nexport interface BoardConfigHttp {\n get<T>(\n path: string,\n query?: Record<string, string | number | boolean | undefined>\n ): Promise<T>;\n}\n\n// =============================================================================\n// WIRE TYPES (Plan 1 §3 definition shape)\n// =============================================================================\n\ninterface WireHandler {\n type?: string;\n agent_uuid?: string;\n team_uuid?: string;\n /**\n * remote_agent → the `remote_agents.uuid` for a `remote_agent` lane (§5.3).\n * Snake-cased on the wire (published JSONB); mapped to `remoteAgentUuid`.\n * WITHOUT this the binding is silently dropped at parse and every published\n * remote_agent lane fails dispatch with \"missing remoteAgentUuid\" (FINDING-6).\n */\n remote_agent_uuid?: string;\n /** Legacy p28 slug ref. */\n agent_ref?: string;\n webhook?: {\n url: string;\n headers?: Record<string, string>;\n timeout_ms?: number;\n retry?: number;\n } | null;\n}\n\nexport interface WireStage {\n id: string;\n key: string;\n name: string;\n color?: string;\n is_initial?: boolean;\n is_terminal?: boolean;\n is_pushback_target?: boolean;\n handler?: WireHandler | null;\n /**\n * Conductor-mode metadata (design §4). `trigger` defaults to `event` when\n * absent; `due_rule`/`cap` apply only to `scheduled` lanes. Snake-cased on\n * the wire; mapped to `KanbanLane.trigger`/`dueRule`/`cap`.\n */\n trigger?: KanbanLaneTrigger;\n due_rule?: DueRule | null;\n cap?: number | null;\n /**\n * Batched-dispatch metadata (design §7). `dispatch` defaults to `per-card`\n * when absent; `chunk_size` applies only to `dispatch: batch` lanes.\n * Snake-cased on the wire; mapped to `KanbanLane.dispatch`/`chunkSize`.\n */\n dispatch?: KanbanLaneDispatch;\n chunk_size?: number | null;\n}\n\ninterface WireTransition {\n id: string;\n from_stage_id: string;\n to_stage_id: string;\n manual_allowed?: boolean;\n auto_on_complete?: boolean;\n kind?: \"forward\" | \"pushback\";\n}\n\ninterface WireDefinition {\n stages: WireStage[];\n transitions?: WireTransition[];\n reserved_keys?: string[];\n shared_context_caps?: Record<string, unknown>;\n card_types?: string[];\n}\n\ninterface WireConfigMeta {\n uuid: string;\n slug?: string;\n name?: string;\n activeVersion?: number | null;\n orgId?: number;\n}\n\n/**\n * A board-config VERSION ROW as Cadra returns it (the `board_config_version`\n * record): the version number + status + the nested flat `definition`. Cadra\n * returns this row both for an active fetch (under `definition`) and a pinned\n * fetch (under `version`).\n */\ninterface WireVersionRow {\n version: number;\n status?: string;\n definition: WireDefinition;\n}\n\n/**\n * Wire envelope returned by `GET /api/v1/board-configs/:uuid`.\n *\n * Cadra (Plan 1) returns a version ROW, not a flat definition:\n * - Active fetch: `{ config, definition: WireVersionRow }` (`getActiveDefinition`).\n * - Pinned fetch (`?version=`): `{ config, version: WireVersionRow }` (`getVersion`).\n *\n * `definition` is also accepted as a flat `WireDefinition` for forward-compat /\n * simpler producers — `parse()` unwraps whichever shape it gets.\n */\ninterface WireConfigResponse {\n config: WireConfigMeta;\n /** Active fetch: Cadra's version row, or a flat definition. */\n definition?: WireDefinition | WireVersionRow;\n /** A number (legacy) or the version row (pinned fetch). */\n version?: number | WireVersionRow;\n}\n\n/** Type guard: a version ROW (has a nested `.definition`) vs a flat definition. */\nfunction isVersionRow(\n d: WireDefinition | WireVersionRow | undefined\n): d is WireVersionRow {\n return (\n !!d &&\n typeof d === \"object\" &&\n \"definition\" in d &&\n !!(d as WireVersionRow).definition\n );\n}\n\n// =============================================================================\n// RESOLVED CONFIG\n// =============================================================================\n\n/**\n * A resolved board config: stable uuid + version + the mapped `KanbanBoard`\n * (lanes + transitions) ready to drive the UI and engine.\n */\nexport interface ResolvedBoardConfig {\n /** Stable config uuid (cards pin this). */\n uuid: string;\n /** Resolved version (cards pin this). */\n version: number;\n /** Config metadata. */\n name?: string;\n slug?: string;\n /** The mapped board (lanes in declared order + transitions). */\n board: KanbanBoard;\n /** The raw mapped definition (stages == lanes, transitions). */\n definition: { stages: KanbanLane[]; transitions: KanbanTransition[] };\n}\n\n// =============================================================================\n// MAPPERS (wire → SDK)\n// =============================================================================\n\nfunction mapHandler(h: WireHandler | null | undefined): KanbanLane[\"handler\"] {\n if (!h || !h.type || h.type === \"none\") {\n // `none`/absent → no handler binding (plain lane).\n return undefined;\n }\n return {\n type: h.type,\n agentUuid: h.agent_uuid,\n teamUuid: h.team_uuid,\n // FINDING-6: carry the remote_agent binding through the wire parse. The\n // engine's remote_agent dispatch reads `remoteAgentUuid`; dropping it here\n // made every published remote_agent lane dispatch-dead.\n remoteAgentUuid: h.remote_agent_uuid,\n agentRef: h.agent_ref,\n webhook: h.webhook\n ? {\n url: h.webhook.url,\n headers: h.webhook.headers,\n timeoutMs: h.webhook.timeout_ms,\n retry: h.webhook.retry,\n }\n : undefined,\n };\n}\n\nfunction mapStage(s: WireStage, index: number): KanbanLane {\n const lane: KanbanLane = {\n // Carry the IMMUTABLE stage id through (p33 §10.2). It is what the\n // webhook-secret fetch + the stage-run idemKey + the UI columns key off —\n // a `key`/`label` rename never breaks dispatch or keying. `key` stays the\n // editable display/slug.\n id: s.id,\n key: s.key,\n label: s.name,\n order: index,\n handler: mapHandler(s.handler),\n terminal: s.is_terminal ?? false,\n initial: s.is_initial ?? false,\n };\n // Conductor-mode metadata (design §4) — carry it through so the resolved\n // config the engine reads knows a lane is `scheduled` + its dueRule/cap.\n // `event` is the default; only thread non-default/present values so existing\n // single-mode boards map identically.\n if (s.trigger) lane.trigger = s.trigger;\n if (s.due_rule != null) lane.dueRule = s.due_rule;\n if (s.cap != null) lane.cap = s.cap;\n // Batched-dispatch (design §7). Only thread non-default/present values so an\n // existing `per-card` lane maps identically (no `dispatch` key).\n if (s.dispatch) lane.dispatch = s.dispatch;\n if (s.chunk_size != null) lane.chunkSize = s.chunk_size;\n return lane;\n}\n\n/**\n * Map a wire transition. Stages reference each other by `*_stage_id`, which in\n * the Plan 1 definition equals the stage `key`/`id` (they are 1:1 in the seed).\n * The SDK board speaks in lane KEYS, so we resolve ids → keys via the stage map.\n */\nfunction mapTransition(\n t: WireTransition,\n idToKey: Map<string, string>\n): KanbanTransition {\n return {\n id: t.id,\n fromLane: idToKey.get(t.from_stage_id) ?? t.from_stage_id,\n toLane: idToKey.get(t.to_stage_id) ?? t.to_stage_id,\n manualAllowed: t.manual_allowed ?? false,\n autoOnComplete: t.auto_on_complete ?? false,\n kind: t.kind,\n };\n}\n\n/**\n * Map a wire definition (+ config meta) → a resolved board config.\n */\nexport function mapDefinitionToBoard(\n config: WireConfigMeta,\n definition: WireDefinition,\n version: number\n): ResolvedBoardConfig {\n const lanes = (definition.stages ?? []).map(mapStage);\n const idToKey = new Map(\n (definition.stages ?? []).map((s) => [s.id, s.key] as const)\n );\n const transitions = (definition.transitions ?? []).map((t) =>\n mapTransition(t, idToKey)\n );\n\n const board: KanbanBoard = {\n id: config.uuid,\n orgId: config.orgId ?? 0,\n lifecycleId: config.uuid,\n lifecycleVersion: version,\n name: config.name,\n lanes,\n transitions,\n };\n\n return {\n uuid: config.uuid,\n version,\n name: config.name,\n slug: config.slug,\n board,\n definition: { stages: lanes, transitions },\n };\n}\n\n// =============================================================================\n// CLIENT\n// =============================================================================\n\nexport interface BoardConfigClientOptions {\n /** HTTP transport (the SDK's HttpClient or a CadraClient-backed get()). */\n http: BoardConfigHttp;\n /** Override the base path (default `/api/v1/board-configs`). */\n basePath?: string;\n}\n\nconst DEFAULT_BASE_PATH = \"/api/v1/board-configs\";\n\n/**\n * Fetch + cache + pin board configs.\n *\n * - `getActive(uuid)` — fetch the config's ACTIVE version (re-validates each\n * call so newly published versions are picked up); falls back to the cached\n * copy when the fetch fails.\n * - `getPinned(uuid, version)` — fetch a SPECIFIC frozen version; cached\n * permanently (published versions are immutable, so a cache hit short-circuits\n * the network entirely).\n */\nexport class BoardConfigClient {\n private readonly http: BoardConfigHttp;\n private readonly basePath: string;\n\n /** Cache keyed by `${uuid}:${version}`. */\n private readonly cache = new Map<string, ResolvedBoardConfig>();\n /** Last-known active version per uuid (for degraded active fetch). */\n private readonly activeVersions = new Map<string, number>();\n\n constructor(options: BoardConfigClientOptions) {\n this.http = options.http;\n this.basePath = options.basePath ?? DEFAULT_BASE_PATH;\n }\n\n /**\n * Fetch a config's ACTIVE version and map it. Re-validates against Cadra each\n * call (a newly published version supersedes the old active one). On a fetch\n * failure, serves the last cached copy for that config (graceful degradation,\n * design.md §11 R-cache); if nothing is cached, the error propagates.\n */\n async getActive(uuid: string): Promise<ResolvedBoardConfig> {\n try {\n const res = await this.http.get<WireConfigResponse>(\n `${this.basePath}/${uuid}`\n );\n const resolved = this.parse(res);\n this.put(resolved);\n this.activeVersions.set(uuid, resolved.version);\n return resolved;\n } catch (err) {\n const cached = this.cachedActive(uuid);\n if (cached) return cached;\n throw err;\n }\n }\n\n /**\n * Fetch a SPECIFIC frozen version and map it. Published versions are\n * immutable, so a cache hit skips the network. On a fetch miss + failure,\n * serves the cached version if present.\n */\n async getPinned(uuid: string, version: number): Promise<ResolvedBoardConfig> {\n const cached = this.cache.get(this.key(uuid, version));\n if (cached) return cached;\n\n try {\n const res = await this.http.get<WireConfigResponse>(\n `${this.basePath}/${uuid}`,\n { version }\n );\n const resolved = this.parse(res, version);\n this.put(resolved);\n return resolved;\n } catch (err) {\n const fallback = this.cache.get(this.key(uuid, version));\n if (fallback) return fallback;\n throw err;\n }\n }\n\n /** Drop all cached configs (e.g. after a known publish). */\n clearCache(): void {\n this.cache.clear();\n this.activeVersions.clear();\n }\n\n // -------------------------------------------------------------------------\n // internals\n // -------------------------------------------------------------------------\n\n private key(uuid: string, version: number): string {\n return `${uuid}:${version}`;\n }\n\n private put(resolved: ResolvedBoardConfig): void {\n this.cache.set(this.key(resolved.uuid, resolved.version), resolved);\n }\n\n private cachedActive(uuid: string): ResolvedBoardConfig | undefined {\n const v = this.activeVersions.get(uuid);\n if (v === undefined) return undefined;\n return this.cache.get(this.key(uuid, v));\n }\n\n /**\n * Normalize the wire envelope (active `{ config, definition, version }` OR\n * pinned `{ config, version: { version, definition } }`) into a resolved\n * config.\n */\n private parse(\n res: WireConfigResponse,\n requestedVersion?: number\n ): ResolvedBoardConfig {\n if (!res?.config?.uuid) {\n throw new Error(\"Invalid board-config response: missing config.uuid\");\n }\n\n let definition: WireDefinition | undefined;\n let version: number | undefined;\n\n if (res.version && typeof res.version === \"object\") {\n // Pinned envelope: `version` is the version row.\n definition = res.version.definition;\n version = res.version.version;\n } else if (isVersionRow(res.definition)) {\n // Active envelope from Cadra: `definition` is the version ROW\n // ({ version, status, definition }), not the flat definition.\n definition = res.definition.definition;\n version = res.definition.version ?? res.config.activeVersion ?? undefined;\n } else {\n // Flat active envelope: `definition` IS the WireDefinition.\n definition = res.definition;\n version =\n typeof res.version === \"number\"\n ? res.version\n : res.config.activeVersion ?? undefined;\n }\n\n if (!definition) {\n throw new Error(\"Invalid board-config response: missing definition\");\n }\n const resolvedVersion = version ?? requestedVersion ?? 1;\n\n return mapDefinitionToBoard(res.config, definition, resolvedVersion);\n }\n}\n\n// =============================================================================\n// CADRA LIFECYCLE SOURCE (LifecycleSource over read-through board-configs)\n// =============================================================================\n\n/**\n * Project a `ResolvedBoardConfig` (the board-config-client's resolved shape)\n * into the source-agnostic `ResolvedLifecycle` the engine + renderer consume\n * (p33 §3). `source` is always `cadra` here — this is the read-through Cadra\n * board-config source. The lane/transition shapes are identical, so this is a\n * thin re-shape (stages/transitions == the board's lanes/transitions).\n */\nexport function toResolvedLifecycle(\n cfg: ResolvedBoardConfig\n): ResolvedLifecycle {\n return {\n uuid: cfg.uuid,\n version: cfg.version,\n source: \"cadra\",\n name: cfg.name,\n slug: cfg.slug,\n stages: cfg.board.lanes,\n transitions: cfg.board.transitions ?? [],\n board: cfg.board,\n };\n}\n\n/**\n * `CadraLifecycleSource` — a `LifecycleSource` backed by read-through Cadra\n * board-configs (p33 §3). The promotion of `BoardConfigClient` to a first-class\n * lifecycle source: same fetch + cache-by-`(uuid, version)` + version-pin +\n * graceful-degradation machinery (it IS a `BoardConfigClient` internally), but\n * `getActive`/`getPinned` return the source-agnostic `ResolvedLifecycle`\n * (`source: 'cadra'`) the engine + renderer consume.\n *\n * - immutable-per-version cache keyed by `(uuid, version)`;\n * - short TTL applies to `getActive` only (re-validate to pick up a fresh\n * publish for NEW cards), inherited from the underlying client's per-call\n * active re-fetch;\n * - on a fetch failure, the last cached copy is served (stale-cache read) so\n * in-flight boards keep operating (NFR Resilience / design §4).\n */\nexport class CadraLifecycleSource implements LifecycleSource {\n private readonly client: BoardConfigClient;\n\n constructor(options: BoardConfigClientOptions);\n /** Wrap an existing `BoardConfigClient` (shares its cache). */\n constructor(client: BoardConfigClient);\n constructor(arg: BoardConfigClientOptions | BoardConfigClient) {\n this.client =\n arg instanceof BoardConfigClient ? arg : new BoardConfigClient(arg);\n }\n\n /** The ACTIVE version, projected to a `ResolvedLifecycle` (`source: cadra`). */\n async getActive(uuid: string): Promise<ResolvedLifecycle> {\n return toResolvedLifecycle(await this.client.getActive(uuid));\n }\n\n /** A PINNED version, projected to a `ResolvedLifecycle` (`source: cadra`). */\n async getPinned(uuid: string, version: number): Promise<ResolvedLifecycle> {\n return toResolvedLifecycle(await this.client.getPinned(uuid, version));\n }\n\n /** Drop the underlying cache (e.g. after a known publish). */\n clearCache(): void {\n this.client.clearCache();\n }\n}\n","/**\n * Stage handlers — dispatch a stage's automated handler (cadra_agent /\n * cadra_team / webhook) from the server engine.\n *\n * The engine owns the state machine; this module owns the OUTBOUND invocation\n * (run an agent/team by reference, or POST a signed webhook). Completion is\n * NOT awaited here — it arrives later via the run stream / a host callback,\n * which the engine turns into `completeStageRun`.\n *\n * Server-only (no DOM imports): uses `fetch` + `crypto` (Web Crypto / Node 18+\n * global `crypto.subtle`).\n *\n * @module @cadraos/sdk/kanban\n */\n\nimport type { KanbanLane } from \"../types.js\";\n\n// =============================================================================\n// CADRA RUN CLIENT (the host's seam to Cadra)\n// =============================================================================\n\nexport interface RunAgentInput {\n /** Concrete Cadra agent uuid. */\n agentUuid: string;\n /** Tenant/org id the run executes under. */\n orgId?: number;\n /** Card context passed to the agent (task + kanban context). */\n input: Record<string, unknown>;\n /** Idempotency key (= cardId:stageId:version). */\n idemKey: string;\n /**\n * Board/headless dispatch forces allowAskUser=false (spec §6.5 / FINDING-5).\n * The engine only ever dispatches cadra_agent stages from board surfaces,\n * which have NO ask_user UI — an ask attempt must FAIL the execution (→ failed\n * callback → completion bridge → §10 reclaim), never pause it. Pinned `false`\n * at the type boundary, matching RunRemoteAgentInput.\n */\n allowAskUser: false;\n /** A host callback reference the run can advance through (optional). */\n callbackRef?: string;\n}\n\nexport interface RunTeamInput {\n /** Concrete Cadra team uuid. */\n teamUuid: string;\n orgId?: number;\n input: Record<string, unknown>;\n idemKey: string;\n /** Board/headless dispatch forces allowAskUser=false (spec §6.5 / FINDING-5). */\n allowAskUser: false;\n callbackRef?: string;\n}\n\nexport interface RunRemoteAgentInput {\n /** Cadra remote_agents registry uuid (§5.3). */\n remoteAgentUuid: string;\n orgId?: number;\n input: Record<string, unknown>;\n idemKey: string;\n /**\n * Board dispatch forces allowAskUser=false (spec §6.5). The engine only ever\n * dispatches remote_agent stages from board/headless surfaces, so this is\n * pinned to `false` at the type boundary — a remote ask_user must fail with\n * ask_user_not_supported, never pause/hang a card.\n */\n allowAskUser: false;\n callbackRef?: string;\n}\n\nexport interface RunResult {\n /** The execution UUID driving the live run stream. */\n executionUuid: string;\n}\n\n/**\n * Per-stage webhook secret material, fetched from Cadra's MUTABLE\n * `board_config_secret` store (NOT from the immutable definition — design §11\n * R4). Rotation updates this row with a grace window; the engine always asks\n * for the current secret at dispatch.\n */\nexport interface WebhookSecret {\n /** Current HMAC signing secret. */\n secret: string;\n /** Scoped callback token the target echoes back to advance the card. */\n callbackToken?: string;\n}\n\n/**\n * The host's seam to Cadra: run an agent/team/remote-agent by reference (reusing\n * the p28 enqueue contract) and fetch webhook secrets. The engine calls only this.\n */\nexport interface CadraRunClient {\n /** Enqueue an agent run; returns the executionUuid for streaming. */\n runAgent(input: RunAgentInput): Promise<RunResult>;\n /** Enqueue a team run; returns the executionUuid for streaming. */\n runTeam(input: RunTeamInput): Promise<RunResult>;\n /**\n * Enqueue a remote_agent run (spec §10.2 / STORY-008).\n * Board dispatch sets allowAskUser=false; the remote runner maps ask_user\n * to run.failed with code='ask_user_not_supported'.\n */\n runRemoteAgent(input: RunRemoteAgentInput): Promise<RunResult>;\n /**\n * Fetch the per-stage webhook secret + callback token from Cadra's mutable\n * secret store (keyed by configUuid + stageId).\n */\n getWebhookSecret(input: {\n boardConfigUuid: string;\n stageId: string;\n }): Promise<WebhookSecret | null>;\n}\n\n// =============================================================================\n// HANDLER DISPATCH\n// =============================================================================\n\nexport interface HandlerContext {\n cardId: string;\n boardConfigUuid: string;\n configVersion: number;\n stage: KanbanLane;\n idemKey: string;\n /** Card context (task + shared context) passed to the handler. */\n input: Record<string, unknown>;\n orgId?: number;\n /** Host callback URL base for webhook completions (design §11 R4). */\n callbackUrl?: string;\n /**\n * BATCH dispatch metadata (design §7). Present only for a `dispatch: \"batch\"`\n * lane's chunk dispatch. When set, this is ONE handler run over MANY cards:\n * `cardId` is the chunk's lead/representative card and `input` carries the\n * full card LIST under `context.kanban.batch`, so a handler/agent can process\n * all N at once. The completion fans out per-card via the chunk's batch key\n * (see `BatchDispatchMeta`). Absent ⇒ a normal per-card dispatch.\n */\n batch?: BatchDispatchMeta;\n}\n\n/**\n * Per-card context inside a batch chunk — the unit a batch handler iterates.\n */\nexport interface BatchCardContext {\n /** Card UUID. */\n cardId: string;\n /** The card's per-card stage-run idempotency key (`cardId:stageId:version`). */\n idemKey: string;\n /** Card title (the agent task line). */\n task: string;\n /** Card shared context (host/GTM fields). */\n sharedContext: Record<string, unknown>;\n}\n\n/**\n * Metadata identifying a batch chunk dispatch (design §7). One handler run\n * processes the whole `cards` list; completion resolves each card's stage-run\n * (`cards[i].idemKey`) and advances it along the lane's single\n * `auto_on_complete` edge (advance-all-on-success; a failed card stays put).\n */\nexport interface BatchDispatchMeta {\n /** The chunk's batch key (`batch:stageId:version:<chunk-token>`). */\n batchKey: string;\n /** Every card in this chunk (each with its own per-card stage-run idemKey). */\n cards: BatchCardContext[];\n}\n\nexport interface HandlerDispatchResult {\n /** Execution UUID (cadra_agent/team) — undefined for fire-and-forget webhooks. */\n executionUuid?: string;\n /** True when the handler dispatched (vs a passive `none`/`human` stage). */\n dispatched: boolean;\n}\n\n/**\n * Options controlling webhook delivery (bounded retry/backoff).\n */\nexport interface WebhookDeliveryOptions {\n /** Injected fetch (defaults to global fetch). */\n fetchImpl?: typeof fetch;\n /** Max attempts on transient (5xx/network) failure (default from binding/3). */\n maxAttempts?: number;\n /** Base backoff ms (default 200). Exponential. */\n baseBackoffMs?: number;\n /** Sleep impl (injectable for tests). */\n sleep?: (ms: number) => Promise<void>;\n /** Clock for the signed timestamp (injectable for tests). */\n now?: () => number;\n}\n\n/** A 4xx is permanent (don't retry); a 5xx / network error is transient. */\nexport class WebhookDeliveryError extends Error {\n constructor(\n message: string,\n readonly status: number | undefined,\n readonly retryable: boolean\n ) {\n super(message);\n this.name = \"WebhookDeliveryError\";\n }\n}\n\n/**\n * Compute the hex HMAC-SHA256 signature of `payload` with `secret`.\n *\n * Uses Web Crypto (`crypto.subtle`) — available as a global in Node 18+ and\n * the edge/worker runtimes a host backend might use. No node:crypto import, so\n * the module stays portable.\n */\nexport async function hmacSign(secret: string, payload: string): Promise<string> {\n const enc = new TextEncoder();\n const key = await crypto.subtle.importKey(\n \"raw\",\n enc.encode(secret),\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"sign\"]\n );\n const sig = await crypto.subtle.sign(\"HMAC\", key, enc.encode(payload));\n return [...new Uint8Array(sig)]\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\nconst sleepDefault = (ms: number) => new Promise<void>((r) => setTimeout(r, ms));\n\n/**\n * Deliver a signed webhook with bounded exponential backoff.\n *\n * - 2xx → resolves.\n * - 4xx → throws a non-retryable `WebhookDeliveryError` immediately.\n * - 5xx / network → retries up to `maxAttempts`, then throws retryable.\n */\nexport async function deliverWebhook(\n ctx: HandlerContext,\n cadra: CadraRunClient,\n opts: WebhookDeliveryOptions = {}\n): Promise<void> {\n const binding = ctx.stage.handler?.webhook;\n if (!binding) throw new Error(`Stage ${ctx.stage.key} has no webhook binding`);\n\n const doFetch = opts.fetchImpl ?? fetch;\n const maxAttempts = opts.maxAttempts ?? binding.retry ?? 3;\n const baseBackoff = opts.baseBackoffMs ?? 200;\n const sleep = opts.sleep ?? sleepDefault;\n const now = opts.now ?? Date.now;\n\n // Secret is fetched from Cadra (NOT the definition), keyed by the IMMUTABLE\n // stage `id` (p33 §10.2 — rename-proof) — falling back to `key` for a lane\n // authored before the stage-identity contract.\n const stageId = ctx.stage.id ?? ctx.stage.key;\n const secretMaterial = await cadra.getWebhookSecret({\n boardConfigUuid: ctx.boardConfigUuid,\n stageId,\n });\n\n const timestamp = now();\n const body = {\n idemKey: ctx.idemKey,\n cardId: ctx.cardId,\n boardConfigUuid: ctx.boardConfigUuid,\n configVersion: ctx.configVersion,\n stageId,\n input: ctx.input,\n callbackUrl: ctx.callbackUrl,\n callbackToken: secretMaterial?.callbackToken,\n timestamp,\n };\n const payload = JSON.stringify(body);\n const signature = secretMaterial?.secret\n ? await hmacSign(secretMaterial.secret, `${timestamp}.${payload}`)\n : undefined;\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"Idempotency-Key\": ctx.idemKey,\n ...(binding.headers ?? {}),\n };\n if (signature) {\n headers[\"X-Cadra-Signature\"] = `t=${timestamp},v1=${signature}`;\n }\n\n let attempt = 0;\n // eslint-disable-next-line no-constant-condition\n while (true) {\n attempt += 1;\n try {\n const res = await doFetch(binding.url, {\n method: \"POST\",\n headers,\n body: payload,\n ...(binding.timeoutMs\n ? { signal: AbortSignal.timeout(binding.timeoutMs) }\n : {}),\n });\n if (res.ok) return;\n if (res.status >= 400 && res.status < 500) {\n // Permanent — bad request / auth. Do not retry.\n throw new WebhookDeliveryError(\n `Webhook ${binding.url} returned ${res.status}`,\n res.status,\n false\n );\n }\n // 5xx — transient.\n throw new WebhookDeliveryError(\n `Webhook ${binding.url} returned ${res.status}`,\n res.status,\n true\n );\n } catch (err) {\n const retryable =\n err instanceof WebhookDeliveryError ? err.retryable : true; // network errors are transient\n if (!retryable || attempt >= maxAttempts) {\n if (err instanceof WebhookDeliveryError) throw err;\n throw new WebhookDeliveryError(\n err instanceof Error ? err.message : String(err),\n undefined,\n true\n );\n }\n await sleep(baseBackoff * 2 ** (attempt - 1));\n }\n }\n}\n\n/**\n * Dispatch a stage's handler. Returns the executionUuid for streamable\n * handlers (cadra_agent/team); webhooks are fire-and-forget (completion lands\n * via the host callback). `human`/`none` stages do not dispatch.\n */\nexport async function dispatchStageHandler(\n ctx: HandlerContext,\n cadra: CadraRunClient,\n webhookOpts?: WebhookDeliveryOptions\n): Promise<HandlerDispatchResult> {\n const handler = ctx.stage.handler;\n if (!handler || handler.type === \"none\" || handler.type === \"human\") {\n return { dispatched: false };\n }\n\n // For a batch chunk, the OUTBOUND run's idempotency key is the chunk's\n // `batchKey` (ONE execution per chunk), not a per-card key — `ctx.input`\n // already carries the full card list under `context.kanban.batch`. Per-card\n // idempotency is enforced separately by the engine's per-card `beginStageRun`\n // CAS before this dispatch is ever issued.\n const runIdemKey = ctx.batch?.batchKey ?? ctx.idemKey;\n\n switch (handler.type) {\n case \"cadra_agent\": {\n if (!handler.agentUuid) {\n throw new Error(`Stage ${ctx.stage.key} (cadra_agent) missing agentUuid`);\n }\n const { executionUuid } = await cadra.runAgent({\n agentUuid: handler.agentUuid,\n orgId: ctx.orgId,\n input: ctx.input,\n idemKey: runIdemKey,\n // Board/headless dispatch always disables ask_user (spec §6.5 / FINDING-5).\n allowAskUser: false,\n callbackRef: ctx.callbackUrl,\n });\n return { dispatched: true, executionUuid };\n }\n case \"cadra_team\": {\n if (!handler.teamUuid) {\n throw new Error(`Stage ${ctx.stage.key} (cadra_team) missing teamUuid`);\n }\n const { executionUuid } = await cadra.runTeam({\n teamUuid: handler.teamUuid,\n orgId: ctx.orgId,\n input: ctx.input,\n idemKey: runIdemKey,\n // Board/headless dispatch always disables ask_user (spec §6.5 / FINDING-5).\n allowAskUser: false,\n callbackRef: ctx.callbackUrl,\n });\n return { dispatched: true, executionUuid };\n }\n case \"webhook\": {\n await deliverWebhook(ctx, cadra, webhookOpts);\n return { dispatched: true };\n }\n case \"remote_agent\": {\n // handler.remoteAgentUuid is the cadra remote_agents registry uuid (§5.3).\n // Cast to any to handle the cadra-web boardDefinition union shape which uses\n // remote_agent_uuid (snake_case from JSONB) while the SDK type uses remoteAgentUuid.\n const h = handler as unknown as Record<string, unknown>;\n const remoteAgentUuid =\n (h[\"remoteAgentUuid\"] as string | undefined) ??\n (h[\"remote_agent_uuid\"] as string | undefined);\n if (!remoteAgentUuid) {\n throw new Error(`Stage ${ctx.stage.key} (remote_agent) missing remoteAgentUuid`);\n }\n const { executionUuid } = await cadra.runRemoteAgent({\n remoteAgentUuid,\n orgId: ctx.orgId,\n input: ctx.input,\n idemKey: runIdemKey,\n // Board/headless dispatch always disables ask_user (spec §6.5).\n allowAskUser: false,\n callbackRef: ctx.callbackUrl,\n });\n return { dispatched: true, executionUuid };\n }\n default:\n // Unknown handler type — treat as passive (forward-compatible).\n return { dispatched: false };\n }\n}\n","/**\n * InMemoryStorageAdapter — a reference KanbanStorageAdapter.\n *\n * Single-threaded JS gives us free atomicity (no real row locks needed): each\n * adapter method runs to completion before the next starts. We still model the\n * CONTRACT faithfully:\n * - `applyTransition` is a CAS on `fromLane` (a stale `fromLane` throws a\n * conflict — the loser of a concurrent race).\n * - `beginStageRun` is a CAS insert on `idemKey` (UNIQUE).\n * - `completeStageRun` is idempotent: a second completion returns\n * `{ applied: false }` and does not re-advance.\n *\n * Used by the engine tests and the Task-6 conformance suite as the proof that\n * the contract is implementable. Hosts use it as a worked example.\n *\n * Server-safe (no DOM imports).\n *\n * @module @cadraos/sdk/kanban\n */\n\nimport type {\n AdapterCapabilities,\n KanbanStorageAdapter,\n} from \"./storage-types.js\";\nimport type {\n Actor,\n ApplyTransitionInput,\n CreateCardServerInput,\n DueRule,\n KanbanCard,\n KanbanHandlerType,\n StageRun,\n TransitionLogEntry,\n} from \"../types.js\";\n\n/**\n * Thrown by `applyTransition` when the CAS `fromLane` guard fails (the card has\n * already moved — a concurrent transition won the race).\n */\nexport class TransitionConflictError extends Error {\n readonly code = \"transition_conflict\";\n constructor(message = \"Card lane changed since the move was computed\") {\n super(message);\n this.name = \"TransitionConflictError\";\n }\n}\n\n/**\n * Thrown by `listDueCards` when a `DueRule.kind` is not in the closed\n * vocabulary (design §6 — fail closed; never silently return everything).\n */\nexport class UnknownDueRuleError extends Error {\n readonly code = \"unknown_due_rule_kind\";\n constructor(kind: string) {\n super(`Unknown DueRule.kind: ${JSON.stringify(kind)}`);\n this.name = \"UnknownDueRuleError\";\n }\n}\n\nlet idSeq = 0;\nfunction nextId(prefix: string): string {\n idSeq += 1;\n return `${prefix}-${idSeq}`;\n}\n\n/** Default stale-`queued` horizon (design §10): 15 minutes. */\nconst DEFAULT_STALE_QUEUED_MS = 15 * 60_000;\n\nexport class InMemoryStorageAdapter implements KanbanStorageAdapter {\n private cards = new Map<string, KanbanCard & { boardConfigUuid: string }>();\n private logs = new Map<string, TransitionLogEntry[]>();\n private runs = new Map<string, StageRun>();\n\n /**\n * A `queued` stage-run older than this (ms) is STALE and re-claimable by\n * `beginStageRun` (design §10) — it models a run whose process died between\n * `beginStageRun` and dispatch, so `failStageRun` never ran. A `failed` run is\n * re-claimable regardless of age. Must comfortably exceed the dispatch time so\n * a genuinely in-flight `queued` run is never re-claimed out from under it.\n */\n private readonly staleQueuedMs: number;\n /** Injectable clock (ms) — real hosts use `Date.now`; tests pin it. */\n private readonly now: () => number;\n\n constructor(opts?: { staleQueuedMs?: number; now?: () => number }) {\n this.staleQueuedMs = opts?.staleQueuedMs ?? DEFAULT_STALE_QUEUED_MS;\n this.now = opts?.now ?? (() => Date.now());\n }\n\n // ----- Cards -----\n\n async listCards(boardConfigUuid: string): Promise<KanbanCard[]> {\n return [...this.cards.values()]\n .filter((c) => c.boardConfigUuid === boardConfigUuid)\n .map((c) => this.publicCard(c));\n }\n\n async getCard(cardId: string): Promise<KanbanCard | null> {\n const c = this.cards.get(cardId);\n return c ? this.publicCard(c) : null;\n }\n\n async createCard(input: CreateCardServerInput): Promise<KanbanCard> {\n const id = nextId(\"card\");\n const now = new Date().toISOString();\n const card = {\n id,\n boardId: input.boardConfigUuid,\n boardConfigUuid: input.boardConfigUuid,\n // Persist BOTH halves of the lifecycle pin as first-class card fields\n // (p33 §10.5): the Cadra lifecycle uuid + version the card was created\n // under. These are surfaced on the public card so the engine's\n // `resolveLifecycleRef` reads a restart-safe, re-link-proof pin.\n cadraLifecycleUuid: input.boardConfigUuid,\n configVersion: input.configVersion,\n lane: input.initialLane,\n title: input.title,\n description: input.description,\n type: input.type,\n sharedContext: input.sharedContext,\n createdAt: now,\n updatedAt: now,\n };\n this.cards.set(id, card);\n this.logs.set(id, []);\n return this.publicCard(card);\n }\n\n async updateCard(\n cardId: string,\n patch: { title?: string; description?: string; sharedContext?: Record<string, unknown> }\n ): Promise<KanbanCard> {\n const c = this.requireCard(cardId);\n if (patch.title !== undefined) c.title = patch.title;\n if (patch.description !== undefined) c.description = patch.description;\n if (patch.sharedContext !== undefined) {\n c.sharedContext = { ...(c.sharedContext ?? {}), ...patch.sharedContext };\n }\n c.updatedAt = new Date().toISOString();\n return this.publicCard(c);\n }\n\n async applyTransition(cardId: string, move: ApplyTransitionInput): Promise<KanbanCard> {\n const c = this.requireCard(cardId);\n // CAS guard: the card must still be in `fromLane`.\n if (c.lane !== move.fromLane) {\n throw new TransitionConflictError(\n `Expected lane ${move.fromLane}, card is in ${c.lane}`\n );\n }\n c.lane = move.toLane;\n if (move.contextPatch) {\n c.sharedContext = { ...(c.sharedContext ?? {}), ...move.contextPatch };\n }\n if (move.executionUuid) c.executionId = move.executionUuid;\n c.updatedAt = new Date().toISOString();\n this.appendLog(cardId, {\n fromLane: move.fromLane,\n toLane: move.toLane,\n transitionId: move.transitionId,\n actor: move.actor,\n executionUuid: move.executionUuid,\n });\n return this.publicCard(c);\n }\n\n async listTransitions(cardId: string): Promise<TransitionLogEntry[]> {\n return [...(this.logs.get(cardId) ?? [])];\n }\n\n // ----- Conductor mode: due queries + counts + capabilities -----\n\n async listDueCards(\n boardConfigUuid: string,\n laneKey: string,\n dueRule: DueRule,\n opts?: { limit?: number }\n ): Promise<KanbanCard[]> {\n // Fail-closed: reject an unknown kind BEFORE touching any card, so a bad\n // rule never silently returns the whole lane (design §6, §14.4).\n this.assertKnownKind(dueRule);\n\n const now = Date.now();\n const due = [...this.cards.values()]\n .filter(\n (c) => c.boardConfigUuid === boardConfigUuid && c.lane === laneKey\n )\n .filter((c) => this.isDue(c, dueRule, now))\n .map((c) => this.publicCard(c));\n\n const limit = opts?.limit;\n if (limit !== undefined && limit >= 0 && due.length > limit) {\n return due.slice(0, limit);\n }\n return due;\n }\n\n async countsByLane(\n boardConfigUuid: string\n ): Promise<Record<string, number>> {\n const counts: Record<string, number> = {};\n for (const c of this.cards.values()) {\n if (c.boardConfigUuid !== boardConfigUuid) continue;\n counts[c.lane] = (counts[c.lane] ?? 0) + 1;\n }\n return counts;\n }\n\n capabilities(): AdapterCapabilities {\n // The reference adapter resolves `field_due`/`predicate` against a card's\n // `sharedContext`, so any key is translatable. `[\"*\"]` advertises \"any\n // field/predicate\" for the worked-example adapter (real hosts enumerate\n // their concrete columns/predicates).\n return {\n dueRuleFields: [\"*\"],\n dueRulePredicates: [\"*\"],\n membership: \"adapter-resolved\",\n };\n }\n\n // ----- Stage runs -----\n\n async beginStageRun(\n cardId: string,\n r: { stageId: string; idemKey: string; handlerType: KanbanHandlerType }\n ): Promise<{ created: boolean; run: StageRun }> {\n const existing = this.runs.get(r.idemKey);\n if (existing) {\n // Re-claim a STRANDED run so a transient dispatch failure self-heals on\n // the next sweep (design §10): a `failed` run (a prior dispatch threw →\n // failStageRun), or a stale `queued` run (a process died before dispatch\n // could flip it to running/failed). A `running` (mid-flight) or\n // `completed` run is NEVER re-claimed — that is the acyclic guarantee\n // (a completed stage is never re-run under the same idemKey). On re-claim\n // we reset to a fresh `queued` intent (dropping the stale\n // error/executionUuid) and bump `attempts`, then return created:true so\n // the engine dispatches again.\n if (this.isReclaimable(existing)) {\n const run: StageRun = {\n idemKey: r.idemKey,\n cardId,\n stageId: r.stageId,\n handlerType: r.handlerType,\n status: \"queued\",\n attempts: (existing.attempts ?? 1) + 1,\n createdAt: new Date(this.now()).toISOString(),\n };\n this.runs.set(r.idemKey, run);\n return { created: true, run: { ...run } };\n }\n return { created: false, run: { ...existing } };\n }\n const run: StageRun = {\n idemKey: r.idemKey,\n cardId,\n stageId: r.stageId,\n handlerType: r.handlerType,\n status: \"queued\",\n attempts: 1,\n createdAt: new Date(this.now()).toISOString(),\n };\n this.runs.set(r.idemKey, run);\n return { created: true, run: { ...run } };\n }\n\n /**\n * A stranded stage-run the next `beginStageRun` may re-claim (design §10): a\n * `failed` run (dispatch threw), or a `queued` run older than `staleQueuedMs`\n * (a process died before dispatch flipped it). `running`/`completed` runs are\n * never re-claimed.\n */\n private isReclaimable(run: StageRun): boolean {\n if (run.status === \"failed\") return true;\n if (run.status === \"queued\") {\n const age = this.now() - Date.parse(run.createdAt);\n return Number.isFinite(age) && age >= this.staleQueuedMs;\n }\n return false;\n }\n\n async completeStageRun(\n idemKey: string,\n c: {\n executionUuid?: string;\n toLane?: string;\n contextPatch?: Record<string, unknown>;\n actor: Actor;\n }\n ): Promise<{ applied: boolean }> {\n const run = this.runs.get(idemKey);\n if (!run) throw new Error(`No stage run for idemKey ${idemKey}`);\n // Idempotent: a duplicate/retried completion is a no-op.\n if (run.status === \"completed\") return { applied: false };\n\n run.status = \"completed\";\n if (c.executionUuid) run.executionUuid = c.executionUuid;\n\n // One \"transaction\": mark complete + advance.\n if (c.toLane) {\n const card = this.requireCard(run.cardId);\n // Advance from the card's CURRENT lane (a lane KEY). The engine resolved\n // `toLane` for a card sitting in this run's stage, so the card's lane is\n // that stage's key — using it as `fromLane` is the CAS and is robust to a\n // stage `id` that differs from its `key` (p33 §10.2: `run.stageId` is the\n // immutable id, not necessarily the lane key). Skip the advance only if\n // the card already moved on (already at the target).\n if (card.lane !== c.toLane) {\n await this.applyTransition(run.cardId, {\n fromLane: card.lane,\n toLane: c.toLane,\n actor: c.actor,\n contextPatch: c.contextPatch,\n executionUuid: c.executionUuid ?? run.executionUuid,\n });\n }\n }\n return { applied: true };\n }\n\n async failStageRun(idemKey: string, f: { error: string }): Promise<void> {\n const run = this.runs.get(idemKey);\n if (!run) throw new Error(`No stage run for idemKey ${idemKey}`);\n if (run.status === \"completed\") return; // don't clobber a completed run\n run.status = \"failed\";\n run.error = f.error;\n }\n\n async getStageRun(idemKey: string): Promise<StageRun | null> {\n const r = this.runs.get(idemKey);\n return r ? { ...r } : null;\n }\n\n async markStageRunDispatched(\n idemKey: string,\n d: { executionUuid?: string }\n ): Promise<void> {\n const run = this.runs.get(idemKey);\n if (!run) return;\n if (run.status === \"queued\") run.status = \"running\";\n if (d.executionUuid) {\n run.executionUuid = d.executionUuid;\n // Mirror the execution uuid onto the card so the UI can stream it.\n const card = this.cards.get(run.cardId);\n if (card) card.executionId = d.executionUuid;\n }\n }\n\n // ----- internals -----\n\n /**\n * Reject (throw) if any node in the rule tree is not a known `kind` — checked\n * up front so a bad rule fails closed before we ever inspect a card.\n */\n private assertKnownKind(rule: DueRule): void {\n switch (rule.kind) {\n case \"always\":\n case \"backlog\":\n case \"field_due\":\n case \"predicate\":\n return;\n case \"and\":\n for (const r of rule.rules) this.assertKnownKind(r);\n return;\n default:\n throw new UnknownDueRuleError(\n (rule as { kind?: string }).kind ?? \"<missing>\"\n );\n }\n }\n\n /**\n * Evaluate a (validated) `DueRule` against an in-memory card. `field_due` /\n * `predicate` read the card's `sharedContext` (the reference adapter's only\n * \"host data\"); a real host pushes these down to SQL over its own columns.\n */\n private isDue(\n card: KanbanCard,\n rule: DueRule,\n now: number\n ): boolean {\n switch (rule.kind) {\n case \"always\":\n // Every card in the lane is due.\n return true;\n case \"backlog\":\n // The card is IN the lane (the caller already filtered to it), so any\n // card in a non-empty lane is due — the \"process the backlog\" rule.\n return true;\n case \"field_due\": {\n const v = card.sharedContext?.[rule.field];\n if (v == null) return false; // no value → not due (fail closed)\n const left = this.toComparable(v);\n const right =\n rule.value === \"now\"\n ? now\n : this.toComparable(rule.value);\n if (left == null || right == null) return false;\n // op is fixed to \"<=\".\n return left <= right;\n }\n case \"predicate\": {\n const v = card.sharedContext?.[rule.ref];\n if (v == null) return false;\n // op is fixed to \"=\".\n return String(v) === String(rule.value);\n }\n case \"and\":\n return rule.rules.every((r) => this.isDue(card, r, now));\n default:\n // Unreachable — assertKnownKind already rejected unknown kinds.\n throw new UnknownDueRuleError(\n (rule as { kind?: string }).kind ?? \"<missing>\"\n );\n }\n }\n\n /**\n * Coerce a value to a comparable primitive for `field_due` (`<=`): dates →\n * epoch ms, numeric strings → numbers, else the raw number/string.\n */\n private toComparable(v: unknown): number | string | null {\n if (typeof v === \"number\") return v;\n if (v instanceof Date) return v.getTime();\n if (typeof v === \"string\") {\n const t = Date.parse(v);\n if (!Number.isNaN(t)) return t; // ISO date-ish string → epoch ms\n const n = Number(v);\n if (!Number.isNaN(n) && v.trim() !== \"\") return n;\n return v;\n }\n return null;\n }\n\n private requireCard(cardId: string) {\n const c = this.cards.get(cardId);\n if (!c) throw new Error(`Card not found: ${cardId}`);\n return c;\n }\n\n private appendLog(cardId: string, entry: Omit<TransitionLogEntry, \"id\" | \"cardId\" | \"createdAt\">) {\n const list = this.logs.get(cardId) ?? [];\n list.push({\n id: nextId(\"log\"),\n cardId,\n createdAt: new Date().toISOString(),\n ...entry,\n });\n this.logs.set(cardId, list);\n }\n\n private publicCard(\n c: KanbanCard & { boardConfigUuid: string }\n ): KanbanCard {\n // Strip only the internal duplicate `boardConfigUuid` (the public card\n // exposes the pin via `boardId` + the first-class `cadraLifecycleUuid` /\n // `configVersion` fields the engine's `resolveLifecycleRef` reads).\n const { boardConfigUuid: _b, ...pub } = c;\n void _b;\n return { ...pub };\n }\n}\n","/**\n * HttpStorageAdapter — the GENERIC, cross-system KanbanStorageAdapter.\n *\n * The second adapter flavor (design.md §10). Where the in-process adapter\n * (crm/yobo) implements `KanbanStorageAdapter` directly over the host's own\n * tables, the `HttpStorageAdapter` satisfies the SAME contract by calling a\n * small, fixed REST contract that a FOREIGN (non-TS) system exposes over its\n * own data. No SDK link, no TypeScript, is required of the foreign host — it\n * just answers HTTP. This is the cross-system drop-in lever: an HRIS, an\n * accounting SaaS, a fulfillment system, or a video pipeline becomes a Cadra\n * board host by answering ~3-4 endpoints.\n *\n * THE HTTP CONTRACT (design.md §10 — the small but NON-trivial endpoint set;\n * read + transition + counts + stage-run durability/idempotency):\n *\n * | Method + path | Adapter method |\n * |--------------------------------------------------------|---------------------------|\n * | GET /boards/:uuid/cards?lane=&dueRule=&limit= | listCards / listDueCards |\n * | GET /boards/:uuid/cards/:cardId | getCard |\n * | POST /boards/:uuid/cards | createCard |\n * | PATCH /boards/:uuid/cards/:cardId | updateCard |\n * | POST /boards/:uuid/cards/:cardId/transition | applyTransition |\n * | GET /boards/:uuid/cards/:cardId/transitions | listTransitions |\n * | GET /boards/:uuid/counts | countsByLane |\n * | GET /capabilities | capabilities (prefetched) |\n * | POST /boards/:uuid/stage-runs | beginStageRun (CAS) |\n * | POST /boards/:uuid/stage-runs/:idemKey/complete | completeStageRun (CAS) |\n * | POST /boards/:uuid/stage-runs/:idemKey/fail | failStageRun |\n * | POST /boards/:uuid/stage-runs/:idemKey/dispatched | markStageRunDispatched |\n * | GET /boards/:uuid/stage-runs/:idemKey | getStageRun |\n *\n * WHO OWNS WHAT (design.md §10, §15 open-question 1 — RESOLVED):\n * - The FOREIGN HOST owns the `idemKey` CAS ledger (a unique-keyed `stage_run`\n * table in its own world). `beginStageRun` / `completeStageRun` are CAS over\n * the host's ledger; a replayed POST is a no-op the HOST enforces. v1 ships\n * NO Cadra-hosted-ledger mode — the realism bar is \"one small adapter\" that\n * includes a unique-keyed ledger, not zero code.\n * - The FOREIGN HOST owns `applyTransition` atomicity (one row-locked tx, CAS\n * on `fromLane`) and the `dueRule` → its-own-WHERE-clause translation. The\n * engine never sees host columns; the declared `dueRule` is PUSHED DOWN on\n * the read as a query param the host evaluates.\n *\n * AUTH / TRANSPORT (design.md §10 — no new auth model):\n * - Bearer key (`Authorization: Bearer <apiKey>`), the same key family as the\n * rest of Cadra.\n * - OPTIONAL HMAC-SHA256 over the request: `X-Cadra-Signature: t=<ts>,v1=<hex>`\n * signed over `${timestamp}.${method} ${path}.${body}` with `hmacSecret`,\n * the SAME scheme as `kanban.*` webhook channels + `board_config_secret`\n * (`hmacSign` is reused verbatim from the webhook handler).\n *\n * Server-safe (no DOM imports): uses global `fetch` + `crypto.subtle` (Node\n * 18+ / edge / worker runtimes). No `node:*` imports, so it stays portable.\n *\n * @module @cadraos/sdk/kanban\n */\n\nimport type {\n AdapterCapabilities,\n KanbanStorageAdapter,\n} from \"./storage-types.js\";\nimport type {\n Actor,\n ApplyTransitionInput,\n CreateCardServerInput,\n DueRule,\n KanbanCard,\n KanbanHandlerType,\n StageRun,\n TransitionLogEntry,\n} from \"../types.js\";\nimport { hmacSign } from \"../engine/handlers.js\";\n\n/**\n * Thrown when a foreign host returns a non-2xx response (other than the 404\n * that `getCard`/`getStageRun` map to `null`). Carries the status + the host's\n * response body for the cron/engine to surface (design §6, §14.4).\n */\nexport class HttpAdapterError extends Error {\n readonly code = \"http_adapter_error\";\n constructor(\n readonly status: number,\n readonly method: string,\n readonly path: string,\n readonly body: string\n ) {\n super(\n `HTTP ${status} from ${method} ${path}${\n body ? `: ${body.slice(0, 500)}` : \"\"\n }`\n );\n this.name = \"HttpAdapterError\";\n }\n}\n\n/**\n * Thrown by `capabilities()` when the manifest has not been prefetched. The\n * `KanbanStorageAdapter.capabilities()` method is SYNCHRONOUS (Cadra caches it\n * into its board-config registry, design §6), but HTTP is async — so the\n * caller MUST call `loadCapabilities()` once (or pass `capabilities` to the\n * constructor) before `capabilities()` is read.\n */\nexport class CapabilitiesNotLoadedError extends Error {\n readonly code = \"capabilities_not_loaded\";\n constructor() {\n super(\n \"HttpStorageAdapter.capabilities() called before the manifest was \" +\n \"fetched — call `await adapter.loadCapabilities()` once (or pass \" +\n \"`capabilities` to the constructor).\"\n );\n this.name = \"CapabilitiesNotLoadedError\";\n }\n}\n\n/** A minimal `fetch` shape (so a host may inject a custom transport / test loopback). */\nexport type FetchLike = (\n input: string,\n init?: {\n method?: string;\n headers?: Record<string, string>;\n body?: string;\n }\n) => Promise<{\n status: number;\n ok: boolean;\n text(): Promise<string>;\n}>;\n\n/**\n * Configuration for the {@link HttpStorageAdapter}.\n */\nexport interface HttpStorageAdapterConfig {\n /**\n * Base URL of the foreign host's board API (no trailing slash), e.g.\n * `https://hris.acme.com/cadra`. All contract paths are appended to this.\n */\n baseUrl: string;\n /**\n * The board config uuid this adapter is bound to (cards/counts/stage-runs all\n * key on it). One adapter instance = one board.\n */\n boardConfigUuid: string;\n /** Bearer key sent as `Authorization: Bearer <apiKey>` (no new auth model). */\n apiKey: string;\n /**\n * OPTIONAL HMAC-SHA256 signing secret. When present, every request carries\n * `X-Cadra-Signature: t=<ts>,v1=<hex>` over `${ts}.${method} ${path}.${body}`\n * — the SAME scheme as the `kanban.*` webhook channels + `board_config_secret`.\n * When absent, requests are bearer-only.\n */\n hmacSecret?: string;\n /**\n * OPTIONAL pre-supplied capability manifest. When provided, `capabilities()`\n * returns it without a network call (Cadra typically already cached it).\n * When omitted, call `await loadCapabilities()` once before `capabilities()`.\n */\n capabilities?: AdapterCapabilities;\n /** Inject a custom `fetch` (default: the global `fetch`). */\n fetchImpl?: FetchLike;\n /** Inject a clock for deterministic HMAC timestamps in tests. */\n now?: () => number;\n}\n\n/**\n * The generic HTTP-backed `KanbanStorageAdapter`. One instance is bound to one\n * `boardConfigUuid`; it maps each adapter method to the §10 REST contract.\n *\n * The Conductor-mode methods (`listDueCards` / `countsByLane` / `capabilities`)\n * are implemented — `HttpStorageAdapter` is a Conductor-capable adapter,\n * because the foreign host owns the due-query + counts (a foreign SOP host that\n * cannot answer them simply does not expose those routes, but then it is not a\n * scheduled-lane host).\n */\nexport class HttpStorageAdapter implements KanbanStorageAdapter {\n private readonly baseUrl: string;\n private readonly boardConfigUuid: string;\n private readonly apiKey: string;\n private readonly hmacSecret?: string;\n private readonly fetchImpl: FetchLike;\n private readonly now: () => number;\n private caps?: AdapterCapabilities;\n\n constructor(config: HttpStorageAdapterConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/+$/, \"\");\n this.boardConfigUuid = config.boardConfigUuid;\n this.apiKey = config.apiKey;\n this.hmacSecret = config.hmacSecret;\n this.fetchImpl = (config.fetchImpl ?? (fetch as unknown as FetchLike));\n this.now = config.now ?? Date.now;\n this.caps = config.capabilities;\n }\n\n private get board(): string {\n return encodeURIComponent(this.boardConfigUuid);\n }\n\n // ----- Cards -----\n\n async listCards(boardConfigUuid: string): Promise<KanbanCard[]> {\n const res = await this.request<{ cards: KanbanCard[] }>(\n \"GET\",\n `/boards/${encodeURIComponent(boardConfigUuid)}/cards`\n );\n return res.cards ?? [];\n }\n\n async getCard(cardId: string): Promise<KanbanCard | null> {\n return this.request<KanbanCard | null>(\n \"GET\",\n `/boards/${this.board}/cards/${encodeURIComponent(cardId)}`,\n undefined,\n { nullOn404: true }\n );\n }\n\n async createCard(input: CreateCardServerInput): Promise<KanbanCard> {\n return this.request<KanbanCard>(\n \"POST\",\n `/boards/${encodeURIComponent(input.boardConfigUuid)}/cards`,\n input\n );\n }\n\n async updateCard(\n cardId: string,\n patch: {\n title?: string;\n description?: string;\n sharedContext?: Record<string, unknown>;\n }\n ): Promise<KanbanCard> {\n return this.request<KanbanCard>(\n \"PATCH\",\n `/boards/${this.board}/cards/${encodeURIComponent(cardId)}`,\n patch\n );\n }\n\n async applyTransition(\n cardId: string,\n move: ApplyTransitionInput\n ): Promise<KanbanCard> {\n // The host runs its OWN transition atomically (row-locked, CAS on fromLane)\n // and is the source of truth for the conflict. A stale fromLane → the host\n // returns 409 → we surface it as an `HttpAdapterError` the engine maps to a\n // conflict (the loser of a concurrent race).\n return this.request<KanbanCard>(\n \"POST\",\n `/boards/${this.board}/cards/${encodeURIComponent(cardId)}/transition`,\n move\n );\n }\n\n async listTransitions(cardId: string): Promise<TransitionLogEntry[]> {\n const res = await this.request<{ transitions: TransitionLogEntry[] }>(\n \"GET\",\n `/boards/${this.board}/cards/${encodeURIComponent(cardId)}/transitions`\n );\n return res.transitions ?? [];\n }\n\n // ----- Conductor mode: due queries + counts + capabilities -----\n\n async listDueCards(\n boardConfigUuid: string,\n laneKey: string,\n dueRule: DueRule,\n opts?: { limit?: number }\n ): Promise<KanbanCard[]> {\n // PUSH THE RULE DOWN: the declared `dueRule` rides as a JSON query param the\n // FOREIGN HOST evaluates over its own data. The engine never sees host\n // columns; the host owns the translation + the fail-closed-on-unknown-kind\n // contract (an unknown kind → the host rejects → we surface its error).\n const qs = new URLSearchParams();\n qs.set(\"lane\", laneKey);\n qs.set(\"dueRule\", JSON.stringify(dueRule));\n if (opts?.limit !== undefined) qs.set(\"limit\", String(opts.limit));\n const res = await this.request<{ cards: KanbanCard[] }>(\n \"GET\",\n `/boards/${encodeURIComponent(boardConfigUuid)}/cards?${qs.toString()}`\n );\n return res.cards ?? [];\n }\n\n async countsByLane(\n boardConfigUuid: string\n ): Promise<Record<string, number>> {\n return this.request<Record<string, number>>(\n \"GET\",\n `/boards/${encodeURIComponent(boardConfigUuid)}/counts`\n );\n }\n\n /**\n * Fetch the host's capability manifest once and cache it, so the SYNCHRONOUS\n * `capabilities()` (which Cadra calls at publish/import, design §6) can return\n * it without a network round-trip. Idempotent — re-call to refresh.\n */\n async loadCapabilities(): Promise<AdapterCapabilities> {\n this.caps = await this.request<AdapterCapabilities>(\"GET\", `/capabilities`);\n return this.caps;\n }\n\n capabilities(): AdapterCapabilities {\n if (!this.caps) throw new CapabilitiesNotLoadedError();\n return this.caps;\n }\n\n // ----- Stage runs (durable + idempotent — host owns the CAS ledger) -----\n\n async beginStageRun(\n cardId: string,\n r: { stageId: string; idemKey: string; handlerType: KanbanHandlerType }\n ): Promise<{ created: boolean; run: StageRun }> {\n // CAS on idemKey at the HOST. A first insert → `{ created: true }`; a replay\n // of the same idemKey → `{ created: false }` (no-op). The host's unique\n // constraint is the source of truth — a retried dispatch never double-fires.\n return this.request<{ created: boolean; run: StageRun }>(\n \"POST\",\n `/boards/${this.board}/stage-runs`,\n { cardId, ...r }\n );\n }\n\n async completeStageRun(\n idemKey: string,\n c: {\n executionUuid?: string;\n toLane?: string;\n contextPatch?: Record<string, unknown>;\n actor: Actor;\n }\n ): Promise<{ applied: boolean }> {\n // Idempotent at the HOST: a duplicate/retried completion returns\n // `{ applied: false }` and does NOT double-advance the card.\n return this.request<{ applied: boolean }>(\n \"POST\",\n `/boards/${this.board}/stage-runs/${encodeURIComponent(idemKey)}/complete`,\n c\n );\n }\n\n async failStageRun(idemKey: string, f: { error: string }): Promise<void> {\n await this.request<{ ok?: boolean }>(\n \"POST\",\n `/boards/${this.board}/stage-runs/${encodeURIComponent(idemKey)}/fail`,\n f\n );\n }\n\n async markStageRunDispatched(\n idemKey: string,\n d: { executionUuid?: string }\n ): Promise<void> {\n await this.request<{ ok?: boolean }>(\n \"POST\",\n `/boards/${this.board}/stage-runs/${encodeURIComponent(\n idemKey\n )}/dispatched`,\n d\n );\n }\n\n async getStageRun(idemKey: string): Promise<StageRun | null> {\n return this.request<StageRun | null>(\n \"GET\",\n `/boards/${this.board}/stage-runs/${encodeURIComponent(idemKey)}`,\n undefined,\n { nullOn404: true }\n );\n }\n\n // ----- transport -----\n\n /**\n * One signed request to the foreign host. Adds bearer auth + (optional) HMAC,\n * parses JSON, maps 404 → `null` for the two getters, and throws\n * `HttpAdapterError` on any other non-2xx.\n */\n private async request<T>(\n method: string,\n path: string,\n body?: unknown,\n opts?: { nullOn404?: boolean }\n ): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const serialized = body === undefined ? \"\" : JSON.stringify(body);\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.apiKey}`,\n };\n if (body !== undefined) headers[\"Content-Type\"] = \"application/json\";\n\n // OPTIONAL HMAC — same scheme as the webhook channels: sign over\n // `${ts}.${method} ${path}.${body}` so the signature binds method+path+body.\n if (this.hmacSecret) {\n const ts = this.now();\n const signature = await hmacSign(\n this.hmacSecret,\n `${ts}.${method} ${path}.${serialized}`\n );\n headers[\"X-Cadra-Signature\"] = `t=${ts},v1=${signature}`;\n }\n\n const res = await this.fetchImpl(url, {\n method,\n headers,\n ...(body === undefined ? {} : { body: serialized }),\n });\n\n if (res.status === 404 && opts?.nullOn404) {\n return null as T;\n }\n\n const text = await res.text();\n if (!res.ok) {\n throw new HttpAdapterError(res.status, method, path, text);\n }\n if (text === \"\") return undefined as T;\n return JSON.parse(text) as T;\n }\n}\n","/**\n * exampleHostHandler — a minimal, NON-crm example host implementing the §10\n * HTTP contract (the documented starter template, design.md §10).\n *\n * This is the \"ONE small adapter, not zero code\" realism bar: a brand-new SOP\n * host (an HRIS, an accounting SaaS, a fulfillment system, a video pipeline)\n * becomes a Cadra board host by answering ~3-4 routes over ITS OWN data. Here\n * the \"own data\" is an in-process `KanbanStorageAdapter` (the reference\n * `InMemoryStorageAdapter`) standing in for the foreign host's real tables — a\n * real host swaps that for its own SQL, owning:\n * - the `applyTransition` atomicity (row-locked, CAS on fromLane),\n * - the `dueRule` → its-own-WHERE-clause translation,\n * - the `idemKey` CAS stage-run ledger (a unique-keyed table),\n * - the `capabilities` manifest.\n *\n * The auth boundary (bearer key + optional HMAC-SHA256 over\n * `${ts}.${method} ${path}.${body}`) is enforced here exactly as the\n * `HttpStorageAdapter` signs it — the same scheme as the `kanban.*` webhook\n * channels + `board_config_secret`. NO new auth model.\n *\n * `exampleHostHandler` is transport-agnostic: it takes a parsed\n * `{ method, path, headers, body }` and returns `{ status, body }`. Wrap it in\n * a `node:http` server (see `startExampleHost`), a Fastify route, a Lambda, a\n * Cloudflare Worker — anything. A real foreign host re-implements this surface\n * in its own language; this TS version is the executable specification + the\n * loopback the conformance suite runs against (design §10, STORY-008).\n *\n * Server-safe (no DOM imports). `node:http` is only imported inside the\n * OPTIONAL `startExampleHost` convenience (a lazy dynamic import) so this module\n * stays portable to edge/worker runtimes.\n *\n * @module @cadraos/sdk/kanban\n */\n\nimport type { KanbanStorageAdapter } from \"./storage-types.js\";\nimport { InMemoryStorageAdapter, TransitionConflictError } from \"./in-memory-adapter.js\";\nimport type {\n Actor,\n ApplyTransitionInput,\n CreateCardServerInput,\n DueRule,\n KanbanHandlerType,\n} from \"../types.js\";\nimport { hmacSign } from \"../engine/handlers.js\";\n\n/** A transport-neutral request the host handler consumes. */\nexport interface HostRequest {\n method: string;\n /** Path + query string, e.g. `/boards/cfg-1/cards?lane=scheduled`. */\n path: string;\n headers: Record<string, string | undefined>;\n /** Parsed JSON body (undefined for GET / empty bodies). */\n body?: unknown;\n}\n\n/** A transport-neutral response the handler returns. */\nexport interface HostResponse {\n status: number;\n /** JSON-serializable body (undefined → empty 204-ish reply). */\n body?: unknown;\n}\n\n/** Options for {@link exampleHostHandler}. */\nexport interface ExampleHostOptions {\n /**\n * The backing storage adapter (the foreign host's \"own data\"). Defaults to a\n * fresh `InMemoryStorageAdapter`. A real host passes an adapter over its own\n * tables.\n */\n adapter?: KanbanStorageAdapter;\n /** The bearer key the host accepts (`Authorization: Bearer <apiKey>`). */\n apiKey: string;\n /**\n * OPTIONAL HMAC secret. When set, every request MUST carry a valid\n * `X-Cadra-Signature: t=<ts>,v1=<hex>` over `${ts}.${method} ${path}.${body}`\n * or the host replies 401.\n */\n hmacSecret?: string;\n}\n\n/**\n * Build a §10-contract host handler backed by `opts.adapter`. The returned\n * function is `async (req) => res` — wire it into any transport.\n */\nexport function exampleHostHandler(\n opts: ExampleHostOptions\n): (req: HostRequest) => Promise<HostResponse> {\n const adapter = opts.adapter ?? new InMemoryStorageAdapter();\n\n return async function handle(req: HostRequest): Promise<HostResponse> {\n // --- auth: bearer + optional HMAC (same scheme as kanban.* webhooks) ---\n const authFail = await checkAuth(req, opts);\n if (authFail) return authFail;\n\n const { pathname, query } = splitPath(req.path);\n const segs = pathname.split(\"/\").filter(Boolean);\n\n try {\n // GET /capabilities\n if (req.method === \"GET\" && segs.length === 1 && segs[0] === \"capabilities\") {\n const caps = adapter.capabilities?.() ?? {\n dueRuleFields: [\"*\"],\n dueRulePredicates: [\"*\"],\n membership: \"adapter-resolved\" as const,\n };\n return { status: 200, body: caps };\n }\n\n // Everything else is /boards/:uuid/...\n if (segs[0] !== \"boards\" || segs.length < 2) {\n return { status: 404, body: { error: \"not_found\" } };\n }\n const boardUuid = decodeURIComponent(segs[1]!);\n const rest = segs.slice(2);\n\n // GET /boards/:uuid/counts\n if (req.method === \"GET\" && rest.length === 1 && rest[0] === \"counts\") {\n const counts = (await adapter.countsByLane?.(boardUuid)) ?? {};\n return { status: 200, body: counts };\n }\n\n // ---- cards ----\n if (rest[0] === \"cards\") {\n // GET /boards/:uuid/cards?lane=&dueRule=&limit=\n if (req.method === \"GET\" && rest.length === 1) {\n const lane = query.get(\"lane\") ?? undefined;\n const dueRuleRaw = query.get(\"dueRule\");\n const limitRaw = query.get(\"limit\");\n const limit = limitRaw != null ? Number(limitRaw) : undefined;\n\n // dueRule present → push it down to listDueCards (the host owns the\n // translation + the fail-closed-on-unknown-kind contract).\n if (dueRuleRaw != null && lane) {\n let dueRule: DueRule;\n try {\n dueRule = JSON.parse(dueRuleRaw) as DueRule;\n } catch {\n return { status: 400, body: { error: \"bad_due_rule_json\" } };\n }\n if (!adapter.listDueCards) {\n return { status: 501, body: { error: \"due_query_unsupported\" } };\n }\n try {\n const cards = await adapter.listDueCards(boardUuid, lane, dueRule, {\n ...(limit !== undefined ? { limit } : {}),\n });\n return { status: 200, body: { cards } };\n } catch (e) {\n // Fail closed: an unknown DueRule.kind rejects here (the host),\n // surfaced to the adapter as a 422 — never a silent \"return all\".\n return {\n status: 422,\n body: { error: \"unknown_due_rule\", message: errMsg(e) },\n };\n }\n }\n\n // plain listing\n const cards = await adapter.listCards(boardUuid);\n return { status: 200, body: { cards } };\n }\n\n // POST /boards/:uuid/cards\n if (req.method === \"POST\" && rest.length === 1) {\n const input = req.body as CreateCardServerInput;\n const card = await adapter.createCard({\n ...input,\n boardConfigUuid: boardUuid,\n });\n return { status: 201, body: card };\n }\n\n const cardId = rest[1] != null ? decodeURIComponent(rest[1]) : undefined;\n if (!cardId) return { status: 404, body: { error: \"not_found\" } };\n\n // GET /boards/:uuid/cards/:cardId\n if (req.method === \"GET\" && rest.length === 2) {\n const card = await adapter.getCard(cardId);\n if (!card) return { status: 404, body: { error: \"card_not_found\" } };\n return { status: 200, body: card };\n }\n\n // PATCH /boards/:uuid/cards/:cardId\n if (req.method === \"PATCH\" && rest.length === 2) {\n const card = await adapter.updateCard(\n cardId,\n req.body as {\n title?: string;\n description?: string;\n sharedContext?: Record<string, unknown>;\n }\n );\n return { status: 200, body: card };\n }\n\n // GET /boards/:uuid/cards/:cardId/transitions\n if (req.method === \"GET\" && rest.length === 3 && rest[2] === \"transitions\") {\n const transitions = await adapter.listTransitions(cardId);\n return { status: 200, body: { transitions } };\n }\n\n // POST /boards/:uuid/cards/:cardId/transition\n if (req.method === \"POST\" && rest.length === 3 && rest[2] === \"transition\") {\n try {\n const card = await adapter.applyTransition(\n cardId,\n req.body as ApplyTransitionInput\n );\n return { status: 200, body: card };\n } catch (e) {\n // A stale fromLane (the loser of a concurrent race) → 409 Conflict.\n if (e instanceof TransitionConflictError) {\n return { status: 409, body: { error: \"transition_conflict\", message: e.message } };\n }\n throw e;\n }\n }\n }\n\n // ---- stage runs (the durable, idempotent CAS ledger) ----\n if (rest[0] === \"stage-runs\") {\n // POST /boards/:uuid/stage-runs\n if (req.method === \"POST\" && rest.length === 1) {\n const b = req.body as {\n cardId: string;\n stageId: string;\n idemKey: string;\n handlerType: KanbanHandlerType;\n };\n const out = await adapter.beginStageRun(b.cardId, {\n stageId: b.stageId,\n idemKey: b.idemKey,\n handlerType: b.handlerType,\n });\n return { status: 200, body: out };\n }\n\n const idemKey = rest[1] != null ? decodeURIComponent(rest[1]) : undefined;\n if (!idemKey) return { status: 404, body: { error: \"not_found\" } };\n\n // GET /boards/:uuid/stage-runs/:idemKey\n if (req.method === \"GET\" && rest.length === 2) {\n const run = await adapter.getStageRun(idemKey);\n if (!run) return { status: 404, body: { error: \"run_not_found\" } };\n return { status: 200, body: run };\n }\n\n // POST /boards/:uuid/stage-runs/:idemKey/complete\n if (req.method === \"POST\" && rest.length === 3 && rest[2] === \"complete\") {\n const out = await adapter.completeStageRun(\n idemKey,\n req.body as {\n executionUuid?: string;\n toLane?: string;\n contextPatch?: Record<string, unknown>;\n actor: Actor;\n }\n );\n return { status: 200, body: out };\n }\n\n // POST /boards/:uuid/stage-runs/:idemKey/fail\n if (req.method === \"POST\" && rest.length === 3 && rest[2] === \"fail\") {\n await adapter.failStageRun(idemKey, req.body as { error: string });\n return { status: 200, body: { ok: true } };\n }\n\n // POST /boards/:uuid/stage-runs/:idemKey/dispatched\n if (req.method === \"POST\" && rest.length === 3 && rest[2] === \"dispatched\") {\n await adapter.markStageRunDispatched?.(\n idemKey,\n req.body as { executionUuid?: string }\n );\n return { status: 200, body: { ok: true } };\n }\n }\n\n return { status: 404, body: { error: \"not_found\", path: pathname } };\n } catch (e) {\n // Any host-side error surfaces as a 500 with a message (the adapter turns\n // it into an HttpAdapterError the engine/cron surfaces — design §14.4).\n return { status: 500, body: { error: \"host_error\", message: errMsg(e) } };\n }\n };\n}\n\n/**\n * Verify bearer + (optional) HMAC. Returns a 401 `HostResponse` on failure, or\n * `null` when the request is authorized.\n */\nasync function checkAuth(\n req: HostRequest,\n opts: ExampleHostOptions\n): Promise<HostResponse | null> {\n const auth = header(req.headers, \"authorization\");\n if (auth !== `Bearer ${opts.apiKey}`) {\n return { status: 401, body: { error: \"unauthorized\" } };\n }\n if (opts.hmacSecret) {\n const sigHeader = header(req.headers, \"x-cadra-signature\");\n if (!sigHeader) return { status: 401, body: { error: \"missing_signature\" } };\n const m = /^t=(\\d+),v1=([0-9a-f]+)$/.exec(sigHeader);\n if (!m) return { status: 401, body: { error: \"bad_signature_format\" } };\n const ts = m[1]!;\n const provided = m[2]!;\n const serialized =\n req.body === undefined ? \"\" : JSON.stringify(req.body);\n const expected = await hmacSign(\n opts.hmacSecret,\n `${ts}.${req.method} ${req.path}.${serialized}`\n );\n if (expected !== provided) {\n return { status: 401, body: { error: \"bad_signature\" } };\n }\n }\n return null;\n}\n\nfunction header(\n headers: Record<string, string | undefined>,\n name: string\n): string | undefined {\n const lower = name.toLowerCase();\n for (const k of Object.keys(headers)) {\n if (k.toLowerCase() === lower) return headers[k];\n }\n return undefined;\n}\n\nfunction splitPath(path: string): { pathname: string; query: URLSearchParams } {\n const qIdx = path.indexOf(\"?\");\n if (qIdx === -1) return { pathname: path, query: new URLSearchParams() };\n return {\n pathname: path.slice(0, qIdx),\n query: new URLSearchParams(path.slice(qIdx + 1)),\n };\n}\n\nfunction errMsg(e: unknown): string {\n return e instanceof Error ? e.message : String(e);\n}\n\n/**\n * OPTIONAL convenience: start the example host on a real `node:http` server.\n * Returns the bound `{ url, close }`. Used by the conformance loopback test so\n * the `HttpStorageAdapter` is exercised over REAL HTTP (real serialization, a\n * real socket), not a stubbed transport.\n *\n * `node:http` is imported lazily so the rest of this module stays edge-portable.\n */\nexport async function startExampleHost(\n opts: ExampleHostOptions\n): Promise<{ url: string; port: number; close: () => Promise<void> }> {\n const http = await import(\"node:http\");\n const handle = exampleHostHandler(opts);\n\n const server = http.createServer((req, res) => {\n const chunks: Buffer[] = [];\n req.on(\"data\", (c) => chunks.push(c as Buffer));\n req.on(\"end\", () => {\n void (async () => {\n const raw = Buffer.concat(chunks).toString(\"utf8\");\n let body: unknown;\n if (raw !== \"\") {\n try {\n body = JSON.parse(raw);\n } catch {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"bad_json\" }));\n return;\n }\n }\n const result = await handle({\n method: req.method ?? \"GET\",\n path: req.url ?? \"/\",\n headers: req.headers as Record<string, string | undefined>,\n body,\n });\n const payload =\n result.body === undefined ? \"\" : JSON.stringify(result.body);\n res.writeHead(result.status, { \"Content-Type\": \"application/json\" });\n res.end(payload);\n })();\n });\n });\n\n await new Promise<void>((resolve) => server.listen(0, \"127.0.0.1\", resolve));\n const addr = server.address();\n const port =\n typeof addr === \"object\" && addr ? addr.port : 0;\n\n return {\n url: `http://127.0.0.1:${port}`,\n port,\n close: () =>\n new Promise<void>((resolve, reject) =>\n server.close((err) => (err ? reject(err) : resolve()))\n ),\n };\n}\n","/**\n * KanbanStorageAdapter conformance test-kit.\n *\n * A reusable suite hosts run against THEIR adapter to prove it honors the\n * durability / idempotency / atomicity contract (design §4/§5/§11 R2). The host\n * imports `runAdapterConformance` and passes a factory that returns a FRESH,\n * empty adapter per case + the test-runner primitives (so this module doesn't\n * hard-depend on vitest at the SDK's runtime entry — the host injects its own\n * `describe`/`it`/`expect`).\n *\n * @example\n * ```ts\n * import { describe, it, expect } from 'vitest';\n * import { runAdapterConformance } from '@cadraos/sdk/kanban/engine';\n * import { MyHostAdapter } from './my-adapter';\n *\n * runAdapterConformance(() => new MyHostAdapter(testDb), { describe, it, expect });\n * ```\n *\n * Server-safe (no DOM imports).\n *\n * @module @cadraos/sdk/kanban\n */\n\nimport type { DueRule, KanbanStorageAdapter } from \"./storage-types.js\";\n\n// =============================================================================\n// INJECTED TEST-RUNNER PRIMITIVES\n// =============================================================================\n\n/** Minimal `expect` surface the suite uses (vitest/jest compatible). */\nexport interface ConformanceExpect {\n (actual: unknown): {\n toBe(expected: unknown): void;\n toEqual(expected: unknown): void;\n toBeNull(): void;\n toBeTruthy(): void;\n toBeGreaterThanOrEqual(n: number): void;\n toContain(item: unknown): void;\n };\n}\n\n/** Minimal describe/it surface (vitest/jest compatible). */\nexport interface ConformanceRunner {\n describe(name: string, fn: () => void): void;\n it(name: string, fn: () => void | Promise<void>): void;\n expect: ConformanceExpect;\n}\n\n/**\n * Factory returning a FRESH, empty adapter for each test (so cases are\n * isolated). May be async (e.g. to truncate a test DB).\n */\nexport type AdapterFactory = () => KanbanStorageAdapter | Promise<KanbanStorageAdapter>;\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\nconst BOARD = \"cfg-conformance\";\n\nasync function seedCard(\n adapter: KanbanStorageAdapter,\n lane: string,\n title = \"Card\",\n sharedContext?: Record<string, unknown>\n) {\n return adapter.createCard({\n title,\n boardConfigUuid: BOARD,\n configVersion: 1,\n initialLane: lane,\n sharedContext,\n });\n}\n\n// =============================================================================\n// SUITE\n// =============================================================================\n\n/**\n * Run the adapter conformance suite. Call inside a host test file.\n *\n * @param makeAdapter - Factory returning a fresh empty adapter per case.\n * @param runner - The injected `{ describe, it, expect }` from the host's\n * test framework.\n */\nexport function runAdapterConformance(\n makeAdapter: AdapterFactory,\n runner: ConformanceRunner\n): void {\n const { describe, it, expect } = runner;\n\n describe(\"KanbanStorageAdapter conformance\", () => {\n it(\"create → list → get round-trips a card at its initial lane\", async () => {\n const adapter = await makeAdapter();\n const card = await seedCard(adapter, \"scheduled\", \"My card\");\n expect(card.lane).toBe(\"scheduled\");\n expect(card.title).toBe(\"My card\");\n\n const list = await adapter.listCards(BOARD);\n expect(list.length).toBe(1);\n expect(list[0]!.id).toBe(card.id);\n\n const got = await adapter.getCard(card.id);\n expect(got).toBeTruthy();\n expect(got!.id).toBe(card.id);\n\n const missing = await adapter.getCard(\"nope\");\n expect(missing).toBeNull();\n });\n\n it(\"createCard persists BOTH halves of the lifecycle pin as first-class card fields (p33 §10.5)\", async () => {\n const adapter = await makeAdapter();\n const card = await adapter.createCard({\n title: \"Pinned card\",\n boardConfigUuid: BOARD,\n configVersion: 3,\n initialLane: \"scheduled\",\n });\n\n // The created card surfaces the pin (uuid + version) so the engine's\n // `resolveLifecycleRef` reads a restart-safe, re-link-proof pin — NOT an\n // in-process map. Both round-trip through get/list.\n expect(card.cadraLifecycleUuid).toBe(BOARD);\n expect(card.configVersion).toBe(3);\n\n const got = await adapter.getCard(card.id);\n expect(got!.cadraLifecycleUuid).toBe(BOARD);\n expect(got!.configVersion).toBe(3);\n });\n\n it(\"applyTransition advances the card + appends a transition-log entry\", async () => {\n const adapter = await makeAdapter();\n const card = await seedCard(adapter, \"scheduled\");\n\n const moved = await adapter.applyTransition(card.id, {\n fromLane: \"scheduled\",\n toLane: \"generate\",\n transitionId: \"t1\",\n actor: { type: \"user\", id: \"u1\" },\n });\n expect(moved.lane).toBe(\"generate\");\n\n const log = await adapter.listTransitions(card.id);\n expect(log.length).toBeGreaterThanOrEqual(1);\n const last = log[log.length - 1]!;\n expect(last.fromLane).toBe(\"scheduled\");\n expect(last.toLane).toBe(\"generate\");\n });\n\n it(\"applyTransition is atomic under a concurrent race: exactly one wins (fromLane guard)\", async () => {\n const adapter = await makeAdapter();\n const card = await seedCard(adapter, \"scheduled\");\n\n // Two transitions computed against the SAME fromLane=scheduled race.\n const results = await Promise.allSettled([\n adapter.applyTransition(card.id, {\n fromLane: \"scheduled\",\n toLane: \"generate\",\n actor: { type: \"user\", id: \"a\" },\n }),\n adapter.applyTransition(card.id, {\n fromLane: \"scheduled\",\n toLane: \"ready\",\n actor: { type: \"user\", id: \"b\" },\n }),\n ]);\n\n const fulfilled = results.filter((r) => r.status === \"fulfilled\");\n const rejected = results.filter((r) => r.status === \"rejected\");\n // Exactly one move wins; the loser observes the stale fromLane and fails.\n expect(fulfilled.length).toBe(1);\n expect(rejected.length).toBe(1);\n\n const final = await adapter.getCard(card.id);\n // The card sits in whichever lane the winner moved it to.\n expect([\"generate\", \"ready\"].includes(final!.lane)).toBe(true);\n });\n\n it(\"beginStageRun dedups on idemKey (CAS)\", async () => {\n const adapter = await makeAdapter();\n const card = await seedCard(adapter, \"generate\");\n const idemKey = `${card.id}:generate:1`;\n\n const first = await adapter.beginStageRun(card.id, {\n stageId: \"generate\",\n idemKey,\n handlerType: \"cadra_agent\",\n });\n expect(first.created).toBe(true);\n\n const second = await adapter.beginStageRun(card.id, {\n stageId: \"generate\",\n idemKey,\n handlerType: \"cadra_agent\",\n });\n expect(second.created).toBe(false);\n\n const run = await adapter.getStageRun(idemKey);\n expect(run).toBeTruthy();\n expect(run!.idemKey).toBe(idemKey);\n });\n\n it(\"completeStageRun is idempotent: second call returns applied=false + no double-advance\", async () => {\n const adapter = await makeAdapter();\n const card = await seedCard(adapter, \"generate\");\n const idemKey = `${card.id}:generate:1`;\n\n await adapter.beginStageRun(card.id, {\n stageId: \"generate\",\n idemKey,\n handlerType: \"cadra_agent\",\n });\n\n const first = await adapter.completeStageRun(idemKey, {\n executionUuid: \"exec-1\",\n toLane: \"ready\",\n actor: { type: \"agent\", id: \"exec-1\" },\n });\n expect(first.applied).toBe(true);\n\n const afterFirst = await adapter.getCard(card.id);\n expect(afterFirst!.lane).toBe(\"ready\");\n\n // Duplicate completion is a no-op.\n const second = await adapter.completeStageRun(idemKey, {\n executionUuid: \"exec-1\",\n toLane: \"ready\",\n actor: { type: \"agent\", id: \"exec-1\" },\n });\n expect(second.applied).toBe(false);\n\n // Only ONE advance happened (the log has a single generate→ready entry).\n const log = await adapter.listTransitions(card.id);\n const toReady = log.filter((l) => l.toLane === \"ready\");\n expect(toReady.length).toBe(1);\n });\n\n it(\"failStageRun marks the run failed without advancing\", async () => {\n const adapter = await makeAdapter();\n const card = await seedCard(adapter, \"generate\");\n const idemKey = `${card.id}:generate:1`;\n await adapter.beginStageRun(card.id, {\n stageId: \"generate\",\n idemKey,\n handlerType: \"cadra_agent\",\n });\n\n await adapter.failStageRun(idemKey, { error: \"boom\" });\n const run = await adapter.getStageRun(idemKey);\n expect(run!.status).toBe(\"failed\");\n expect(run!.error).toBe(\"boom\");\n\n const still = await adapter.getCard(card.id);\n expect(still!.lane).toBe(\"generate\"); // not advanced\n });\n\n // -----------------------------------------------------------------------\n // Conductor mode: listDueCards / countsByLane / capabilities (design §6)\n //\n // OPT-IN per host. These cases run ONLY when the adapter implements all\n // three Conductor methods. An event-only host (cadra-web, yobo) omits them\n // and the cases are SKIPPED — the base suite above still runs for ALL\n // adapters. A Conductor host (in-memory reference, crm) implements them, so\n // the cases run + assert the full due-query / counts / capabilities\n // contract.\n //\n // `makeAdapter` may be async, so we can't synchronously probe the adapter\n // at `it()`-registration time. Instead each Conductor case constructs the\n // adapter first, then no-ops (passes) when the methods are absent — the net\n // effect is \"skip on an event-only host, run on a Conductor host\". A typed\n // local guard narrows the optional methods so the rest of the case is\n // type-safe.\n // -----------------------------------------------------------------------\n\n /**\n * Narrow the adapter to one that implements all three Conductor methods, or\n * return null when the host opted out (event-only). When it returns null\n * the calling case simply returns — registered, but a no-op pass.\n */\n type ConductorAdapter = KanbanStorageAdapter &\n Required<\n Pick<\n KanbanStorageAdapter,\n \"listDueCards\" | \"countsByLane\" | \"capabilities\"\n >\n >;\n const asConductor = (\n adapter: KanbanStorageAdapter\n ): ConductorAdapter | null =>\n adapter.listDueCards && adapter.countsByLane && adapter.capabilities\n ? (adapter as ConductorAdapter)\n : null;\n\n /**\n * Does the adapter DECLARE it can translate `field_due` on `field`? The\n * conformance suite drives concrete field/ref names (`next_touch_at`,\n * `status`); a FAIL-CLOSED host (design §6) only supports the fields it\n * enumerates in `capabilities()` and throws on the rest — that rejection is\n * CORRECT contract behavior, not a conformance failure. So a case that drives\n * a field/ref the adapter doesn't advertise is SKIPPED (the adapter's own\n * `listDueCards` matrix tests its real vocabulary). The reference in-memory\n * adapter advertises `[\"*\"]` (any), so it still runs every case.\n */\n const supportsField = (adapter: ConductorAdapter, field: string): boolean => {\n const fields = adapter.capabilities().dueRuleFields;\n return fields.includes(\"*\") || fields.includes(field);\n };\n const supportsPredicate = (\n adapter: ConductorAdapter,\n ref: string\n ): boolean => {\n const preds = adapter.capabilities().dueRulePredicates;\n return preds.includes(\"*\") || preds.includes(ref);\n };\n\n it(\"listDueCards {kind:'always'} returns every card in the lane\", async () => {\n const base = await makeAdapter();\n const adapter = asConductor(base);\n if (!adapter) return; // event-only host: skip Conductor case\n await seedCard(adapter, \"scheduled\", \"a\");\n await seedCard(adapter, \"scheduled\", \"b\");\n await seedCard(adapter, \"other\", \"c\"); // different lane — excluded\n\n const due = await adapter.listDueCards(BOARD, \"scheduled\", {\n kind: \"always\",\n });\n expect(due.length).toBe(2);\n // All returned cards are in the swept lane.\n expect(due.every((c) => c.lane === \"scheduled\")).toBe(true);\n });\n\n it(\"listDueCards {kind:'backlog'} returns cards when the lane has any\", async () => {\n const base = await makeAdapter();\n const adapter = asConductor(base);\n if (!adapter) return;\n const empty = await adapter.listDueCards(BOARD, \"scheduled\", {\n kind: \"backlog\",\n });\n expect(empty.length).toBe(0);\n\n await seedCard(adapter, \"scheduled\", \"a\");\n const full = await adapter.listDueCards(BOARD, \"scheduled\", {\n kind: \"backlog\",\n });\n expect(full.length).toBe(1);\n });\n\n it(\"listDueCards {kind:'field_due'} selects only cards whose field is due (<= now)\", async () => {\n const base = await makeAdapter();\n const adapter = asConductor(base);\n if (!adapter) return;\n // Fail-closed host that doesn't declare `next_touch_at` → skip (correct\n // rejection is proven by the host's own capabilities/listDueCards tests).\n if (!supportsField(adapter, \"next_touch_at\")) return;\n const past = new Date(Date.now() - 60_000).toISOString();\n const future = new Date(Date.now() + 60_000).toISOString();\n await seedCard(adapter, \"scheduled\", \"due\", { next_touch_at: past });\n await seedCard(adapter, \"scheduled\", \"not-due\", {\n next_touch_at: future,\n });\n await seedCard(adapter, \"scheduled\", \"no-field\"); // missing → not due\n\n const rule: DueRule = {\n kind: \"field_due\",\n field: \"next_touch_at\",\n op: \"<=\",\n value: \"now\",\n };\n const due = await adapter.listDueCards(BOARD, \"scheduled\", rule);\n expect(due.length).toBe(1);\n expect(due[0]!.title).toBe(\"due\");\n });\n\n it(\"listDueCards {kind:'predicate'} matches an equality predicate\", async () => {\n const base = await makeAdapter();\n const adapter = asConductor(base);\n if (!adapter) return;\n if (!supportsPredicate(adapter, \"status\")) return;\n await seedCard(adapter, \"queued\", \"approved\", { status: \"approved\" });\n await seedCard(adapter, \"queued\", \"draft\", { status: \"draft\" });\n\n const rule: DueRule = {\n kind: \"predicate\",\n ref: \"status\",\n op: \"=\",\n value: \"approved\",\n };\n const due = await adapter.listDueCards(BOARD, \"queued\", rule);\n expect(due.length).toBe(1);\n expect(due[0]!.title).toBe(\"approved\");\n });\n\n it(\"listDueCards {kind:'and'} requires every nested rule (the Approve gate)\", async () => {\n const base = await makeAdapter();\n const adapter = asConductor(base);\n if (!adapter) return;\n // The Approve gate combines a field_due + a predicate; skip unless the host\n // declares BOTH targets (a fail-closed host that lacks either rejects — its\n // own tests cover that).\n if (\n !supportsField(adapter, \"next_touch_at\") ||\n !supportsPredicate(adapter, \"status\")\n )\n return;\n const past = new Date(Date.now() - 60_000).toISOString();\n const future = new Date(Date.now() + 60_000).toISOString();\n // due + approved → in\n await seedCard(adapter, \"queued\", \"send-me\", {\n next_touch_at: past,\n status: \"approved\",\n });\n // due but NOT approved → out (un-approved is simply not due, §9)\n await seedCard(adapter, \"queued\", \"unapproved\", {\n next_touch_at: past,\n status: \"draft\",\n });\n // approved but NOT due → out\n await seedCard(adapter, \"queued\", \"too-early\", {\n next_touch_at: future,\n status: \"approved\",\n });\n\n const rule: DueRule = {\n kind: \"and\",\n rules: [\n { kind: \"field_due\", field: \"next_touch_at\", op: \"<=\", value: \"now\" },\n { kind: \"predicate\", ref: \"status\", op: \"=\", value: \"approved\" },\n ],\n };\n const due = await adapter.listDueCards(BOARD, \"queued\", rule);\n expect(due.length).toBe(1);\n expect(due[0]!.title).toBe(\"send-me\");\n });\n\n it(\"listDueCards honors opts.limit (caps the sweep)\", async () => {\n const base = await makeAdapter();\n const adapter = asConductor(base);\n if (!adapter) return;\n for (let i = 0; i < 5; i++) await seedCard(adapter, \"scheduled\", `c${i}`);\n\n const due = await adapter.listDueCards(\n BOARD,\n \"scheduled\",\n { kind: \"always\" },\n { limit: 2 }\n );\n expect(due.length).toBe(2);\n });\n\n it(\"listDueCards FAILS CLOSED on an unknown DueRule.kind (rejects, never returns all)\", async () => {\n const base = await makeAdapter();\n const adapter = asConductor(base);\n if (!adapter) return;\n await seedCard(adapter, \"scheduled\", \"a\");\n await seedCard(adapter, \"scheduled\", \"b\");\n\n // A kind outside the closed vocabulary must reject, not silently return\n // every card in the lane (design §6, §14.4).\n const bogus = { kind: \"everything\" } as unknown as DueRule;\n let rejected = false;\n try {\n await adapter.listDueCards(BOARD, \"scheduled\", bogus);\n } catch {\n rejected = true;\n }\n expect(rejected).toBe(true);\n });\n\n it(\"listDueCards fails closed when an unknown kind is nested inside 'and'\", async () => {\n const base = await makeAdapter();\n const adapter = asConductor(base);\n if (!adapter) return;\n await seedCard(adapter, \"scheduled\", \"a\", { status: \"approved\" });\n\n const nested = {\n kind: \"and\",\n rules: [\n { kind: \"predicate\", ref: \"status\", op: \"=\", value: \"approved\" },\n { kind: \"wat\" },\n ],\n } as unknown as DueRule;\n let rejected = false;\n try {\n await adapter.listDueCards(BOARD, \"scheduled\", nested);\n } catch {\n rejected = true;\n }\n expect(rejected).toBe(true);\n });\n\n it(\"countsByLane returns a per-lane card count for the board\", async () => {\n const base = await makeAdapter();\n const adapter = asConductor(base);\n if (!adapter) return;\n await seedCard(adapter, \"sourced\", \"a\");\n await seedCard(adapter, \"sourced\", \"b\");\n await seedCard(adapter, \"scored\", \"c\");\n\n const counts = await adapter.countsByLane(BOARD);\n expect(counts.sourced).toBe(2);\n expect(counts.scored).toBe(1);\n });\n\n it(\"capabilities() advertises dueRule fields/predicates + adapter-resolved membership\", async () => {\n const base = await makeAdapter();\n const adapter = asConductor(base);\n if (!adapter) return;\n const caps = adapter.capabilities();\n expect(caps.membership).toBe(\"adapter-resolved\");\n expect(Array.isArray(caps.dueRuleFields)).toBe(true);\n expect(Array.isArray(caps.dueRulePredicates)).toBe(true);\n });\n });\n}\n","/**\n * @cadraos/sdk/kanban/engine — the SERVER-SIDE board engine.\n *\n * Runs in the HOST BACKEND (route/worker), never the browser (design §11 R1).\n * Drives the state machine and calls exactly two things: the host\n * `KanbanStorageAdapter` for persistence, and Cadra (or a webhook) for stage\n * execution. The host writes only the adapter.\n *\n * Operations:\n * - `createCard(boardConfigUuid, input)` — resolve the ACTIVE config → insert\n * at the initial stage (pinning the version) → run the stage if it has a\n * handler.\n * - `transition(cardId, toLane?)` — load the card + its PINNED config → resolve\n * a `manual_allowed` edge (single outgoing edge when `toLane` omitted; reject\n * ambiguous) → `applyTransition` → run the new stage's handler if any.\n * - `runStage(cardId, stageId)` — `idemKey = cardId:stageId:version` →\n * `beginStageRun` (CAS; no-op if already dispatched) → dispatch the handler →\n * stamp the executionUuid on the run.\n * - `onStageComplete(idemKey, …)` — invoked by the host when a run/webhook\n * reports terminal → resolve the single `auto_on_complete` edge →\n * `completeStageRun` (idempotent advance).\n *\n * Server-safe: NO DOM / React imports.\n *\n * @module @cadraos/sdk/kanban\n */\n\nimport type { KanbanStorageAdapter } from \"../adapters/storage-types.js\";\nimport type { BoardConfigClient } from \"../config-client.js\";\nimport { toResolvedLifecycle } from \"../config-client.js\";\nimport type {\n LifecycleSource,\n ResolveLifecycleRef,\n ResolvedLifecycle,\n} from \"../lifecycle/types.js\";\nimport type { Actor, CreateCardInput, KanbanCard, KanbanLane, KanbanTransition } from \"../types.js\";\nimport {\n dispatchStageHandler,\n type BatchCardContext,\n type CadraRunClient,\n type HandlerDispatchResult,\n type WebhookDeliveryOptions,\n} from \"./handlers.js\";\n\n// Re-export the host-facing engine surface from the `@cadraos/sdk/kanban/engine`\n// entry: the storage contract, config client, handler seams, and the reference\n// in-memory adapter.\nexport type {\n AdapterCapabilities,\n KanbanStorageAdapter,\n} from \"../adapters/storage-types.js\";\nexport {\n InMemoryStorageAdapter,\n TransitionConflictError,\n UnknownDueRuleError,\n} from \"../adapters/in-memory-adapter.js\";\n// The generic HTTP-backed adapter (the cross-system drop-in, design §10) + the\n// §10-contract example host that doubles as the documented starter template.\nexport {\n HttpStorageAdapter,\n HttpAdapterError,\n CapabilitiesNotLoadedError,\n} from \"../adapters/http-adapter.js\";\nexport type {\n HttpStorageAdapterConfig,\n FetchLike,\n} from \"../adapters/http-adapter.js\";\nexport {\n exampleHostHandler,\n startExampleHost,\n} from \"../adapters/example-host.js\";\nexport type {\n ExampleHostOptions,\n HostRequest,\n HostResponse,\n} from \"../adapters/example-host.js\";\nexport { runAdapterConformance } from \"../adapters/conformance.js\";\nexport type {\n AdapterFactory,\n ConformanceExpect,\n ConformanceRunner,\n} from \"../adapters/conformance.js\";\nexport {\n BoardConfigClient,\n CadraLifecycleSource,\n mapDefinitionToBoard,\n toResolvedLifecycle,\n} from \"../config-client.js\";\nexport type {\n BoardConfigClientOptions,\n BoardConfigHttp,\n ResolvedBoardConfig,\n} from \"../config-client.js\";\n// Lifecycle source contract (p33 §3) — the pluggable read-through definition\n// the engine consumes.\nexport type {\n LifecycleRef,\n LifecycleSource,\n LifecycleSourceKind,\n ResolveLifecycleRef,\n ResolvedLifecycle,\n Stage,\n Transition,\n} from \"../lifecycle/types.js\";\nexport {\n dispatchStageHandler,\n deliverWebhook,\n hmacSign,\n WebhookDeliveryError,\n} from \"./handlers.js\";\nexport type {\n BatchCardContext,\n BatchDispatchMeta,\n CadraRunClient,\n HandlerContext,\n HandlerDispatchResult,\n RunAgentInput,\n RunRemoteAgentInput,\n RunResult,\n RunTeamInput,\n WebhookDeliveryOptions,\n WebhookSecret,\n} from \"./handlers.js\";\nexport type {\n Actor,\n ApplyTransitionInput,\n CreateCardServerInput,\n DueRule,\n KanbanLaneDispatch,\n KanbanLaneTrigger,\n StageRun,\n StageRunStatus,\n TransitionLogEntry,\n} from \"../types.js\";\n\n// =============================================================================\n// TRIGGER GATING (design §5 — Conductor mode)\n// =============================================================================\n\n/**\n * Is a lane dispatched on ENTRY (card arriving in the lane fires its handler)?\n *\n * `event` (or absent — `event` is the default) → yes, dispatch on entry exactly\n * as today. `scheduled` → no; the card waits in the lane for the timed sweep\n * (`runDueStages`). This gate is applied at every entry point — `createCard`,\n * `transition`, and `onStageComplete`'s auto-advance — so a `scheduled` lane is\n * never event-driven (design §5). Event lanes are byte-identical to today.\n */\nfunction dispatchesOnEntry(lane: KanbanLane | undefined): boolean {\n return (lane?.trigger ?? \"event\") === \"event\";\n}\n\n/**\n * Does a lane have an automated handler the engine can dispatch? (A `none` /\n * `human` / absent handler is a passive lane — nothing to run.)\n */\nfunction hasAutomatedHandler(lane: KanbanLane | undefined): boolean {\n const h = lane?.handler;\n return !!h && h.type !== \"none\" && h.type !== \"human\";\n}\n\n/**\n * Thrown by `runDueStages` when the target lane is not `scheduled` (an `event`\n * lane is never swept — it is event-driven, design §5 step 1).\n */\nexport class NotScheduledLaneError extends Error {\n readonly code = \"not_scheduled_lane\";\n constructor(laneKey: string, trigger: string) {\n super(\n `Lane \"${laneKey}\" is not scheduled (trigger=\"${trigger}\") — runDueStages only sweeps scheduled lanes`\n );\n this.name = \"NotScheduledLaneError\";\n }\n}\n\n/**\n * Thrown by `runDueStages` when the host adapter does not implement the\n * OPTIONAL Conductor-mode methods (`listDueCards` / `countsByLane` /\n * `capabilities`). Conductor mode (scheduled-lane sweeps) is OPT-IN per host\n * (design §6); an event-only host never needs them and never sweeps a\n * scheduled lane. The event/entry-dispatch path is unaffected — only the\n * scheduled sweep requires these methods.\n */\nexport class ConductorUnsupportedError extends Error {\n readonly code = \"conductor_unsupported\";\n constructor(laneKey: string) {\n super(\n `Host adapter does not implement Conductor-mode methods (listDueCards); scheduled lanes require them (lane \"${laneKey}\")`\n );\n this.name = \"ConductorUnsupportedError\";\n }\n}\n\n/**\n * The per-tick summary `runDueStages` returns for the cron/digest (design §5\n * step 5).\n */\nexport interface RunDueStagesSummary {\n /** Due cards the sweep examined this tick (after the cap). */\n swept: number;\n /**\n * Due CARDS whose handler was dispatched this tick (each created a stage-run\n * CAS). This is always counted per-CARD — in `batch` mode it is the number of\n * cards across all chunks that got dispatched, NOT the number of chunks (see\n * `batches`). So `dispatched` has the SAME meaning in both modes: how many\n * cards the sweep put in flight.\n */\n dispatched: number;\n /** Due cards already mid-run (beginStageRun CAS `created === false`). */\n skipped: number;\n /** Due cards whose dispatch threw (surfaced; the sweep continues). */\n failed: number;\n /**\n * Number of HANDLER RUNS dispatched this tick. In `per-card` mode this equals\n * `dispatched` (one run per card). In `batch` mode this is the number of\n * CHUNKS dispatched (⌈eligible / chunkSize⌉) — the no-LLM-per-lead win: many\n * cards, far fewer runs. A chunk whose dispatch throws is NOT counted here\n * (its cards are counted in `failed`).\n */\n batches: number;\n}\n\n// =============================================================================\n// EDGE RESOLUTION (pinned definition)\n// =============================================================================\n\n/**\n * The minimal resolved-definition shape the engine reads. Both\n * `ResolvedLifecycle` (the source-agnostic p33 shape) AND the legacy\n * `ResolvedBoardConfig` structurally satisfy it (`{ uuid, version, board }`),\n * so the engine helpers work with either source.\n */\ntype EngineConfig = Pick<ResolvedLifecycle, \"uuid\" | \"version\" | \"board\">;\n\n/** The immutable stage identity for a lane (p33 §10.2): `id`, falling back to `key`. */\nfunction stageIdOf(lane: KanbanLane): string {\n return lane.id ?? lane.key;\n}\n\n/** Find a lane by key in a resolved config. */\nfunction laneByKey(cfg: EngineConfig, key: string): KanbanLane | undefined {\n return cfg.board.lanes.find((l) => l.key === key);\n}\n\n/**\n * Find a lane by its immutable stage `id` (p33 §10.2) — falling back to `key`\n * for a lane authored before the stage-identity contract. Used to recover the\n * lane from an idemKey's `stageId` (which is now the immutable id).\n */\nfunction laneById(cfg: EngineConfig, stageId: string): KanbanLane | undefined {\n return cfg.board.lanes.find((l) => stageIdOf(l) === stageId);\n}\n\n/** All outgoing transitions from a lane. */\nfunction outgoing(cfg: EngineConfig, fromLane: string): KanbanTransition[] {\n return (cfg.board.transitions ?? []).filter((t) => t.fromLane === fromLane);\n}\n\n/**\n * Resolve the manual edge to take from `fromLane`.\n *\n * - `toLane` given → require a `manual_allowed` edge to that lane.\n * - `toLane` omitted → require EXACTLY ONE outgoing `manual_allowed` edge;\n * reject ambiguous (multiple) or absent.\n */\nexport function resolveManualEdge(\n cfg: EngineConfig,\n fromLane: string,\n toLane?: string\n): KanbanTransition {\n const manual = outgoing(cfg, fromLane).filter((t) => t.manualAllowed);\n if (toLane) {\n const edge = manual.find((t) => t.toLane === toLane);\n if (!edge) {\n throw new Error(\n `No manual_allowed edge from \"${fromLane}\" to \"${toLane}\"`\n );\n }\n return edge;\n }\n if (manual.length === 0) {\n throw new Error(`No manual_allowed edge from \"${fromLane}\"`);\n }\n if (manual.length > 1) {\n throw new Error(\n `Ambiguous manual transition from \"${fromLane}\": ${manual.length} outgoing edges — specify a target lane`\n );\n }\n return manual[0]!;\n}\n\n/**\n * Resolve the single `auto_on_complete` edge from `fromLane`.\n *\n * Automated stages MUST have exactly one (design §11 R5). Enforced at runtime:\n * zero → null (nothing to advance, e.g. a human stage); more than one → throw.\n */\nexport function resolveAutoEdge(\n cfg: EngineConfig,\n fromLane: string\n): KanbanTransition | null {\n const auto = outgoing(cfg, fromLane).filter((t) => t.autoOnComplete);\n if (auto.length === 0) return null;\n if (auto.length > 1) {\n throw new Error(\n `Stage \"${fromLane}\" has ${auto.length} auto_on_complete edges (expected exactly one)`\n );\n }\n return auto[0]!;\n}\n\n// =============================================================================\n// ENGINE\n// =============================================================================\n\nexport interface CreateEngineOptions {\n /** Host persistence adapter (durable cards + stage runs). */\n adapter: KanbanStorageAdapter;\n /**\n * The pluggable lifecycle source (p33 §3) — `getActive` (new cards) /\n * `getPinned` (in-flight cards). A `CadraLifecycleSource` (read-through\n * board-configs) or a `NativeLifecycleSource` (host tables). Preferred over\n * `configClient`; supply EITHER this OR `configClient` (this wins when both\n * are given).\n */\n lifecycleSource?: LifecycleSource;\n /**\n * @deprecated Prefer `lifecycleSource`. The legacy board-config client\n * (fetch/cache/pin board configs from Cadra). A `BoardConfigClient` satisfies\n * this; the engine adapts it to a `LifecycleSource` internally. Kept for\n * backward compatibility — existing callers passing `configClient` keep\n * working unchanged.\n */\n configClient?: Pick<BoardConfigClient, \"getActive\" | \"getPinned\">;\n /** Cadra run client (run agents/teams by uuid + webhook secrets). */\n cadraClient: CadraRunClient;\n /**\n * Resolve a card's PERSISTED lifecycle pin — BOTH halves (p33 §10.5 / Codex\n * R5): `(card) => ({ uuid: card.cadraLifecycleUuid, version: card.configVersion })`.\n * This is the REQUIRED host wiring for restart-safe pinning: it reads the\n * first-class persisted fields so an in-flight card keeps resolving its\n * ORIGINAL `(uuid, version)` even across an engine restart AND after the host\n * lifecycle is later re-linked to a different Cadra lifecycle — the engine\n * never repoints in-flight cards. Preferred over `resolveConfigVersion`.\n */\n resolveLifecycleRef?: ResolveLifecycleRef;\n /**\n * @deprecated Prefer `resolveLifecycleRef` (pins BOTH halves). Resolve only\n * the per-card config VERSION (the uuid is assumed to be `card.boardId`).\n * Kept for backward compatibility.\n */\n resolveConfigVersion?: (card: KanbanCard) => number | undefined;\n /** Host callback URL base for webhook completions (design §11 R4). */\n callbackUrl?: string;\n /** The default org id threaded into runs (host may override per card). */\n orgId?: number;\n /** Webhook delivery tuning (retry/backoff/fetch) — passed to handlers. */\n webhookOptions?: WebhookDeliveryOptions;\n /** Actor stamped on engine-driven (auto) transitions. Default system/engine. */\n systemActor?: Actor;\n /**\n * Board-wide ceiling on how many due cards a single `runDueStages` tick may\n * dispatch when neither `opts.limit` nor `lane.cap` is set (design §7 — caps\n * are load-bearing; a sweep never fans out to thousands). The effective cap\n * is `opts.limit ?? lane.cap ?? boardCeiling`. Defaults to\n * `DEFAULT_BOARD_CEILING` when omitted.\n */\n boardCeiling?: number;\n}\n\n/**\n * The default board ceiling applied when a scheduled lane declares no `cap` and\n * the caller passes no `opts.limit` (design §7). A finite ceiling keeps an\n * unconfigured sweep bounded rather than fanning out across the whole lane.\n */\nexport const DEFAULT_BOARD_CEILING = 200;\n\n/**\n * One card's outcome inside a batch completion (design §7). The host reports\n * the per-card result of a chunk's handler run; the engine resolves each card's\n * stage-run + advance accordingly (advance-all-on-success; a `failed` card\n * stays put).\n */\nexport interface BatchCardCompletion {\n /** The card's per-card stage-run idempotency key (`cardId:stageId:version`). */\n idemKey: string;\n /** `completed` ⇒ advance the card; `failed` ⇒ leave it + mark the run failed. */\n status: \"completed\" | \"failed\";\n /** Context patch merged on advance (completed cards only). */\n contextPatch?: Record<string, unknown>;\n /** Error message (failed cards only). */\n error?: string;\n}\n\n/** The aggregate result of fanning out a batch completion. */\nexport interface BatchCompleteResult {\n /** Cards advanced along the auto edge (status completed + applied). */\n advanced: number;\n /** Cards left in place + marked failed. */\n failed: number;\n /**\n * Cards whose completion was a no-op (already completed — a duplicate/retried\n * batch callback; idempotent, not re-advanced).\n */\n noop: number;\n}\n\nexport interface KanbanEngine {\n createCard(boardConfigUuid: string, input: CreateCardInput): Promise<KanbanCard>;\n transition(cardId: string, toLane?: string, actor?: Actor): Promise<KanbanCard>;\n runStage(cardId: string, stageId: string): Promise<{ dispatched: boolean; executionUuid?: string }>;\n onStageComplete(\n idemKey: string,\n completion: { executionUuid?: string; contextPatch?: Record<string, unknown>; actor?: Actor }\n ): Promise<{ applied: boolean }>;\n /**\n * Sweep a `scheduled` lane: ask the adapter for due cards (bounded by the\n * effective cap) and dispatch them. A `per-card` lane (default) dispatches one\n * handler run PER due card through the SAME idempotent `runStage` machinery\n * the event path uses. A `dispatch: \"batch\"` lane CHUNKS the due cards (by\n * `chunkSize ?? cap`) and dispatches ONE handler run per chunk over the card\n * LIST (design §7 — the no-LLM-per-lead routine path); per-card idempotency\n * (a stage-run CAS per card) still holds. Refuses an `event` lane\n * (`NotScheduledLaneError`). Returns a\n * `{ swept, dispatched, skipped, failed, batches }` summary (design §5/§7).\n */\n runDueStages(\n boardConfigUuid: string,\n laneKey: string,\n opts?: { limit?: number }\n ): Promise<RunDueStagesSummary>;\n /**\n * Complete a BATCH chunk's handler run (design §7): fan the per-card results\n * out across the chunk — each `completed` card advances along the lane's\n * single `auto_on_complete` edge (via the SAME idempotent\n * `completeStageRun`/`applyTransition` machinery `onStageComplete` uses), each\n * `failed` card stays put and its stage-run is marked failed. Idempotent: a\n * duplicate batch callback re-resolves already-completed cards as `noop`.\n *\n * The host calls this when the chunk's single execution reaches a terminal\n * state, passing the per-card outcomes its handler produced. `batchKey` is the\n * chunk's batch key surfaced at dispatch.\n */\n onBatchComplete(\n batchKey: string,\n completion: {\n executionUuid?: string;\n actor?: Actor;\n cards: BatchCardCompletion[];\n }\n ): Promise<BatchCompleteResult>;\n}\n\n/**\n * The engine carries the card's pinned config version through `runStage` /\n * `onStageComplete` via the stage run's `idemKey` (`cardId:stageId:version`),\n * so completions resolve the SAME pinned config the dispatch used.\n */\nfunction parseIdemKey(idemKey: string): { cardId: string; stageId: string; version: number } {\n // idemKey = cardId:stageId:version. cardId / stageId never contain ':' in\n // our id scheme; version is the trailing integer.\n const lastColon = idemKey.lastIndexOf(\":\");\n const version = Number(idemKey.slice(lastColon + 1));\n const rest = idemKey.slice(0, lastColon);\n const midColon = rest.indexOf(\":\");\n return {\n cardId: rest.slice(0, midColon),\n stageId: rest.slice(midColon + 1),\n version,\n };\n}\n\nexport function createEngine(options: CreateEngineOptions): KanbanEngine {\n const {\n adapter,\n cadraClient,\n callbackUrl,\n webhookOptions,\n } = options;\n const systemActor: Actor = options.systemActor ?? { type: \"system\", id: \"engine\" };\n\n // The pluggable lifecycle source (p33 §3). Prefer `lifecycleSource`; fall back\n // to adapting the legacy `configClient` (which returns `ResolvedBoardConfig`,\n // structurally an `EngineConfig`). Exactly one MUST be supplied.\n const source: LifecycleSource | undefined =\n options.lifecycleSource ??\n (options.configClient\n ? {\n getActive: async (uuid) =>\n toResolvedLifecycle(await options.configClient!.getActive(uuid)),\n getPinned: async (uuid, version) =>\n toResolvedLifecycle(\n await options.configClient!.getPinned(uuid, version)\n ),\n }\n : undefined);\n if (!source) {\n throw new Error(\n \"createEngine requires a `lifecycleSource` (or the deprecated `configClient`)\"\n );\n }\n\n // Per-card pinned version, recorded at createCard, kept ONLY as a within-process\n // convenience for cards created in this same process when the host has not yet\n // wired the persisted pin. It is NEVER the restart-safe pin — `resolveLifecycleRef`\n // (the persisted card fields) is. A card with a persisted ref always resolves\n // through it and never touches this map (so a re-link elsewhere can't repoint it).\n const pinnedVersions = new Map<string, number>();\n\n // batchKey → the per-card idemKeys in that chunk, so `onBatchComplete` can fan\n // the completion out over the right cards even if the host only echoes back\n // the batchKey + a subset of results. Recorded at batch dispatch. (A host that\n // persists its own chunk membership can ignore this and pass full `cards[]`.)\n const batchMembers = new Map<string, string[]>();\n\n function idemKeyFor(cardId: string, stageId: string, version: number): string {\n return `${cardId}:${stageId}:${version}`;\n }\n\n // A monotonic per-engine token so two chunks of the same (stage, version) in\n // one tick (or across ticks) get DISTINCT batch keys — the chunk is the\n // retry/partial-failure boundary, so its key must be unique to the chunk.\n let batchSeq = 0;\n function batchKeyFor(stageId: string, version: number): string {\n batchSeq += 1;\n return `batch:${stageId}:${version}:${batchSeq}`;\n }\n\n async function pinnedConfigFor(card: KanbanCard): Promise<ResolvedLifecycle> {\n // 1) PERSISTED PIN — both halves (p33 §10.5). This is the restart-safe,\n // re-link-proof path: the card's own first-class `(cadraLifecycleUuid,\n // configVersion)` fields, surfaced via `resolveLifecycleRef`. When both\n // halves are present we pin to the card's ORIGINAL lifecycle+version and\n // NEVER fall through to `getActive` — so a re-link of the host lifecycle\n // elsewhere can never repoint this in-flight card.\n const ref = options.resolveLifecycleRef?.(card);\n if (ref?.uuid && ref.version) {\n return source!.getPinned(ref.uuid, ref.version);\n }\n\n // 2) Legacy/back-compat: version-only resolver or the in-process map,\n // pinned against the card's board uuid.\n const boardConfigUuid = card.boardId;\n const version =\n options.resolveConfigVersion?.(card) ?? pinnedVersions.get(card.id);\n if (boardConfigUuid && version) {\n return source!.getPinned(boardConfigUuid, version);\n }\n if (!boardConfigUuid) {\n throw new Error(`Card ${card.id} has no boardConfigUuid to pin its config`);\n }\n // Last resort — active, when the host recorded no pin at all (a card\n // created outside the engine with no persisted ref). A card with a\n // persisted ref never reaches here.\n return source!.getActive(boardConfigUuid);\n }\n\n function cardContext(card: KanbanCard, stage: KanbanLane): Record<string, unknown> {\n return {\n task: card.title,\n context: {\n // Thread the host/tenant org as `tenantOrgId` so cadra-api scopes tool\n // calls to the tenant (X-Org-Id + per-tenant credential resolution),\n // never to the Cadra API-key org. Mirrors the chat adapter\n // (`chat/adapters/default-adapter.ts` → `context: { tenantOrgId }`).\n // When host == platform (single-org harness) this equals the Cadra org\n // and is inert; it only changes behaviour for a distinct-org tenant host.\n ...(options.orgId != null ? { tenantOrgId: options.orgId } : {}),\n kanban: {\n cardId: card.id,\n boardConfigUuid: card.boardId,\n // The IMMUTABLE stage id (p33 §10.2), falling back to `key`.\n stageId: stageIdOf(stage),\n sharedContext: card.sharedContext ?? {},\n },\n },\n };\n }\n\n /**\n * Run a stage's handler idempotently: begin the stage run (CAS), and only\n * dispatch when this call created the run. Stamps the executionUuid.\n *\n * `laneKey` addresses the lane in the engine's lane-key space (the renderer +\n * card.lane speak keys); the stage-run idemKey + the adapter's `stageId` are\n * keyed off the lane's IMMUTABLE `id` (p33 §10.2) so a `key` rename never\n * collides with a prior run.\n *\n * ★ Stranded-run recovery (design §10): if the DISPATCH throws (a transient\n * cadra-api blip), the stage-run must NOT be left `queued` — the idemKey CAS\n * (`cardId:stageId:version`) would then skip it forever, silently parking the\n * card. We `failStageRun(idemKey)` on throw so the next sweep's\n * `beginStageRun` RE-CLAIMS the failed run and re-dispatches, then re-throw so\n * the caller (the `runDueStages` per-card loop, or the event path) surfaces\n * the failure exactly as before. v1 is acyclic-only: same-lane re-entry is\n * impossible under the versioned idemKey, so a re-claim only re-runs a FAILED\n * attempt of THIS stage, never a completed one.\n */\n async function runStage(\n cardId: string,\n laneKey: string\n ): Promise<{ dispatched: boolean; executionUuid?: string }> {\n const card = await adapter.getCard(cardId);\n if (!card) throw new Error(`Card not found: ${cardId}`);\n const cfg = await pinnedConfigFor(card);\n const stage = laneByKey(cfg, laneKey);\n if (!stage) throw new Error(`Stage \"${laneKey}\" not in config ${cfg.uuid}`);\n\n const handler = stage.handler;\n if (!handler || handler.type === \"none\" || handler.type === \"human\") {\n // Passive stage — nothing to dispatch.\n return { dispatched: false };\n }\n\n // idemKey + the persisted stageId key off the IMMUTABLE stage id (p33 §10.2).\n const stageId = stageIdOf(stage);\n const idemKey = idemKeyFor(cardId, stageId, cfg.version);\n const begin = await adapter.beginStageRun(cardId, {\n stageId,\n idemKey,\n handlerType: handler.type,\n });\n if (!begin.created) {\n // Already dispatched (a retry / duplicate) — no-op.\n return { dispatched: false, executionUuid: begin.run.executionUuid };\n }\n\n let result: HandlerDispatchResult;\n try {\n result = await dispatchStageHandler(\n {\n cardId,\n boardConfigUuid: card.boardId,\n configVersion: cfg.version,\n stage,\n idemKey,\n input: cardContext(card, stage),\n orgId: options.orgId,\n callbackUrl,\n },\n cadraClient,\n webhookOptions\n );\n } catch (err) {\n // ★ Stranded-run recovery (design §10): fail the just-claimed run so the\n // next sweep re-claims + re-dispatches it (rather than leaving a `queued`\n // row the CAS skips forever), then re-throw to preserve the caller's\n // error signal.\n await adapter.failStageRun(idemKey, {\n error: err instanceof Error ? err.message : String(err),\n });\n throw err;\n }\n\n // Stamp the executionUuid on the run (status → running) so the UI can\n // stream the live run before completion. Optional adapter hook; when the\n // host doesn't implement it, the executionUuid is surfaced to the caller.\n if (result.executionUuid && adapter.markStageRunDispatched) {\n await adapter.markStageRunDispatched(idemKey, {\n executionUuid: result.executionUuid,\n });\n }\n return { dispatched: result.dispatched, executionUuid: result.executionUuid };\n }\n\n /**\n * The batch handler input: the same `task`/`context` envelope as a single\n * card, but `context.kanban.batch` carries the FULL card list so a handler /\n * agent can process all N at once (design §7). `cardId`/`task` mirror the\n * chunk's lead card for handlers that only read the top-level shape.\n */\n function batchContext(\n lead: KanbanCard,\n stage: KanbanLane,\n cards: BatchCardContext[]\n ): Record<string, unknown> {\n return {\n task: `Batch (${cards.length}) — ${stage.label}`,\n context: {\n ...(options.orgId != null ? { tenantOrgId: options.orgId } : {}),\n kanban: {\n // Lead card (representative) — keeps the single-card shape readable.\n cardId: lead.id,\n boardConfigUuid: lead.boardId,\n // The IMMUTABLE stage id (p33 §10.2), falling back to `key`.\n stageId: stageIdOf(stage),\n sharedContext: lead.sharedContext ?? {},\n // The batch payload: every card in the chunk, each with its task +\n // shared context. THIS is what a batch handler iterates.\n batch: cards.map((c) => ({\n cardId: c.cardId,\n task: c.task,\n sharedContext: c.sharedContext,\n })),\n },\n },\n };\n }\n\n /**\n * Dispatch ONE handler run over a CHUNK of cards (design §7 — batch mode).\n *\n * Per-card idempotency first: `beginStageRun` (CAS) for each card; cards\n * already mid-run (`created === false`) are EXCLUDED from the chunk, so\n * overlapping ticks never double-process a card. If every card was excluded,\n * the chunk is empty and nothing is dispatched. Otherwise ONE\n * `dispatchStageHandler` call carries the eligible card list. The chunk's\n * single `executionUuid` is stamped on every included card's stage-run, and\n * the batchKey → member idemKeys mapping is recorded for `onBatchComplete`.\n *\n * @returns the eligible card idemKeys (the ones actually dispatched) + the\n * skipped count (in-flight cards) + whether a run was dispatched.\n */\n async function runStageBatch(\n cardIds: string[],\n cfg: EngineConfig,\n stage: KanbanLane\n ): Promise<{ dispatchedKeys: string[]; skipped: number; dispatched: boolean }> {\n const handler = stage.handler;\n if (!handler || handler.type === \"none\" || handler.type === \"human\") {\n return { dispatchedKeys: [], skipped: 0, dispatched: false };\n }\n\n // idemKeys + the persisted stageId key off the IMMUTABLE stage id (p33 §10.2).\n const stageId = stageIdOf(stage);\n\n // Per-card CAS: claim each card's stage-run; exclude in-flight cards.\n const eligible: { card: KanbanCard; idemKey: string }[] = [];\n let skipped = 0;\n for (const cardId of cardIds) {\n const card = await adapter.getCard(cardId);\n if (!card) {\n // Card vanished between listDueCards and now — treat as skipped.\n skipped += 1;\n continue;\n }\n const idemKey = idemKeyFor(cardId, stageId, cfg.version);\n const begin = await adapter.beginStageRun(cardId, {\n stageId,\n idemKey,\n handlerType: handler.type,\n });\n if (!begin.created) {\n // Already mid-run — excluded from this chunk (no double-process).\n skipped += 1;\n continue;\n }\n eligible.push({ card, idemKey });\n }\n\n if (eligible.length === 0) {\n return { dispatchedKeys: [], skipped, dispatched: false };\n }\n\n const batchKey = batchKeyFor(stageId, cfg.version);\n const batchCards: BatchCardContext[] = eligible.map(({ card, idemKey }) => ({\n cardId: card.id,\n idemKey,\n task: card.title,\n sharedContext: card.sharedContext ?? {},\n }));\n batchMembers.set(batchKey, batchCards.map((c) => c.idemKey));\n\n const lead = eligible[0]!.card;\n let result: HandlerDispatchResult;\n try {\n result = await dispatchStageHandler(\n {\n cardId: lead.id,\n boardConfigUuid: lead.boardId,\n configVersion: cfg.version,\n stage,\n idemKey: eligible[0]!.idemKey,\n input: batchContext(lead, stage, batchCards),\n orgId: options.orgId,\n callbackUrl,\n batch: { batchKey, cards: batchCards },\n },\n cadraClient,\n webhookOptions\n );\n } catch (err) {\n // ★ Stranded-run recovery (design §10) for the batch path: the chunk's\n // per-card stage-runs were already CAS-claimed (`queued`) above; a chunk\n // dispatch throw must FAIL them so the next sweep re-claims + re-dispatches\n // — not leave them stranded. Then re-throw: `runDueStages`' per-chunk catch\n // counts the group as failed exactly as before.\n const msg = err instanceof Error ? err.message : String(err);\n for (const { idemKey } of eligible) {\n await adapter.failStageRun(idemKey, { error: msg });\n }\n throw err;\n }\n\n // Stamp the chunk's single executionUuid on EVERY included card's stage-run\n // so each card streams the same live run.\n if (result.executionUuid && adapter.markStageRunDispatched) {\n for (const { idemKey } of eligible) {\n await adapter.markStageRunDispatched(idemKey, {\n executionUuid: result.executionUuid,\n });\n }\n }\n\n return {\n dispatchedKeys: eligible.map((e) => e.idemKey),\n skipped,\n dispatched: result.dispatched,\n };\n }\n\n async function transition(\n cardId: string,\n toLane?: string,\n actor: Actor = { type: \"user\" }\n ): Promise<KanbanCard> {\n const card = await adapter.getCard(cardId);\n if (!card) throw new Error(`Card not found: ${cardId}`);\n const cfg = await pinnedConfigFor(card);\n\n const edge = resolveManualEdge(cfg, card.lane, toLane);\n const moved = await adapter.applyTransition(cardId, {\n fromLane: card.lane,\n toLane: edge.toLane,\n transitionId: edge.id,\n actor,\n });\n\n // If the new stage has an automated handler AND is event-triggered, run it\n // on entry. A `scheduled` destination lane is NOT dispatched here — the card\n // waits for the next sweep (`runDueStages`) (design §5 entry-dispatch gating).\n const newStage = laneByKey(cfg, moved.lane);\n if (hasAutomatedHandler(newStage) && dispatchesOnEntry(newStage)) {\n await runStage(cardId, moved.lane);\n }\n return moved;\n }\n\n async function createCard(\n boardConfigUuid: string,\n input: CreateCardInput\n ): Promise<KanbanCard> {\n const cfg = await source!.getActive(boardConfigUuid);\n const initialLane =\n input.lane ??\n cfg.board.lanes.find((l) => l.initial)?.key ??\n cfg.board.lanes[0]?.key;\n if (!initialLane) {\n throw new Error(`Config ${boardConfigUuid} has no lanes`);\n }\n\n const card = await adapter.createCard({\n ...input,\n boardConfigUuid,\n configVersion: cfg.version,\n initialLane,\n });\n pinnedVersions.set(card.id, cfg.version);\n\n // If the initial stage has an automated handler AND is event-triggered, fire\n // it on entry. A `scheduled` initial lane is NOT dispatched here — the card\n // waits for the next sweep (`runDueStages`) (design §5 entry-dispatch gating).\n const initialStage = laneByKey(cfg, initialLane);\n if (hasAutomatedHandler(initialStage) && dispatchesOnEntry(initialStage)) {\n await runStage(card.id, initialLane);\n }\n return (await adapter.getCard(card.id)) ?? card;\n }\n\n async function onStageComplete(\n idemKey: string,\n completion: { executionUuid?: string; contextPatch?: Record<string, unknown>; actor?: Actor }\n ): Promise<{ applied: boolean }> {\n const { cardId, stageId, version } = parseIdemKey(idemKey);\n const card = await adapter.getCard(cardId);\n if (!card) throw new Error(`Card not found: ${cardId}`);\n\n // Resolve the SAME pinned config the dispatch used. Prefer the card's\n // persisted ref (re-link-proof), else the idemKey's (uuid:version) pin.\n const ref = options.resolveLifecycleRef?.(card);\n const boardConfigUuid = card.boardId;\n const cfg = ref?.uuid && ref.version\n ? await source!.getPinned(ref.uuid, ref.version)\n : boardConfigUuid && version\n ? await source!.getPinned(boardConfigUuid, version)\n : await pinnedConfigFor(card);\n\n // The idemKey's `stageId` is the IMMUTABLE stage id (p33 §10.2); recover the\n // lane to resolve its auto edge in the engine's lane-KEY space (transitions\n // + card.lane speak keys). Falls back to treating `stageId` as a key.\n const stageLane = laneById(cfg, stageId);\n const autoEdge = resolveAutoEdge(cfg, stageLane?.key ?? stageId);\n const applied = await adapter.completeStageRun(idemKey, {\n executionUuid: completion.executionUuid,\n toLane: autoEdge?.toLane,\n contextPatch: completion.contextPatch,\n actor: completion.actor ?? systemActor,\n });\n\n // Entry-dispatch gating (design §5): the auto-advance just landed the card\n // in `autoEdge.toLane`. The engine does NOT chain-dispatch the downstream\n // lane's handler here — and it especially MUST NOT for a `scheduled`\n // downstream lane (that card waits for the next sweep). This is made\n // explicit so any future chaining respects `dispatchesOnEntry`: only an\n // `event` lane would ever be a candidate for chain-dispatch; a `scheduled`\n // lane is always picked up by `runDueStages`, never on completion.\n void dispatchesOnEntry; // gate reference — see the rule above.\n return applied;\n }\n\n /**\n * Complete a BATCH chunk's run (design §7): fan the per-card outcomes out over\n * the chunk's cards. Each `completed` card advances along its single\n * `auto_on_complete` edge via the SAME idempotent `onStageComplete` path; each\n * `failed` card is left in place and its stage-run marked failed. Idempotent —\n * a re-delivered batch callback re-resolves already-completed cards as `noop`\n * (the stage-run CAS in `completeStageRun` does not re-advance).\n *\n * The host passes the per-card results its handler produced. If it omits\n * `cards` (or passes a partial list) the engine falls back to the recorded\n * chunk membership and treats any unreported member as `completed` (the\n * advance-all default) — so a host that only signals \"the batch finished\" gets\n * advance-all for free.\n */\n async function onBatchComplete(\n batchKey: string,\n completion: {\n executionUuid?: string;\n actor?: Actor;\n cards: BatchCardCompletion[];\n }\n ): Promise<BatchCompleteResult> {\n const reported = new Map(completion.cards.map((c) => [c.idemKey, c]));\n const members = batchMembers.get(batchKey) ?? [];\n\n // The set of cards to resolve = the recorded chunk members ∪ any explicitly\n // reported idemKeys (a host that tracks its own membership may report cards\n // the engine didn't record, e.g. after a restart).\n const allKeys = new Set<string>([...members, ...reported.keys()]);\n\n let advanced = 0;\n let failed = 0;\n let noop = 0;\n\n for (const idemKey of allKeys) {\n // Default unreported members to `completed` — advance-all-on-success.\n const outcome = reported.get(idemKey) ?? { idemKey, status: \"completed\" as const };\n if (outcome.status === \"failed\") {\n await adapter.failStageRun(idemKey, {\n error: outcome.error ?? \"batch card failed\",\n });\n failed += 1;\n continue;\n }\n const res = await onStageComplete(idemKey, {\n executionUuid: completion.executionUuid,\n contextPatch: outcome.contextPatch,\n actor: completion.actor,\n });\n if (res.applied) advanced += 1;\n else noop += 1;\n }\n\n // Chunk is fully resolved — drop the membership record.\n batchMembers.delete(batchKey);\n return { advanced, failed, noop };\n }\n\n /**\n * Sweep one `scheduled` (board, lane): ask the adapter for the DUE cards\n * (bounded by the effective cap) and dispatch each through the SAME idempotent\n * `runStage` machinery the event path uses. The engine owns: resolve lane →\n * ask adapter for due cards → drive the idempotent dispatch. It does NOT own\n * the clock (host cron), the due SQL (adapter), or judgment (design §5).\n */\n async function runDueStages(\n boardConfigUuid: string,\n laneKey: string,\n opts?: { limit?: number }\n ): Promise<RunDueStagesSummary> {\n // Conductor mode is OPT-IN per host (design §6). Guard up-front: if the\n // adapter doesn't implement the Conductor-mode methods, a scheduled sweep\n // is impossible — fail with a clear typed error rather than a `not a\n // function` TypeError. The event/entry-dispatch path never reaches here.\n if (!adapter.listDueCards) {\n throw new ConductorUnsupportedError(laneKey);\n }\n\n const cfg = await source!.getActive(boardConfigUuid);\n const lane = laneByKey(cfg, laneKey);\n if (!lane) {\n throw new Error(`Lane \"${laneKey}\" not in config ${cfg.uuid}`);\n }\n\n // §5 step 1 — event lanes are NEVER swept; refuse with a typed error.\n const trigger = lane.trigger ?? \"event\";\n if (trigger !== \"scheduled\") {\n throw new NotScheduledLaneError(laneKey, trigger);\n }\n\n // §5 step 3 — caps are load-bearing: opts.limit ?? lane.cap ?? boardCeiling.\n const effectiveCap =\n opts?.limit ?? lane.cap ?? options.boardCeiling ?? DEFAULT_BOARD_CEILING;\n\n // A scheduled lane MUST carry a dueRule; without one there is nothing to\n // push down — treat as a misconfiguration (publish-time validation in\n // STORY-003 prevents this, but the engine fails closed rather than sweep\n // the whole lane).\n if (!lane.dueRule) {\n throw new Error(\n `Scheduled lane \"${laneKey}\" has no dueRule — nothing to push down (config ${cfg.uuid})`\n );\n }\n\n // §5 step 2 — push the declared dueRule down to the adapter; honor the cap\n // as the query LIMIT so the read is bounded. `listDueCards` is guaranteed\n // present (guarded at the top of this function).\n const dueCards = await adapter.listDueCards!(\n boardConfigUuid,\n laneKey,\n lane.dueRule,\n { limit: effectiveCap }\n );\n\n let dispatched = 0;\n let skipped = 0;\n let failed = 0;\n let batches = 0;\n\n const mode = lane.dispatch ?? \"per-card\";\n\n if (mode === \"batch\") {\n // §7 — BATCHED dispatch: chunk the due cards (by `chunkSize ?? cap`) and\n // dispatch ONE handler run per chunk over the card LIST. Per-card\n // idempotency is preserved INSIDE the chunk (a stage-run CAS per card;\n // in-flight cards are excluded), so overlapping ticks never double-process\n // a card — only far fewer handler runs (the no-LLM-per-lead win). A whole\n // chunk's dispatch failing is isolated: those cards count as `failed` and\n // the sweep continues with the next chunk.\n const stage = lane; // `lane` is the resolved scheduled stage.\n const chunkSize = Math.max(1, lane.chunkSize ?? effectiveCap);\n for (const group of chunk(dueCards, chunkSize)) {\n try {\n const res = await runStageBatch(\n group.map((c) => c.id),\n cfg,\n stage\n );\n dispatched += res.dispatchedKeys.length;\n skipped += res.skipped;\n if (res.dispatched) batches += 1;\n } catch {\n // The whole chunk's dispatch threw — count every card in it as failed.\n failed += group.length;\n }\n }\n } else {\n // §5 step 4 — per-card dispatch (default): each due card through the\n // existing runStage flow (idemKey CAS → already-running cards skipped, so\n // overlapping/back-to-back ticks never double-dispatch). Per-card failures\n // are isolated: the sweep continues and surfaces the count. `batches`\n // tracks runs and equals `dispatched` here (one run per card).\n for (const card of dueCards) {\n try {\n const res = await runStage(card.id, laneKey);\n if (res.dispatched) {\n dispatched += 1;\n batches += 1;\n } else {\n // Not dispatched = a CAS skip (already mid-run) for an automated lane.\n skipped += 1;\n }\n } catch {\n failed += 1;\n }\n }\n }\n\n // §5 step 5 / §7 — summary for the cron/digest. `swept` is what we examined\n // this tick (post-cap); dispatched + skipped + failed partition it by CARD.\n // `batches` is the number of handler RUNS (chunks in batch mode; == dispatched\n // in per-card mode).\n return { swept: dueCards.length, dispatched, skipped, failed, batches };\n }\n\n return {\n createCard,\n transition,\n runStage,\n onStageComplete,\n onBatchComplete,\n runDueStages,\n };\n}\n\n/**\n * Split `items` into chunks of at most `size` (the last chunk may be smaller).\n * `size` is assumed ≥ 1 (the caller clamps it).\n */\nfunction chunk<T>(items: T[], size: number): T[][] {\n const out: T[][] = [];\n for (let i = 0; i < items.length; i += size) {\n out.push(items.slice(i, i + size));\n }\n return out;\n}\n"]}