Hermes was useful as soon as it could inspect a repository, search the web, edit files, and operate a browser. That was already more capable than a chatbot. It was also nowhere near an operating system for a company.

The gap was not intelligence. The model could usually produce a plausible plan. The gap was everything around the plan: knowing which context mattered, waking up without a prompt, carrying work through several tools, proving what happened, and stopping before a convenient action became an expensive mistake.

Hermes gave us a strong base. It is an open-source agent framework with model routing, persistent state, tools, skills, scheduled jobs, gateways, profiles, and delegation.[1] But those features are ingredients. The operating system emerged from the less glamorous work of deciding who may do what, where state lives, what counts as evidence, and when an agent must hand control back to me.

This is the layer we built at Comelse. It works on bounded workflows and remains unfinished. “Finished autonomous company” is still more marketing category than operating reality.

Chat was the wrong unit of work

An early setup centred on one broadly capable agent. It had access to files, a terminal, a browser, project notes, and enough personal context to be useful. The same agent could handle research in the morning, a code change after lunch, and an operational problem in the evening.

That felt efficient because every conversation started with a capable generalist. It also created a quiet failure mode: context accumulated faster than responsibility became clear.

A coding task could inherit irrelevant business history. Research could bleed into implementation assumptions. A personal preference could sit beside client delivery rules. The agent was not deliberately mixing them; it was doing what language models do, using whatever context looked predictive. More context produced more confidence, not necessarily better judgment.

The problem got worse once the agent could act. A vague answer is annoying. A vague answer with a terminal, an issue tracker, a mail account, and a production dashboard is an employee with no job description and every key in the building.

We now treat each task as a bounded run rather than one more turn in a conversation:

  • one objective;
  • an explicit source of context;
  • a defined tool and permission set;
  • a completion claim with an evidence gate;
  • a retry budget;
  • a known human boundary.

That sounds bureaucratic. It is. So are database transactions and seat belts.

Giving the agent hands changed the risk

Hermes tools cover web research, files, terminal commands, browser automation, memory, scheduling, and delegation.[3] In our setup, the same agent can inspect a repository, read a project brief, patch code, run a build, open the deployed page, and compare the result with the request.

That continuity is the point. It removes the human work of copying output between five specialist apps and explaining the same project six times.

It also means a successful tool call cannot be the definition of success. A click can land on the wrong control. A deploy command can return successfully while the old build remains live. A browser can display cached CSS against new HTML. An API can accept a request that another process later reverses.

During this website’s rebuild, new HTML reached production while the stable stylesheet URL could still return an older cached body. The pages existed; the rendered release was inconsistent.

The fix was not “hard refresh.” The build now fingerprints the stylesheet URL from its contents. We checked that production HTML requested the expected fingerprint and that the returned stylesheet matched the local build. That small failure taught the larger rule: verify the state the user receives, not the action the agent performed.

Memory is not one thing

“Persistent memory” sounds like one feature. In practice, one giant memory is a landfill with embeddings.

Hermes includes bounded profile memory that is injected when a session starts.[5] We use that only for hot facts that should shape almost every turn: how I like to work, hard security boundaries, canonical project locations, and rules that would cause damage if forgotten.

Everything else has a different home.

Stable preferences belong in bounded profile memory. Project truth belongs in canonical records, transactional state in the run database, and reusable procedures in skills. Searchable conversation history remains evidence of what was said, not the current source of truth.

Hermes skills are on-demand procedural documents rather than permanent prompt material.[4] If an agent learns how to deploy a particular application, recover a browser session, or verify a production bug, that method becomes a skill. The next run loads it when relevant. It does not carry a forty-page operations manual into a request to edit one paragraph.

The agent should consult the source that owns a fact before leaning on recent conversation, and use old transcripts only for archaeology. That preserves continuity without letting a stale chat fragment outrank the current record.

One agent became several roles

Hermes profiles run independent agents on the same machine. Each profile has its own configuration, credentials, memory, sessions, skills, scheduled jobs, and gateway state.[2]

We use that separation for coordination, implementation, verification, research, communications, finance, and experimental work. The profile names are less important than the ownership map.

The coordinator can read broadly, break down work, and route it. The implementation role can modify source and produce a tested change. The verification role inspects the resulting commit and the deployed system. Research can range widely without inheriting delivery authority. Finance remains separate because “helpful agent with broad context” is not an accounting control.

This separation reduces accidental trust without pretending profiles are a security sandbox.

A Hermes profile isolates agent state, not operating-system permissions. A local terminal still runs with the permissions of its user.[2] If two profiles can read the same directory, calling them separate agents does not make the directory separate. We use profiles to prevent memory and responsibility from blending. Sensitive boundaries still require filesystem permissions, separate credentials, restricted tools, or a different process account.

We learned to enforce authority by removing capabilities, not by adding stern prose. An implementation subprocess that should not mutate the project tracker does not receive the tracker credential. Telling a model “do not touch production” while leaving production credentials in its environment is not a permission system. It is a motivational poster.

Prompt-only restrictions proved too weak. Implementation workers no longer receive mutation credentials unless the task requires them and the run’s role allows it.

Agents hand off artifacts, not confidence

Hermes can delegate work into child agents with fresh, isolated conversation context.[7] That is useful for parallel research, focused code review, and workstreams that would otherwise fill the parent conversation with noise.

Fresh context is also merciless. A child knows only what the parent gives it, plus explicit project context files. It does not share the parent’s intuition, half-finished assumptions, or memory of a screenshot from twenty minutes ago.[7]

We treat that as a feature. Every handoff should survive amnesia.

A useful implementation handoff contains the task, constraints, repository state, changed files, test output, commit identity, and unresolved risks. A deployment handoff adds the live target and build identity. A QA handoff records the expected behavior, version under test, browser evidence, and pass or failure reason. The summary helps with orientation; the artifacts carry the claim.

For coding work, we also use isolated Git worktrees when the canonical checkout is dirty or shared. Git worktrees provide separate working directories attached to the same repository.[9] The agent can implement and test without rearranging a human’s uncommitted work. Push blocking can be installed when the slice is review-only. “The coding agent probably will not push” is not rollback planning.

Scheduled work needs a contract

An agent waiting for a prompt is an assistant. Scheduled work becomes an operations layer only when its scope and reporting rules are explicit.

Hermes scheduled jobs run in fresh sessions, can attach skills, execute recurring or one-shot work, and deliver to configured destinations.[6] Its messaging gateway connects the agent to communication surfaces and runs the scheduler in the background.[8]

That lets us build routines around actual operating rhythms: inspect queues, collect research, watch deployment health, prepare briefings, or check whether a previous run needs recovery.

The trap is to schedule open-ended ambition. “Improve the company every night” sounds exciting until the agent invents busywork at 03:00 and sends a cheerful report about it.

A good scheduled job has a finite source, a narrow decision, and a silence contract. It knows exactly what to inspect. It knows what change crosses the reporting threshold. If nothing requires action, silence is a valid result. If the check itself failed, silence is not valid.

Some scheduled work does not need a model at all. Deterministic health checks, cleanup scripts, and threshold alerts should remain scripts. Adding an LLM to a disk-space check is an elegant way to make df slower and less trustworthy.

We also limit unattended runs to one meaningful task where possible. That keeps retries, evidence, and rollback attached to one outcome. A cron job that claims five tasks, edits three repositories, deploys two apps, and runs out of context before state writeback has not increased throughput. It has created archaeology.

Operational state belongs outside language

Once several runs could wake without me, conversational context was no longer enough to coordinate them. Automated runs now use a small control plane.

Runs have explicit states. Workers claim leases. Retries are bounded. Idempotency keys stop repeated jobs from performing the same side effect twice. Deployment identity and QA status are stored as data rather than described in a summary.

Language models are good at interpreting messy situations and bad at being the only database for those situations. “I think another agent is handling it” is not a lock. “This was probably deployed” is not a state transition. The control plane makes those failures visible and recoverable.

We separate semantic knowledge from transactional coordination for the same reason. The knowledge system can remember that a project uses a particular deployment pattern. The run database decides whether this task is claimed, implemented, awaiting deployment, awaiting QA, complete, failed, or blocked. One helps the agent reason. The other prevents two agents from reasoning themselves into the same side effect.

Status words became contracts

The most useful protocol we added is embarrassingly simple: an agent may not upgrade a status claim beyond the evidence it can produce.

“Done” means the requested artifact exists and was read back.

“Verified” means the relevant test, build, browser check, or external readback actually ran.

“Deployed” means the provider accepted the release and the live target returned the expected version or content.

“Blocked” means a concrete dependency remains after bounded alternatives, not that the first command was annoying.

“Silent” means the required checks ran and nothing crossed the reporting threshold. It does not mean the detector died quietly.

These definitions sound pedantic until several agents and scheduled jobs start producing summaries. Without shared semantics, every green message means something different. One worker means “I wrote code.” Another means “tests passed locally.” A third means “the deployment command returned zero.” The human sees three versions of “done” and discovers the difference in production.

We now design high-impact workflows backwards from the allowed claim. If the job is expected to say “deployed,” the protocol must include live verification. If it cannot access the live target, it may say “deploy triggered, not live-verified”—a less impressive and far more useful claim.

The builder cannot grade its own homework

Implementation and verification have different incentives. The builder wants to complete the task. A good verifier wants to break the claim.

Our implementation workers stop before final approval. A separate QA role reads the task, checks the commit and deployment identity, exercises the live behavior, and either passes the work or reopens it with evidence.

For frontend work, that means rendered browser checks, not only source inspection. The earlier deployment contract requires the live endpoint and expected build identity. External mutations are read back. A missing page must return a real HTTP 404 rather than a custom error design served with status 200.

The verifier is still an agent, so independence is not magic. It needs a different context, explicit acceptance criteria, and access to the evidence. It must also be allowed to fail the work. A “review agent” whose prompt is optimized to celebrate the builder is two instances of the same lie.

We keep humans in the final loop for high-impact or taste-heavy work. Independent agent QA reduces the amount I must inspect. It does not transfer legal, commercial, or aesthetic responsibility to a model.

What broke along the way

A few failures exposed gaps that the contracts above did not cover.

Browser sessions taught us to distinguish public pages, isolated automation profiles, and a human’s logged-in browser. The fastest way to destroy confidence in an agent is to let it steal the tab someone is using.

Deployment drift is why the “deployed” contract records both source and live build identity.

Noisy scheduled jobs taught us that a healthy system should often say nothing. Alerting on every transient failure trains the human to ignore the one alert that matters.

Long, confident summaries taught us to prefer IDs, paths, URLs, checksums, screenshots, and test output. Prose can explain evidence. It should not replace it.

None of these are exotic AI research problems. They are ordinary operations problems made sharper by a worker that can move quickly and explain mistakes persuasively.

What is genuinely autonomous today

In configured workflows, we have used bounded runs to gather context, modify code, run tests, build artifacts, and prepare handoffs. Separate deployment and QA runs can inspect the live target and return failures to the queue. Scheduled research and operational checks can wake themselves, use stored procedures, and report only when something needs attention.

We feed recurring failures back into the operating layer. A repeated browser failure becomes a reusable recovery skill. A deployment ambiguity becomes a provenance check. A noisy monitor becomes a deterministic script. The point of “self-improving” is not that the model rewrites its personality every night. It is that recurring work gets a better procedure and a smaller chance of surprising us next time.

This is autonomy at the workflow level. It is not general authority.

What still requires me

I own the decisions that change the company’s exposure.

That includes public claims, client commitments, payment, credential handoff, destructive production actions, legal or compliance judgment, and anything where taste is the product. The agent can research, draft, simulate, or prepare. It does not get to convert ambiguity into consent.

I also decide what deserves automation. Agents are very capable of improving a process that should have been deleted. Sometimes the correct output is a small script. Sometimes it is a clearer form. Sometimes it is leaving a competent human alone.

The intended trade is less founder time carrying context between tools and more time setting boundaries, reviewing evidence, and deciding where the system should act next. That is a better use of a founder than copying task details from an inbox into a ticket and then asking whether staging updated.

The operating system is the boring part

Hermes is the runtime underneath this setup. It provides the agent loop, tools, profiles, memory, skills, schedules, gateways, and delegation. We built the operating system in the contracts between them.

Writing code and opening a browser are commodities. The useful part is a piece of work waking with the right context, using bounded authority, surviving a failed tool, producing an inspectable artifact, passing through independent verification, and stopping at the human boundary.

That system is less cinematic than an autonomous-agent demo. It is also the first version I would trust with real work.