Systems operations / Field note
Four Surfaces, One Operating Record
I use separate surfaces for execution, commitments, conversation, and durable knowledge. The system works because each one has a narrow job and none becomes a competing version of reality.
The problem was never a shortage of tools
An AI operation can become confusing very quickly. A request starts in chat. An agent begins work. A task gets created. A document appears somewhere else. Soon four places claim to describe the same work, and each says something slightly different.
I did not want a larger dashboard. I wanted a reliable answer to four ordinary questions:
- What did we agree to do?
- Who or what is doing it?
- What needs my approval?
- Where is the material I should actually read?
My current setup uses Hermes, Vikunja, Discord, and Docmost. The names matter less than the roles. Hermes executes and orchestrates. Vikunja holds commitments and approval state. Discord is where conversation and approval happen. Docmost holds durable, human-readable knowledge.
That division is not a recommendation that everyone install these four products. It is an implementation pattern that fits the operation I have built. A small team could reproduce it with different software, or fewer surfaces, as long as the ownership boundaries remain clear.
“One operating record” also does not mean one giant database. It means one coherent account of the work, with each class of information stored once and linked across the surfaces that need it.
A source of truth for each kind of information
I use a simple responsibility table:
| Information | Authoritative surface | What belongs there |
|---|---|---|
| Execution | Hermes | Tool use, routing, bounded delegation, validation, retries, and internal automation |
| Commitment state | Vikunja | The agreed outcome, owner, priority, blocker, approval requirement, and completion state |
| Conversation | Discord | Questions, discussion, review, and explicit human decisions |
| Durable knowledge | Docmost | The complete artifact, operating guide, decision packet, or production material people need to read |
This keeps each surface useful without asking it to become something it is not.
Hermes may know that a worker ran, a file changed, or a validation passed. That does not make its session history the project plan. Vikunja may say that a review is waiting on me, but the task should not contain a second copy of a long report. Discord may contain the conversation that produced a decision, but scrolling through old messages is a poor way to discover current state. Docmost may contain the approved working material, but it should not pretend that every paragraph is a task.
The links between these systems carry less information than people expect. A task can point to the durable document. A document can state its status and decision boundary. A chat message can name the task and link to the material under review. Hermes can update the task after it verifies the document. The full content does not need to be pasted everywhere.
One work item moving through all four surfaces
Consider a sanitized example: I ask for an internal operating guide that may later support a public article. The public release is a separate decision.
The request begins in Discord because that is where I can explain intent in ordinary language. I can say what I want, correct a misunderstanding, and set a boundary such as “prepare the package, but do not publish it.” Conversation is allowed to be messy. Commitment state is not.
Once the request is clear enough to act on, Vikunja gets one outcome-level task. It records the owner, priority, current state, and the fact that publication requires my approval. If the work has several internal steps, those do not automatically become several tasks. Detailed production activity belongs with the work unless a step creates a distinct commitment or blocker that I need to see.
Hermes then performs the bounded internal work. It can collect the approved source material, route a specialist review, assemble the guide, and run checks. The agent is allowed to organize, research, draft, and maintain internal systems. It is not allowed to turn preparation into publication, spending, outreach, credential changes, or another external commitment. If the boundary is unclear, the operation stops and comes back to me.
When the guide is coherent enough for human use, the full material goes into Docmost. This is important. A task comment saying “finished” beside an obscure server path is not a handoff. The durable page needs the actual recommendations, caveats, evidence boundaries, and next action. Vikunja receives a concise update and a link rather than a duplicate copy.
The item then moves to a visible approval state. Discord is where I discuss it and give or withhold the decision. Vikunja records that the decision is still required, or that it has been supplied for this exact action. Silence is not approval. Approval for one article is not standing permission to publish the next one.
After the internal deliverable and its task state are verified, the task can close. If publication is later approved, that is handled as its own controlled action against the exact reviewed revision.
A write is only a claim until it is read back
The most useful implementation rule in this stack is also the least glamorous: after a consequential write, read the exact target back.
An API returning success tells me that a request was accepted. It does not prove that the right record now has the right state. We have seen why this distinction matters. A replacement-style task update can preserve the title while accidentally clearing an assignee or description. A create request can fail ambiguously after the server has already committed the record. Retrying blindly can create a duplicate. A document update can succeed while leaving the page under the wrong parent or missing a required section.
The control is concrete:
- Search for the stable task, page, or marker before creating anything.
- Write to one exact target.
- Read that target back.
- Check the fields that matter, not merely the title or HTTP status.
- Retry only after reconciling what the system actually stored.
For a task, that may mean verifying owner, labels, description, approval state, and open or completed status. For a durable page, it may mean checking the parent, expected headings, current decision, and absence of superseded instructions. For a message delivery, it means preserving enough evidence to distinguish delivered, failed, and uncertain. “Probably sent” is not a safe state from which to send again.
This is also why the automation uses stable markers and idempotent transitions. If a run stops halfway through, the next run should resume from verified state rather than recreate the work from memory.
Where competing records come from
Most failures are not dramatic. They are small disagreements that survive long enough to become operational facts.
A stale chat message says the draft is ready, while the task still shows an unresolved blocker. Someone creates a new task because they did not find the existing one. A decision is made in conversation but never reflected in the approval state. An agent writes a document, receives a success response, and reports completion without checking that the correct page changed. A long task comment becomes a second document and then stops matching Docmost.
Duplicated state creates a nasty question: which copy wins? If the answer depends on timestamp archaeology or personal memory, there is no operating record. There are only clues.
My prevention rules are deliberately plain. Search before create. Keep one outcome-level task. Put full human-facing material in the knowledge surface. Keep operational task updates short. Record approval against the exact action. Read every consequential write back. Preserve uncertain delivery evidence instead of treating uncertainty as permission to retry.
These controls do add maintenance. Links break. APIs change. Permissions drift. Backups and access boundaries need attention. Every surface creates another place to secure, test, and explain. I would not add a fifth system because it has a pleasant interface or overlaps one feature. I would add one only if it owns a genuinely new information class or enforces an authority boundary the current four cannot handle cleanly.
The test is not whether the stack looks sophisticated. The test is whether I can open the commitment, reach the current material, see the approval boundary, and trust that the recorded state was verified. If I can do that, four surfaces still behave like one operation.