LaufwerkLaufwerk

Human decisions

Pause a workflow, review the context, then continue with a recorded answer.

A human decision belongs at a meaningful boundary: before returning a candidate, accepting a report or authorizing the next step. Give the reviewer the actual evidence.

A complete small example

Create laufwerk/workflows/decision/workflow.ts in your initialized project:

import { Workflow } from "@effect/workflow";
import { Human } from "@laufwerk/sdk";
import { Effect, Schema } from "effect";

export const workflow = Workflow.make({
  name: "decision",
  payload: { executionKey: Schema.String },
  success: Schema.String,
  error: Schema.String,
  idempotencyKey: input => input.executionKey,
});

export const layer = workflow.toLayer(() => Effect.gen(function* () {
  const accepted = yield* Human.confirm({
    key: "accept",
    title: "Accept this demonstration result?",
    description: "This records a local decision. Nothing will be published.",
  });
  return accepted ? "accepted" : "declined";
}).pipe(Effect.mapError(String)));

Run from the project root:

bun run --cwd laufwerk check
bunx laufwerk@0.0.1-alpha.6 run decision --input '{"executionKey":"decision-1"}'

Expect waiting and one pending confirmation. This command can exit successfully while the workflow waits.

Run → waiting for your decision → accepted or declined → completed

Respond in Studio

Run bunx laufwerk@0.0.1-alpha.6 studio, open the printed URL, and review the run's pending interaction. Answer it there. The workflow continues with the recorded answer.

Or use the CLI

The run output shows both IDs. Replace RUN_ID and INTERACTION_ID with those exact values:

bunx laufwerk@0.0.1-alpha.6 respond RUN_ID INTERACTION_ID --response '{"kind":"confirmation","value":true}'
bunx laufwerk@0.0.1-alpha.6 status RUN_ID

Use false to decline. The response must be the typed object, not a bare Boolean. Text requests use {"kind":"text","value":"your answer"}; choices use {"kind":"single-choice","value":"AN_OFFERED_VALUE"}.

approve is the separate convenience command for an agent's tool approval. It is not a replacement for Human.confirm.

An answer of “declined” can correctly finish the workflow. Business acceptance and runtime completion are different things.

Inspect and debug runs →

On this page