The runtime checkpoint for AI agents — deterministic tool-call risk classification, human-in-the-loop gating, and audit hooks.
Project description
phinq (Python)
The runtime checkpoint for AI agents — deterministic tool-call risk classification, human-in-the-loop gating, and audit hooks. This is the Python port of the same engine the Phinq proxy uses; the test suite mirrors the TypeScript cases so the two engines provably agree.
pip install phinq
Gate a tool execution
from phinq import PhinqGovernor
governor = PhinqGovernor()
def ask_operator(req):
print(f"HOLD: {req.name} — {', '.join(req.classification.reasons)}")
return "approve" if input("approve? [y/N] ").lower() == "y" else "deny"
result = governor.gate("delete_file", {"path": "/data/old"}, on_hold=ask_operator)
if result.allowed:
run_tool()
- ALLOW decisions pass straight through (
resolution == "allowed"). - HOLD decisions call your
on_holdhandler (returns"approve"or"deny"), auto-denying on timeout (hold_timeout_s, default 240s). - With no handler, held calls are denied by default (
default_on_hold="approve"flips this).
Classify only
from phinq import classify_tool_call
c = classify_tool_call("shell_exec", '{"cmd": "sudo rm -rf /data"}')
c.decision # "HOLD"
c.action_class # AgentActionClass.IRREVERSIBLE_HIGH
c.triggers # ["PERMISSION_ESCALATION", "BULK_DELETE"]
c.reasons # human-readable, one per rule that fired
Deterministic: same call + same session counts → same decision. No network, no LLM judge.
Velocity triggers
The governor tracks per-session rolling windows (60 min): outbound-comms volume, delete counts, and bulk-operations-after-an-error. The fourth send in a session holds even though each send looks innocent alone.
governor.record_error() # arms AFTER_ERROR_BULK for 10 minutes
governor.gate("send_email", {...}, session_key="agent-7")
Audit hook
events = []
governor = PhinqGovernor(on_audit=events.append)
Every gate emits an AuditEvent (never containing arguments — only sizes and classifications). Feed these to your logger, or run the Phinq proxy for the full hash-chained, tamper-evident audit log and the phinq report oversight evidence.
Tuning
from phinq import ClassifierRules, ClassifierThresholds, AgentActionClass, PhinqGovernor
rules = ClassifierRules(
thresholds=ClassifierThresholds(external_comm_volume=10, bulk_delete_count=20),
tool_class_overrides={"send_newsletter": AgentActionClass.REVERSIBLE},
)
governor = PhinqGovernor(rules=rules)
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file phinq-0.1.0.tar.gz.
File metadata
- Download URL: phinq-0.1.0.tar.gz
- Upload date:
- Size: 13.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c5ecfb6adc23cf2021880d932553253420a2a948204a8d1f107084107617686f
|
|
| MD5 |
c4f4b0777a660bffbdc40e0d46aabda2
|
|
| BLAKE2b-256 |
1f72788a5d0f2f6a241e8e4695dfb727a33eec35809fc0a0c442653a838a7b03
|
File details
Details for the file phinq-0.1.0-py3-none-any.whl.
File metadata
- Download URL: phinq-0.1.0-py3-none-any.whl
- Upload date:
- Size: 12.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
22956e517ac3d8ee98f086610454a24c46351d974444c235af252e78d47daf5e
|
|
| MD5 |
effe5bb6a62e0cf3c59ff5948b0c022e
|
|
| BLAKE2b-256 |
4e89633a46c03a1e24f82f182c7886dd7da20a6d02847f5d614712fdfe4d45ea
|