Compliance & Audit
AI agents your compliance team will actually approve
Human-in-the-loop approvals, auditable thread history, and deterministic testing โ built into the framework, not bolted on.
The problem
Why this is hard today.
Black-box AI decisions
Regulators require explainability. Most agent frameworks stream opaque outputs with no tool-call history.
No human gate before action
SOX, HIPAA, and GDPR demand human approval before consequential actions. Retrofitting interrupts is a rewrite.
Untestable agent behavior
Compliance needs reproducible test evidence. Non-deterministic LLM calls make that nearly impossible without the right tooling.
Architecture
How the three libraries compose.
Three libraries give your compliance team what they need โ without slowing your engineering team down.
Agent
@threadplane/langgraphProduction agent state with first-class interrupt support. Every agent action can require human approval before execution. Durable thread persistence preserves the full record of every tool call and state transition.
See Agent docs โRender
@threadplane/renderApproval workflows rendered as structured UI โ not chat messages. The agent proposes an action, renders a confirmation card, and waits for the human gate before proceeding.
See Render docs โChat
@threadplane/chatDebug overlay shows every tool call, interrupt, and state transition. Your compliance team can review exactly what happened, when, and why โ in a UI they can understand.
See Chat docs โWhat you ship
Capabilities the framework delivers.
Agent action recorded โ tool calls, interrupts, and state transitions captured in the thread record
Each approval is written into the checkpoint beside the action it gated โ the decision and the proposal are one record
Thread persistence preserves the full decision path for review by auditors and your compliance team
In practice
What it looks like in your codebase
audit-trail.component.ts โ reading the thread record
export class AuditTrailComponent {
private readonly agent = injectAgent(REVIEW_AGENT);
// Runtime-neutral timeline: every checkpoint the thread passed through.
readonly checkpoints = computed(() => this.agent.history());
// Raw LangGraph ThreadState[], for the fields an auditor asks about.
private readonly raw = computed(() => this.agent.langGraphHistory());
// The decisions themselves, lifted out of the checkpoint values. Each row
// pairs what was proposed with what a human answered, and when.
readonly approvals = computed(() =>
this.raw()
.filter((state) => state.values?.['approval_result'])
.map((state) => ({
at: state.created_at,
action: state.values['proposed_action'],
decision: state.values['approval_result'],
})),
);
}audit-trail.component.html
<table class="audit">
@for (row of approvals(); track row.at) {
<tr>
<td>{{ row.at | date: 'medium' }}</td>
<td>{{ row.action.description }}</td>
<td>{{ row.decision.approved ? 'Approved' : 'Rejected' }}</td>
<td>{{ row.decision.reason }}</td>
</tr>
}
</table>
<p class="muted">{{ checkpoints().length }} checkpoints on this thread.</p>See it running
The approval gate, in the product
The agent proposes a destructive action, the graph pauses, and nothing runs until a human approves it.
Recorded from the live demo, which you can drive yourself.
Field report
The last-mile gap in Angular AI.
- Six production-readiness dimensions for Angular AI
- Concrete patterns โ error boundaries, fallbacks, observability, deploy
- No vendor pitch. Just what we learned shipping it.
Already on the list? Download the PDF directly.
Ship compliant AI agents โ without the compliance tax
Download the field report or start a pilot. Your compliance team will thank you.