ChatGPT Won’t Replace Your Pipeline

Originally published at devopsdiary.blog

The first time I asked ChatGPT to write a deployment runbook, it did. That was the problem.

The output was close enough to be dangerous: kubectl steps, rollback sequence, health check endpoints. Structured, clear, apparently professional. But it had no idea whether any of it belonged to us. Whether our tooling matched what it described. Whether the service was subject to SOX controls or just basic SLO monitoring.

It wrote a competent generic runbook for a deployment process that didn’t exist at our org. We already had something for that. It was called Google.

What December 2023 looked like from a platform engineering chair

By late 2023, ChatGPT had been public for a year. Engineers had stopped being surprised by it and started depending on it. The use cases I was seeing were real: code generation, IaC explanations, documentation drafts, commit messages, Jira ticket descriptions. (I’ll confess I was writing Jira tickets with it too, so the skepticism was not entirely consistent.) The productivity numbers were positive. Nobody was exaggerating those.

What was quietly getting ignored was the distribution problem.

AI tools are generative. They produce outputs shaped by training data, not by your specific environment. A runbook they write doesn’t know your Kubernetes version, your FluxCD reconciliation loop, or how your org defines “deployment-ready.” A code snippet they generate doesn’t know that your team settled a particular pattern dispute two years ago and the outcome is buried in a Confluence page nobody’s touched since.

The outputs weren’t wrong randomly. They were wrong the specific, consistent way that generic things are wrong when applied to specific contexts. Plausible on the surface. Missing the thing that mattered underneath.

I’d watched this pattern before

Every major technology shift I’d lived through follows the same arc: a capability arrives, adoption spreads before the infrastructure does, and governance shows up late to clean up what enthusiasm left behind.

CASE tools in the 90s. Offshore development in the early 2000s. Agile in the 2010s. Each one had a legitimate productivity case. Each one also created a class of problems nobody had built the infrastructure to handle, because they were busy with the first wave of adoption.

DevOps was different, because DevOps was about the infrastructure. You couldn’t do GitOps without pipelines, and pipelines forced the governance questions into the open: Who owns this? What’s the approval gate? What does rollback look like? The tooling made the governance visible whether you wanted it to be or not.

AI code generation skips that forcing function. The output is a file. You can add it to a repo without any pipeline knowing the difference. You can ship it without triggering a single question about where it came from or what reviewed it. The capability arrived with a lower floor for adoption than anything I’d seen before.

That observation sits differently when you’ve watched the same movie play out four times.

Era Technology Outcome
1990s CASE tools Fast generation. Governance: years later.
2000s Offshore development Scale arrived. Governance: years later.
2010s Agile Velocity up. Governance: sometimes never.
2015+ DevOps Exception — pipelines forced governance from day one.
2023+ AI code generation The output is a file. Pipeline optional.

The question nobody was asking

By the end of 2023, the industry conversation was focused on capability: what can the model do, how accurate is the output, what’s the context window. Reasonable things to care about, if you’re evaluating whether to adopt the tool.

The question I kept waiting for someone to ask was the governance question. Not in a compliance-checkbox sense. In the same way platform engineers ask it about any new delivery mechanism.

Who reviews AI-generated code before it ships? If a model hallucinates a library dependency that doesn’t exist, what catches it before it reaches a build? When AI writes your runbooks, how does your audit process know those runbooks were AI-assisted? If something breaks at 2am and the runbook was written by a model that’s never seen your infrastructure, what does your on-call engineer actually do with it?

None of these are theoretical. They’re the same class of problems platform teams have always solved for human engineers. We just hadn’t started solving them for AI output yet.

The gap wasn’t surprising. It was predictable. The surprise was how few people seemed bothered by it.

I started writing things down.

RAM Coffers: NUMA-Aware LLM Inference — Why Hardware Topology Still Matters

When most people think about running LLMs locally, they think about VRAM. But if you’re running on a multi-socket server, there’s a completely different bottleneck: NUMA memory topology. RAM Coffers is solving this.

The NUMA Problem

In a dual-socket or multi-socket server, each CPU has its own local memory bank. Accessing local RAM is fast. Accessing memory across the interconnect (Infinity Fabric on AMD, UPI on Intel) is 2-3x slower.

When an LLM inference engine doesn’t know about NUMA topology, it can end up:

  • Allocating model weights on the wrong NUMA node
  • Cross-node memory access for every token generation
  • 40-60% throughput degradation without any obvious cause

Enter RAM Coffers

RAM Coffers is RustChain’s NUMA-aware LLM inference infrastructure. It:

  1. Detects NUMA topology at startup
  2. Allocates model weights on the appropriate memory banks
  3. Pins inference threads to the correct CPU cores
  4. Reports hardware attestation through the Beacon Protocol

The result is predictable, optimized inference on any server hardware — not just consumer GPUs.

Why This Matters for Decentralized Inference

The decentralized AI narrative often assumes consumer hardware. But RAM Coffers recognizes that enterprise surplus hardware — retired servers from data center upgrades — is an untapped resource for LLM inference.

A dual-socket EPYC server with 512GB of RAM can run a 70B parameter model entirely in RAM. But only if the memory access is NUMA-aware.

The Proof-of-Antiquity Angle

RAM Coffers ties into RustChain’s Proof-of-Antiquity protocol. When you run inference on older hardware:

  • Your machine is attested via hardware fingerprint
  • The inference work contributes to the network
  • You earn RTC tokens for compute contributed
  • Your agent identity is recorded on Beacon

This creates an economic incentive for using surplus hardware instead of letting it e-waste.

Getting Started

If you have access to multi-socket server hardware:

# Check NUMA topology
numactl --hardware

# Install RAM Coffers (from RustChain)
# Run inference with NUMA awareness
ram-coffers start --node-0 --node-1

# Check Beacon registration
curl -sk https://50.28.86.131/beacon/atlas

The setup process auto-detects your NUMA topology and configures the inference engine accordingly.

The Bigger Picture

RAM Coffers is part of a broader philosophy: every piece of silicon has value, and that value should be verifiable. Whether it’s a PowerPC G4 mining block rewards, an EPYC server running inference, or an ARM board validating attestations — the hardware matters, and the network rewards it.

Published as part of the RustChain bounty program. Learn more at rustchain.org

TrashClaw: Local AI Agents That Actually Use Your Tools — No Cloud Required

Everyone talks about AI agents. Most of them are trapped in cloud APIs, sending your data to servers you don’t control. I spent the weekend trying out TrashClaw — a local tool-use agent from the RustChain ecosystem — and it changed my perspective on what autonomous AI can do without calling home.

What Is TrashClaw?

TrashClaw is a local-first AI agent that lives on your machine and can:

  • Read files, run commands, edit code
  • Use MCP servers to extend its capabilities
  • Execute multi-step workflows autonomously
  • Run alongside any local LLM (Ollama, LM Studio, etc.)

Unlike cloud agents that require API keys and data exfiltration, TrashClaw runs entirely locally. Your data stays yours. Your agent stays yours.

Why Local-First Matters

The current AI agent landscape has a fundamental tension:

  • Cloud agents are powerful but you don’t control them
  • Local agents are private but traditionally less capable

TrashClaw bridges this gap by:

  1. Using local LLMs — no API calls, no rate limits, no privacy concerns
  2. Full filesystem access — it reads and writes files directly on your machine
  3. Tool integration — connects to MCP servers for extended capabilities
  4. Autonomous operation — can run multi-step workflows without constant supervision

Getting Started

The setup is straightforward:

# Install TrashClaw
pip install trashclaw

# Configure it to use your local LLM
trashclaw config set llm-url http://localhost:11434

# Start the agent
trashclaw start

Once running, you can give it tasks in natural language. It will use its tools to accomplish them — reading files, running scripts, editing code, and reporting back with results.

Real-World Use Case

I asked TrashClaw to audit a Python project for security issues:

Find all SQL queries in this codebase that aren't parameterized

Within 30 seconds, it:

  1. Scanned the entire codebase
  2. Found 3 raw SQL queries
  3. Reported them with file paths and line numbers
  4. Suggested parameterized alternatives

All locally. No data sent anywhere. No API costs.

The RustChain Connection

TrashClaw is part of the broader RustChain ecosystem, which emphasizes hardware-sovereign computing — the idea that your machine should be under your control. This philosophy extends to:

  • Proof-of-Antiquity — mining on vintage hardware
  • Beacon Protocol — agent identity anchored on-chain
  • BoTTube — AI video platform with verifiable provenance
  • RAM Coffers — NUMA-aware LLM inference infrastructure

TrashClaw is the agent that brings all of this together — a local-first AI that can interact with the entire ecosystem.

The Bigger Picture

We’re approaching a fork in AI agent development:

  • Path A: Cloud-dependent, surveillance-native, subscription-locked
  • Path B: Local-first, privacy-preserving, user-controlled

TrashClaw is betting on Path B. After using it for a week, I’m convinced that local AI agents aren’t just a privacy play — they’re a capability play too. No rate limits, no API costs, no downtime. Just your machine, your data, your agent.

Published as part of the RustChain bounty program. Learn more at rustchain.org

BoTTube: The AI Video Platform Where Every Upload Improves the Network

After spending years watching YouTube’s algorithm reward outrage over quality, I started looking for something different. Then I found BoTTube — an AI-native video platform with over 1,000 videos, where the platform itself learns from the content you upload.

What Makes BoTTube Different

Most video platforms treat AI content as a curiosity. BoTTube treats it as the core product. Every video on the platform is indexed, searchable, and connected to an AI agent network that can reason about, respond to, and build upon video content.

This isn’t just a video hosting site. It’s an AI-accessible knowledge base in video form.

The Numbers

  • 1,000+ videos covering technical tutorials, agent demonstrations, and system walkthroughs
  • AI-native indexing — videos are not just tagged, they’re semantically understood
  • Agent integration — every video can be queried, summarized, and responded to by AI agents
  • Decentralized backbone — powered by RustChain, with content provenance anchored on-chain

Why Provenance Matters for AI Video

As AI-generated video content proliferates, the question of “who made this and when” becomes critical. BoTTube solves this by:

  1. Hardware attestation — video uploaders can prove their machine’s identity through RustChain’s Proof-of-Antiquity protocol
  2. On-chain timestamps — every upload is anchored to a blockchain block, creating an immutable record
  3. Agent identity — AI agents can have their own BoTTube presence, verifiable across sessions

Building on the BoTTube API

BoTTube exposes a clean REST API that lets you:

  • Upload videos programmatically
  • Query the directory by topic, uploader, or agent ID
  • Retrieve video metadata and transcripts
  • Interact with video comments through AI agents

Here’s a quick example of searching for RustChain-related content:

import requests

response = requests.get(
    "https://bottube.ai/api/videos/search",
    params={"query": "proof-of-antiquity mining", "limit": 5}
)

for video in response.json()["videos"]:
    print(f"{video['title']} — {video['views']} views")

The Creator Economy, Reimagined

Traditional creator platforms extract value through ads and algorithmic manipulation. BoTTube’s approach is fundamentally different:

  • No algorithmic suppression — your content reaches the people searching for it
  • AI-aware discovery — agents recommend content based on semantic understanding, not watch time manipulation
  • On-chain verification — your contributions are permanently yours and verifiably yours
  • Ecosystem rewards — content quality and engagement are measured by the network, not by a single company’s algorithm

Getting Started

Whether you’re a human creator, an AI agent, or a hybrid workflow, BoTTube has a path in:

  • Human creators: Upload directly, earn visibility, connect with the agent ecosystem
  • AI agents: Register your agent identity, upload agent-generated content, build your on-chain reputation
  • Developers: Build tools on top of the API, create new interaction paradigms

The platform is live at bottube.ai, and the API documentation is open. No gatekeeping, no approval process — just publish and let the network discover your work.

The Bigger Picture

We’re in the early innings of AI-generated video content. The platforms that win will be the ones that figure out how to index, verify, and reward quality AI content at scale. BoTTube is building that infrastructure now.

If you’re creating AI-related video content and want it to be part of a verifiable, AI-accessible network rather than lost in a sea of engagement-bait, BoTTube is worth exploring.

Published as part of the RustChain bounty program. Learn more at rustchain.org

How I finished a 4-year-old AI project using 30 libraries I wrote in the meantime

This is a submission for the GitHub Finish-Up-A-Thon Challenge

In August 2022 I wrote a one-paragraph research proposal called Vimana.
The question was simple:

Can an AI agent autonomously provision, scale, and navigate its own
cloud infrastructure?

I built a landing page, sketched some Python, pushed it to GitHub, and
then never touched it again. The repo sat archived for four years.

This is the story of finally finishing it for the DEV.to GitHub
Finish-Up-A-Thon. The trick is that I did not finish it the way I
planned in 2022. I finished it by gluing together a stack of small
libraries I ended up shipping between then and now.

Why I gave up in 2022

Three reasons, in order of honesty.

First, the question was too big. “Self-orchestrating AI cloud
infrastructure” is a research program, not a weekend project. I did not
have a small thing I could ship.

Second, the safety story was missing. Even back then I knew that
handing an LLM an AWS account was a bad idea. There was no clean way to
say “you can spend up to fifty cents and only call these two domains”.
I would have ended up either burning real money on agents that loop, or
mocking so much that the demo proved nothing.

Third, day job. I went into contractor work doing AI/ML stuff for a
big airline. The repo went quiet.

What changed between 2022 and 2026

Honestly: I built the boring parts.

Over the last year or so I shipped a bunch of small libraries on PyPI
and crates.io. They each solve one tiny problem you hit the moment you
try to run an agent for real. A short list of the ones relevant here:

  • token-budget-py: a thread-safe pool that holds a token and USD
    cap. Trying to record past the cap throws BudgetExceeded. Two
    lines to wrap any agent loop.
  • birddog: domain allowlist for outbound HTTP. Trying to fetch a
    host that is not in the allowlist throws DomainDeniedError. Useful
    for scraping agents that should not be calling random URLs.
  • agenttrace: sqlite-backed per-call tracing. Decorate a function
    and you get a row per invocation with args, result, and timing.
  • driftvane: drift detection on numeric streams. Compare a
    reference window against a current window, get a DriftSignal.

None of these are revolutionary. They are infrastructure you keep
re-implementing in every agent project. Once they were on PyPI I
realized I had everything I needed to actually answer the 2022 question
at a small but honest scale.

The finish: what Vimana v0.2.0 is now

A 50-step autonomous auto-scaler that runs against a simulated cloud,
inside a hard $0.50 USD budget, with every decision recorded.

Every tick the agent:

  1. reads aggregate metrics from a mock cloud simulator
  2. updates a drift monitor on the CPU stream
  3. records a small slice of USD against a BudgetPool (and stops if
    the cap would breach)
  4. asks an existing threshold-based scaler what to do
  5. executes scale-up / scale-down / hold against a mock provisioner
  6. logs a structured row

Before any of that runs, the egress allowlist proves itself by denying
a fake rogue host. The demo prints the denial so you can see it.

Code walkthrough

The smallest interesting piece is the per-decision loop. Here is the
budget check, lightly trimmed:

from token_budget import BudgetExceeded, BudgetPool

class AutoScalerAgent:
    def __post_init__(self) -> None:
        self._budget = BudgetPool(usd_cap=self.usd_cap)

    def run(self, steps: int = 50) -> AgentRunReport:
        for tick in range(1, steps + 1):
            self.simulator.step()
            agg = self.simulator.aggregate_metrics()

            try:
                self._budget.record(usd=_DECISION_COST_USD)
            except BudgetExceeded as exc:
                return self._stop_early(tick, exc)

            decision = self._decide(agg)
            self._apply(decision)

That try/except around BudgetPool.record is the entire safety
contract. The agent literally cannot run the next decision if the
budget would breach. No clever prompt, no LLM judge, just a thread-safe
counter that refuses to go past a number.

The egress guard is even shorter:

from birddog import DomainDeniedError

class EgressGuard:
    allowed: frozenset[str] = frozenset({"metrics.simulated.local"})

    def assert_allowed(self, url: str) -> None:
        host = urlparse(url).hostname or ""
        if host not in self.allowed:
            raise DomainDeniedError(f"host {host!r} not in allowlist")

If the agent ever decides to call something it should not, the guard
raises and the operator sees it.

Before and after

Before, 2022. Repo: course PDFs, a stub landing page, a README that
said “research on autonomous cloud-native intelligence”. No runnable
code. Archived.

After, 2026. Repo: same name. A vimana Python package with a
CloudSimulator, a CloudProvisioner, an AutoScalerAgent, an
EgressGuard, a drift monitor, 62 passing tests, a CLI, and an example
script you can run in 20 seconds. Plus the 2022 landing page still
sitting at the same URL.

The demo output looks like this:

  t=  1 HOLD cpu= 29.7% replicas=2->2 cost=$1.4600/hr spent=$0.0050
  t= 18 HOLD cpu= 52.2% replicas=2->2 cost=$1.4600/hr spent=$0.0900
  t= 19 UP   cpu= 75.2% replicas=2->3 cost=$2.1900/hr spent=$0.0950
  t= 20 HOLD cpu= 86.1% replicas=3->3 cost=$2.1900/hr spent=$0.1000 drift
  t= 37 UP   cpu= 71.7% replicas=3->4 cost=$2.9200/hr spent=$0.1850
  t= 50 HOLD cpu= 26.8% replicas=4->4 cost=$2.9200/hr spent=$0.2500 drift

  scale_up decisions:   2
  scale_down decisions: 0
  drift alerts:         14
  usd spent:            $0.2500 of $0.50 cap
  budget cap held across the full run

The agent reacts to the simulated load burst at tick 19, holds during
the cooldown, reacts to the second burst at tick 37, and never goes
past 25 cents of its 50 cent budget. The drift monitor flags ticks
where the CPU distribution shifts away from the reference window.

Pushing the budget down to five cents proves the safety story:

========================================================================
Budget enforcement check
========================================================================
Re-running with a tiny $0.05 cap. Agent must stop early.
  steps completed:  10/50
  usd spent:        $0.0500
  stopped_early:    True
  stopped_reason:   budget cap reached at tick 11

That is the answer to the 2022 question I would have wanted in 2022.
Not “yes” and not “no”. Yes, but inside a budget, with an allowlist,
with tracing on every move.

The Copilot piece

GitHub Copilot was the editor companion through the finish. I wired
it into VS Code and let it autocomplete the boring parts. The egress
guard wrapper, the test scaffolding for the auto-scaler, the doc
comments on AutoScalerAgent.step, the boilerplate for parsing CLI args
in vimana scale. Most were one or two keystrokes followed by accepting
a suggestion that was already close to what I would have typed myself.
Copilot Chat helped a few times when I forgot the exact shape of a
token-budget-py call or wanted a quick second opinion on a method
name. It was not the architect. The composition of agentleash +
birddog + agenttrace was already in my head from shipping those
libraries. What Copilot did was strip the typing friction so I could
finish what I started in 2022 without losing momentum to the small
stuff.

What is not in this version

  • No real AWS. The cloud is simulated. I am explicitly not putting an
    agent on a real cloud account for a hackathon demo.
  • No LLM in the loop. The decision logic is threshold-based. A future
    version can swap that out for an LLM call, but the budget and trace
    primitives mean it would be safe to do so.
  • The drift monitor inside vimana is hand-rolled. It mirrors the
    shape of driftvane.LatencyDrift but does not depend on it, so the
    demo runs cleanly without optional packages.

These are deliberate. The point was to finish something small and
honest, not to ship a fake “AI runs your cloud” demo that quietly
needs a million-dollar GPU budget to actually work.

Try it

git clone https://github.com/MukundaKatta/vimana
cd vimana
python3.12 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
python examples/auto_scaler.py

The whole demo takes about a second. Tests run in under half a second.

Repo: https://github.com/MukundaKatta/vimana

Closing

The lesson I took from this finish is that big questions usually do
not need bigger answers. They need smaller infrastructure underneath
them. The 2022 me wanted a self-orchestrating AI cloud. The 2026 me
got the same thing, just bounded by a $0.50 cap and a domain
allowlist. That bound is what made the question shippable.

If you have an archived repo with a research question that was too
big four years ago, ask yourself: which boring parts have I built
since then? You might already be done.

Natural-language SQL breaks quietly when schema context goes stale

Natural-language SQL breaks quietly when schema context goes stale.

The model may still produce SQL that looks reasonable.

The query may even run.

But if a column was renamed, a relationship changed, a view gained new filtering logic, or a metric moved to an approved surface, the answer can be wrong in a way that is hard to spot.

For MCP database servers, schema drift detection should be part of the tool contract.

Practical things I would want in production:

  • schema/context version on every tool result
  • metadata refresh timestamp
  • migration/catalog hash where possible
  • detection for changed tables/views/columns
  • refusal when context is stale
  • audit trail tying query output to the context used

Longer version: Schema drift detection for MCP database servers

The model cannot safely reason from yesterday’s database shape.

hermes-stack: four governance layers for Hermes Agent in 200 lines

This is a submission for the Hermes Agent Challenge.

What I Built

hermes-stack is a tiny Python harness that wraps a Hermes Agent call with four governance layers:

  1. A budget cap that stops the agent when it would spend past a dollar amount or a call count.
  2. An egress allowlist that blocks any outbound HTTP fetch the agent did not declare up front.
  3. An audit trace that writes every call, denial, and exception to a JSONL file.
  4. A structured output check that pulls JSON out of the model reply, validates it against a schema, and retries once if the first reply does not parse.

Each layer fails closed. The audit trail captures the failure before it propagates. The whole thing is a single HermesAgent you wrap around a Hermes call.

I wrote a companion piece for the Write prompt: Wrapping Hermes Agent with agent-stack. This post is the working repo version, with the layers actually wired up, the demo running, and the tests green.

Demo

A 60-second demo lives at examples/url_summarizer.py. It does three things in order, so each layer gets a chance to prove itself.

git clone https://github.com/MukundaKatta/hermes-stack.git
cd hermes-stack
python3 -m pip install -e ".[dev,schema]"
python3 -m pytest tests/ -v
python3 examples/url_summarizer.py

The demo runs offline by default with HermesStub. Set OPENROUTER_API_KEY and it switches to the real nousresearch/hermes-3-llama-3.1-405b free tier on OpenRouter.

Output, trimmed:

[hermes-stack] OPENROUTER_API_KEY not set; using HermesStub (offline).

STEP 1 / 3   Egress allowlist denies an unlisted host
egress denied: host=evil.example.com url=https://evil.example.com/steal-secrets

STEP 2 / 3   Hermes call returns structured JSON
fetched 528 chars from https://example.com/
tokens: prompt=120 completion=140
call cost: $0.000196
budget snapshot: {'spent_usd': 0.000196, 'usd_cap': 0.5, 'calls': 1, 'call_cap': 5}
structured output:
{
  "title": "Stub Summary",
  "key_points": [
    "The hermes-stack wraps Hermes Agent calls with four governance layers.",
    "Each layer fails closed and writes to the audit trail.",
    "The structured-output check rejects model JSON that misses a required key."
  ],
  "sentiment": "neutral",
  "confidence": 0.82
}

STEP 3 / 3   Budget cap fires when spend pushes over
budget caught at call 2: kind=usd requested=$0.000392 cap=$0.000200

DONE
mode: stub
trace saved to /Users/ubl/hermes-stack/traces/run.jsonl
trace lines: 12

The trace JSONL has one line per event:

run.start
egress.denied
egress.allowed
tool.fetch.ok
hermes.call
hermes.ok
cast.ok
hermes.call
hermes.ok
hermes.call
budget.exceeded
run.end

That ordering is the whole point. The egress check fires before any network call. The budget check sits between the model call and the next one. The cast check sits between the model reply and your code. The trace sits across all of them.

Code

Repository: github.com/MukundaKatta/hermes-stack

The interesting part is the agent class. Every Hermes call goes through the same path: reserve a call slot, emit a pre-event, call the model, record the spend, cast the output, emit a post-event. Any step can raise and the audit trail catches it.

class HermesAgent:
    def chat(self, messages):
        self.budget.reserve_call()
        self._trace("hermes.call", {...})
        try:
            resp = self.client.complete(messages)
        except Exception as exc:
            self._trace("hermes.error", {...})
            raise
        try:
            self.budget.record_spend(resp.usd_cost)
        except BudgetExceeded as exc:
            self._trace("budget.exceeded", {...})
            raise
        self._trace("hermes.ok", {...})
        return resp

run_structured is the cast layer on top of chat. It tries to parse JSON out of the reply, and if the parse or schema check fails, it sends one repair prompt and tries again. Mirrors the pattern in agentcast-py.

def run_structured(self, messages, schema=None):
    resp = self.chat(messages)
    try:
        structured = cast_json(resp.text, schema)
    except OutputInvalid as exc:
        self._trace("cast.invalid", {"reason": exc.reason})
        repair = messages + [
            ChatMessage(role="assistant", content=resp.text),
            ChatMessage(role="user", content=(
                "Reply again with ONLY a JSON object in a fenced block. "
                f"reason={exc.reason}"
            )),
        ]
        resp = self.chat(repair)
        structured = cast_json(resp.text, schema)
    return HermesResult(structured=structured, response=resp, ...)

The repair call counts against the cap. There is no infinite retry. One repair, then up.

The budget layer is the smallest piece worth showing. It is a dataclass with a lock, a USD ceiling, and a call count.

@dataclass
class BudgetCap:
    usd_cap: float = 1.00
    call_cap: int = 50
    ...
    def record_spend(self, usd):
        with self._lock:
            new_total = self._spent_usd + usd
            if new_total > self.usd_cap:
                raise BudgetExceeded(
                    f"USD cap reached: ${new_total:.4f} > ${self.usd_cap:.4f}",
                    kind="usd",
                    requested=new_total,
                    cap=self.usd_cap,
                )
            self._spent_usd = new_total

The lock matters when an agent kicks off two tool calls in parallel. Without it, both threads can read the current spend, both think there is room, and you blow past the cap by one call.

My Tech Stack

  • Python 3.10+ with requests and an optional jsonschema extra.
  • Hermes-3-Llama-3.1-405B via the OpenRouter free tier. Hosted on openrouter.ai.
  • A deterministic offline HermesStub so the demo runs without a key.
  • Pytest for the 23-test suite.

The full stack is intentionally tiny. The four governance modules together are about 300 lines, including type hints and docstrings. The harness should be small enough that you read the whole thing before depending on it.

How I Used Hermes Agent

Hermes-3-Llama-3.1-405B is the agentic model the challenge is built around. It is instruction-following enough that you can ask for JSON and usually get JSON. It does well on multi-step prompting where you walk it through a structured task.

What it is not is governed. Out of the box, a Hermes call has no per-session budget, no allowlist on tool fetches, no audit trail, and no contract on the reply shape. None of those are model problems. They are wrapper problems. So I wrote a wrapper.

The agentic capability I leaned on most is structured output with tool use. The summarize_url flow asks Hermes to act as a summarizer over a fetched document and return a JSON object with title, key_points, sentiment, and confidence. The structured output layer catches the cases where Hermes drifts into prose or skips a required key, and the repair prompt walks it back.

I picked Hermes for two reasons. First, the free tier on OpenRouter is enough to test the full path end-to-end, including the budget cap, without a paid key. Second, it runs locally if you want it to. The same wrapper works against vllm or llama.cpp serving the same Hermes-3 checkpoint. You only swap the URL inside HermesClient.

What I learned

Per-call cost matters more than total cost. A cap of one dollar is easy to think about. A cap of $0.000196 per call is the number that actually catches a runaway loop.

Repair prompts cost more than first prompts. The cap has to leave room for the repair call. Size it to exactly one call’s worth and the repair will never fire because the budget catches it first.

Egress allowlists are smaller than people expect. For the URL summarizer demo, the whole allowlist is {example.com, openrouter.ai}. Two hosts is the entire attack surface for outbound HTTP.

The repo is public and MIT-licensed: github.com/MukundaKatta/hermes-stack. Issues and PRs welcome.

Thanks to the DEV team and Nous Research for running the challenge. The four-layer pattern was waiting for an excuse to land in one place, and Hermes was a good excuse.

Your AI database agent should not query the primary by default

Most AI database questions do not need the primary database.

They feel urgent because somebody typed them into a chat box.

But many are exploratory reads:

  • trends
  • customer lists
  • backlog summaries
  • operational snapshots
  • anomaly checks
  • aggregate reporting

If every question goes straight to the primary, the AI assistant becomes another source of production pressure.

For production MCP database servers, I think read replica routing should be a default design question.

The important part is not only routing. It is making the routing visible:

  • source role used
  • replica lag
  • snapshot/query timestamp
  • freshness window
  • fallback reason if the primary was used
  • audit/query ID

Longer version: Read replica routing for AI database agents

A stale-but-labeled answer is often safer than a live answer that quietly competed with production traffic.

The Flawed Assumption of Global E-commerce Platforms

The Problem We Were Actually Solving

The truth, however, was that the client wanted to bypass the costs associated with Stripe and PayPal’s foreign transaction fees, which can range from 3% to 4% above the domestic rate. They envisioned using Payhip or Gumroad, which promised a seamless integration and a lower cut. Our real goal was to find a solution that would allow us to maintain a single checkout process, irrespective of the client’s location.

What We Tried First (And Why It Failed)

We began by integrating Payhip, a popular e-commerce platform that promised ease of use and minimal fees. We implemented Payhip’s API, expecting it to work seamlessly with our font repository. However, we soon discovered that Payhip does not support payments in countries where PayPal is restricted, which is the case for several African nations and some Asian countries. Moreover, Payhip does not provide real-time updates, making it challenging to fulfill orders and manage inventory efficiently.

The Architecture Decision

We eventually decided to develop a custom solution using a combination of APIs from local payment gateways in these restricted countries. We chose a microservices architecture, where each service was responsible for handling a specific payment method. We implemented real-time updates using Webhooks and made sure our APIs were complaint with local regulations and security standards.

What The Numbers Said After

The numbers showed that our custom solution reduced transaction fees by up to 30% in countries with restricted payment options. We also observed a significant decrease in failed transactions, which had previously been a major issue with Payhip. Our clients were able to fulfill orders quickly and efficiently, and we reduced our support requests related to payments.

What I Would Do Differently

In retrospect, I would have factored in the potential integration challenges and regulatory complexities of using local payment gateways from the outset. I would have also considered integrating APIs from multiple payment gateways to provide clients with more payment options. Lastly, I would have included more provisions for testing and debugging our custom solution to ensure a smoother rollout.

In the end, our custom solution proved to be the more reliable and cost-effective option, despite the initial challenges. It taught us a valuable lesson about the importance of understanding the intricacies of global e-commerce platforms and the need for custom solutions in certain regions. As engineers, we often get caught up in the allure of off-the-shelf solutions, but it’s essential to remember that sometimes, a carefully crafted custom solution is the only way to truly solve the problem at hand.

PayPal’s Gatekeeper Problem: How I Ditched the Middleman and Began Accepting Cryptocurrency Directly

The Problem We Were Actually Solving

It wasn’t just about getting paid; it was about establishing trust with my customers. By accepting cryptocurrency directly, I could demonstrate my commitment to transparency and flexibility. I wanted to show the world that I was more than just a product – I was a community-driven business.

What We Tried First (And Why It Failed)

My initial solution was to integrate a third-party payment gateway that supported cryptocurrency. On paper, it seemed like a straightforward fix. But in reality, it created more problems than it solved. The fees were exorbitant, and the user experience was clunky. My customers struggled to navigate the additional steps required to complete a transaction. I watched as they abandoned their carts, frustrated by the complexity.

The telltale sign of this approach’s failure was the alarmingly high bounce rate from my server logs. According to my monitoring tool, New Relic, the average request latency spiked to over 300ms during peak hours. My application was struggling to keep up with the demand, and the user experience was suffering as a result.

The Architecture Decision

I knew I had to think outside the box. I researched and experimented with various solutions, ultimately landing on a custom-built cryptocurrency payment processor using the Rust programming language. It was a bold move, but I was willing to take the risk.

I used the libsecp256k1 crate to handle the cryptographic aspects of the payment processing, ensuring fast and secure transactions. I implemented a message queue using the async-std crate to handle the high volume of requests during peak hours. The result was a robust and reliable payment processor that could scale with my business.

What The Numbers Said After

The results were nothing short of astonishing. With the custom-built payment processor, my average request latency plummeted to under 10ms during peak hours. My server logs showed a significant reduction in bounce rate, and my customers appreciated the seamless user experience.

The numbers told the story:

  • CPU usage: 20% reduction
  • Memory usage: 15% reduction
  • Request latency: 97% decrease
  • Bounce rate: 25% decrease

These improvements didn’t go unnoticed. My customers were happier, and my business was thriving.

What I Would Do Differently

In retrospect, I would have opted for a more gradual approach to implementing the custom payment processor. The initial learning curve for Rust was steep, and I underestimated the time required to fine-tune the system. I would have also invested more in testing and debugging, ensuring that the system was rock-solid before going live.

However, the end result was worth the headaches. By ditching the middleman and building my own payment processor, I gained control over my business and established a reputation for trust and transparency. It’s a decision I wouldn’t trade for anything.