AI Coworkers: Not Just Chatbots or Agents
Two codebases asking where a long-running AI coworker should live. ai-coworkers is a standalone TypeScript runtime driven by markdown job descriptions. hermes-governance is the same boundary model rebuilt as a Hermes plugin, to find out how much of it an existing host can carry.
Overview
Two repositories, written in that order, testing the same idea from opposite ends. ai-coworkers is a TypeScript runtime where each coworker is a directory of markdown role docs plus its own SQLite event log and tiered memory. The docs are the job description: ROLE.md and RESPONSIBILITIES.md for the remit, TOOLS.md and SENSORS.json for capabilities and what it can perceive, WORKSPACE.md for the teams, systems and health signals it watches, RELATIONSHIPS.md for the humans and other coworkers it works alongside, AUTHORITY.md for what it settles alone against what it escalates, BOUNDARIES.md for the hard lines, and RITUALS.md for recurring work. A tick loop senses the world through read-only sensors, skips the LLM entirely when nothing changed, and checks every write action against the boundary docs before it executes. hermes-governance takes one component of that runtime, the boundary check, and rebuilds it in Python as a plugin for Hermes: 529 lines across boundaries_parser.py and __init__.py, hooked on pre_tool_call and on_session_start, parsing the same BOUNDARIES.md into three rule types and blocking the call inside the host. The first asks what a coworker needs. The second asks how much of that an existing agent host will accept.
Problem
I met people running Hermes agents as digital coworkers, one per team member, and the setups work. The agent remembers, it has a personality file, you talk to it in Slack. It is still a chat agent with continuity, and the human is still the one holding the map of the work. What I am after is an entity with a job description: role and responsibilities, sensors and capabilities, a graph of the work it touches (tasks, docs, systems), the customers and business domain it serves, its coworkers and how it relates to each of them, boundaries and rules, escalation paths, and broader goals broken down into tasks. Given that, it can notice work, decide whether it is theirs, and escalate instead of guessing. Chat-native agents act when spoken to, and none of the harnesses already out there (Hermes, OpenClaw, ElizaOS as long-running assistants, CrewAI as a task orchestrator) model the rest of it.
Constraints
- A coworker that runs all day cannot call the LLM every tick, idle cost has to be zero
- Write actions against real systems (Linear, GitHub, Slack) need a hard gate, not a prompt suggestion
- Role tuning has to be editable by a human in markdown, no YAML, no code changes
- Must reuse existing tool integrations rather than invent another plugin format
Approach
Studied the harnesses already out there (Hermes and OpenClaw for SOUL/MEMORY files and skills, ElizaOS for providers-actions-evaluators, Vercel Eve for the filesystem-first agent folder, MemGPT and the CoALA paper for tiered memory) and fused the parts that survive contact with a real backlog. The runtime is a tick loop: budget, sense, perceive, quiet gate, deliberate, boundaries, act, record. The quiet gate is the thesis. If nothing changed and no ritual is due, the tick costs nothing. Everything ships dry-run by default so you can watch a coworker for a day before granting live access. The second track runs the experiment the other way round. Rather than argue that a new runtime is needed, I took the boundary layer to Hermes as a plugin and measured what fitted. Three rule types, one markdown file, the same discovery order a Hermes user would expect, and a missing file left as a no-op warning rather than a hard failure. Where the port stopped tells me as much as where it worked.
Key Decisions
A quiet gate that skips the LLM when the world has not changed
A long-running coworker is idle most of the time. Sensors are cheap read-only calls, so the loop compares world state, pending rituals, and operator notes before spending a single token. Quiet ticks also double the sleep interval up to a cap, so an idle coworker converges on near-zero cost.
One directory per coworker, role defined entirely in markdown
The docs read like a job description because that is what they are. RELATIONSHIPS.md names the manager who consumes the summaries and the sibling coworkers who escalate into this one. WORKSPACE.md holds the projects, the health signals, and how the manager likes summaries written. AUTHORITY.md splits decide-alone from escalate from never. Edit markdown, restart, new behaviour. The layout takes Eve's filesystem-first idea and extends it from one agent definition to a fleet of roles that know about each other.
Boundaries enforced by the runtime rather than the prompt
Every action is checked against BOUNDARIES.md before it reaches the target system. A blocked call logs boundary.block and never executes. A prompt is only a suggestion. The runtime check is what guarantees a coworker stays out of a client-data team.
Adapters over a new plugin format
MCP servers, Hermes/OpenClaw/Anthropic skills, and Eve agent folders already exist and already have tools. An adapter layer means a coworker can use any of them without this project owning a plugin registry.
Build the boundary layer twice, once standalone and once inside Hermes
Hermes has the users and the momentum, and SOUL.md is prose, which is an aspiration rather than a fence. hermes-governance is the second build: a Python plugin that parses BOUNDARIES.md into a must-not-touch denylist, a per-tool field allowlist and resource limits, then evaluates every pre_tool_call and blocks the ones that violate them. Must-not-touch entries use word-boundary matching against the tool name and every string value in the args, so billing does not match billion. The markdown format is identical to the runtime's, so a role directory moves between the two without a rewrite. Two implementations of one rule set is the only way to tell which parts of a coworker are portable.
Keep the runtime alive rather than fold it into the plugin
The plugin proved the boundary model travels. It also showed what does not: the work graph, the relationships between coworkers, and the escalation paths have no hook to attach to, because Hermes has no place where an agent's model of its own remit lives. Retiring the runtime now would retire the parts still being tested. Which of the two survives is the open question, not a decision already taken.
Dry-run as the default, live access granted per coworker
Every write returns {dryRun: true, would: {...}} until the operator passes --live. Trust is earned per coworker, the same way you would onboard a person.
Tech Stack
TypeScript Node.js SQLite FTS5 MCP Vitest systemd Ollama Linear API Python (Hermes plugin)
Result & Impact
- ~4.2k lines TypeScript, 279 tests, 97.8% line coverageai-coworkers runtime
- 529 lines Python, 16 tests, 2 Hermes hookshermes-governance plugin
- MCP, Hermes skills, Eve folders, nativeTool adapters
- 6 (working to reflective, CoALA taxonomy)Memory tiers
The runtime is stable and has been running against a real Linear workspace, triaging a live backlog in dry-run and then live mode. The highlights log interleaves the coworker's private thoughts with its actions, so a human can skim a day of work in one file. The coding coworker is scaffolded but not yet wired to a real coding agent. hermes-governance is at 0.1.0 and enforces the boundary rules it parses, which answers one third of the fit question and leaves the rest open. Where this ends up is undecided: a standalone runtime, a set of contributions to Hermes, or a boundary plugin that outlives the runtime it came from.
Learnings
- Deciding not to act is the hard part. Getting a model to do work is easy, getting it to recognise that a tick contains no work for its role took the quiet gate, the noop action, and an explicit pace signal.
- Job descriptions are a better agent config format than YAML. Writing AUTHORITY.md forces you to decide what the coworker settles alone versus escalates, which is the exact question that makes delegation to a person work.
- A private thoughts channel that threads across ticks does a lot of work. The coworker reads its own recent thinking on the next tick, which turns a stateless loop into something that follows through on what it started.
- Escalation beats guessing. A persistent questions file the coworker sees until a human answers removes the pressure to invent an answer and act on it.
- Meeting people who run one Hermes agent per team member changed what I think the missing piece is. Memory and personality are solved. The map of the work is not, and it currently lives in the human's head.
- Writing the same rules twice, in TypeScript and in Python, is what told me which ideas are portable. Anything expressible as a check on a tool call fits a Hermes hook. The work graph, the relationships between coworkers, and the escalation paths do not, because there is no hook where a model of the agent's own remit lives.