← All work
ProductionMarch to September 2026Final-year engineering project

Ops Agent

A harness I developed that turns an AI coding runtime into an autonomous operational agent, run entirely from plain-language files.

70–80%lower instruction-loading token cost
~42%less run time with parallel sub-agents (estimated)
~70%fewer unsupported claims (estimated)

The need

Generative AI can produce working code on demand, yet companies still struggle to put it to work on real operations. Building and maintaining a bespoke agent for every need recreates the engineering bottleneck that automation was meant to remove, and the knowledge those agents rely on ages the moment it is written down.

At the company where I built this, operational know-how was fragmented and quickly stale, classic automation broke on every exception, and hiring an engineer per AI use case did not scale.

What I owned

The whole project, from framing the problem to the architecture, the implementation, the validation and the performance analysis. It was defended as my engineering final-year project in September 2026.

The solution

The Ops Agent is not a new model or a standalone application. It is a harness on top of Claude Code: Claude Code supplies the reasoning engine, and the harness supplies the identity, the guardrails, the memory and the enforcement that turn it into a disciplined, domain-specific operator.

One principle runs through everything: judgment lives in the agent, enforcement lives in the harness. Domain experts shape the agent by editing plain-language files, and changes apply at the next session, with no code and no redeployment.

It brings together four ideas that had not been combined for a real, guard-railed setting: a ReAct-style reasoning loop, a self-maintaining LLM Wiki, standard tool connectivity through MCP and CLI wrappers, and harness engineering.

The implemented harness: six layers around Claude Code. This is a capability map, showing what the system is made of.

Inside the harness

The AI brain

Claude Code is the reasoning core, and it holds no hard-coded business logic. It reads its governance files, matches the request against the skill index, opens the right skill, then alternates between reasoning and running commands.

Its defining constraint is that it is stateless: every session starts blank, and anything not written to disk is lost. Much of the architecture exists to compensate for that, including the knowledge base, the lessons log, the self-update rule and the hooks.

Governance: what the agent is and may do

Two files are injected in full before a single user message is read, and they are kept apart because they change for different reasons. This separates infrastructure from intelligence, so a non-engineer can shape how the agent reasons.

  • CLAUDE.md, the boot loader and permission ledger. It sequences session start, then defines three tiers that the agent checks before every tool call: pre-approved actions run directly, writes to external systems need human confirmation, and banned actions are refused even on explicit request.
  • AGENTS.md, the constitution. Nine sections cover identity, communication rules, hard guardrails, correction signals, skill dispatch, agent invocation, knowledge navigation, the self-update rule and the link format.
CLAUDE.md hands off to AGENTS.md, and both load before any work begins.

Execution: how the work gets done

Execution is the only sanctioned way the agent reaches outside its repository. It has four kinds of component:

  • Skills. One Markdown file per workflow, readable like a manual. Each one mixes reasoning instructions, exact CLI commands and hand-offs to other skills or tools, and documents its prerequisites, edge cases and what counts as done.
  • Scripts and CLI wrappers. Deterministic Python or shell programs that handle authentication, pagination and errors. Every script takes arguments, returns JSON, and offers a --dry-run for anything that writes. The agent may never bypass this layer.
  • MCP connectors. Ready-made integrations for services such as Notion, Slack and Google Drive, each with declared actions and permissions. Custom wrappers are kept for cases needing tighter control.
  • Schema references. Exact field names, parameters and IDs kept next to the skill that needs them, so the agent never guesses, and never pays to load a global schema it rarely uses.
Sub-agents, skills, schema references and scripts: how the agent acts on the outside world.
A real skill header. Its description is the text the dispatch index matches each request against.

Knowledge: what the agent knows

Nothing here is loaded in full just in case. The agent consults the specific file it needs, which keeps its context lean.

  • Skill and agent indexes. Compact dispatch tables. The agent matches a request to a skill by meaning, never by keyword, and only opens that one skill. Agents are spawned only under conditions written in the index.
  • Knowledge base. Three strict document types: best practices (“what should be done?”), expertise (“what is true here?”) and templates (“what format should this take?”).
  • lessons-learned.md. The agent’s persistent memory. Every correction is logged and re-injected at the start of every session, so a mistake fixed once is not repeated months later.
  • WIKI_structure.md. A registry of everything that exists and where it lives, which the consistency checks compare against what is really on disk.
Indexes route the request, the knowledge base informs the answer, and lessons learned compound over time.

Generative agents: how new capability enters

A hard guardrail forbids the main agent from writing a new skill, script or knowledge document itself. It must delegate to a specialist, spawned as a separate instance with its own clean context. None of them invents a missing detail: where something is unknown, they ask.

  • skill_creator checks a brief for completeness, batches clarifying questions, and writes only after the outline is approved.
  • script-creator builds from fixed templates, so every script is dry-run safe and follows the same CLI contract, then declares its permissions.
  • knowledge_base_creator first classifies what a document answers, then builds it from the matching template.
Each creator owns the complete process of adding one kind of capability.

Self-maintenance: staying coherent

Two agents keep what already exists correct. They never create production files.

  • wiki-updater keeps the structure accurate. After any turn that changed files, it reconciles the indexes and registry against the change log. If nothing is out of date, it correctly changes nothing.
  • CAM-updater keeps the meaning consistent. When a user corrects a rule, it finds the sibling files encoding the same logic, reads each one in full, fixes those that need it, and records the lesson.
Structural and semantic maintenance, with an independent consistency gate running outside the agent.

Hooks: turning “probably” into “always”

A rule in a prompt is only ever probabilistic, since the agent might forget or decide it is unnecessary. A hook is a shell script fired by a lifecycle event, and the agent has no say in it. Four are used: session-start.sh syncs the repository and injects memory, post-tool-use.sh logs every file change, stop.sh triggers maintenance at the end of a turn, and session-end.sh runs the audit at close.

For a system that must stay coherent across thousands of changes, the difference is everything.

Versioning: nothing is lost

Every turn ends with an automatic commit and push, using a denylist that excludes secrets and temporary state. Each push runs a GitHub Actions audit of eight checks, including required files, .env safety, index counts, path resolution and frontmatter validity.

Closing a session is stricter: a local audit, then the commit, then validation, and the push happens only if everything passes. So stop.sh optimises for liveness and session-end.sh for safety. A direct push by the agent needs human confirmation, while hook pushes are pre-approved, because the distinction is about who initiates the action.

Cross-references: the roads through the repository

Files are nodes and Markdown links are edges. Because the agent is stateless and context is expensive, it follows links to exactly the file it needs and reads nothing else. This is what makes the token saving possible, and it lets the whole repository be inspected as a graph in Obsidian.

Fewer tokens, less time and fewer hallucinations, all from following the path instead of scanning the tree.
The base version: structure, templates and internal agents.
A developed instantiation: the same core, surrounded by skills and knowledge.

How a session runs

Whether a person opens it from the terminal, the desktop app or VS Code, or a schedule or external event starts it with nobody present, every session follows the same three phases:

  • Working. The agent loads its context, detects whether the message is a correction or a request, then either propagates the correction or dispatches a skill, and answers with evidence.
  • End of turn. The change log decides whether maintenance runs at all. If files changed, the wiki-updater reconciles the indexes and the turn is committed and pushed.
  • Session close. A gated audit protects the shared repository, so a broken state never reaches it as a final version.
The work lifecycle from session start to session close.

How it was built

The project followed a 16-week plan that moved from a generic base, through instantiation, to autonomous operation. A base version with no domain content came first. Then came a full instantiation on a real system, Atlas, a competitive intelligence platform whose research agent, web app, deployment and monitoring are all produced and operated by the Ops Agent. Its skills, knowledge and integrations were generated by the base’s own creator agents, which is the proof that the architecture is reusable.

Results

All figures were derived from the Atlas repository and from a real competitor run.

  • 70–80% lower instruction-loading cost. The fixed boot context is about 10,900 tokens, only 8.6% of the governance tree, and the agent follows links to the files it needs.
  • About 42% less run time, estimated. A 28-minute sequential run could drop to 16–19 minutes by fanning out the nine independent research steps.
  • About 70% fewer unsupported claims, estimated. Nine grounding mechanisms were confirmed in the real run, including 67 explicit “not found” markers written in place of plausible filler.
The three KPIs as presented at the defence, including the scope of the token saving.