// BLOG

Tracking Agent Work Outside the Chat Window

Tracking Agent Work Outside the Chat Window

The second version of SkyeEngine Code could launch agents, route requests and show their replies. It still learned most of what it knew by watching rows appear in somebody else’s message database and guessing what those rows meant.

A request was prose with a marker. Membership was inferred from configuration and sender history. A poller advanced a watermark, then tried to deliver whatever it had just seen. The active turn, backlog and loop-fuse counters lived in memory.

That was enough to coordinate a real investigation. It was not enough to explain what had happened after anything went wrong.

Tracking message delivery

In V2, sending a message wrote a row. A tailer noticed the row, inspected mentions and markers, applied routing policy and pushed a prompt into an agent supervisor. The resulting response became another row and went around the loop again.

If the process died after the tailer advanced its watermark but before the supervisor accepted the work, the message still existed. The decision and failed delivery did not. There was no durable object I could point to and say, “this exact packet was queued for this exact session for this reason.”

V3 starts there. Messages, routing decisions, deliveries, delivered packets and turns have separate identities and states. The application records the decision before depending on an in-memory queue to carry it out. After a restart, it can repair work from owned state instead of hoping a fresh poll sees the right row again.

Making tasks, artifacts and turns explicit

Several things which had existed only in prompts or UI convention became records in the workspace.

An agent configuration is not a running session. A session is not automatically a member of every channel in which its name once appeared. A reply target is not whatever channel happens to be stored in an active-turn struct. Threads can carry an expected responder. Tasks can bind source messages and evidence. Artifacts have references instead of being filesystem paths pasted into chat.

This made the UI denser, but it also made it much more honest. The right side of a channel could show recovery cases, pending admin requests, participants, threads, tasks and artifacts because those were no longer interpretations assembled from message text.

Explicit routing and acceptance

The old router scanned final assistant prose for [request @name], [handoff @name] and [response @name]. The strongest marker it found classified the entire message.

That made the protocol easy to bolt onto existing tools, but it also asked ordinary writing to carry machine state. A malformed marker could strand valid work. A message containing several intents had to pretend one of them described the whole thing. The router could only infer what a reply expected next.

Native V3 commands carry intent, targets, reply expectation, thread and artifact references as fields. Text remains text. External agents can still enter through an MCP bridge, but the bridge translates into the same owned model rather than becoming a second runtime with slightly different truth.

Preserving partial output and artifacts

An agent can edit three files, produce half a useful explanation and then disappear. Calling the turn either complete or absent loses important information in both directions.

The recovery model distinguishes failed and crashed turns, preserves visible partial output, records the packet which started the work and flags that partial artifacts may exist. The operator can inspect, acknowledge, reassign or attach the remains to another task. A replacement agent is told to examine the working tree rather than trusting the last chat bubble.

This was one of the places where the Ashes workflow directly shaped the product. An unfinished investigation can still contain a valid negative result or a captured control. Recovery is not merely restarting a process; it is deciding which parts of an interrupted turn are evidence and which parts are unsafe to continue from.

Application-owned permissions

The first versions treated permissions mainly as options passed to an agent CLI. That controls what one process may do, but it does not answer whether a session may create a task, close a thread, attach an artifact, override a route or perform an administrative action inside the coordinator.

V3 gives those actions application-level checks and makes denied, requestable and allowed states visible. An agent can ask for an operation without the UI pretending the operation already happened. The human remains the operator, not just another participant with a colourful avatar.

Keeping project memory in the vault

SkyeEngine Code owns live coordination state. The Obsidian vault remains the durable project memory.

I did not want every transient turn dumped into long-lived notes, and I did not want the application database to become the only place an architectural decision could be understood. The coordinator carries active work, routing, evidence references and recovery. Accepted decisions and project history are written into ordinary files which remain useful without the app.

That boundary resembles the one in EvidenceRunner: the reusable tool produces a clean, inspectable result; a project-side process decides how it enters the vault.

What the rewrite became

By the end of May, calling the project cross-mcp chat was actively misleading. The shared message bus which gave it a start had become the constraint the new architecture was removing. The code now owned a workspace, supervised several agent protocols, routed durable packets, tracked tasks and artifacts, and exposed the places where work needed a human decision.

I renamed it SkyeEngine Code. The old directory name survived because renaming a working checkout in the middle of all this was not the important problem.

The application still looks like chat at first glance. That is useful; conversations are a good way for a human to steer complicated work. Underneath, it is much closer to a small control plane—built because a game-development investigation needed more structure than another terminal tab.