Agent Island

JSONL is easy to underestimate. One object per line sounds like a format you can parse with a short loop. A live coding-agent transcript adds the cases that make that loop unsafe: a partial final append, an unusually large record, duplicate events, provider-specific envelopes, and old completion markers that later activity has invalidated.

Here is the defensive design we use before inferring session state.

Bound I/O before JSON parsing

Do not read an unbounded transcript into one string. Use a streaming reader and a documented line policy. Agent Island v1.7.1 currently uses different released safeguards on each platform: the macOS Claude reader has a 64 MiB backstop, while the Windows reader skips a line above 1,000,000 characters before parsing.

Those are not one shared limit. They are platform-specific policies with the same goal: one malformed or pathological record should not take down the rest of the scan.

Project only fields that can change state

Broad deserialization creates accidental dependencies on unrelated payloads. A monitor needs a smaller provider-aware projection.

For Claude, useful fields include type, uuid, timestamp, message.stop_reason, isSidechain, isApiErrorMessage, and toolEndsTurn. For Codex, released readers inspect fields such as type, payload.type, payload.turn_id, role, timestamp, completed_at, and started_at.

read bounded line
  -> parse JSON
  -> project provider-specific fields
  -> attach identity and semantic time
  -> reduce ordered events into state

Enter fullscreen mode Exit fullscreen mode

Completion is a candidate

A completion-shaped event belongs to one turn. A later user message or start event means the session moved on. The reducer must compare semantic order and allow later activity to supersede the older completion.

This is also why file modification time is not enough. One file can contain several turns, and the newest event may contradict an earlier stop marker.

Reject false completion envelopes

A syntactically valid line can still be semantically wrong for a foreground alert.

  • Rate-limit and API-error envelopes are not successful completion.
  • A sidechain or subagent finish is not automatically a main-thread handoff.
  • Tool activity can continue after a model stop marker.

Run provider-specific guards before the generic completion reducer.

Let file changes trigger a fresh reduction

Agent Island watches JSONL files for changes and keeps polling as a fallback. Event-driven observation reduces delay; polling recovers from a missed watcher notification. A partial line skipped now can be reconsidered after the next append.

Caching unchanged files by path, size, and modification time is useful, but the cache must invalidate when the source changes. Caching is an optimization, not permission to freeze an old state.

Eight tests worth keeping

  1. A malformed line does not abort later valid records.
  2. A partial final line becomes readable after an append.
  3. An oversized line follows the documented platform policy.
  4. A duplicated event does not create a second alert.
  5. Later user activity supersedes older completion.
  6. An API-error envelope does not become completed.
  7. A sidechain finish does not page the user for the parent session.
  8. Polling recovers a missed watcher event.

Safe JSONL parsing is bounded I/O plus provider-aware semantics, ordering, deduplication, and refresh behavior. The complete implementation notes and current scope are in the canonical guide.