Approvals
HITL Workflow
Any AI reply can be routed through human review before it reaches the user. HITL covers sensitive topics, low-confidence answers, and intents the system has not yet learned to trust.
When HITL Is Triggered
A reply is routed to HITL if any of these apply:
- Low confidence — RAG confidence score below 0.7.
- Trigger word — the user message or reply contains a configured trigger (e.g.
конфлікт,суд,штраф,звільнення,lawsuit,termination). - Novel interaction — first time this employee hits this intent.
- Trust not established — the intent has not reached the autonomous threshold yet.
- Stochastic sampling — autonomous intents still route a fraction (default 10%) to HITL for ongoing validation.
- Injection detected — prompt injection patterns found in the user message or RAG context.
Approval Status Flow
pending → approved (send to user)
→ rejected (discard, log reason)
→ edited (content modified)
→ escalated (routed to higher role)
Actions
Approve
Approve the AI reply as-is. The reply is queued for delivery to the channel.
POST /api/v1/approvals/:id/approve
Approve with Edit
Approve a modified reply. editedContent replaces the original.
POST /api/v1/approvals/:id/approve
Body: { "editedContent": "Modified response text" }
Reject
Reject the reply. Nothing is sent to the user. The approver can add notes.
POST /api/v1/approvals/:id/reject
Body: { "reason": "Inaccurate information about policy X" }
Escalate
Route the approval to a higher role (e.g. approver → dept_head).
POST /api/v1/approvals/:id/escalate
Body: { "escalatedToId": "<user-id>", "reason": "Legal question, needs dept head review" }
Trust Matrix Update
On approval:
- The intent's
successfulCountis incremented. - Once
successfulCount >= threshold(default 5),isAutonomousflips totrue. - Future messages for this intent may bypass HITL, subject to
samplingRate.
See Auto-Bypass for the full flow.
Viewing Approvals
Approval detail includes:
- Original AI reply
- RAG sources used (chunks, documents, scores)
- Classified intent
- Confidence score
- Conversation context
GET /api/v1/approvals/:id
Audit Trail
Every approval action is written to the audit log:
approve,reject,escalateactions- Actor (approver user)
- Timestamp
- Edits or notes
Batch Approvals
Handle multiple approvals in one call during high-volume periods.
Endpoint
POST /api/v1/approvals/batch
Request
{
"decisions": [
{ "approvalId": "approval-1", "action": "approve" },
{ "approvalId": "approval-2", "action": "approve", "editedContent": "Modified response" },
{ "approvalId": "approval-3", "action": "reject", "reason": "Inaccurate" }
]
}
Constraints
- Maximum 50 decisions per request
- Each decision is processed independently — partial failures are possible
- Auth: permission
canApprove
Response
Returns results for each decision with success/failure status:
{
"results": [
{ "approvalId": "approval-1", "status": "success" },
{ "approvalId": "approval-2", "status": "success" },
{ "approvalId": "approval-3", "status": "success" }
]
}
Use Case
The frontend approval queue supports batch selection. Approvers pick multiple pending items and approve or reject them in one shot. Useful for routine queries queued up during off-hours.
Auto-Bypass (Trust Matrix)
The trust matrix gives the assistant gradual autonomy. As approvers validate replies for a given intent, the system learns which intents are safe to auto-send.
Trust Matrix Model (IntentTrust)
Each namespace + intent pair has a trust record:
| Field | Default | Description |
|---|---|---|
successfulCount | 0 | Approved replies so far |
threshold | 5 | Approvals needed for autonomy |
isAutonomous | false | Auto-send enabled |
samplingRate | 0.1 | Fraction still sent to HITL (10%) |
Autonomy Decision Flow
1. Message received
2. Intent classified (vector similarity)
3. Check confidence fallback:
a. Confidence < 0.7 → FORCE HITL
b. Trigger word detected → FORCE HITL
c. First interaction for this intent → FORCE HITL
4. If fallback triggered → create Approval, wait for human
5. Check trust matrix:
a. Not autonomous → HITL
b. Autonomous + random() > samplingRate → AUTO-SEND
c. Autonomous + random() <= samplingRate → HITL (sampling)
Confidence Fallback
Implementation: src/channels/bypass.ts
Three conditions always force HITL, even for autonomous intents:
- Low confidence — RAG confidence below 0.7.
- Trigger words — keywords from
INTENT_TRIGGER_WORDSthat mark sensitive topics. - Novel interaction — employee's first message classified to this intent.
Stochastic Sampling
Even fully autonomous intents send a fraction of replies (default 10%) to HITL. This gives you:
- Continuous quality validation
- Drift detection
- Ongoing training signal
samplingRate is configurable per intent.
Trust Progression Example
Intent: "leave_policy"
Namespace: "hr"
Day 1: 0/5 approved → HITL for all
Day 2: 3/5 approved → HITL for all
Day 3: 5/5 approved → autonomous, 90% auto-send
Day 30: 150 total → autonomous, 90% auto-send (with 15 sampled HITL reviews)
API
View Trust Matrix
GET /api/v1/intents/trust?namespaceId=<id>
Returns every intent trust record for the namespace.
Auth: permission canManageNamespaces.
Reset Trust
To disable autonomy for an intent, update the trust row directly in the database to set isAutonomous: false and successfulCount: 0. There is no API endpoint for this yet.
Configuration
Trigger words come from the environment:
INTENT_TRIGGER_WORDS=конфлікт,суд,штраф,звільнення,скарга,позов,conflict,lawsuit,fine,termination,complaint