Metronisys Human Approval Tool/Skill
Article text.
What it is
human_approval is a built-in tool (not a .skill file). It acts as a human-in-the-loop gate: the agent can “call” it when a step needs human sign-off before continuing.
In practice, the real approval flow is driven by policy (soul + profile), not by the model choosing to call human_approval; the tool is the stub that returns a “pending” result when the system has already decided approval is required.
What it does
As a callable tool (stub)
When the agent (or capability resolver) selects human_approval, the handler runs and returns a pending result.
It does not wait for a real human or UI; it just returns structured data so the rest of the stack can pause the run and record that approval was requested.
Two approval types
- client – approval of an agent output or action (e.g. “send this email”, “write this file”). The operator approves.
- compliance_officer – approval of builder changes (e.g. skill/prompt/rule/policy updates). Only this role is valid for approval.
Stub behaviour
The implementation returns:
status: "pending"state: "pending"approval_type- Optional
run_id - A message indicating this is a stub (no real gate)
For approval_type == "compliance_officer", it also includes:
required_approver_role_idrequired_approver_role_name
In short: it declares that this step is a human-approval gate and returns a pending result. The decision itself is made earlier by the policy engine.
How it works (end-to-end)
1. When is approval required?
Approval is required when the policy engine returns:
AuthorizationResult(allowed=True, requires_human_approval=True)
This happens in two ways:
Profile-level
If the policy profile has require_human_approval: true, then all allowed tools (except exempt ones like unit_conversion, current_datetime, system_health_check) require approval.
Soul-level
Defined in soul.yaml using human_approval_required rules. These match:
- Tool name
- Optional path conditions
Each rule sets approval_type as either client or compliance_officer.
So the same tool (e.g. write_file) may or may not require approval depending on configuration.
2. When a tool requires approval
The tool executor:
- Checks authorization
- If approval is required and not yet granted, it does not execute the tool
Instead, it returns:
ok: true_approval_metadata(tool name, params, approval type)- A message explaining the reason
This effectively pauses execution.
3. Handling approval metadata
When _approval_metadata is returned:
- A checkpoint is saved (with run state, memory snapshot, etc.)
- Audit events are logged (ISO-style)
- The run is marked as pending
Later, a user or UI resumes the process via:
resume_after_approval(approval_id, approved=True|False)
4. Resume after approval
If approved:
- The original tool (e.g.
write_file) is executed - If the step was
human_approvalitself, it is not re-run - A synthetic “approved” result is injected
If rejected:
- The checkpoint is closed
- No tool is executed
All decisions are logged for audit.
5. Workflow skip logic
If approval has already been granted in a workflow:
- Further steps do not require repeated approval
- The executor proceeds normally
Where it sits in the solution
| Layer | Role of human_approval |
|---|---|
| Tool registry | Registered as a built-in tool with metadata (tags: approval, governance, human) |
| Policy / soul | Defines which actions require approval |
| Capability resolver | Uses human_approval only when necessary |
| ReAct / guardrails | Treats its output specially; avoids retries |
| Tool executor | Returns approval metadata instead of executing tools |
| Main app / API | Saves checkpoints, logs events, resumes workflows |
| Audit system | Tracks full lifecycle (request → decision → resume) |
Summary
human_approval represents a human gate in the workflow. The real logic—blocking execution, saving state, resuming, and auditing, is handled by:
- Policy engine
- Tool executor
- Main application
- Checkpoint + audit systems
The tool itself is a lightweight stub that simply returns a structured “pending” response and approval metadata.