# Codex Monitor

**Live public monitoring**

Codex Monitor displays real events copied by Codex Gateway from HTTP, SSE and WebSocket traffic. A non-blocking outbox publishes sanitized events to NATS JetStream, a projector stores the view in SQLite, and Bun/Vue exposes sessions, reasoning, tools, usage, errors and public broadcasts.

Source version: `72fb980fa7d15d106326e0665c662362d0725699`

Codex Gateway integration and monitoring release: 7–8 September 2026.

[Project notes](https://komaroff-dev.ru/projects/agents/) · [Online documentation](https://komaroff-dev.ru/projects/agents/docs/)

[Demo](https://agents.komaroff-dev.ru/)

[Source repository](https://github.com/komaroffsergei/nats-synadia-dev)

## Task

The goal was to observe Codex activity on a separate subdomain without affecting model requests. Monitoring must tolerate NATS outages, resume by cursor and separate owner-only sessions from explicitly published broadcasts.

The owner observes Codex work while visitors see only explicitly published read-only sessions.

## Work done

- Added HTTP, SSE and WebSocket observation inside the Ruby proxy without changing the primary relay flow.
- Implemented sanitization, a bounded file outbox, a dedicated JetStream stream and a durable SQLite WAL projector.
- Extended the Vue interface with sessions, reasoning and tool timeline, traffic, usage, delivery health and comparison.
- Added manual chat titles, collapsible service context, publication preview, expiring links and immediate broadcast revocation.

## What sets the implementation apart

Events come from the real proxy rather than a UI simulator. eventId and sequence make projection idempotent, the durable consumer acknowledges after persistence, and usage is counted per attempt without re-adding snapshots. Temporary links can be revoked immediately; the older YouTrack flow remains a separate subsystem.

## Application-code composition

- Vue / TypeScript: 42%
- Node.js / YouTrack worker: 27.8%
- Bun / NATS monitor API: 16.5%
- SQLite / TypeScript projector: 9.6%
- Bun / HTTP server: 2.8%
- TypeScript event contracts: 1.3%

Shares use Git application-file bytes at pinned revisions. Each file belongs to one subsystem under scripts/generate-stack-share.mjs rules; tests, assets, dependencies and generated files are excluded. Rounded to 0.1%. This describes code composition, not proficiency.

## Stack

| Technology | Role |
| --- | --- |
| Vue 3 / TypeScript | Protected console, public broadcast, timeline and cursor-based UI recovery. |
| Bun | Protected and public HTTP/WebSocket APIs, preview, publication and link revocation. |
| NATS JetStream | CODEX_TRACE stream, retention limits, durable delivery and separate credentials. |
| SQLite WAL | Idempotent projection of events, attempts, usage, titles and publications. |
| Ruby Codex proxy | HTTP/SSE/WebSocket observation, sanitization and a non-blocking file outbox. |

## Architecture and decisions

- The proxy copies sanitized events into a bounded outbox; NATS downtime does not stop a Codex request.
- The JetStream consumer acknowledges an event after a transactional projection write; eventId and sequence protect history from redelivery.
- Usage is stored per attempt and revision snapshot: cached counts within input, reasoning within output, and legacy aggregates remain separate.
- The default title comes from the first user message. A manual Codex Monitor title takes precedence and does not rename the chat in Codex.
- A public link contains only the permitted history of one selected session, lasts up to seven days and stops immediately on revocation.
- The earlier YouTrack/NATS worker remains a separate path and is not mixed with passive Codex monitoring.
- The monitor and YouTrack gateway use NATS directly. The Synadia Agents SDK, discovery and generic prompt bridge were removed; job and result queues are preserved.

### Observed Codex event flow

![Observed Codex event flow](https://komaroff-dev.ru/evidence/agents/live/diagrams/event-flow.svg)

[Mermaid source](https://komaroff-dev.ru/evidence/agents/live/diagrams/event-flow.mmd)

### Publishing and revoking a selected session

![Publishing and revoking a selected session](https://komaroff-dev.ru/evidence/agents/live/diagrams/publication.svg)

[Mermaid source](https://komaroff-dev.ru/evidence/agents/live/diagrams/publication.mmd)

## Code map

| Feature | Screen / API | Module | Data / verification |
| --- | --- | --- | --- |
| Traffic observation | Codex Gateway | docker/monitor/proxy.rb; observer.rb | HTTP/SSE/WS, split UTF-8, gzip, limits; observer tests |
| Delivery | CODEX_TRACE | server/monitor/ingest.ts; setup.ts | outbox, PubAck, 1 GiB / 24 h stream |
| Projection | /api/v1/monitor | server/monitor/store.ts; service.ts | events, sessions, attempts, usage; idempotence tests |
| Timeline | /console/ | MonitorApp.vue; MonitorTimelineItem.vue | cursor, long-text pages, folded service context |
| Publication | /live/:token | service.ts; public routes | share token hash, range, TTL, revoke and audit |
| YouTrack | /console/youtrack | youtrack-gateway.js; codex-worker.js | separate earlier JetStream path |

Before changing a feature, trace its interface, API, state and storage dependencies. Check inputs, errors, retries and related workflows. Update the map and affected diagrams alongside the code, rerun the related checks and attach evidence for the source version.

## Workflows and API

1. Select a session, set a clear title and inspect the instruction, reasoning, messages and tools in chronological order.
2. Open Traffic and correlate request, attempt, transport, duration and sanitized event identifiers.
3. Review per-attempt usage and inspect proxy, NATS, projector, cursor and outbox state.
4. Review the permitted history range, publish a temporary link, open it as a visitor and revoke it immediately.

## Verification

- CI: Ruby observer tests, Bun projector tests, TypeScript checks and a production Vue build for SHA 9da19ee.
- Real SSE and WebSocket traffic, reasoning and responses, exact usage increments, refresh recovery and projector restart were verified on the VPS.
- Ten concurrent public WebSocket viewers received 100 updates; delivery p95 was 172 ms and revoking ten connections took 83 ms.
- Fragmented-secret sanitization, private-session isolation, safe Markdown/JSON text and desktop/mobile layouts without horizontal overflow were verified.

[CI: Proxy monitoring checks](https://github.com/komaroffsergei/nats-synadia-dev/actions/runs/34168312212) — `9da19ee0b1111fa82ca11cebfbd6996864690555`, 2026-09-07T22:55:40Z; historical run of a different version.

[CI: Native NATS / Codex Monitor checks](https://github.com/komaroffsergei/nats-synadia-dev/actions/runs/34220817632) — `72fb980fa7d15d106326e0665c662362d0725699`, 2026-09-08; this demo's version.

## Results and measurements

- In the live load snapshot, event delivery p50 was 128 ms and p95 was 172 ms; model response time is excluded.
- One validation session ledger increased by 272 tokens and retained the same total after a projector restart.
- During validation the outbox was empty, NATS had no pending or ackPending messages, and no OOM event was found.

These checks apply to the listed version. Business metrics and model quality on an independent dataset were not measured.

![Container memory: three snapshots without external processing](https://komaroff-dev.ru/evidence/agents/revision-d5b786da/metrics/resources.svg)

[Container memory: three snapshots without external processing: source data](https://komaroff-dev.ru/evidence/agents/revision-d5b786da/metrics/resources.json)

## Limitations

- Codex Gateway is the sole data source; local Codex Desktop and App Server files are not read.
- Encrypted reasoning is not reconstructed, hidden system/developer instructions are not stored, and no traffic only means no new events.
- Agent hierarchy appears only with explicit proxy identifiers; the system does not start, stop or reconfigure models.
- Automatic sanitization covers known secrets, while the owner still reviews the full preview before publishing.

## Running and operating

Monitoring is enabled independently for permitted proxy users. Ordinary raw tracing remains disabled.

Text history is retained for 24 hours, the usage ledger for 90 days, the stream is limited to 1 GiB and the file outbox to 256 MiB.

Before a change, trace UI to API to SQLite projection to JetStream event to proxy observer, update the contract and verify redelivery.

Disable with MONITOR_ENABLED=false and proxy recreation; keep SQLite, JetStream and outbox data during rollback.

The current console is named Codex Monitor. /console/youtrack exposes gateway, NATS and queue status. Archived screenshots may show the previous UI. Upstream styling license notices remain in the repository.

## Screenshot index

1. [Archived screenshot of the previous version: The protected owner console shows real Codex sessions, the active request, available reasoning text, responses and proxy token usage.](https://komaroff-dev.ru/evidence/agents/live/full/01-owner-console.png) — 2026-09-07, source `abbb6e4328f545dc7a6867bb58efb57b313a931a`.

2. [Archived screenshot of the previous version: A validation scenario for the Traffic tab: request attempts, duration, transport and sanitized event JSON share correlation identifiers.](https://komaroff-dev.ru/evidence/agents/live/full/02-traffic-inspector.png) — 2026-09-07, source `abbb6e4328f545dc7a6867bb58efb57b313a931a`.

3. [Archived screenshot of the previous version: A usage-accounting validation scenario separates input, cached, output and reasoning tokens and marks incomplete history.](https://komaroff-dev.ru/evidence/agents/live/full/03-usage-ledger.png) — 2026-09-07, source `abbb6e4328f545dc7a6867bb58efb57b313a931a`.

4. [Archived screenshot of the previous version: The Connection screen reports proxy, NATS, projector, cursor, outbox queue and any detected delivery gap.](https://komaroff-dev.ru/evidence/agents/live/full/04-delivery-health.png) — 2026-09-07, source `abbb6e4328f545dc7a6867bb58efb57b313a931a`.

5. [Archived screenshot of the previous version: The publication preview reveals the permitted text, history starting point and link lifetime before a public broadcast is created.](https://komaroff-dev.ru/evidence/agents/live/full/05-publication-preview.png) — 2026-09-07, source `abbb6e4328f545dc7a6867bb58efb57b313a931a`.

6. [Archived screenshot of the previous version: After test links are revoked, the public index exposes neither private work sessions nor owner-side service identifiers.](https://komaroff-dev.ru/evidence/agents/live/full/06-public-index.png) — 2026-09-07, source `abbb6e4328f545dc7a6867bb58efb57b313a931a`.

7. [Archived screenshot of the previous version: A published validation session renders a real model response, reasoning and messages in read-only mode without control actions.](https://komaroff-dev.ru/evidence/agents/live/full/07-public-session.png) — 2026-09-07, source `abbb6e4328f545dc7a6867bb58efb57b313a931a`.

8. [Archived screenshot of the previous version: The mobile console retains session selection, event timeline and usage indicators in a narrow viewport without horizontal scrolling.](https://komaroff-dev.ru/evidence/agents/live/full/08-owner-console-mobile.png) — 2026-09-07, source `abbb6e4328f545dc7a6867bb58efb57b313a931a`.

Screenshots, diagrams and the original evidence package retain their source language. Captions and this document are translated into English.

[Original evidence package](https://komaroff-dev.ru/downloads/agents-evidence.zip)
