Human gates
A human gate is a node with shapehexagon that pauses the workflow and presents the user with a choice. The options are derived from the outgoing edge labels:
Keyboard accelerators
The prefixes[A], [R], [S] in edge labels serve as keyboard accelerators. Fabro supports three formats:
When matching the user’s selection to an edge, Fabro strips the accelerator prefix so typing
A matches [A] Approve.
Freeform input
In addition to fixed choices, a human gate can accept freeform text input. Add an edge withfreeform=true:
human.gate.text in the run context.
When a gate has only a freeform edge and no fixed choices, the user goes directly to a text input prompt — skipping the multiple-choice menu entirely. This is useful for conversational loops like REPL workflows where the user provides open-ended instructions each iteration.
Question types
Human gates infer their interview type from their edges: fixed choices becomemultiple_choice, and a gate with only a freeform edge becomes freeform. To force another interviewer presentation, set question_type on the node:
yes_no, confirmation, multiple_choice, multi_select, and freeform.
Review targets
A human gate can present one external document as the primary review link. Setreview_target=true on the gate:
review_target context key. A routing response can do this directly:
Review the Quarry review exercise document, then choose the next action.The link uses the target URL from context. The example uses a placeholder secret, not a live Quarry document. Fabro generates this question text from the target. A
label on the gate is
not used while review_target=true.
The target object has three required fields:
Fabro validates the target before it starts the interview. A missing or invalid
target fails the gate deterministically. A gate without
review_target=true
ignores this context key and keeps its normal label.
The context value remains available after the human answers. A feedback loop
can return to the same gate without recreating the target. A later stage can
replace the target by writing a new value to the same context key.
Fabro does not fetch the URL. Web and Slack clients open it as an external link.
Treat bearer-capability links as secrets and only provide them to people who
can access the run.
Default choice on timeout
If a human gate has a timeout configured, you can specify a default choice using thehuman.default_choice attribute:
Unanswered gates fail closed
Fabro does not treat missing input as approval. A human gate advances only when one of these happens:- A person explicitly answers the question
- The gate times out and
human.default_choiceis set - The run uses
--auto-approve
condition="outcome=failed" or a retry_target.
Auto-approve
For testing or fully automated runs, pass--auto-approve to skip all human gates:
Yes for yes/no gates and the first option for multiple-choice gates.
Where to place human gates
Human gates are most valuable at high-leverage decision points:- Before implementation — Approve a plan before the agent writes code
- After review — Confirm that a code review’s findings are worth fixing
- At branch points — Choose a strategy when multiple approaches are viable
- Before external actions — Approve before deploying, merging, or sending notifications
Context set by human gates
When a user makes a selection, the human gate sets several context values for downstream use:
These can be read in edge conditions or referenced by downstream agents.