Skip to content

Support durable human approval gates in authored TypeScript flows #400

Description

@willwashburn

Problem

Software-factory onboarding needs a real human approval gate after automated review, before any merge or other follow-up action. The authored TypeScript surface exposes f.human(question, { to }), but the authored executor currently throws unsupported_verb when it is called.

Verified against the repository's default-branch source on September 14, 2026:

Minimal reproduction

Save as human-gate.flow.mts:

import { flow } from "@relayflows/surface";

export default flow<{ approver: string }>("human-gate", {}, async (f, input) => {
  const approved = await f.human("Approve this PR?", { to: input.approver });
  if (!approved) return f.done("canceled");
  f.done("success");
});
flows run --local-agent human-gate.flow.mts --input '{"approver":"owner"}'

The failure is established by source inspection; this issue does not claim a live agent execution was performed.

Expected behavior / acceptance criteria

  • Reaching f.human() creates a durable pending approval and parks the run instead of failing.
  • The local CLI exposes a documented way for the intended human to inspect the request and approve or reject it. Include enough context to identify the run and PR under review.
  • Approval resolves the call to true; rejection resolves it to false. No operation after the gate runs before a decision.
  • Approval authority is enforced; an agent's output cannot satisfy the human gate.
  • The decision and its actor are recorded in the journal. Restart/resume preserves the pending request and recorded decision without repeating earlier agent work or PR creation.
  • Duplicate or conflicting decisions are handled safely and predictably.
  • Tests cover approval, rejection, noninteractive operation, persistence across restart, and safe resume.

Current onboarding workaround

The local download currently uses return f.done("needs_human") and tells the user to inspect and merge the PR manually in GitHub. This records a handoff, but does not supply the boolean decision or continuation promised by f.human().

Scope: implement the authored/direct runner's human gate and its local approval interface. Cloud approval delivery can use the same durable decision model; Cloud runtime support was not verified as part of this finding.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions