<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Khristian</title>
    <description>The latest articles on DEV Community by Khristian (@kopachelli).</description>
    <link>https://dev.to/kopachelli</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2096047%2F915a10b2-7e10-481b-b8e1-cfd3fe35bfee.png</url>
      <title>DEV Community: Khristian</title>
      <link>https://dev.to/kopachelli</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kopachelli"/>
    <language>en</language>
    <item>
      <title>I gave an on-call autopilot a hard "stop and ask a human" gate — here's the state machine that makes it safe</title>
      <dc:creator>Khristian</dc:creator>
      <pubDate>Wed, 22 Jul 2026 18:30:54 +0000</pubDate>
      <link>https://dev.to/kopachelli/i-gave-an-on-call-autopilot-a-hard-stop-and-ask-a-human-gate-heres-the-state-machine-that-hm5</link>
      <guid>https://dev.to/kopachelli/i-gave-an-on-call-autopilot-a-hard-stop-and-ask-a-human-gate-heres-the-state-machine-that-hm5</guid>
      <description>&lt;p&gt;It's 3am. Your phone lights up with a page you've seen four times this quarter. You know the fix. You've &lt;em&gt;documented&lt;/em&gt; the fix. And yet here you are, half-awake, SSH-ing into a box to run the same three commands you ran last month, because the runbook doesn't run itself and nobody trusts it to.&lt;/p&gt;

&lt;p&gt;That gap — between an incident being &lt;em&gt;understood&lt;/em&gt; and being &lt;em&gt;resolved&lt;/em&gt; — is where PRAXIS lives.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem: solved incidents that still wake you up
&lt;/h2&gt;

&lt;p&gt;Most on-call pain isn't novel failure. It's &lt;em&gt;recurring, already-diagnosed&lt;/em&gt; failure. The knowledge exists; it just lives in a wiki page, a Slack thread, or one senior engineer's head. So the org pays for it twice: once to figure it out, and forever after in interrupted sleep.&lt;/p&gt;

&lt;p&gt;The obvious answer is "automate the remediation." The obvious reason nobody does is fear. Silent auto-remediation is a great idea right up until it confidently runs the wrong &lt;code&gt;DROP&lt;/code&gt;, reports success it never verified, and turns a five-minute blip into a postmortem. The cost of a wrong automated action is asymmetric — one bad write can outweigh a hundred correct ones.&lt;/p&gt;

&lt;p&gt;So the real design question isn't "can a model fix this?" It's "how do we let a model do the tedious bulk of the work while keeping a human firmly in front of anything that changes state?"&lt;/p&gt;

&lt;h2&gt;
  
  
  The core idea: an autopilot with a hard approval gate
&lt;/h2&gt;

&lt;p&gt;PRAXIS is an alert-to-remediation autopilot with a &lt;strong&gt;mandatory human-in-the-loop approval gate&lt;/strong&gt;. The word "autopilot" is deliberate: it flies the plane, but a human still has the controls for anything irreversible.&lt;/p&gt;

&lt;p&gt;Here's the full flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A &lt;strong&gt;signed&lt;/strong&gt; operational alert arrives.&lt;/li&gt;
&lt;li&gt;Qwen models &lt;strong&gt;classify&lt;/strong&gt; it and reason about &lt;strong&gt;root cause&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;PRAXIS gathers &lt;strong&gt;read-only evidence&lt;/strong&gt; — logs, state, context — never touching anything that mutates.&lt;/li&gt;
&lt;li&gt;It drafts a &lt;strong&gt;risk-labelled remediation plan&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;It &lt;strong&gt;stops&lt;/strong&gt;. Nothing state-changing happens until a human approves the &lt;em&gt;exact&lt;/em&gt; plan.&lt;/li&gt;
&lt;li&gt;On approval, it &lt;strong&gt;executes the approved actions&lt;/strong&gt; against an isolated target.&lt;/li&gt;
&lt;li&gt;Every step lands in an &lt;strong&gt;auditable decision trail&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Resolved incidents become &lt;strong&gt;reusable incident memory&lt;/strong&gt; for next time.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The interesting engineering isn't the "AI reasons about an alert" part — plenty of things do that. It's steps 5 through 7: making the stop &lt;em&gt;unskippable&lt;/em&gt;, and making execution honest about what it did and didn't do.&lt;/p&gt;

&lt;h2&gt;
  
  
  The design: fail-closed, or don't move at all
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;AWAITING_APPROVAL&lt;/code&gt; is the only door into &lt;code&gt;EXECUTING&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;PRAXIS is built as a &lt;strong&gt;fail-closed state machine&lt;/strong&gt;. The property I care about most is structural, not procedural: there is exactly one transition into the &lt;code&gt;EXECUTING&lt;/code&gt; state, and it originates from &lt;code&gt;AWAITING_APPROVAL&lt;/code&gt;. There's no side door. No "high-confidence" bypass. No config flag that quietly flips it to autonomous. If a plan hasn't been explicitly approved by a human, no state-changing tool runs. Full stop.&lt;/p&gt;

&lt;p&gt;This matters because "we prompt the model to always ask first" is not a safety property — it's a suggestion the model can wander away from. Making approval the &lt;em&gt;only&lt;/em&gt; topological path into execution means the guarantee holds even if the reasoning layer misbehaves. The safety lives in the state graph, not in the vibes of a system prompt.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reconciliation under uncertainty
&lt;/h3&gt;

&lt;p&gt;Distributed systems don't have the courtesy of clean failures. Sometimes you fire an action and never learn whether it landed — the connection drops, the response is ambiguous, the target goes dark mid-call. Naive automation handles this in one of two catastrophic ways: it assumes success (and lies to you), or it blindly retries (and double-applies).&lt;/p&gt;

&lt;p&gt;PRAXIS does neither. Before dispatching any real action, it records a &lt;strong&gt;durable pre-dispatch intent&lt;/strong&gt; — a written-down "I am about to do X." If the outcome of that action can't be verified afterward, the incident doesn't get marked resolved and it doesn't get retried. It moves to a terminal &lt;strong&gt;&lt;code&gt;RECONCILIATION_REQUIRED&lt;/code&gt;&lt;/strong&gt; state and waits for a human.&lt;/p&gt;

&lt;p&gt;The design stance is blunt: &lt;strong&gt;it would rather stop and admit uncertainty than report a false success.&lt;/strong&gt; An incident parked in &lt;code&gt;RECONCILIATION_REQUIRED&lt;/code&gt; is a human getting an honest "I'm not sure what happened here, come look" — which is exactly the message you want at 3am, and exactly the one silent automation refuses to send.&lt;/p&gt;

&lt;h3&gt;
  
  
  The approved plan is the plan that runs
&lt;/h3&gt;

&lt;p&gt;The approval gate is only meaningful if the thing being approved is the thing that runs. A human approves the &lt;em&gt;exact&lt;/em&gt; plan — a concrete, bounded set of actions — not a vague intention the executor is free to reinterpret. The blast radius is deliberately tiny: the one real write adapter only restarts an &lt;strong&gt;isolated, disposable Function Compute demo target&lt;/strong&gt;. Every caution- or dangerous-tier tool is a &lt;strong&gt;visibly labelled dry-run&lt;/strong&gt;. You can watch it reason about a scary action without it ever being able to take one.&lt;/p&gt;

&lt;h2&gt;
  
  
  The stack
&lt;/h2&gt;

&lt;p&gt;The runtime is &lt;strong&gt;Qwen-only&lt;/strong&gt;, served from &lt;strong&gt;Qwen Cloud&lt;/strong&gt; (Alibaba's Model Studio):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reasoning:&lt;/strong&gt; &lt;code&gt;qwen3.7-max&lt;/code&gt;, with a same-Qwen OpenRouter fallback for availability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Classification:&lt;/strong&gt; &lt;code&gt;qwen-flash&lt;/code&gt; — cheap and fast for the high-volume triage step.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory embeddings:&lt;/strong&gt; &lt;code&gt;text-embedding-v4&lt;/code&gt; (1024-dim).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It runs on &lt;strong&gt;Alibaba Cloud Function Compute 3.0&lt;/strong&gt;, and semantic incident memory lives in &lt;strong&gt;Alibaba Cloud Tablestore&lt;/strong&gt; vector search. Resolved incidents get embedded and stored so a future recurrence can pull up how the last one went — recall grounded in your own history, not a generic model prior.&lt;/p&gt;

&lt;h2&gt;
  
  
  A note on how it was built
&lt;/h2&gt;

&lt;p&gt;PRAXIS was built with AI coding agents — primarily &lt;strong&gt;OpenAI Codex running GPT-5.6&lt;/strong&gt; as the development agent. That's worth stating precisely, because it's easy to garble: Codex and GPT-5.6 are &lt;strong&gt;build-time tooling only&lt;/strong&gt;. They wrote and refactored code; they do &lt;strong&gt;not&lt;/strong&gt; run inside the product. The PRAXIS runtime is Qwen-only. Nothing in the live incident path touches an OpenAI model. Keeping that boundary crisp matters as much for honesty as for architecture — the thing that reasons about your incidents and the thing that helped write the reasoner are two different systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honest limitations
&lt;/h2&gt;

&lt;p&gt;I'd rather undersell this than have you discover the gaps yourself.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Memory isn't proven end-to-end live yet.&lt;/strong&gt; The write-and-recall path is &lt;em&gt;implemented and tested&lt;/em&gt; — but a fresh approved resolution writing a memory row &lt;em&gt;and&lt;/em&gt; a genuinely distinct later recurrence recalling it, proven live in one continuous run, is not yet demonstrated. "Implemented and tested," not "proven in production."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It's a single-operator demo.&lt;/strong&gt; Incidents are process-local, not cross-instance durable. This is not multi-tenant, and it's not making production-grade durability claims. It's an honest demonstration of a safety architecture, not a fleet-ready SaaS.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Neither of these undercuts the point PRAXIS is trying to make. The point is the &lt;em&gt;shape&lt;/em&gt; of safe automation — the gate, the reconciliation, the audit trail — and that shape is real and running.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it / read the code
&lt;/h2&gt;

&lt;p&gt;There's a &lt;strong&gt;live, public, read-only demo&lt;/strong&gt; — no login required. Open it and watch incidents flow through the state machine in real time. You can see everything; only the maintainer's operator token can approve anything, so the approval gate stays intact even for you.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live demo:&lt;/strong&gt; &lt;a href="https://praxis.kopachelli.dev" rel="noopener noreferrer"&gt;https://praxis.kopachelli.dev&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Source (Apache-2.0):&lt;/strong&gt; &lt;a href="https://github.com/Kopachelli/praxis" rel="noopener noreferrer"&gt;https://github.com/Kopachelli/praxis&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The repo ships with a README and &lt;strong&gt;859 passing automated tests&lt;/strong&gt;. If you've ever wanted auto-remediation but couldn't stomach handing a model the keys to production, the interesting bit here is exactly the part that refuses to let it drive alone.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>ai</category>
      <category>oncall</category>
      <category>reliability</category>
    </item>
    <item>
      <title>From a broken tool call to a regression test: building Agent Black Box in 4 days</title>
      <dc:creator>Khristian</dc:creator>
      <pubDate>Tue, 21 Jul 2026 19:35:08 +0000</pubDate>
      <link>https://dev.to/kopachelli/from-a-broken-tool-call-to-a-regression-test-building-agent-black-box-in-4-days-5248</link>
      <guid>https://dev.to/kopachelli/from-a-broken-tool-call-to-a-regression-test-building-agent-black-box-in-4-days-5248</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; — When an agent fails, the model's final answer is the least useful thing to look at. &lt;strong&gt;Agent Black Box&lt;/strong&gt; captures every OpenAI Agents SDK run as structured spans, renders it as a timeline, replays any run against &lt;strong&gt;GPT-5.6&lt;/strong&gt; with captured tool outputs stubbed in (side-effect-free), and turns the corrected behavior into a portable regression eval. Built solo in four days for OpenAI Build Week 2026. Live demo: &lt;strong&gt;&lt;a href="https://blackbox.kopachelli.dev" rel="noopener noreferrer"&gt;blackbox.kopachelli.dev&lt;/a&gt;&lt;/strong&gt; · 99s video: &lt;strong&gt;&lt;a href="https://youtu.be/rxBLF6QtJkE" rel="noopener noreferrer"&gt;youtu.be/rxBLF6QtJkE&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When an agent fails in production, the real cause is usually several steps before the final message: a bad handoff, malformed function arguments, an unexpected guardrail result, or an MCP call that returned something the next agent misread. The raw JSON has the evidence — it just doesn't tell the story.&lt;/p&gt;

&lt;p&gt;That's the problem I built &lt;strong&gt;Agent Black Box&lt;/strong&gt; to solve: a self-hostable flight recorder for OpenAI agents. Capture a run as structured spans, inspect it as a timeline, replay it safely on GPT-5.6, and turn the corrected behavior into a regression eval.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with the one path that must work
&lt;/h2&gt;

&lt;p&gt;With four days, a normal feature backlog would have been dangerous. I treated one user journey as sacred:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;seeded failing run → timeline → failing span → replay on GPT-5.6 → diff red→green → generate eval → Run all green&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feg5iy2pb19209pk90n2o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feg5iy2pb19209pk90n2o.png" alt="The canonical four-run demo dataset, with one intentional failure" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every technical choice had to protect that path; anything that threatened it was cut or deferred. The canonical incident is small but realistic: a two-agent support flow hands off to a refund agent that calls &lt;code&gt;refund_order&lt;/code&gt; with the malformed amount &lt;code&gt;"12.OO"&lt;/code&gt;. That failure is reproducibly generated through the real Python Agents SDK &lt;code&gt;Runner&lt;/code&gt; and tracing lifecycle using a local scripted model — so anyone can produce it without an API key or model variance. The &lt;strong&gt;replay&lt;/strong&gt;, by contrast, is a live GPT-5.6 operation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0vvoc72a222nxy3h732b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0vvoc72a222nxy3h732b.png" alt="The malformed refund amount and its captured validation error" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A thin capture layer, not a second agent framework
&lt;/h2&gt;

&lt;p&gt;The Python integration consumes the Agents SDK's public &lt;code&gt;TracingProcessor&lt;/code&gt; callbacks directly. Register &lt;code&gt;AbbProcessor&lt;/code&gt;, and completed spans are normalized and exported as one authenticated batch when the trace ends — in a background worker, so callback or transport failures never alter the host agent.&lt;/p&gt;

&lt;p&gt;The wrapper is deliberately thin. It doesn't replace &lt;code&gt;Runner&lt;/code&gt; or invent a tracing format; it preserves IDs, parentage, timing, and errors, then maps everything into five span types: &lt;code&gt;turn&lt;/code&gt;, &lt;code&gt;tool_call&lt;/code&gt;, &lt;code&gt;handoff&lt;/code&gt;, &lt;code&gt;guardrail&lt;/code&gt;, &lt;code&gt;mcp_call&lt;/code&gt;. At the server boundary, Phoenix does the unglamorous work that makes an observability tool trustworthy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;spans are &lt;strong&gt;idempotent&lt;/strong&gt; on run + external span ID;&lt;/li&gt;
&lt;li&gt;input/output/error bodies are &lt;strong&gt;recursively redacted before persistence&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;raw project keys are never stored — only uniquely indexed SHA-256 digests;&lt;/li&gt;
&lt;li&gt;bodies over 256 KiB become a bounded truncation sentinel, not broken JSON;&lt;/li&gt;
&lt;li&gt;PostgreSQL transactions + advisory locks keep concurrent version allocation consistent.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Phoenix PubSub announces new runs and LiveView re-queries PostgreSQL as the source of truth. No separate frontend framework, no client-side store to reconcile.&lt;/p&gt;

&lt;h2&gt;
  
  
  The important replay boundary
&lt;/h2&gt;

&lt;p&gt;"Replay" is easy to over-claim. Agent Black Box does &lt;strong&gt;not&lt;/strong&gt; pretend model generation is deterministic — GPT-5.6 stays live and its wording may vary. The deterministic boundary is &lt;strong&gt;captured-tool execution&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The engine rebuilds the conversation up to the point before the original terminal answer, reconstructs strict tool definitions, and calls GPT-5.6 through the &lt;strong&gt;Responses API with Programmatic Tool Calling&lt;/strong&gt;. When the model emits a client-owned function call, the harness matches it to the captured sequence and returns the &lt;strong&gt;stored&lt;/strong&gt; output. The real tool never runs — so replaying a refund, an email, or a DB mutation never repeats the side effect.&lt;/p&gt;

&lt;p&gt;The seeded failure exposed a nice edge case: its malformed args were rejected &lt;em&gt;before&lt;/em&gt; &lt;code&gt;refund_order&lt;/code&gt; executed, so there was no historical output to return. Rather than falsify the original span, the trace carries an explicitly labeled safe &lt;code&gt;replay_stub_output&lt;/code&gt; used only when the captured output is absent; if neither exists, the engine records a divergence instead of invoking the tool.&lt;/p&gt;

&lt;p&gt;The final verdict needs no extra model call: a failed source followed by a successful child replay is deterministically labeled &lt;strong&gt;FAILURE FIXED&lt;/strong&gt;. The judge sees a stable verdict while the underlying generation stays honestly live.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkvw83zf2u14gelot0yqk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkvw83zf2u14gelot0yqk.png" alt="A live GPT-5.6 replay changes the malformed amount and completes successfully" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Turning a debugging session into a test
&lt;/h2&gt;

&lt;p&gt;A green replay is useful once. A saved eval makes it useful on every future deploy.&lt;/p&gt;

&lt;p&gt;Agent Black Box compacts the captured source plus its latest successful replay and asks GPT-5.6 for a &lt;strong&gt;strict Structured Output&lt;/strong&gt; that must match a closed, versioned assertion schema and pass local validation before anything is stored. Synthesis focuses on replay-stable structure: a tool was called, a JSON-Pointer argument matched an expected scalar, the run stayed within a turn bound, and no span errored. &lt;code&gt;Run all&lt;/code&gt; re-replays each eval and checks assertions locally — no model-as-judge — and the stored contract is portable JSON, not an Elixir closure, leaving a clean path to a future CI runner.&lt;/p&gt;

&lt;p&gt;This came from a real bug: the first generated eval copied full prose from a replay; a later replay phrased the same result differently and correctly failed the string check. The fix wasn't a looser green button — it was separating stochastic prose from durable structural behavior.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3zzdloee2743q7ldgdn6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3zzdloee2743q7ldgdn6.png" alt="The generated portable eval focuses on tool calls, arguments, and clean execution" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Safety and cost are part of the feature
&lt;/h2&gt;

&lt;p&gt;Captured traces can hold credentials, private prompts, and expensive replay contexts, so safety is on the product path, not in deployment notes. Every OpenAI call goes through one audited &lt;code&gt;AgentBlackBox.OpenAI&lt;/code&gt; module: &lt;code&gt;store: false&lt;/code&gt; by default, pinned service tier for predictable accounting, explicit low reasoning for the demo, and one frozen cacheable prefix under a stable non-PII key. Before any network I/O, a supervised in-process ledger reserves a conservative cost bound, settles from reported usage, and charges the full bound when a sent request's outcome becomes unknowable — with a provider-side project cap as the restart-safe outer limit. The public demo runs in demo mode: ingestion returns &lt;code&gt;403&lt;/code&gt; while replay/eval stay interactive on the known dataset.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Phoenix, PostgreSQL, and NixOS
&lt;/h2&gt;

&lt;p&gt;Phoenix LiveView was a deadline choice, not a novelty one: one app owns ingestion, persistence, replay supervision, PubSub, and the streamed UI, and tests swap the OpenAI boundary for Mox while exercising the whole path offline. The hosted instance is the same release packaged natively for a NixOS fleet — &lt;code&gt;beamPackages.mixRelease&lt;/code&gt; builds it, systemd runs it under a dynamic user, sops + &lt;code&gt;LoadCredential&lt;/code&gt; deliver secrets, PostgreSQL 17 uses local peer auth, and Caddy is the only public listener. Publication was fail-closed (a hostname-scoped Caddy &lt;code&gt;503&lt;/code&gt; until loopback acceptance passed), and Docker Compose remains the portable self-host route.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgmsmrml0dss5sok7z1sd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgmsmrml0dss5sok7z1sd.png" alt="The native NixOS production topology" width="800" height="326"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What Codex changed about the build
&lt;/h2&gt;

&lt;p&gt;Codex didn't replace product ownership — it made a disciplined, evidence-heavy solo workflow possible under a deadline. One primary Codex task held the substantive implementation, driven by an &lt;code&gt;AGENTS.md&lt;/code&gt; operating contract that defined the sacred path, coding rules, safety boundaries, and session protocol; bounded specialist agents reviewed isolated risks (replay semantics, redaction, deployment, UI, submission claims) while the primary task owned integration. Every unit of work had a Linear issue before implementation, decisions became immutable ADRs when made, and worklogs recorded evidence and cost.&lt;/p&gt;

&lt;p&gt;The deeper lesson: &lt;strong&gt;an agent works far better with explicit invariants than with "build the app."&lt;/strong&gt; The contract turned scope, truthfulness, and completion evidence into inputs the coding system could reason about.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons I'd carry forward
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Build backward from one undeniable outcome.&lt;/strong&gt; The sacred path kept infrastructure subordinate to product value.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Name the deterministic boundary precisely.&lt;/strong&gt; Captured tools can be deterministic and side-effect-free even when live model generation is not.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prefer structural evals to prose snapshots.&lt;/strong&gt; Stable behavioral invariants survive harmless wording changes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fail closed around money, secrets, and public state.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make decisions durable when they happen.&lt;/strong&gt; An ADR directory is useful to humans &lt;em&gt;and&lt;/em&gt; coding agents.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Try the complete path
&lt;/h2&gt;

&lt;p&gt;Zero setup: open the &lt;a href="https://blackbox.kopachelli.dev" rel="noopener noreferrer"&gt;live seeded demo&lt;/a&gt;, pick &lt;code&gt;error-bad-tool-args&lt;/code&gt;, select the red &lt;code&gt;refund_order&lt;/code&gt; span, replay it on GPT-5.6, generate an eval from the successful replay, and hit &lt;strong&gt;Run all&lt;/strong&gt; — the whole capture → replay → eval loop in about a minute. It's self-hostable: one Phoenix + PostgreSQL release on a single box.&lt;/p&gt;

&lt;p&gt;Agent Black Box started as a way to make one malformed tool call understandable. The useful result is broader: a concrete pattern for going from opaque agent history → safe live replay → a regression contract another human (or coding agent) can inspect and run.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fncxrae0xnzurlu09iuzq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fncxrae0xnzurlu09iuzq.png" alt="The complete trace-to-replay-to-eval operating flow" width="800" height="284"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Disclosure: I built Agent Black Box, and I drafted this write-up with AI assistance (writing and editing). Every technical claim here is verified against the running system.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>openai</category>
      <category>elixir</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
