{"slug": "building-phinq-how-a-cronjob-failure-forced-me-to-redesign-agent-governance-from", "title": "Building Phinq: How a Cronjob Failure Forced Me to Redesign Agent Governance From Scratch", "summary": "Hytham H built Phinq, an agent governance system, after a cronjob failure exposed the inadequacy of per-tool hooks. The system uses a proxy that intercepts LLM API calls to enforce deterministic rules on tool calls, blocking or holding risky actions. A calibration loop in pass-through mode ensures zero false positives before enforcement is enabled.", "body_md": "*By Hytham H -- June 29, 2026*\n\nHermes overwrote a file. Phinq didn't catch it.\n\nNot because the code was wrong. Two reasons.\n\nFirst, the skill wasn't even loaded in that session. The agent had no instructions to consult itself against. No prompt, no rule, no safety net.\n\nSecond, even if it had been loaded, it still wouldn't have caught it. The skill only watched file operations. The cronjob mutated state through an API -- a different surface, a different path, and completely invisible to a file-op hook.\n\nI was trying to govern an actor that didn't know it was being governed.\n\nThat failure forced an honest question: why did a tool built specifically to prevent this, fail to prevent this?\n\nThe answer is uncomfortable. A markdown skill is advisory. The agent has to choose to consult it, under token pressure, mid-task, and there's no mechanism forcing that.\n\nGovernance the governed party can ignore is not governance.\n\nI could keep adding hooks for every tool in existence -- file operations, API calls, database queries, network requests -- but that's whack-a-mole. You're always one tool behind. The next cronjob, the next API surface, the next thing you didn't think to watch. You can't enumerate danger one surface at a time and expect to stay ahead of an agent that can call anything.\n\nThe problem wasn't the missing hook. The problem was the architecture.\n\nInstead of trying to intercept every tool individually, move enforcement to the one chokepoint every tool call already passes through: the LLM API call itself.\n\nEvery action your agent takes starts as a tool call in a request to an LLM provider -- OpenAI, Anthropic, OpenRouter, anything that speaks those APIs. Trap it there and you don't need to know what tools exist. You don't need a hook per surface. You sit at the gate every action has to walk through.\n\nThat's what the proxy does. A Fastify/TypeScript intercepting server. Point your agent's base URL at it. Every request flows through before reaching the upstream. Tool calls get classified, checked against your declared rules, and either pass, block, or pause for your approval.\n\nNo code changes. No SDK. No per-tool hook maintenance. Just swap the URL.\n\n(There's also an SDK path for in-process gating, but the proxy is the simpler story.)\n\nA deterministic rule set scores every tool call into one of five levels:\n\n| Level | Behaviour | Examples |\n|---|---|---|\n| RISK_REDUCING | Always pass | Cancelling a task, reverting a change |\n| REVERSIBLE | Always pass | Reading a file, writing a draft |\n| IRREVERSIBLE_LOW | Pass | Single email, single file write |\n| IRREVERSIBLE_MEDIUM | HOLD | Deletions, comms volume, config changes |\n| IRREVERSIBLE_HIGH | HOLD + escalate | Credential access, billing, disable safeguards |\n\nPlus structural triggers that always escalate -- bulk deletes, credential reads, permission changes, anything that disables safeguards.\n\nReversible actions pass through with no latency you'd notice. The only thing that ever waits is a risky action held for your approval. Which is exactly the point.\n\nNo ML, no second black box. Just hard rules enforced at the only point where enforcement is guaranteed.\n\nBefore you turn enforcement on, you calibrate. The proxy can run in pass-through mode -- classify every action, log every decision, but never block anything. You feed a real corpus through it, check for false HOLDs, tune the thresholds.\n\nOnly turn enforcement on once you have zero false HOLDs on routine operations.\n\nThis isn't a nice-to-have. It's the difference between a tool operators keep installed and one they rip out after the third time it blocks a harmless action. The false-positive rate determines whether governance survives contact with real workflows. If you're building a governance tool and you haven't designed a calibration loop, you haven't finished the product.\n\nSelf-reported audit logs from the entity being audited are worth nothing without tamper evidence.\n\nEvery governed action is written to a hash-chained JSONL file. The first entry is a genesis block with a random log ID. Every subsequent entry includes the hash of the previous entry. Change a single byte anywhere in the chain and verification fails.\n\nOne command to prove the history is intact.\n\nThis isn't about catching malicious agents. It's about the fact that if an agent can write to a log file, it can quietly edit that log file. The audit trail has to be structurally unalterable by the thing being audited. Otherwise you're asking the fox to maintain the chicken count.\n\nPhinq is MIT licensed. Two components on GitHub:\n\nThe hosted layer (cross-session dashboards, anomaly detection, shareable reports) is in development. [Join the waitlist](https://phinq.co) if that's useful to you.\n\nThe cronjob failure was the best thing that happened to this project. It proved that governance has to be environmental -- actions physically pass through it, or they don't pass at all. You cannot govern an actor by asking it nicely.\n\nReversible actions pass through. Irreversible ones pause.\n\nThat's the whole idea.", "url": "https://wpnews.pro/news/building-phinq-how-a-cronjob-failure-forced-me-to-redesign-agent-governance-from", "canonical_source": "https://dev.to/hythamh/building-phinq-how-a-cronjob-failure-forced-me-to-redesign-agent-governance-from-scratch-47og", "published_at": "2026-06-30 20:24:46+00:00", "updated_at": "2026-06-30 20:49:00.768851+00:00", "lang": "en", "topics": ["ai-agents", "ai-safety", "developer-tools"], "entities": ["Hytham H", "Phinq", "OpenAI", "Anthropic", "OpenRouter", "Fastify", "TypeScript"], "alternates": {"html": "https://wpnews.pro/news/building-phinq-how-a-cronjob-failure-forced-me-to-redesign-agent-governance-from", "markdown": "https://wpnews.pro/news/building-phinq-how-a-cronjob-failure-forced-me-to-redesign-agent-governance-from.md", "text": "https://wpnews.pro/news/building-phinq-how-a-cronjob-failure-forced-me-to-redesign-agent-governance-from.txt", "jsonld": "https://wpnews.pro/news/building-phinq-how-a-cronjob-failure-forced-me-to-redesign-agent-governance-from.jsonld"}}