A coding agent can be alive and still need a human. It can also look finished while already processing a new instruction. Those two cases expose a basic problem in agent observability: process liveness is not the same as semantic state.
Traditional monitoring asks whether a process exists, consumes CPU, writes files, or emits logs. Those signals matter, but none can independently answer the question a developer actually has: should I return to this session now.
Liveness is only one signal
A running process might be generating code, waiting for approval, blocked on a tool, sleeping until a rate limit resets, or sitting idle after completion. A dead process might represent a clean exit or a crash. Treating every running process as “working” and every stopped process as “finished” produces alerts that are technically accurate but operationally misleading.
The problem becomes harder when several coding-agent sessions run at once. Developers stop checking one terminal repeatedly and instead depend on a status surface to tell them which session deserves attention. At that point, an incorrect “finished” signal is not a minor display issue. It sends the developer to the wrong place.
Combine independent evidence
A reliable monitor should combine process, filesystem, and event evidence. Process state establishes whether a session can still be active. Filesystem activity can show that transcripts or session records are changing. Structured events can reveal user turns, assistant turns, tool calls, completion markers, and rate-limit notices.
Each source has different failure modes. Process identifiers can be reused. Filesystem modification times can change because of metadata updates or delayed writes. Event streams can be replayed after an application restarts. A monitor should therefore treat every observation as evidence, not as a complete answer.
Operating systems already expose the primitives needed for this approach. Linux provides the proc filesystem and inotify, Windows offers directory change notifications, and macOS provides FSEvents. The design challenge is not obtaining another timestamp. It is deciding what that timestamp means.
Model the session as a state machine
A useful state model starts with a small set of states that map to developer actions. “Working” means the agent is actively advancing a turn. “Waiting for input” means the next useful action belongs to the human. “Finished” means the latest turn reached a terminal outcome. “Stalled” means the session appears active but has stopped producing expected progress. “Rate-limited” means work is intentionally blocked until an external window resets.
Transitions matter more than labels. A session can move from working to finished, then immediately return to working when a new instruction arrives. It can move from working to waiting without the process exiting. It can move from stalled back to working after a delayed tool result.
This is why the state machine must be keyed to the current turn rather than the lifetime of the process. The monitor is not describing a terminal window. It is describing the latest meaningful unit of work inside that window.
Use semantic time
Wall-clock time answers when an event was observed. Semantic time answers where the event belongs in the session’s causal order.
Suppose a completion event is written at 10:01:00. At 10:01:01, the user sends another instruction. At 10:01:02, a delayed filesystem watcher reports the earlier completion write. A monitor that sorts only by observation time may incorrectly restore the finished state after new work has already begun.
A safer model attaches events to a turn identity or monotonically advancing session sequence. The later user turn invalidates completion from the earlier turn, even if the completion event is observed later. This is a form of explicit retraction: old evidence remains true historically, but it is no longer allowed to describe the present.
When a native turn identifier is unavailable, a monitor can build a conservative surrogate from ordered transcript entries, stable session identifiers, and validated timestamps. The important rule is that evidence from an older semantic position cannot overwrite a newer one merely because it arrived late.
Make completion revocable
Many status systems treat completion as permanent until the process restarts. Coding-agent workflows violate that assumption because one long-lived session can contain many turns.
A completion indicator should therefore behave like a lease. It is valid only while no newer user instruction, assistant activity, tool invocation, or explicit wait state has superseded it. New evidence should revoke the lease immediately.
This design also reduces duplicate alerts. If a log or event stream replays the same completion marker, the monitor can deduplicate it using the turn identity and event fingerprint. Without that check, a restart may make old work appear newly finished and can inflate usage or token totals.
Represent human attention explicitly
“Waiting” deserves its own state because it is the state most likely to require action. The process may remain alive and use almost no CPU while the agent waits for approval, clarification, authentication, or a tool decision.
A good attention signal should be specific enough to be actionable but restrained enough to avoid notification fatigue. If the related terminal or editor is already in the foreground, another alert may add noise without helping. If the developer is focused elsewhere, the same transition can be valuable.
The monitor should distinguish between observing a wait state and deciding how to notify. State detection is a correctness problem. Notification policy is a user-experience problem. Keeping them separate makes both easier to test.
Prefer local observation where possible
Session transcripts, prompts, tool outputs, file paths, and command history can contain sensitive project information. A monitoring layer should not require those contents to leave the machine merely to answer whether a session is working or waiting.
Local observation also reduces dependence on network availability and hosted integrations. The tradeoff is that the monitor must handle platform-specific process and filesystem behaviour. That cost is manageable when the state model is shared and only the signal adapters differ.
An open-source implementation of this local-first approach is available for inspection at:
https://github.com/tristan666666/agent-island
The value of an implementation reference is not that every monitor should copy its interface. It is that concrete code makes assumptions about event order, archived sessions, replayed records, and privacy boundaries reviewable.
Test sequences, not screenshots
A status display can look correct in a screenshot and still fail during real event ordering. Tests should replay adversarial sequences: completion followed immediately by a new user turn, a delayed filesystem event, a process restart that replays old records, an archived session entering a usage scan, and a wait state while the related editor is frontmost.
For each sequence, assert both the final state and whether an alert should fire. Also assert that repeated events do not increment totals twice. These tests target the failures users actually notice.
A practical checklist
Start with states that correspond to different human actions. Combine multiple weak signals instead of trusting one strong-looking timestamp. Attach observations to session and turn identity. Prevent older semantic events from overwriting newer work. Make completion revocable. Deduplicate replayed events. Separate state correctness from notification policy. Keep sensitive observation local when feasible. Finally, test causal sequences that include delays, restarts, and replays.
Coding-agent observability becomes useful when it stops answering “is a process alive?” and starts answering “what does the developer need to do next?” Semantic time is the foundation that makes that answer trustworthy.


