Human Review Queue¶
HumanReviewQueue is a durable human-in-the-loop gate for halted outputs and
post-halt correction proposals. It is separate from ReviewQueue, which is only
the continuous batching queue for scorer throughput.
The queue stores pending cases, reviewer decisions, release decisions, and retry requests in SQLite. Candidate text is never included in default audit payloads; callers must explicitly request it when they are inside the tenant boundary.
from director_ai import HumanReviewQueue
queue = HumanReviewQueue("review.db")
case = queue.enqueue_case(
candidate_text="Corrected answer that still needs review.",
evidence_refs=("kb://policy-42", "trace://halt-17"),
tenant_id="tenant-a",
request_id="req-123",
source_kind="halt",
reason="coherence halt",
)
queue.decide(
case.case_id,
reviewer_id="reviewer-1",
action="approve",
reason="source verified",
)
released_text = queue.release(
case.case_id,
reviewer_id="reviewer-1",
release_id="release-20260513-001",
)
Correction Proposals¶
Use enqueue_correction_proposal() to connect the queue to
CorrectionLoop. The correction loop still supplies verifier consensus and an
unreleased candidate; the human review queue supplies durable reviewer approval
and release audit.
case = queue.enqueue_correction_proposal(
proposal,
tenant_id="tenant-a",
request_id="req-123",
reason="post-halt correction proposal",
)
State Transitions¶
| Current status | Allowed action | New status | Release text available |
|---|---|---|---|
pending |
approve |
approved |
No |
approved |
release() |
released |
Yes |
pending |
reject |
rejected |
No |
pending |
request_retry |
retry_requested |
No |
Rejected, retry-requested, and released cases cannot be re-decided. release()
requires an approved case, a reviewer id, and a release id.
Retry Gate¶
retry_payload() is available only after a reviewer requests retry. It returns
tenant-safe routing context and evidence references, never candidate text.
queue.decide(
case.case_id,
reviewer_id="reviewer-1",
action="request_retry",
reason="needs fresher source",
metadata={"retry_budget": 1},
)
payload = queue.retry_payload(case.case_id)
Tenant-Safe Audit¶
HumanReviewCase.to_dict() excludes candidate_text by default:
Use include_candidate=True only inside a tenant-controlled review surface.
Full API¶
director_ai.core.runtime.human_review.HumanReviewQueue
¶
SQLite-backed human review queue with gated release and retry paths.
enqueue_case
¶
enqueue_case(*, candidate_text: str, evidence_refs: Sequence[str], tenant_id: str = '', request_id: str = '', source_kind: str = 'halt', reason: str = '', safety_event: SafetyEvent | Mapping[str, Any] | None = None, metadata: Mapping[str, str] | None = None, case_id: str | None = None) -> HumanReviewCase
Add a pending review case.
enqueue_correction_proposal
¶
enqueue_correction_proposal(proposal: CorrectionProposal, *, tenant_id: str = '', request_id: str = '', reason: str = '', metadata: Mapping[str, str] | None = None) -> HumanReviewCase
Queue a correction proposal for human release approval.
list_cases
¶
list_cases(*, status: ReviewStatus | None = None, tenant_id: str | None = None, limit: int = 0) -> list[HumanReviewCase]
List cases, newest first, optionally filtered by status or tenant.
decide
¶
decide(case_id: str, *, reviewer_id: str, action: str, reason: str = '', metadata: Mapping[str, str] | None = None) -> HumanReviewCase
Apply a reviewer decision and append it to the audit trail.
release
¶
Return candidate text only after a case has been approved.
retry_payload
¶
Return tenant-safe retry instructions only after retry approval.
decisions
¶
Return append-only decision history for one case.
director_ai.core.runtime.human_review.HumanReviewCase
dataclass
¶
HumanReviewCase(case_id: str, status: ReviewStatus, source_kind: str, candidate_text: str, evidence_refs: Sequence[str], tenant_id: str = '', request_id: str = '', reason: str = '', safety_event: Mapping[str, Any] | None = None, metadata: Mapping[str, str] = dict(), release_id: str = '', created_at: float = time.time(), updated_at: float = time.time())
Durable case awaiting explicit reviewer decision.
to_dict
¶
Serialise a tenant-safe case payload.
Candidate text is excluded by default because review queues commonly feed dashboards, alerts, and audit exports outside the tenant boundary.
director_ai.core.runtime.human_review.HumanReviewDecision
dataclass
¶
HumanReviewDecision(decision_id: str, case_id: str, reviewer_id: str, action: ReviewAction, reason: str = '', metadata: Mapping[str, str] = dict(), timestamp: float = time.time())
Append-only reviewer decision for one queued case.