Inspiration

AI coding agents like Codex take real, consequential actions on your machine - running shell commands, editing files, touching credentials. Once a session ends, or the transcript compacts, the reasoning behind any single action is usually gone. We wanted a "why did it do that" that's answerable forever, not just for the length of one conversation.

What it does

Zetesis is a local, real-time black box for AI coding-agent sessions. It hooks into Codex CLI's native hook system and a bundled terminal agent we built directly on GPT-5.6 via the OpenAI Responses API, logging every consequential action each one takes, paired with the reasoning that preceded it, into a single local SQLite + JSONL store. A React/FastAPI viewer gives you a live timeline, per-action detail (arguments, result, reasoning, git state), full-database search with qualifiers (tool:, risk:, session:, provider:, ...), and deterministic risk tiering that flags sensitive actions with a desktop alert before they run.

How we built it

The hook is the entry point Codex calls on every lifecycle event, it's designed to exit 0 unconditionally, because a recorder that can break the agent it's watching is worse than no recorder at all. Reasoning is extracted from the live transcript at the moment of each action, with a snapshot shield that copies the transcript before Codex's PreCompact event can erase it. Everything lands in SQLite (WAL mode) with a JSONL mirror for durability and easy grepping, no daemon required, fr ui just starts a FastAPI process that reads the same store. The terminal agent (fr api-ui) runs directly on GPT-5.6 through the OpenAI Responses API, recording its own reasoning into the same store as it works.

Challenges we ran into

  • Pairing pre/post events reliably. A tool call's PreToolUse and PostToolUse hooks can fire out of order or go missing entirely (a malformed command's PreToolUse sometimes never gets a matching PostToolUse), so we built a self-healing pairing system that retries recent unpaired calls opportunistically on every later hook invocation.
  • Reasoning capture from live transcripts. The transcript file write can lag the hook's own dispatch, so a reasoning window can be genuinely unavailable the moment an action fires. We treat every capture gap as an honest gap rather than fabricating an answer, and retry recovery on the next hook event.
  • Merging parallel work across branches. With multiple people building different features (session stats, agent-scope filtering, token budgets, a project-wide rename from flight_recorder to zetesis) at once, several of our merges touched the same files in incompatible ways and needed careful, semantic conflict resolution rather than picking one side.

Accomplishments that we're proud of

A recorder that actually works across both Codex sessions and our own GPT-5.6-powered terminal agent without ever being the thing that breaks a session, and a "Known gaps" section in our own README that's honest about what isn't validated yet, because we'd rather ship something real than oversell something that isn't.

What we learned

That a monitoring tool has to be provably harmless to the thing it's monitoring before anything else matters, exiting 0 unconditionally on the hook, regardless of what breaks internally, mattered more than any feature. We also learned the cost of silent failure modes: an early version quietly capped event history at 500 rows and let network-risk tags collapse into "sensitive," both invisible until we went looking. And merging three people's independent work on the same files taught us that "keep both sides" is usually right when two branches add different capabilities to the same function, the conflict is rarely actually a conflict.

What's next for Zetesis

Incident report export, multi-session cross-search, and file diffs, the things we knew we wanted but didn't have time to build during the Submission Period.

Built With

Share this project:

Updates