Intermediate~14 minHazelJS
Human Approval Gate
Pause a HazelJS AgentRun with durableSuspend before high-impact tools until a human approves or rejects via approveAndResume.
- Authors
- editorial-team
- Published
- Last reviewed
Problem
Some tool calls are irreversible or high-impact; full autonomy creates unacceptable blast radius.
Context
Payments, production changes, customer communications, data deletion, privilege changes—any write PolicyEngine marks as require_approval inside Agent OS.
Forces and constraints
- Autonomy improves speed
- Humans remain accountable for certain risks
- Approval UX must be fast or people rubber-stamp
- Paused runs must survive process restarts (durable AgentRun store)
Recommended design
PolicyEngine marks tools as gated. When proposed, AgentRuntime with durableSuspend: true persists a SUSPENDED AgentRun (createDurableRunStore or createSqlDurableRunStore), returns waiting state to the caller, and notifies reviewers. On approveAndResume(runId, { approved, approvedBy }), execute the tool with the same idempotency semantics; on reject, cancel without side effects.
Minimal pseudocode
import {
AgentRuntime, PolicyEngine, createDurableRunStore,
} from '@hazeljs/agent';
const store = createDurableRunStore('./.hazel/runs');
const runtime = new AgentRuntime({
runRepository: store.runRepository,
durableSuspend: true,
policyEngine: new PolicyEngine(/* require_approval on refund_charge */),
});
const waiting = await runtime.execute('BillingAgent', { intent: 'refund' });
// waiting.status === SUSPENDED — notify approver with redacted args
const done = await runtime.approveAndResume(waiting.executionId, {
approved: true,
approvedBy: 'lead@example.com',
});Failure modes
- Approvers rubber-stamp due to alert fatigue
- Approval payloads leak secrets in email/Slack
- Timeouts leave runs stuck without escalation
- Approve-after-expiry executes stale actions
- In-memory-only runtime (no durable store) loses HITL across restarts
Security considerations
- Authenticate approvers; dual control for critical classes
- Redact secrets and PII in approval channels
- Bind approval to executionId + tool hash; prevent replay
- Audit trail of who approved what and when (AgentRun + observability)
Observability signals
- Metrics: approval latency, reject rate, timeout rate
- Inspector getTimeline links suspended step to resume
- Alert on stuck SUSPENDED runs past SLA
Evaluation approach
Policy coverage tests (gated tools never auto-fire without approveAndResume); UX time-to-approve; sample reviews of approval quality.
Trade-offs
- Safety and accountability vs latency and throughput
- Too many gates recreate a manual process