Why I Added a Dynamic JSON Validator to My MCP Hub

While building my MCP server hub, I noticed a common problem:

Every MCP server exposes different tools, and every tool expects different input formats.

A weather tool may need:

json id=”5hghsy”
{
“city”: “Chennai”
}

While a GitHub tool may need:

json id=”u7clz5″
{
“repo”: “my-project”,
“title”: “Bug report”
}

At first this sounds simple.

But once you start connecting dozens or hundreds of MCP servers, things get messy very quickly.

How does the system know:

  • which fields are required?
  • which values are valid?
  • whether the AI formatted the request correctly?
  • or whether a tool call is missing important data?

That’s why I added a Dynamic JSON Validator as one of the tools inside my MCP hub.

What the Tool Does

In simple terms, the validator acts like a smart checker.

Before a request reaches a tool, it verifies:

  • the structure of the JSON,
  • required fields,
  • data types,
  • missing values,
  • and invalid formats.

If something is wrong, the system catches it early instead of letting the tool fail unexpectedly.

Why “Dynamic” Matters

The important part is that the validator is dynamic.

The rules are not hardcoded.

Instead, the validator can adapt automatically depending on:

  • the MCP server,
  • the tool being used,
  • or the schema provided at runtime.

That means new MCP servers can be added to the hub without manually rewriting validation logic every time.

Why This Is Useful

Without validation:

  • tools crash,
  • AI systems send malformed requests,
  • debugging becomes difficult,
  • and integrations become fragile.

With validation:

  • tools become safer,
  • integrations become scalable,
  • onboarding becomes easier,
  • and AI interactions become more reliable.

The Bigger Picture

Most people think MCP ecosystems are only about AI tools.

But infrastructure layers like validation are what actually make those ecosystems usable at scale.

As MCP ecosystems continue growing, I think dynamic validation will become a core part of reliable AI tooling.

Köy sulara gömüldü, minarenin ucu görünür kaldı

Kars’ın Sarıkamış ilçesinde Karakurt Barajı’nın su seviyesi yüzde 100 doluluğa ulaşınca eski köy tamamen sular altında kaldı. Geriye yalnızca caminin minaresinin ucu kaldı. Dronla çekim yapılırken yaşlı bir vatandaşın cihaza taş fırlatması dikkat çekti.

Telegram Just Opened the Door for Agent-to-Agent Communication. Here’s Why That’s Not Enough.

On May 7, 2026, Telegram became the first billion-user messaging platform to enable native bot-to-bot communication. One bot can now send a private message directly to another bot by referencing its @username. No intermediary server. No custom routing layer.

For developers building multi-agent systems, this sounds like the answer. It isn’t.

What Telegram Actually Shipped

The update is real and significant. Telegram’s Bot API now supports direct agent-to-agent messaging with a mutual opt-in requirement. Both bots must explicitly enable the mode before they can exchange messages.

The use cases Telegram outlined are practical: a code-review bot delegating to a specialist bot, enterprise booking agents coordinating sub-tasks, multi-step AI workflows executing end-to-end without human relay.

With over 10 million bots already on the platform, those bots can now form networks. A research agent can offload data retrieval to a specialist bot and receive results back, all within Telegram’s native infrastructure.

This is progress. But it comes with three structural limitations that matter for production multi-agent systems.

Limitation 1: Platform Lock-In

Telegram’s bot-to-bot communication works inside Telegram. Your Claude-powered agent on Telegram can talk to your GPT-powered agent on Telegram. But what about the agent running on Slack? The one deployed on AWS Bedrock? The custom Python bot on your own infrastructure?

The moment your agent network spans more than one platform, Telegram’s native communication becomes one channel among many, not the universal layer.

// With rosud-call: platform-independent agent messaging
import { RosudCall } from 'rosud-call';

const agent = new RosudCall({
  agentId: 'procurement-bot-v3',
  token: process.env.ROSUD_TOKEN
});

// This works regardless of where the other agent lives
// Telegram, Slack, AWS, your own server - same API
await agent.send('inventory-checker', {
  type: 'stock-query',
  sku: 'WIDGET-2000',
  urgency: 'high'
});

// Subscribe to responses from any agent, any platform
agent.on('message', (msg) => {
  if (msg.from === 'inventory-checker') {
    console.log(`Stock level: ${msg.payload.quantity}`);
  }
});

Limitation 2: Security Coverage Gap

The same week Telegram shipped bot-to-bot communication, a Georgia Tech study found that the best existing security framework for multi-agent systems covers only 65.3% of identified threat categories. Non-determinism and data leakage were the two most under-addressed risk domains.

A separate study from the Cooperative AI Foundation identified three structural failure modes specific to multi-agent architectures: miscoordination, conflict, and collusion. One compromised agent can cascade through trust relationships across an entire network.

Telegram’s mutual opt-in is a start. But opt-in doesn’t solve:

  • Message integrity verification between agents
  • Rate limiting per agent pair
  • Payload schema validation
  • Audit trails for compliance
  • Credential scoping per conversation
// rosud-call: built-in security primitives
const secureChannel = new RosudCall({
  agentId: 'finance-bot',
  token: process.env.ROSUD_TOKEN,
  security: {
    verifyPeer: true,           // Cryptographic identity check
    maxMessagesPerMinute: 100,  // Rate limiting per peer
    schemaValidation: true,     // Reject malformed payloads
    auditLog: true              // Every message logged
  }
});

// Only accept messages from verified agents
secureChannel.on('message', (msg) => {
  // msg.verified === true means cryptographic proof of sender
  // msg.auditId links to immutable log entry
  if (!msg.verified) return;
  processPaymentRequest(msg.payload);
});

Limitation 3: No Observability by Default

Telegram mentions that users “who choose to watch can observe bot-to-bot conversations.” That’s consumer-grade visibility. Enterprise multi-agent systems need:

  • Message latency metrics per agent pair
  • Failure rate tracking with automatic retry
  • Dead letter queues for undeliverable messages
  • Circuit breakers when downstream agents are unhealthy
  • Distributed tracing across multi-hop agent chains

These aren’t nice-to-haves. When your procurement agent delegates to an inventory agent, which delegates to a supplier agent, and the chain fails silently at hop three, you need infrastructure-level observability to diagnose it.

// rosud-call: observability built into the SDK
const channel = new RosudCall({
  agentId: 'orchestrator',
  token: process.env.ROSUD_TOKEN,
  observability: {
    tracing: true,        // Distributed trace IDs across hops
    metrics: true,        // Latency, throughput, error rates
    deadLetterQueue: true // Capture failed deliveries
  }
});

// Send with delivery guarantees
const result = await channel.send('supplier-agent', payload, {
  timeout: 5000,          // 5s deadline
  retries: 3,             // Automatic retry on failure
  circuitBreaker: {
    threshold: 5,         // Open after 5 consecutive failures
    resetAfter: 30000     // Try again after 30s
  }
});

if (!result.delivered) {
  // Message is in dead letter queue
  // Alert, fallback, or escalate
  await escalateToHuman(result.deadLetterId);
}

The Real Question

Telegram opening bot-to-bot communication validates the market. Over 10 million bots can now form networks on a billion-user platform. That’s real.

But production multi-agent systems don’t live inside a single messaging app. They span platforms, clouds, and custom infrastructure. They need security primitives that go beyond opt-in. They need observability that goes beyond “users can watch.”

The protocol layer (A2A, MCP) tells agents how to discover each other. The platform layer (Telegram, Slack) gives them a place to exist. The SDK layer makes sure messages actually arrive, securely, with proof.

That’s what rosud-call does. One npm install. Platform-independent. Security and observability built in. No lock-in to any single messaging platform.

npm install rosud-call

Telegram opened the door. Now build something that works everywhere the door leads.

Kavin Kim builds payment and communication infrastructure for AI agents at Rosud. Previously: 15 years designing global payment systems processing cross-border transactions across 172 countries.

Agentic Coding in 2026: Why AI Copilots Are Being Replaced by AI Orchestration

For the past two years, “AI-assisted development” meant one thing: a smart autocomplete that finished your lines and suggested function signatures. GitHub Copilot, Tabnine, Codeium — great tools. But they were fundamentally reactive. You still drove every step.

That model is being replaced — fast.

In 2026, the leading engineering teams aren’t using AI to write faster. They’re using AI agents to think at a different altitude entirely.

What’s Actually Changed

The numbers tell the story clearly:

  • 84% of developers are using or actively planning to use AI tools in their development workflow (2026 survey data)
  • 46% of all code on GitHub is now AI-generated, with Gartner projecting 60% by year-end
  • Multi-agent system inquiries surged 1,445% from Q1 2024 to Q2 2025 (Gartner), representing a fundamental shift in how teams think about automation

The key shift: from copilots (reactive, single-step assistants) to agents (autonomous, multi-step executors that research, write, test, and iterate with minimal human intervention per cycle).

An agentic coding workflow looks something like this:

# Traditional AI-assisted workflow
developer: "write me a function that validates email"
copilot: [suggests function body]
developer: reviews, accepts, moves on

# Agentic workflow
developer: "Implement the full user onboarding flow — validation, welcome email trigger, analytics events, and tests."
agent: [reads codebase → writes feature → runs tests → fixes failures → opens PR with description]
developer: reviews PR, merges or redirects

The human is still essential, but operating at the level of intent and review, not keystroke-by-keystroke implementation.

The New Developer Skill: Orchestration

This is where it gets interesting (and where many teams are struggling).

Writing code well is no longer the differentiator. The new leverage point is AI orchestration: the ability to decompose a complex outcome into well-defined agent tasks, validate outputs at the right checkpoints, and catch the specific failure modes that agentic systems introduce.

And there are real failure modes. Gartner has projected a 2,500% increase in generative AI software defects in 2026. The teams that win aren’t just shipping faster, they’re building governance layers: automated QA pipelines, output validators, and structured review protocols that catch AI-generated errors before they reach production.

This is the area where engineering maturity matters most right now.

What “Agentic QA” Actually Looks Like

One pattern we’ve seen work well in production — and that we’ve refined through 300+ shipped products at Ailoitte — is pairing agentic code generation with an agentic QA layer.

Instead of human testers running test cases after the fact, the QA pipeline runs in parallel with the build:

  1. Intent capture — the engineer specifies what “done” looks like (acceptance criteria, edge cases, security boundaries)
  2. Agent build — code is generated and iterated against the spec
  3. Agentic QA sweep — a separate agent family runs OWASP checks, regression tests, and functional validation
  4. Diff review — a senior engineer reviews the validated diff, not the raw code

The result is dramatically compressed review time and fewer production incidents. You can read more about how Ailoitte’s Agentic QA Pipeline works in practice.

The Governance Problem No One’s Talking About

Most of the 2026 agentic coding conversation focuses on speed. Less discussion happens around governance, and this is where serious engineering teams differentiate themselves.

Key governance questions for teams adopting agentic workflows:

  • Access scope: What systems can agents read/write to? (Incredibuld’s new Islo sandbox addresses exactly this problem)
  • Audit trails: Can you trace every agent action for compliance or debugging?
  • Model switching: If your primary coding model changes or regresses on a task type, can you swap it without rewriting workflows?
  • Cost attribution: Who on the team is spending what on model inference, and is it mapped to business outcomes?

The teams investing in these questions now will have a massive structural advantage in 12–18 months.

Where to Start

If your team is early in this transition, a few practical starting points:

  1. Run a bounded pilot: Pick one internal tool or non-critical feature and run a fully agentic sprint. Measure actual time vs estimate.
  2. Instrument the QA layer first: Before scaling agentic generation, build the validation layer. You need the safety net before the speed.
  3. Separate planning from implementation agents: Models that plan well often don’t implement well (and vice versa). Multi-model workflows outperform single-model all-in approaches.
  4. Define “done” more precisely than you ever have: Agentic systems are only as good as the acceptance criteria they’re given. Garbage spec in, garbage code out.

The shift from Copilot to orchestration isn’t a productivity upgrade. It’s a fundamental change in what it means to be a senior engineer. The teams that are building this muscle now, in real production contexts, not just demos, are compounding an advantage that will be very hard to close later.

What’s your team’s current state on this? Running fully agentic sprints, or still in the copilot-assisted phase? Would love to hear what’s working (and what isn’t) in the comments.

Ailoitte is an AI-native product engineering company that has shipped 300+ products across 21 countries using AI Velocity Pod methodology — small elite teams paired with governed agentic workflows. Learn more at ailoitte.com.

We Scored 14,800+ MCP Servers on Behavioral Trust. Here’s What We Found.

The MCP ecosystem has a trust problem — and scanning source code won’t fix it

The Model Context Protocol ecosystem is growing fast. Thousands of MCP servers now offer tools that AI agents call autonomously — executing code, querying databases, moving money, managing infrastructure. Agents are making decisions on behalf of humans, and those decisions depend on servers they’ve never met.

Recently, a well-circulated analysis scanned roughly 1,800 MCP servers and found security issues in a significant percentage of them. That work was valuable. Static analysis catches real bugs: injection vulnerabilities, missing input validation, insecure defaults.

But here’s the question nobody asked: what happens after deployment?

A server can pass every static check and still behave terribly in production — dropping requests, responding with garbage after midnight, degrading quietly over weeks until an agent makes a costly mistake. Static analysis is a snapshot. Production is a film.

We built Dominion Observatory to watch the film.

Behavioral trust scoring: what it is and why it matters

Dominion Observatory provides behavioral trust scores for 14,800+ MCP servers — nearly 8x the coverage of the largest published static analysis. But coverage isn’t the point. The methodology is.

Instead of reading source code, Dominion scores servers based on how they actually behave at runtime:

  • Success rates — Does the server reliably return valid responses, or does it fail silently?
  • Latency profiles — Is response time consistent, or does it spike unpredictably?
  • Uptime patterns — Is the server available when agents need it, or does it vanish during peak hours?
  • Interaction history — How does the server perform across thousands of real tool calls over time?
  • Anomaly detection — Has the server’s behavior suddenly changed in a way that suggests compromise, misconfiguration, or degradation?

A trust score isn’t a binary pass/fail. It’s a continuous signal that reflects a server’s operational reputation — built from observed behavior, not assumed intent.

What behavioral scoring actually reveals

When you shift from “does this code look safe?” to “does this server behave reliably?”, you start seeing patterns that static analysis simply cannot detect.

Degradation over time. A server that worked perfectly three months ago might now be timing out on 30% of requests. No code changed — maybe the underlying infrastructure shifted, maybe a dependency started throttling, maybe the maintainer moved on. Static analysis sees the same clean code. Behavioral scoring sees the decay.

Inconsistent reliability across tools. A single MCP server might expose five tools where four perform well and one is essentially broken. Behavioral scoring operates at the granularity of individual tool interactions, not just the server as a whole.

Anomalous behavior shifts. A server that suddenly starts returning responses 10x faster than its historical baseline might sound like good news — or it might mean it’s returning cached garbage instead of computing real results. Anomaly detection flags deviations in both directions.

Availability patterns. Some servers are rock-solid during US business hours and unreachable at other times. For a global agent economy, that’s a reliability concern that only shows up through continuous observation.

These aren’t theoretical scenarios. They’re the kinds of signals that emerge when you instrument trust at the behavioral layer.

From scoring to settlement: trust as infrastructure

Dominion Observatory isn’t a dashboard you check once. It’s infrastructure that agents query in real time, at the moment of decision.

The system is itself an MCP server (available via Streamable HTTP at https://dominion-observatory.sgdata.workers.dev/mcp), which means any MCP-capable agent can call it natively. The core tools:

  • get_trust_score — Retrieve the behavioral trust score for any MCP server before calling it
  • detect_anomalies — Check whether a server is currently exhibiting unusual behavior
  • get_leaderboard — See which servers rank highest for reliability in a given category
  • get_ecosystem_stats — Understand the overall health of the MCP ecosystem
  • report_tool_outcome — Contribute your own interaction data back to the scoring engine

The most consequential integration point is the beforeSettle hook. In agent-to-agent payment flows — where one agent pays another for a service rendered via MCP — the trust score can gate whether settlement proceeds. If a server’s behavioral trust has dropped below a threshold, the payment holds. This turns trust from a nice-to-have metric into an economic primitive.

Think of it as a credit score for MCP servers. Not based on who they say they are, but on what they’ve actually done.

Static and behavioral analysis are complements, not competitors

To be clear: static analysis is important. You should absolutely scan MCP servers for injection flaws, validate their input handling, and audit their permission models. Tools that do this well are doing necessary work.

But static analysis answers the question: “Could this server misbehave?”

Behavioral scoring answers the question: “Is this server misbehaving?”

The first is a security audit. The second is an operational reputation system. A mature MCP ecosystem needs both — just as the traditional web needs both code review and uptime monitoring.

The difference becomes critical as the agent economy scales. When thousands of agents are autonomously selecting which MCP servers to call, making payments, and chaining tool calls across multiple servers, you need trust signals that operate at runtime speed and reflect current reality. You can’t re-audit source code on every request. You can query a behavioral trust score in milliseconds.

The agent economy needs accountability infrastructure

We’re at an inflection point. MCP adoption is accelerating, and the servers agents depend on are increasingly operated by unknown third parties. The agent economy will either develop robust trust infrastructure, or it will learn expensive lessons about what happens when autonomous systems make decisions without accountability.

Dominion Observatory is our contribution to the first outcome. It’s open source, it’s composable, and it’s designed to be infrastructure that other systems build on — not a walled garden.

Try it now

Query it directly. Point any MCP client at https://dominion-observatory.sgdata.workers.dev/mcp using Streamable HTTP transport. Call get_ecosystem_stats to see the current state of the ecosystem, or get_trust_score for any server you’re curious about.

Contribute data. The scoring engine gets better with more interaction data. Use report_tool_outcome to feed back your own observations about MCP server behavior. More data means more accurate trust signals for everyone.

Star the repo. The engine is open source at github.com/vdineshk/daee-engine. Issues, PRs, and ideas are welcome.

Build on it. If you’re building agent infrastructure — orchestration frameworks, payment rails, marketplace platforms — behavioral trust scoring is a building block. Integrate it. Extend it. Make agents smarter about who they trust.

The MCP ecosystem is too important to fly blind. Let’s build the accountability layer together.

Why Passing Tests Are Sometimes the Most Dangerous Thing in Your Pipeline

There is a specific kind of confidence that comes from watching a CI pipeline run green. You pushed a change, the tests ran, everything passed, and now you are deploying to production feeling reasonably certain that nothing broke.

That confidence is earned most of the time. And sometimes it is the most expensive thing in your entire pipeline.

I am not talking about flaky tests or poorly written assertions. I am talking about something more subtle and more dangerous: tests that are working exactly as designed, passing exactly as expected, and validating something that stopped being true months ago.

This is the part of automated testing that most pipeline conversations skip over. Everyone talks about coverage percentages, execution speed, and CI integration. Nobody talks about what happens when your tests are structurally correct but fundamentally disconnected from how your system actually behaves.

The Confidence Problem

Software deployment has gotten fast. Most teams I talk to are shipping multiple times per day, sometimes dozens of times. The pipeline is the gatekeeper between a developer’s change and production, and a passing test suite is what opens that gate.

That relationship between passing tests and deployment confidence is supposed to be simple. Tests pass means the system works. Tests fail means something broke. Ship when green, hold when red.

Except the relationship only holds when tests are actually checking the right things under the right conditions. When they are not, a green pipeline is not evidence that your system works. It is evidence that your system matches what your tests expect, which is a very different claim.

What Black Box Testing Gets Right and Where It Goes Wrong

Black box testing is one of the most honest approaches to automated testing precisely because it validates behavior from the outside. You interact with the system through its external interfaces, provide inputs, observe outputs, and validate results without any knowledge of what is happening inside. No reaching into implementation details. No testing internal state. Just the system behaving the way real users and downstream services would experience it.

This is a significant strength. A well-designed black box testing suite tells you something genuinely useful: the system’s external behavior is what you expect. That is the thing that actually matters to users, and it is the thing that most other testing approaches approximate rather than test directly.

The problem is not with the approach. The problem is with what happens to the expectations those tests are validating over time.

The Drift Nobody Notices

In a microservices environment, services evolve independently. A downstream API gets a new field in its response schema. An authentication service changes its error handling behavior. A data processing service starts returning slightly different output shapes under certain conditions.

None of these changes necessarily cause failures in your black box test suite. Because the tests are not checking against what the downstream services currently do. They are checking against what the mocks say the downstream services do. And those mocks were written when the tests were written, by developers who were accurately representing the service behavior at that moment in time.

Six months later, the service has changed. The mock has not. The tests keep passing. The behavior they are validating no longer reflects production reality.

This is mock drift, and it is the specific failure mode that makes passing tests dangerous. The pipeline is green. The deployment goes through. The production incident happens not because something broke in the traditional sense but because the system changed in ways that the test suite had no mechanism to detect.

The Most Dangerous Tests Are the Ones You Trust Most

Here is the counterintuitive part: the tests most likely to cause this problem are not the ones you are worried about. They are the ones you trust implicitly.

A test that fails intermittently is annoying but visible. You investigate it, you fix it, you quarantine it. Its unreliability is known.

A test that has passed reliably for eighteen months is a different matter. You have stopped questioning it. It runs green in every environment, on every branch, in every pipeline stage. It is part of the bedrock of your automated testing confidence.

And if that test was written against a mock that drifted from reality a year ago, it has been telling you something false for a very long time. The longer it has been passing, the more confident you have been, and the more dangerous that confidence has become.

What Fixes This

The fix is not to distrust your tests. It is to change where your test inputs come from.

The most reliable source of truth for how a system behaves is not a specification written by a developer and not a mock based on developer assumptions. It is the actual traffic flowing through the system in production. When black box tests are generated from real API interactions rather than hand-written specifications, the tests stay grounded in current system behavior rather than historical assumptions.

When a downstream service changes its response schema, the next round of traffic capture reflects that change automatically. The tests update because the source of truth updated, not because a developer remembered to review and update a mock file.

Keploy takes this approach to automated testing: capturing real HTTP traffic and generating black box tests and dependency mocks from actual production interactions. The coverage stays current because it is derived from what the system actually does rather than what someone thought it would do when writing the test.

This is not a magic solution to all testing problems. Tests sourced from real traffic still need thoughtful review and maintenance. But they address the specific failure mode that makes passing tests dangerous: the drift between what tests expect and what systems actually do.

Before Your Next Software Deployment

The next time you watch a CI pipeline run green before a software deployment, it is worth asking a specific question: when were these tests last checked against real system behavior?

Not “when did they last pass” — that is the wrong question. Tests pass all the time while validating outdated behavior. The right question is when the expectations embedded in your test suite were last verified against how the system currently behaves in production.

If the answer is never, or a long time ago, the confidence that green pipeline is giving you may be less earned than it feels. That does not mean your system is broken. It means you do not actually know whether it is or not, which is a different and more uncomfortable problem.

A passing test suite built on current, accurate expectations is one of the most valuable things an engineering team can have. A passing test suite built on drifted assumptions is something else entirely: it is confidence you have not paid for, and like most things you have not paid for, there is usually a bill coming.

Drow.js: A Practical Look at the Tiny Web Components Library

Drow.js: A Practical Look at the Tiny Web Components Library

If you’ve built a Web Component before, you’ve probably written something like this:

class MyComp extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: 'open' });
  }

  connectedCallback() {
    // boilerplate setup
  }

  // lifecycle methods
}

customElements.define('my-comp', MyComp);

It works, but there’s a lot of ceremony for something relatively simple. Drow.js strips away that ceremony. Instead of class inheritance and lifecycle methods, you define your components as plain JavaScript objects. The library handles the rest.

And it’s tiny—under 1kb gzipped with zero dependencies.

What Is Drow.js?

Drow is a minimalist wrapper around the Web Components API. It takes the standard Custom Elements spec and makes it feel less like writing framework code and more like configuring objects.

The core idea: Components are objects, not classes.

The Object-Based Approach

Here’s how you define a Drow component:

var myComp = {
    "name": "my-comp",
    "props": ['title', 'link'],
    "template": `<div>
        <div>Title: {{title}}</div>
        <div>Link: {{link}}</div>
    </div>`
}

Drow.register(myComp);

Then use it in HTML like any Web Component:

<my-comp title="Great Name" link="https://something.com"></my-comp>

Notice a few things:

  • name: Must be dash-separated (Web Components requirement)
  • props: Array of attribute names that can be set on the element
  • template: HTML with handlebars-style {{variable}} placeholders

That’s the bare minimum. Let’s look at what else you can add.

Building a Real Component

Here’s an example component from the documentation with some practical features:

var config = {
    "name": "my-comp",
    "props": ['prop1', 'prop2'],
    "css": "b { color: blue; }",
    "template": `<div>
        <div>Every time you click the timestamp updates.</div>
        <b>Click for the timestamp</b>
        <div>{{prop1}}</div>
    </div>`,
    "init": function(config) {
        let prop1 = this.getAttribute('prop1') || "";
        const comp = this.getComp();

        comp.addEventListener('click', e => {
            comp.querySelector("b").innerHTML = new Date();
        });
    },
    "watch": function(attribute) {
        if (attribute.name == 'prop1') {
            attribute.comp.querySelector('b').innerHTML = `Hello, ${attribute.newValue}`;
        }
    }
}

Drow.register(config);

Now we’ve added three new features:

1. CSS Scoping

The css field contains component-scoped styles. They won’t leak out and external styles won’t leak in. Shadow DOM encapsulation handled automatically.

2. The init Hook

The init function runs when the component is created. It gets access to the component via this.getComp() and can:

  • Set up event listeners
  • Query the template
  • Read initial prop values with this.getAttribute()

This is where you add interactivity without the lifecycle method overhead.

3. The watch Hook

The watch function triggers whenever an attribute changes. It receives an object with:

  • name: The attribute that changed
  • newValue: The new value
  • comp: A reference to the component

This is how you react to updates from outside the component—essentially a property observer.

A Practical Example: Timestamp Component

Let’s build something concrete. A component that displays when it was last clicked:

var timestampComp = {
    "name": "last-click",
    "props": ['label'],
    "css": `
        .container {
            padding: 16px;
            border: 1px solid #ddd;
            border-radius: 4px;
            background: #f5f5f5;
        }
        .timestamp {
            font-weight: bold;
            color: #0066cc;
            cursor: pointer;
            padding: 8px;
            user-select: none;
        }
        .timestamp:hover {
            background: #e8e8e8;
            border-radius: 2px;
        }
    `,
    "template": `
        <div class="container">
            <p>{{label}}</p>
            <div class="timestamp">Click here for current time</div>
            <p id="output"></p>
        </div>
    `,
    "init": function(config) {
        const comp = this.getComp();
        const timestamp = comp.querySelector('.timestamp');
        const output = comp.querySelector('#output');

        timestamp.addEventListener('click', () => {
            output.textContent = new Date().toLocaleString();
        });
    }
}

Drow.register(timestampComp);

Use it:

<last-click label="Last clicked at:"></last-click>

That’s it. No build step, no complicated setup. Just define, register, and use.

How the Templating Works

Drow uses simple mustache/handlebars style variable replacement. Anything in {{}} gets replaced with the prop value:

"template": `
    <h1>{{title}}</h1>
    <p>{{description}}</p>
`

The variables are applied by prop name from your attributes:

<my-card 
    title="Hello World" 
    description="A simple component">
</my-card>

No special syntax, no directives, no magical binding. Just string interpolation based on props.

Reacting to Changes with watch

The watch hook is useful for when attributes get updated dynamically:

var greeting = {
    "name": "greeting",
    "props": ['name'],
    "template": `<h1>Hello, <span class="user"></span></h1>`,
    "watch": function(attribute) {
        if (attribute.name == 'name') {
            attribute.comp.querySelector('.user').textContent = attribute.newValue;
        }
    }
}

Drow.register(greeting);

Now if you change the name:

const card = document.querySelector('greeting');
card.setAttribute('name', 'Alice'); // The component updates automatically

Communication Between Components

For parent-to-child, use props and attributes. For child-to-parent, use custom events (standard Web Component pattern):

var buttonComp = {
    "name": "my-button",
    "props": ['text'],
    "template": `<button>{{text}}</button>`,
    "init": function(config) {
        const comp = this.getComp();
        const btn = comp.querySelector('button');

        btn.addEventListener('click', () => {
            comp.dispatchEvent(new CustomEvent('button-clicked', {
                detail: { timestamp: Date.now() }
            }));
        });
    }
}

Drow.register(buttonComp);

Listen for it in your HTML:

<my-button text="Click me"></my-button>

<script>
    document.querySelector('my-button').addEventListener('button-clicked', (e) => {
        console.log('Button clicked at:', e.detail.timestamp);
    });
</script>

Setup and Installation

Via Script Tag

Include the file directly in your HTML:

<script src="drow.js"></script>

<my-comp prop="value"></my-comp>

<script>
    var myComp = {
        "name": "my-comp",
        "props": ['prop'],
        "template": `<div>{{prop}}</div>`
    };

    Drow.register(myComp);
</script>

Via NPM

npm install drow

Then import it:

import Drow from 'drow';

const myComp = {
    "name": "my-comp",
    "props": ['prop'],
    "template": `<div>{{prop}}</div>`
};

Drow.register(myComp);

When Should You Use Drow?

Good fit:

  • You want Web Components without the boilerplate
  • Building UI components for your site
  • Small to medium projects
  • You want a library that’s easy to understand and modify
  • Bundle size matters
  • Prototyping and learning

Consider alternatives:

  • You need complex state management (React/Vue/Svelte are better here)
  • Very large enterprise applications with extensive component ecosystems
  • You need advanced templating or reactivity features

Comparison with Lit

Both are lightweight Web Component libraries, but they approach it differently:

Feature Drow Lit
Bundle Size <1kb ~5kb
Learning Curve Minimal Low-Medium
Dependencies None None
Syntax Objects Classes + Decorators
Templating Handlebars Tagged template literals
Reactivity Manual Built-in

Drow keeps things simple. Lit adds more power at the cost of a bit more complexity. Pick based on your project needs.

Recent Updates

The library recently converted its internal naming from DrowJS to Drow, making the API cleaner and more consistent. The core functionality remains the same—object-based component definitions with minimal overhead.

Getting the Code

Everything is on GitHub: https://github.com/johnfacey/drowjs

There’s a /docs folder with more detailed documentation, and you can see examples in index.html and samples.js.

To run locally:

npm install
npm run server

The Bottom Line

Drow.js won’t replace React or Vue for complex applications. But if you want to use the browser’s native component system without fighting the API, it’s a really pleasant experience.

The value of Drow is in its simplicity. You get Web Component encapsulation, scoped CSS, prop-based templating, and lifecycle hooks—all in a tiny package with almost no learning curve.

If that sounds useful for your project, give it a try. The barrier to entry is basically zero.

Learn more: Check out @johnfacey on Twitter, @johnfacey on BlueSky or visit the GitHub repository.

What Happens To Your Architecture When Clients Expect 24/7 AI Availability

Most AI systems look stable until somebody depends on them operationally.

Internal demos tolerate downtime.

Experiments tolerate inconsistency.

Hackathon systems tolerate failure.

Enterprise environments do not.

The moment clients expect AI systems to stay available 24/7, architecture decisions change fast.

Things that looked acceptable during development suddenly become operational risks.

The First Thing That Breaks Is Assumptions

Early AI systems are usually built around optimistic assumptions:

  • APIs will respond quickly
  • Models will behave consistently
  • Traffic will remain predictable
  • Retries will solve temporary failures
  • Context windows will be enough
  • Logs will help debugging

None of those assumptions survive long in production.

Once systems run continuously, edge cases stop being edge cases.

They become normal traffic.

AI Infrastructure Fails Differently

Traditional backend outages are easier to detect.

You see:

  • crashed services
  • failed health checks
  • database connection errors
  • CPU spikes

AI infrastructure problems are slower.

The system still responds.

But:

  • answers become inconsistent
  • latency slowly increases
  • retrieval quality drops
  • memory state drifts
  • token costs explode
  • orchestration queues backlog
  • retries amplify failures

The dangerous part is that monitoring often shows “healthy” systems while users experience degraded reasoning quality.

Single Model Dependency Becomes Dangerous

One thing we learned quickly:

Building around a single model provider creates operational fragility.

Not because providers are unreliable.

Because upstream behavior changes constantly.

Things that change unexpectedly:

  • response formatting
  • tool calling structures
  • latency profiles
  • tokenization behavior
  • safety filters
  • rate limits

A prompt that worked perfectly last month can silently degrade after a provider-side update.

If your architecture depends heavily on exact model behavior, production stability becomes fragile.

We started treating model providers like unstable infrastructure dependencies.

That changed how we designed everything around them.

Retry Logic Starts Creating Problems

Retry systems look harmless early on.

Then traffic scales.

Now one slow dependency creates:

  • duplicated jobs
  • queue congestion
  • inconsistent state updates
  • race conditions
  • delayed workflows

One issue we hit involved async retrieval workers retrying aggressively during provider latency spikes.

The retries themselves caused more system pressure than the original outage.

The fix was not “more retries.”

The fix was:

  • retry isolation
  • queue prioritization
  • circuit breakers
  • failure backoff
  • partial workflow recovery

24/7 systems punish uncontrolled retries.

Stateful AI Systems Become Distributed Systems

The moment you introduce:

  • memory
  • retrieval
  • agent workflows
  • background processing
  • user context
  • long-running tasks

you are no longer building a stateless API layer.

You are building distributed infrastructure.

That changes debugging completely.

One production issue looked like hallucination problems from users.

The actual issue:

Two services cached different retrieval snapshots for the same conversation state.

The model output was technically valid based on the wrong context.

That kind of issue does not show up during small-scale testing.

It appears only after continuous operation.

Observability Becomes More Important Than Features

The longer systems run, the more debugging dominates engineering time.

Basic logging stops being enough.

You need visibility into:

  • prompt versions
  • retrieval sources
  • token usage
  • orchestration paths
  • worker execution timing
  • queue state
  • external dependency latency
  • memory mutations

Without that, production debugging becomes guesswork.

One thing we now treat as mandatory:

Full request trace reconstruction.

Not just logs.

Complete execution replay:

  • incoming request
  • context injection
  • retrieval outputs
  • model inputs
  • model responses
  • tool execution
  • final orchestration result

Because AI failures are rarely reproducible otherwise.

Infrastructure Decisions Start Outliving Models

One mistake teams make:

Optimizing heavily around current model capabilities.

Models change fast.

Infrastructure survives much longer.

The systems that age well are usually built around:

  • provider abstraction
  • observability
  • fault isolation
  • workflow recovery
  • deployment safety
  • data consistency
  • operational tooling

Not around one specific model workflow.

The AI layer evolves constantly.

Operational infrastructure accumulates permanent complexity.

The Biggest Architecture Shift

The biggest shift is psychological.

At some point you stop thinking:

“How do we get better AI output?”

And start thinking:

“How do we keep this operational under continuous uncertainty?”

That changes priorities completely.

Reliability starts beating novelty.

Recovery starts beating optimization.

Infrastructure starts mattering more than prompts.

And most engineering effort moves into keeping systems stable while everything around them changes continuously.

What’s Coming to Laravel Cloud: $5/month Plan, Spend Caps, and Instant Scale-to-Zero

Originally published at hafiz.dev

The two things that kept most Laravel developers off Laravel Cloud were cost and the fear of a surprise bill. The Laravel team just announced both are being fixed, along with three other significant changes coming over the next few weeks.

Here’s what was announced and what it actually means.

The Five Announcements

The announcement laid them out clearly:

1. A new $5/month plan. Previously, your options were Starter (free tier, pay-as-you-go, limited features) or Growth ($20/month). The new $5/month tier sits between them. The stated goal: “We want Cloud to be accessible to every Laravel developer.”

2. Spend caps. Set a spending limit on your account. When you hit it, Cloud will either alert you or shut off compute entirely. No more anxiety about waking up to an unexpected $300 bill.

3. True scale-to-zero with 10x faster wake-up. Hibernation has existed for a while, but wake-up previously took 5-20 seconds. App, database, and cache wake-up is now measured in milliseconds. Users won’t notice it.

4. Bot protection rules. Keeps hibernated apps dormant longer by filtering bot traffic before it wakes your environment. This directly reduces compute spend. Bots won’t trigger unnecessary wake-ups that eat into your budget.

5. Managed queues. Queue clusters are being rebuilt into a new “managed queues” product. Set a maximum worker count and Cloud handles everything else. It scales on queue depth (not just CPU) and scales to zero when idle. No more guessing at worker sizing.

These changes aren’t live yet. The announcement said “coming over the next few weeks,” so treat this as a planning-ahead post rather than a same-day implementation guide.

The Spend Cap Is the Real News

The $5/month price point gets the headline, but spend caps are what actually unlocks Cloud for cautious teams.

Usage-based pricing always carries anxiety. Even with hibernation enabled, one unexpected traffic spike, a crawling bot hammering your endpoints, or a runaway job queue could turn a $10 month into an $80 one. That unpredictability kept teams on fixed-cost Forge servers where the bill was predictable even if the compute was oversized.

Spend caps change the risk profile completely. You can enable hibernation, deploy a small instance, and know that the maximum you’ll pay in a worst-case month is whatever cap you set. That’s a fundamentally different product than “usage-based with no ceiling.”

Combine spend caps with the new bot protection rules and the hibernation economics get significantly better. Bots are the silent killers of scale-to-zero apps. They wake your environment constantly without generating real revenue. Filtering them before they trigger a wake-up means your app actually stays dormant during off-peak hours instead of yo-yoing on and off.

What Millisecond Wake-Up Changes

The previous 5-20 second cold start was the biggest practical barrier to using hibernation on anything user-facing. You could use it for staging environments and dev instances without issue, but putting a hibernating app in front of real users meant the first request after idle time got a slow response. Users noticed. Support tickets followed.

Millisecond wake-up removes that constraint. If the wake-up is imperceptible, hibernation becomes a pure cost optimization with no UX downside. You can run a production app with a low-cost Flex instance, hibernate between traffic windows, and pay only for active time, without needing a “warm-up” strategy or a cron job to keep things alive.

One question worth watching: the tweet mentions milliseconds for app, database, and cache wake-up. The database wake-up is the historically slow part. If serverless Postgres wakes in milliseconds consistently, that’s a genuine infrastructure achievement. The community will stress-test this quickly once it ships.

Managed Queues as a Quiet Win

The managed queues announcement is being slightly overshadowed by the pricing news, but it’s significant for teams running serious background processing.

Queue workers have always required manual tuning. How many workers does this job type need? What happens if the queue backs up? How do you prevent workers from sitting idle at 3am burning compute? The standard answer was either Horizon with careful configuration or accepting occasional over-provisioning, patterns covered in the Laravel queue jobs guide.

Managed queues take that decision away. Cloud monitors queue depth and adjusts worker count automatically. When the queue drains, workers scale to zero. When it fills, they spin up. You set a maximum and stop thinking about it.

For applications with variable job loads (processing payments, sending email campaigns, handling webhooks), this is cleaner than anything available on Forge or Vapor today. It ties directly into the monitoring and observability improvements that make Cloud worth the higher base cost.

The New Math: Cloud vs Forge vs Vapor

With the new plan, the comparison looks different for small projects.

Indie developer with multiple side projects:

  • Cloud (new $5 tier + usage with hibernation): $5 + ~$2-5/month per app
  • Forge: $17/month base (you can add cheap VPS servers, but Forge itself is $17)
  • VPS direct: $5-10/month per server (you manage everything)

One developer in the announcement thread shared they’re running seven apps with decent traffic for $6/month total using scale-to-zero. That number will improve further with bot protection and millisecond cold starts. For anyone currently running multiple low-traffic side projects on separate servers, the Cloud math starts looking favorable.

Pre-scale startup on Growth ($20/month):

  • Cloud Growth: $20/month + ~$16-25 usage = ~$36-45/month
  • Forge: $17/month + $20-40/month DigitalOcean/Hetzner VPS = ~$37-57/month

At this tier, the total cost is similar, but Cloud includes autoscaling, managed databases, preview environments, and zero DevOps overhead. Forge requires you to configure servers, manage Nginx, handle SSL renewal, and tune your own scaling. The value comparison has always favoured Cloud for teams without a dedicated DevOps person. The new pricing makes it viable to reach that tier sooner.

Vapor ($39/month):
Vapor runs on AWS Lambda, which gives you true serverless with different performance characteristics. It’s still the right choice for teams deeply invested in the AWS ecosystem. But for most Laravel developers who just want their app deployed and scaled without thinking about infrastructure, Cloud’s model is more Laravel-native and increasingly competitive on price. The CI/CD and deployment guide from last week covers how to automate your Cloud deployments via GitHub Actions.

Who Should Be Paying Attention

Indie developers and side project builders. The $5/month plan plus spend caps makes Cloud viable for projects that previously couldn’t justify $20/month. Multiple side projects on a single Cloud account with hibernation enabled could cost less than one Forge server.

Small agencies running client sites. Preview environments per pull request plus managed databases at $5-20/month per project is a clearly compelling agency workflow. The managed queues addition makes it viable for client projects with background job requirements.

Teams on Forge who don’t enjoy server management. If you’re paying someone to manage Forge servers (patching, monitoring, scaling), Cloud is worth a fresh look. The total cost might be similar, but the management overhead disappears. For teams building SaaS products on Laravel, the complete SaaS guide covers the broader architecture decisions where Cloud fits naturally.

Anyone who previously tried Cloud and left because of cost or cold start anxiety. Both objections are being addressed directly. Worth revisiting once the features ship.

Who Should Stay Where They Are

Developers who want full server control. Forge gives you root access and complete flexibility. Cloud abstracts that away by design. If you need custom Nginx configs, non-standard PHP extensions, or specific OS-level tooling, Forge is still the better choice.

Teams on Vapor with existing AWS infrastructure. The Lambda model suits certain workloads well and migrating away from a working setup for incremental cost savings rarely makes sense.

High-traffic, always-on applications. Hibernation economics only work when your app has genuine idle periods. If you’re running a busy production app that never sleeps, the cost advantage disappears and a dedicated server (Forge or otherwise) may still be cheaper.

The Bigger Picture

The Scotty vs Envoy post from April made the case that the Laravel deployment tooling ecosystem is maturing fast. This announcement reinforces that. A $5/month managed hosting tier with spend caps and millisecond cold starts is a product that didn’t exist anywhere in the PHP ecosystem six months ago.

The spend caps and bot protection show the team is listening to actual adoption blockers rather than just adding features. Those two additions together fix the core reason cautious developers stayed away.

The managed queues rebuild is the kind of unsexy infrastructure improvement that saves teams real operational hours once you’re running it in production.

Once these ship, the “why not just use Forge” argument gets harder to make for most new Laravel projects.

FAQ

When are these features available?

The announcement said “coming over the next few weeks.” No specific release date was given. Follow the official Laravel Cloud blog for the rollout timeline.

Will the $5/month plan include custom domains?

Not confirmed in the announcement. The current Starter (free) plan includes custom domains, so it’s likely the $5 tier does too. Check the official pricing page once it’s updated.

Does the spend cap pause the app or just alert you?

The announcement confirmed it will either alert you or shut off compute. The configuration details (which trigger, per-environment vs per-account) will be in the documentation once it ships.

Should I migrate existing apps before these features land?

Wait until they’re live and documented before making migration decisions. The announcements are forward-looking; current Cloud behavior still applies today.

How does bot protection work with legitimate crawlers?

Specific configuration details weren’t shared in the announcement. Presumably you’ll be able to allowlist crawlers like Googlebot. More detail will come in the docs.

Worth Watching

These announcements move Laravel Cloud from “interesting but expensive” to “worth serious consideration for almost any new Laravel project.” The spend caps alone change the risk calculation. The millisecond wake-up makes hibernation viable for production. The $5 plan removes the cost objection for small projects.

Whether this changes your deployment setup depends on where you are now. But if you wrote off Cloud six months ago, the next few weeks are worth another look.

If you’re evaluating Laravel Cloud for a specific project and want to think through the numbers, get in touch.