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
PreToolUseandPostToolUsehooks can fire out of order or go missing entirely (a malformed command'sPreToolUsesometimes never gets a matchingPostToolUse), 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_recordertozetesis) 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
- claude-code
- codex-cli
- fastapi
- openai-api
- python
- react
- sqlite
- tailwindcss
- typescript
- uvicorn
- vite
Log in or sign up for Devpost to join the conversation.