Skip to main content

Human review

Pause a decision that needs judgment, route it to the right person, and resume only after the request reaches a terminal state.

Status: Beta Companion docs: Verdicts and modes · Webhooks API · Receipts Source of truth: the HiTL API contract exposed by tr.hitl and result.review.

Start from a HiTL result

from trinitite import Trinitite

tr = Trinitite(env="prod")
refunds = tr.scope(
"refund-flow",
goal="Resolve refunds within policy.",
hitl_zones=["refunds over $500"],
)

resp = refunds.client(
"openai",
credential="cred_openai_prod",
).chat.completions.create(
model="gpt-4o",
messages=[{
"role": "user",
"content": "Refund order #4821 for $900.",
}],
)

result = tr.result(resp)
if result.verdict == "HiTL" and result.review is not None:
review = result.review
print(review.request_id)

result.review is present only when the verdict is HiTL and the result carries a review request id.

Assign and decide

review.assign(reviewer="finance-oncall")
review.comment(text="Order history checked.")
review.approve(reason="Refund is within the approved exception.")

Use one decision method per pending request:

review.approve(reason="Verified against policy.")
review.reject(reason="Amount exceeds the delegation limit.")
review.escalate(reason="Needs finance leadership review.")

All three methods send a decision to the same endpoint. The lifecycle is pending to approved, rejected, escalated, or expired.

Wait for another reviewer

ReviewHandle.wait(...) polls until the request is terminal. It raises Python's built-in TimeoutError if the maximum wait elapses.

try:
final = review.wait(
poll_interval_seconds=2,
max_wait_seconds=120,
)
except TimeoutError:
final = review.get()
print("Still waiting:", final.body.get("status"))
else:
print("Decision:", final.body["status"])

The timeout limits local polling. It does not cancel or expire the review request.

Work the shared queue

queue = tr.hitl.queue(
status="pending",
reviewer="finance-oncall",
limit=20,
)

for item in queue.body.get("requests", []):
handle = tr.hitl.get(id=item["request_id"])
print(handle.get().body)

You can also create a review directly for an existing decision or asset:

review = tr.hitl.create(
subject_type="decision",
subject_id="log_abc123",
rationale_request="Refund over $500 needs sign-off.",
risk_zone="refunds",
sla_deadline="2026-08-24T17:00:00Z",
)
portal_url = review.portal_url
if portal_url is not None:
send_to_reviewer(portal_url)

The link is minted on first access and cached on the handle. If link minting is unavailable, the property returns None; SDK decisions and queue polling still work.

Verify the transition log

events = review.events()
for event in events.body.get("events", []):
print(event["event_type"], event.get("actor"))

verification = review.verify()
assert verification.body["verified"] is True

Every create, assign, comment, decision, and expiry transition is appended to the review event chain.

Next steps