AWS Basics But Needs to Be Known Before You Start Your Certification

You don’t need to memorize 200 services to start your AWS journey. But you do need to understand the foundations. Here’s everything I wish someone had explained to me before I started studying for my AWS certification.

1. What Even Is Cloud Computing?

Let’s start from the very beginning. Cloud computing sounds fancy, but the core idea is simple: there’s a physical server somewhere, and you’re renting it over the internet.

Instead of buying your own hardware, setting up a server room, and hiring people to maintain it — you use someone else’s infrastructure (like AWS) and pay only for what you use.

Here’s the official NIST definition:

“A model for enabling ubiquitous, convenient, on-demand network access to a shared pool of **configurable computing resources* that can be rapidly provisioned and released with minimal management effort or service provider interaction.”*

Let’s break that down into human language:

  • On-demand → You get resources whenever you want them
  • Shared pool → Multiple customers share the same physical infrastructure
  • Configurable → You choose how much CPU, RAM, storage you need
  • Rapidly provisioned and released → Spin up a server in minutes, shut it down when you’re done
  • Minimal management effort → No need to physically touch any hardware

2. What’s Actually Behind the “Cloud”?

Behind the cloud, there are real, physical server racks sitting in massive data centers around the world. AWS has these data centers spread across the globe, and the infrastructure is organized in a clear hierarchy:

Region

A large geographic area (e.g., eu-west-1 for Ireland, us-east-1 for N. Virginia). You choose a region based on where your users are, compliance requirements, or pricing.

Availability Zone (AZ)

Each Region contains multiple AZs (e.g., eu-west-1a, eu-west-1b, eu-west-1c). An AZ is one or more data centers with independent power, networking, and connectivity. Multiple AZs exist for redundancy — if one goes down, the others keep running.

Edge Locations / Points of Presence (PoP)

These are smaller, lightweight locations spread even more widely than Regions. They’re used primarily for caching content closer to end users.

3. Edge Networks and CDN — Speed Matters

Imagine your origin server is in the US, but a user in Southeast Asia wants to load your website. Without any optimization, every single request travels across the Pacific Ocean and back. That’s slow.

This is where Edge Networks and CDN (Content Delivery Network) come in.

How it works:

  1. Your original content lives on the Origin Server (e.g., in us-east-1)
  2. AWS caches copies of your static content (images, CSS, JS, videos) at PoP / Edge Locations around the world
  3. When a user in Singapore requests your site, they get the cached version from the nearest PoP — not from the US
  4. Result: dramatically lower latency

CDN vs Edge Network — are they the same thing?

Not exactly. The Edge Network is the infrastructure — the distributed network of servers worldwide. CDN is the most well-known use case of that infrastructure. In practice, people use the terms interchangeably, and that’s mostly fine.

AWS’s CDN service is called CloudFront, and it leverages these Edge Locations.

4. Virtualization and the Hypervisor

Here’s where it gets interesting. When you launch an EC2 instance, you’re not getting a dedicated physical server. Here’s what’s actually happening:

  1. Host Computer → The physical AWS server rack in a data center
  2. Host OS → The operating system running on that physical machine
  3. Hypervisor → Software that sits on top of the Host OS and splits the physical machine into multiple virtual machines
  4. Your EC2 Instance → One of those virtual machines

So if a physical server has 64 CPUs and 256 GB RAM, the hypervisor might split it into four isolated instances of 16 CPUs / 64 GB RAM each. Different customers can be using the same physical hardware without ever knowing about each other — completely isolated.

AWS built their own hypervisor called Nitro, which operates at the hardware level for minimal performance overhead.

Key takeaway: EC2 instances are virtual slices of physical servers, managed by a hypervisor. Multiple instances from different customers can live on the same physical machine, fully isolated from each other.

5. The Shared Responsibility Model — Who’s Responsible for What?

This is probably the most important concept for your certification exam. AWS and the customer share security responsibilities, but the line between them is very clear.

Security OF the Cloud → AWS’s Job

AWS is responsible for protecting the infrastructure that runs all the services:

  • Physical security — data center access, cameras, biometric entry
  • Hardware — servers, storage, networking equipment
  • Software — compute, storage, database, networking services
  • Global infrastructure — Regions, Availability Zones, Edge Locations
  • Host OS & Hypervisor — you can’t even access these

Security IN the Cloud → Your Job

You are responsible for everything you put in and configure on the cloud:

  • Customer data — whatever you upload, store, or process
  • Platform, applications & IAM — who has access to what, roles, permissions, secret keys
  • OS & firewall configuration — if you launched an EC2 with Ubuntu, patching it is on you
  • Encryption — client-side, server-side, in-transit, at-rest decisions
  • Network traffic protection — security groups, NACLs, VPN configurations

The Three Control Categories

Category Who? Examples
Inherited AWS only Physical & environmental security, host OS, physical servers
Shared Both Patch management, configuration management, awareness & training
Customer-Specific Customer only Guest OS, custom applications, data encryption strategies

Quick Quiz — Test Yourself

Question Answer
Patching your EC2 instance’s operating system? You
Guest OS security patches? You
Running the host OS and virtualization layer? AWS
Managing IAM user access and secret keys? You
Maintaining the server under your Lambda functions? AWS
Physical security of data centers? AWS
Encryption-at-rest strategy for your RDS database? You

Simple rule of thumb: If you can configure it in the AWS Console or CLI → it’s your responsibility. If you can’t even touch it → it’s AWS’s responsibility. If both sides need to do their part → it’s shared.

Think of it like renting an apartment: AWS gives you a secure building (locked doors, fire alarms, security guards). But whether you lock your own door, put your valuables in a safe, or leave your windows open — that’s entirely on you.

6. AWS Support Plans — Developer vs Business

When you create an AWS account, you’ll need to choose a support plan. Here’s the practical difference between the two most common ones:

Feature Developer (~$29/mo) Business (~$100/mo or % of usage)
Who can open tickets 1 person (primary contact) Unlimited team members
Response time (critical) 12 hours 1 hour
Support channels Email only Email + Phone + Chat
Trusted Advisor Limited checks Full access
Third-party software support No Yes

Which one should you pick?

  • Developer → Great for learning, experimenting, and building prototypes. Start here if you’re just getting started.
  • Business → Essential when you’re running production workloads with real users. The 1-hour critical response time alone is worth it when something goes down.

Good news: You can start with Developer and upgrade to Business anytime from the AWS Console (Support Center > Change Plan). Billing is prorated, so you only pay for what you use. You can also downgrade later if needed.

Wrapping Up

Before diving into specific services like S3, Lambda, or DynamoDB, make sure these foundational concepts are solid:

  1. Cloud = renting virtual resources from physical infrastructure over the internet
  2. Regions → AZs → Edge Locations form the backbone of AWS’s global presence
  3. CDN / Edge Networks cache content close to users for speed
  4. Hypervisors split physical servers into isolated virtual machines (EC2 instances)
  5. Shared Responsibility Model — know what’s yours vs what’s AWS’s (this will be on the exam)
  6. Support Plans can be upgraded/downgraded as your needs evolve

These aren’t glamorous topics, but they’re the bedrock everything else is built on. Nail these, and the rest of your certification journey will make a lot more sense.

Happy cloud learning! If you found this helpful, drop a reaction or follow for more AWS certification notes.

5 AI Agent Patterns Every Developer Should Know in 2026

AI agents are moving from research demos to production systems. But most tutorials still show toy examples. Here are 5 battle-tested patterns that actually work at scale.

1. ReAct (Reasoning + Acting)

The most versatile pattern. The agent thinks about what to do, takes an action, observes the result, and repeats.

def run_react_agent(task, tools, max_steps=10):
    messages = [{"role": "user", "content": task}]

    for step in range(max_steps):
        response = client.messages.create(
            model="claude-sonnet-4-20250514",
            tools=tools,
            messages=messages
        )

        if response.stop_reason == "tool_use":
            tool_results = execute_tools(response)
            messages.extend([
                {"role": "assistant", "content": response.content},
                {"role": "user", "content": tool_results}
            ])
        else:
            return response.content[0].text

When to use: General-purpose tasks — research, data analysis, customer support.

2. Router Pattern

Instead of one agent doing everything, use a lightweight router to dispatch to specialized agents.

class RouterAgent:
    def __init__(self):
        self.agents = {
            "code": CodeAgent(),
            "research": ResearchAgent(),
            "writing": WritingAgent(),
        }

    def route(self, task):
        category = classify_task(task)  # haiku-level model
        return self.agents[category].run(task)

Why it works: Specialized agents with focused system prompts outperform generalist agents by 30-40% on benchmarks. And routing with a small model costs <$0.001 per request.

3. Tool-Use with Fallback Chain

Production agents need graceful degradation. If Tool A fails, try Tool B. If both fail, fall back to the LLM’s knowledge.

class FallbackToolAgent:
    def execute_with_fallback(self, tool_name, params):
        try:
            return self.tools[tool_name](**params)
        except Exception:
            pass

        fallback = self.fallbacks.get(tool_name)
        if fallback:
            try:
                return fallback(**params)
            except Exception:
                pass

        return self.llm_fallback(tool_name, params)

Key insight: In production, tools fail 5-15% of the time (API timeouts, rate limits, data issues). Without fallbacks, your agent fails 5-15% of the time too.

4. Multi-Agent with Shared Memory

When tasks are complex enough to need multiple agents, they need to share context efficiently.

class SharedMemory:
    def __init__(self):
        self.facts = {}
        self.history = []

    def add_fact(self, agent, key, value):
        self.facts[key] = {"value": value, "source": agent}
        self.history.append({"agent": agent, "action": "added", "key": key})

    def get_context_for(self, agent):
        return {k: v for k, v in self.facts.items()
                if self._is_relevant(k, agent)}

The mistake everyone makes: Sharing the entire conversation history between agents. This explodes token usage. Instead, share structured facts.

5. Human-in-the-Loop Checkpoints

The most important pattern for production: let the agent work autonomously, but pause for human approval at critical points.

class CheckpointAgent:
    def __init__(self, checkpoints):
        self.checkpoints = checkpoints

    async def run(self, task):
        plan = self.create_plan(task)

        for step in plan:
            if step.name in self.checkpoints:
                approved = await self.request_human_approval(step)
                if not approved:
                    return self.handle_rejection(step)

            result = await self.execute_step(step)

        return result

Rule of thumb: Any action that’s hard to reverse (sending emails, making payments, modifying production data) should have a checkpoint.

Framework Comparison (Quick Reference)

Framework Best For Learning Curve
LangGraph Complex workflows with branching Moderate
CrewAI Multi-agent collaboration Low
Claude Agent SDK Tool-use agents Low
OpenAI Agents SDK GPT-based agents Low
Custom (no framework) Simple agents, full control Varies

Next Steps

Originally published on paxrel.com

Mutable tags. 10,000 pipelines. One credential. — What the Trivy attack taught me about implicit trust

A few days ago I was designing a GitHub Actions pipeline with security scanning tools. Choosing what to integrate, how to structure it, what permissions to give it — especially for the context of the project I was building it for. The kind of work that feels productive — you’re building something that will improve the team’s security posture.

That’s when I found out what had happened to Trivy.

On March 19, 2026, TeamPCP compromised the most widely used open-source vulnerability scanner in the cloud-native ecosystem. They didn’t hack a business application. They didn’t exploit a vulnerability in production code. They compromised the tool that thousands of organizations use to find vulnerabilities in their own applications. The security scanner became the weapon.

That made me stop. Not to throw the pipeline away — but to rethink from what principles I was building it.

This post is not a threat intelligence analysis. I’m a practitioner who is learning more and more about building security pipelines and who reflected on this case. What I found along the way changed how I think about trust in external dependencies.

What exactly happened?

The attack wasn’t a single event — it was a multi-phase campaign that lasted several days and started earlier than most people think.

Three weeks before March 19, an automated bot called hackerbot-claw exploited a misconfigured workflow in the Trivy repository and stole a Personal Access Token. Aqua Security detected the incident and rotated credentials — but the rotation was incomplete. TeamPCP retained access to the credentials that survived. That’s what made everything that followed possible. [Palo Alto Networks]

On March 19 at 17:43 UTC, using those retained credentials, TeamPCP compromised three components simultaneously:

The Trivy binary. A malicious version — v0.69.4 — was published across all official distribution channels: GitHub Releases, Docker Hub, GHCR, ECR Public, deb/rpm repositories, and get.trivy.dev. The scanning logic lives in this binary. The other two components are wrappers that invoke it. [Wiz Research]

trivy-action. The GitHub Action most teams use to integrate Trivy into their pipelines. TeamPCP force-pushed 76 of 77 version tags to point at malicious commits. Pipelines referencing these actions by tag began executing the attacker’s code on their next run — with no visible change to the tag name or the releases page. [Microsoft Security Blog]

setup-trivy. The Action that installs the binary. All 7 existing tags were compromised in the same way.

The payload was an infostealer that harvested SSH keys, cloud tokens, Kubernetes credentials, and pipeline environment variables — all while Trivy ran normally and produced the expected output. To an engineer reviewing the logs, the step appeared successful. [SANS Institute]

Exposure windows ranged from 3 to 12 hours depending on the component. Three days later, on March 22, TeamPCP published additional malicious images on Docker Hub — v0.69.5 and v0.69.6 — using separately compromised Docker Hub credentials, extending exposure by another ~10 hours. [Legit Security]

According to SANS Institute, more than 10,000 CI/CD workflows are reported to have been affected.

They didn’t exploit code — they exploited trust

When most teams think about an attack, they picture someone finding a buffer overflow, an SQL injection, an RCE. A technical vulnerability in the code that needs to be patched.

TeamPCP did none of that.

They didn’t find a bug in Trivy. They didn’t break any cryptographic algorithm. They exploited something much harder to patch: the implicit trust logic that organizations place in their dependencies. The premise that if a tool comes from the official vendor, through the official channel, with the official tag — it’s safe.

That premise is what failed.

There’s a brutal irony in how the impact was distributed. The most diligent teams — the ones who had integrated Trivy into every PR, every merge, every deploy — were the most exposed. The more disciplined the team was about running their security pipeline, the more times the infostealer ran. The good practice became the attack vector. [SANS Institute]

This is not an argument to stop scanning. It’s an argument to understand that trusting an external tool without verifying its integrity is exactly the same as trusting a user without verifying their identity. In IAM, nobody accepts that. In dependencies, we accept it all the time.

The expansion of the attack confirms it. TeamPCP didn’t stop at Trivy. On March 23 they compromised Checkmarx KICS — the infrastructure-as-code scanner. On March 24 they reached LiteLLM on PyPI, using credentials stolen from BerriAI’s Trivy pipeline. According to SANS Institute, one stolen token propagated across five distinct ecosystems: CI/CD, npm, Docker, PyPI, and AI infrastructure. [Arctic Wolf]

TeamPCP isn’t targeting business applications. It’s targeting the security tooling ecosystem — exactly the tools that the most security-conscious teams have integrated into their pipelines.

Mutable tags: not the vector, but the multiplier

When the attack was reported, much of the media focus fell on mutable tags. That makes sense — it’s the most striking technical detail. But it’s worth understanding exactly what role they played, because they weren’t the entry vector — they were what turned a single point of access into a massive problem.

To understand the difference, three concepts need to be separated.

The attack vector was the retained credential — the Personal Access Token that survived an incomplete rotation from a prior incident. That credential with write permissions over Aqua Security’s repositories is what gave TeamPCP initial access. Without it, nothing that followed would have been possible. [Palo Alto Networks]

The attack surface was the CI/CD pipelines of thousands of organizations referencing Trivy and its GitHub Actions by tag. Every pipeline running uses: aquasecurity/[email protected] was an exposed surface — not because it had a vulnerability, but because its trust model depended on the immutability of a tag that wasn’t immutable. According to SANS Institute, more than 10,000 CI/CD workflows were part of that surface.

Mutable tags were the multiplier. Once TeamPCP had access, tag mutability allowed them to silently redirect 76 of 77 tags in trivy-action and all 7 tags in setup-trivy to malicious commits — with no visible change in names, dates, or release pages. [Microsoft Security Blog]

Now, the fundamental difference between a tag and a digest.

A tag is a named pointer — v0.35.0, latest, v0.69.4. In Git and container registries, that name can be redirected to any commit or image without the name changing. No notification. No alert. No visible change on the releases page.

A digest is the SHA256 of the actual content — sha256:a3f8d2c1.... It’s immutable by definition. If the content changes, the digest changes. It can’t be forged, it can’t be redirected. Referencing a dependency by digest anchors it to a specific verified piece of content.

Any pipeline referencing those actions by tag began executing malicious code on its next run. Without any visible change. Without any alert. If those same pipelines had referenced the actions by digest, the force-push would have had no effect. The digest would still point to the original commit. The blast radius would have been dramatically smaller. [Legit Security]

Supply chain security = least privilege applied to dependencies

There’s a principle any engineer working with AWS knows by heart: least privilege. You don’t give a role more permissions than it needs. You don’t create access keys when you can use temporary roles. You don’t leave a * in a Resource when you can specify the exact ARN.

It’s the most repeated principle in cloud security. And yet, when it comes to external dependencies, we systematically ignore it.

When a pipeline runs uses: aquasecurity/[email protected], it’s placing full trust in that tag — without verifying its integrity, without anchoring to specific content, without questioning whether the pointer still points to what it pointed to yesterday. It’s the equivalent of giving AdministratorAccess to a role because “it’s easier.” It works. Until it doesn’t.

Supply chain security isn’t a separate domain from the security you already practice. It’s the same least privilege principle applied to a different level: your dependencies. The question isn’t “do I trust this tool?” — it’s “what verification do I have that what I’m executing is exactly what I think it is?”

The expansion of the attack illustrates why this matters at scale. TeamPCP didn’t need to compromise each organization individually. It compromised a central tool in the ecosystem and let implicit trust do the rest. LiteLLM was compromised because its pipeline used Trivy — the infostealer stole the PyPI publishing token, and from there TeamPCP published malicious versions with 3.6 million daily downloads. [SANS Institute]

One token. Five compromised ecosystems. That’s the geometry of a well-executed supply chain attack.

What makes this case especially uncomfortable is that the victims weren’t careless teams. They were teams that had invested in security, that scanned their pipelines, that used cloud-native tooling. Diligence didn’t protect them — because the diligence was applied inside the trust perimeter, not at the perimeter itself.

The solution is not to stop using external tools

The wrong conclusion from this incident would be to stop using Trivy, to distrust all open-source tools, or to build everything in-house. That’s neither viable nor the right lesson.

The lesson is that trust in external dependencies needs to be explicit and verifiable — not implicit and assumed.

Digest pinning

The most concrete and immediate change is to reference GitHub Actions by digest instead of by tag.

Instead of this:

- uses: aquasecurity/[email protected]

This:

- uses: aquasecurity/trivy-action@sha256:57a97c7...

The digest anchors the pipeline to a specific verified piece of content. If someone force-pushes the tag, the pipeline keeps executing the original commit. Tag mutability stops being a problem because the pipeline doesn’t depend on the tag. [Legit Security]

The obvious objection is that this makes updates harder — and it’s valid. A fixed digest doesn’t update itself. That’s where the second part comes in.

Dependabot and Renovate

Dependabot and Renovate can manage GitHub Actions updates automatically, including digest pinning. When a new verified version is released, they open a PR with the updated digest. The team reviews, approves, and the pipeline updates in a controlled and auditable way.

The combination closes the loop: digest pinning eliminates exposure to mutable tags, and Dependabot/Renovate eliminates the friction of maintaining digests manually.

Confirmed safe versions

For those using Trivy at the time of the incident, confirmed safe versions are: Trivy binary v0.69.3 or earlier, trivy-action v0.35.0 at commit 57a97c7, setup-trivy v0.2.6 at commit 3fb12ec. Any reference to v0.70.0 in logs should be treated as suspicious — the attacker attempted to publish that version but was stopped before the tag was pushed. [Legit Security]

Secrets: less is more

One thing this incident makes clear is the problem of pipelines that inherit more secrets than they need. If a scanning job doesn’t need production credentials, it shouldn’t have them — regardless of whether they’re temporary or static. Applying least privilege to what secrets get passed to each job reduces the blast radius when a tool is compromised.

Immediately rotate any credential that was exposed to a pipeline that ran compromised versions of Trivy between March 19 and March 22. That includes GitHub tokens, cloud credentials, registry tokens, SSH keys, and database passwords. [Legit Security]

Closing — what happened in LATAM

All of the above reflection could remain theoretical if it weren’t for someone in our community who lived this in real time.

Alejandro Castañeda, AWS Community Builder and Cloud Engineer from Colombia, shared on LinkedIn what happened to his team. His pipeline was compromised. The infostealer ran on a self-hosted runner inside his EKS cluster and sent approximately 80KB to the attacker’s server. To put that in perspective: 80KB is enough to carry away all the secrets from a complete pipeline.

And yet, they reviewed CloudTrail top to bottom and the result was zero lateral movement. No API calls from the attacker’s IP. No IAM user creation, no policy changes, no resource access.

Why?

Because Alejandro’s team had made an architecture decision ahead of time, when they were defining the foundations of their infrastructure: OIDC with IAM Roles instead of static access keys. Their pipelines assumed temporary roles that expired in minutes. By the time the attacker had the credentials in hand, they were already worthless. And the role’s trust policy only allowed use from GitHub — so even if they hadn’t expired, they couldn’t be used from anywhere else.

If they had had static access keys stored as GitHub secrets, the story would be completely different. The attacker would have had access to ECR to inject malicious images into production containers, and to Secrets Manager to read database credentials and financial service tokens.

The difference between “our secrets were stolen and nothing happened” and a real disaster was an architecture decision that nobody made thinking about this specific attack. They made it because it was the right way to build.

That’s what I take from this incident. Not the list of affected versions — that changes. Not the name of the threat actor — that changes too. What doesn’t change is the principle: design so that when someone compromises a dependency, they don’t find anything useful on the other side.

Security isn’t about building a perfect wall. It’s about making sure that when someone jumps it, there’s nothing useful on the other side.

About the author

Gerardo Castro is an AWS Security Hero and Cloud Security Engineer focused on LATAM. Founder and Lead Organizer of the AWS Security Users Group LatAm. He believes the best way to learn cloud security is by building real things — not memorizing frameworks. He writes about what he builds, what he finds, and what he learns along the way.

🔗 GitHub: gerardokaztro
🔗 LinkedIn: gerardokaztro

Porting Test Drive II from SNES to PC, Part 37: Narrowing the SNES clock-slot timing drift

SNES Select Opponent BG1 surface

Porting Test Drive II from SNES to PC, Part 37: Narrowing the SNES clock-slot timing drift

The previous checkpoint closed the organic default-rival path:

L00C20B -> 01:C1D2 -> L00BE76 -> L008B87 -> 01:902D -> active_main = 02:9016

That left one narrow front-end problem:

can the fourth Select Opponent clock slot be chosen organically in the same
live corridor?

This checkpoint does not close that slot yet.

It does something almost as useful:

it proves why the obvious fixed-frame approach is still failing.

SNES Select Opponent BG1 surface

The remaining problem is not the button map

Static bank-1 reading at L00C32A..L00C371 already showed that the input loop
applies vertical and horizontal bits in sequence.

So right+down is not being discarded because of a bad button interpretation.

The problem is timing.

More precisely:

the live 01:C1D2 window itself keeps sliding when the earlier confirmation
windows move.

Two bounded follow-ups prove the drift

In v3, I moved right+down later and kept start relatively early.

That run reaches:

  • L00C20B at frame 1600
  • first 01:C1D2 only at 1615..1617

So right+down at 1600..1605 was still too early.

The run simply fell through the already-known default-rival path again.

In v4, I delayed the later confirmation window to create more room.

That changed the corridor itself:

  • L00C20B moved to frame 1613
  • first 01:C1D2 moved to 1628..1637

So the delayed right+down at 1620..1625 was still too early too.

This time the run only reached L00BE76 and then stayed on the later
01:BE43 callback in the sampled window, without falling through to
L008B87 or 01:902D.

Why this matters

This is a real narrowing, not a failed rerun with no information.

The remaining clock-slot problem is now better described as:

  • callback-relative timing drift

not as:

  • uncertain button semantics
  • generic “needs later frames”

That changes the next probe design.

The next move is stricter now

The next defensible probe is no longer “slide the absolute frame numbers
forward again”.

It is:

  • overlap right+down with the live 01:C1D2 window itself
  • or trigger the direction change relative to first 01:C1D2

In other words, the problem is now local enough that the next step should be
callback-relative instead of frame-absolute guesswork.

OpenClaw Alternatives for Enterprise Security: Honest 2026 Comparison

Three-panel technical diagram comparing security architectures: wrapper layer, container isolation, and compact single-unit approaches

Why Enterprise Teams Are Looking Beyond OpenClaw

OpenClaw dominates the AI agent framework space. With 186,000+ GitHub stars and the broadest skill and messaging ecosystem in the category, it is the default starting point for most teams building autonomous agents.

The problem is that popularity and security are not the same thing. As enterprise adoption has accelerated through 2025 and into 2026, the gap between what OpenClaw offers out of the box and what regulated or high-security environments require has become harder to ignore. The CVE disclosures, the malicious skill reports, and the publicly exposed instances are not theoretical risks. They are documented, numbered, and scored.

This article covers the six alternatives worth evaluating, from a team that runs OpenClaw in production every day. We are not switching away from it. We are also not pretending the security posture is adequate without significant hardening.

What follows is a framework comparison structured for enterprise decision-making: what each alternative actually secures, what it gives up, and which one fits which use case. We include a side-by-side comparison table, a decision framework, and honest assessments of what we would and would not switch to ourselves.

Quick Reference: How the Alternatives Stack Up

Framework Security Model Self-Hosted Best For
NemoClaw Kernel sandbox + YAML policy Yes Hardening existing OpenClaw
NanoClaw Container isolation + audit log Yes Regulated industries
ZeroClaw Deny-by-default + Rust safety Yes Edge/IoT, minimal footprint
Moltworker Cloudflare security stack No Zero infrastructure management
Moltis Rust memory safety, zero unsafe Yes Enterprise Rust (if stability improves)

OpenClaw’s Security Track Record in 2026

OpenClaw has 186,000+ GitHub stars and a massive ecosystem. It is also, as of early 2026, a recurring entry in vulnerability databases.

In February 2026 alone, OpenClaw disclosed multiple CVEs spanning path traversal, missing webhook authentication, arbitrary file reads, and environment variable injection. The most severe, CVE-2026-25253, scored CVSS 8.8 and enabled one-click remote code execution. An attacker could craft a link that, when clicked, exfiltrated a user’s gateway token, connected to their local instance, modified configuration, disabled safety controls, and ran arbitrary commands on the host machine. In plain terms: an attacker sends a link to anyone on your team. If they click it, the attacker controls your agent infrastructure — no password required, no authentication bypass needed, just one click on a malicious URL.

That vulnerability was patched in version 2026.1.29, but the pattern is concerning. CVE-2026-22177 allowed environment variable injection for startup-time code execution. CVE-2026-26329 enabled path traversal through browser uploads. CVE-2026-32064 exposed noVNC sessions without authentication on multi-tenant hosts.

Beyond code vulnerabilities, the ecosystem itself has problems. Security researchers have reported 820+ malicious skills in the ClawHub marketplace. And scans have identified over 135,000 publicly exposed OpenClaw instances, many running unpatched versions.

The cumulative effect matters more than any single CVE. Each vulnerability requires teams to evaluate exposure, apply patches, and verify their deployments are not affected. For enterprise security teams accustomed to change management processes that take weeks, OpenClaw’s patch cadence creates a constant operational burden. And for regulated industries — healthcare, finance, legal — the mere presence of this many vulnerabilities in a production tool raises questions during compliance audits that are difficult to answer with “we patched it.”

None of this means OpenClaw is unusable. It means the default deployment posture, the one most teams run is not built for environments where a breach has regulatory or financial consequences.

What We Actually Run

Fountain City runs OpenClaw in production. Our autonomous SEO research agent (Scott) runs 9 scheduled workflows per week, producing 40+ content briefs per month. Aria handles content writing and publishing. Kai runs conversion optimization. Daisy manages social distribution. These are real agents doing real work on OpenClaw every day.

We stay on OpenClaw because it has the deepest ecosystem, the broadest messaging integrations, and the most mature skill library. For our use case — multi-agent orchestration across content research, writing, optimization, and social distribution — no other framework supports the full workflow without significant custom development. But we do not run defaults. Our security posture includes:

  • Agent scoping: Each agent has access only to the systems and tools it needs. No agent can reach another agent’s credentials or data stores.
  • Control steps: Agents perform work, then a secondary process reviews output for hallucinations, malicious injection, or actions that deviate from scope.
  • Surface reduction: Agents communicate only through controlled channels. No email or other external input sources that could enable prompt injection.
  • Downstream sanitation: For agents with external inputs, we sanitize data before passing it to subsequent agents in the system.
  • Firewall restrictions: The server sits behind a firewall that allows only specific IP addresses and ports. Without the current tunnel configuration, there is no path in.
  • Zero trust on dependencies: We review every dependency for risk and malware before installation. We prefer extending our platform manually rather than relying on community packages until security standards mature.
  • Data transients: We audit every location where data is sent, processed, and stored. Running all LLM calls locally is possible for clients who prioritize security over model capability.
  • Secrets management: Read-only access, never stored in configuration files, with flags for rotation.
  • Credential isolation: Every client gets their own server. No multi-tenant mixing.

This works for us because we built it deliberately. We also apply these same patterns when building AI workflow automation for clients. Most teams evaluating OpenClaw do not have 27 years of operational infrastructure experience to draw on. That is exactly why the alternatives below matter.

The Six Alternatives Worth Evaluating

The AI agent framework space has fractured into specialized approaches since OpenClaw’s security issues became public. The space includes forks, clean-room rebuilds, and frameworks from infrastructure companies with their own agendas. Here is how each option handles enterprise security requirements.

NemoClaw (NVIDIA): Enterprise Security Wrapper

NemoClaw is NVIDIA’s enterprise security wrapper for OpenClaw, announced at GTC on March 17, 2026.

The architecture has three layers. OpenShell provides kernel-level sandboxing for every agent execution — not container-level isolation like NanoClaw, but OS-level sandboxing that runs beneath the application. A YAML-based policy engine defines what each agent can access, what tools it can call, and what data it can read. This is where security teams spend most of their configuration time, defining granular access controls per agent. A privacy router handles hybrid local/cloud inference, keeping sensitive data on local models while routing general tasks to cloud providers. For organizations with data residency requirements, the privacy router is the feature that matters most.

NemoClaw is fully open source and hardware-agnostic at the infrastructure level — it runs on AWS, Azure, GCP, or bare metal, not just NVIDIA hardware. There are two caveats worth knowing. First, the current release is Linux-only; Windows and macOS deployments are not supported. Second, the privacy router’s local inference capability is optimized for NVIDIA’s Nemotron model family. You can use other local models, but the integration is smoother if you stay within NVIDIA’s model ecosystem.

Strengths: Most comprehensive enterprise option for existing OpenClaw users. You keep your skills, your configurations, your messaging integrations. NemoClaw adds the security layer that OpenClaw lacks without requiring migration.

Weaknesses: It is eight days old as of this writing. Nobody has run it in production at scale. The deployment is heavier than raw OpenClaw, adding latency and infrastructure complexity. Linux-only deployment limits options for teams with Windows-based infrastructure. And as CIO coverage noted, NemoClaw does not solve governance, audit trails, or cross-system reasoning. Those are still your problem.

Best for: Teams already running OpenClaw who need enterprise-grade security without ripping out their existing setup. If you have invested months building custom skills, configuring messaging channels, and tuning agent behaviors, NemoClaw lets you add a security layer without starting over. The question is whether you trust a week-old tool to protect production workloads.

NanoClaw: Container-First Security in 700 Lines

NanoClaw takes the opposite approach to OpenClaw’s 430,000+ lines of TypeScript. The entire framework is roughly 700 lines of TypeScript, with around 21,500 GitHub stars. That line count is not a limitation — it is an engineering choice that prioritizes auditability over feature breadth.

The security model is built on container isolation. Every chat group runs in its own sandboxed Docker container. Permission gates are mandatory, not optional. There is a built-in audit log for every action an agent takes. This is the architecture that enterprise security teams want to see during compliance reviews.

Dextra Labs rated NanoClaw highest on security architecture in their SARA assessment framework, specifically for compliance-driven enterprises in healthcare, finance, and legal.

Strengths: The codebase is small enough that a security team can audit the entire thing in a day. Container isolation means a compromised agent cannot touch anything outside its own sandbox. Built-in audit logs satisfy compliance requirements without bolting on third-party tooling.

Weaknesses: NanoClaw requires container and DevOps expertise that not every team has. Setting up Docker-based agent isolation is straightforward for teams with existing container infrastructure, but adds significant complexity for organizations that have not adopted containers. The ecosystem is much smaller than OpenClaw’s — fewer skills, fewer integrations, fewer community examples to learn from. And according to Till Freitag’s analysis, NanoClaw is Claude-only with no multi-LLM support, which limits flexibility for teams running multiple model providers.

Best for: Regulated industries (healthcare, finance, legal) where auditability and container isolation are requirements, not preferences. If your security team’s first question is “can we audit the entire codebase?” and their second question is “can a compromised agent escape its sandbox?”, NanoClaw answers both.

ZeroClaw: The Rust Rewrite at 3.4MB

ZeroClaw starts from the opposite premise. Written in Rust with roughly 26,200 GitHub stars, the entire framework compiles to a 3.4MB binary. It boots in under 10 milliseconds and uses less than 5MB of RAM.

The security model is deny-by-default. Out of the box, a ZeroClaw agent cannot do anything. You explicitly permit each operation: file access, network calls, tool execution. This is the inverse of OpenClaw, where the default posture is permissive and you lock things down after the fact.

ZeroClaw supports 22+ AI providers, includes SQLite-based hybrid search, and can import OpenClaw SOUL.md and IDENTITY.md files directly, which reduces migration friction. The multi-provider support is notable because it means teams are not locked into a single LLM vendor — you can route different tasks to different models based on cost, capability, or data residency requirements.

Strengths: Rust provides memory safety guarantees that TypeScript cannot. The minimal footprint means fewer dependencies, which means fewer attack surfaces and faster patch cycles. The deny-by-default model is what security-first organizations expect.

Weaknesses: The deny-by-default approach has a real cost. Users on Reddit have described ZeroClaw as “oversecured and useless by default,” requiring manual permission grants for basic operations. A task that takes 5 minutes to configure on OpenClaw might take 30 minutes on ZeroClaw because you need to explicitly permit each file path, network endpoint, and tool invocation. The ecosystem is younger than OpenClaw’s, and browser control and canvas features are not available yet.

Best for: Edge deployments, IoT scenarios, or teams where minimal footprint and maximum control over permissions are the primary requirements. If your deployment target is a VPS with 512MB of RAM or a single-board computer running in a factory or retail environment, ZeroClaw is the only serious option.

Moltworker (Cloudflare): Serverless at the Edge

Moltworker is Cloudflare’s adaptation of the OpenClaw model for their serverless infrastructure. Agents run on Cloudflare Workers with R2 buckets for persistent state, giving you a global edge network, automatic scaling, and built-in DDoS protection without managing any infrastructure.

The security argument for Moltworker is essentially the Cloudflare security argument: a mature, battle-tested security stack that has been absorbing attacks at scale for years. You do not manage servers, patch operating systems, or configure firewalls. The trade is that Cloudflare manages all of that for you, which means your agents and their data flow through Cloudflare’s infrastructure.

Strengths: Zero infrastructure overhead. Cloudflare handles scaling, security, and availability. If your team does not want to manage servers, this removes a significant operational burden.

Weaknesses: You are locked into Cloudflare’s infrastructure. Self-hosting is not an option, and migrating away from Moltworker means rebuilding your agent deployment from scratch on a different platform. Pricing at scale can surprise teams who did not model their usage patterns carefully — agent workloads with high-frequency tool calls or large file operations can generate unexpected Worker invocation costs. And you give up the fine-grained execution control that self-hosted alternatives provide.

Best for: Teams that want managed infrastructure and are comfortable with vendor dependency. Good for organizations where “we don’t want to manage servers” is the driving requirement. Moltworker is particularly appealing for teams deploying agents as customer-facing products, where global edge distribution and automatic scaling matter more than fine-grained local control.

Moltis: Enterprise Rust with Rough Edges

Moltis aims for the enterprise Rust space, with roughly 2,000 GitHub stars and around 150,000 lines of code. The project claims zero unsafe code blocks. In Rust, “unsafe” bypasses the borrow checker and memory safety guarantees, so zero usage is a meaningful security property.

The enterprise feature set is ambitious: comprehensive agent management, extensive configuration options, multi-model support, and the Rust memory safety guarantees that security teams value. On paper, it combines the security properties of Rust with the feature depth of OpenClaw.

Strengths: Rust memory safety. Zero unsafe code. Enterprise-oriented feature depth.

Weaknesses: Stability is a documented problem. Users on Reddit’s r/LocalLLaMA have reported that the author rushed features in response to community requests, leading to bugs and reliability issues. In a production environment, framework instability translates directly to agent downtime and unreliable task completion. The community is smaller than any other alternative listed here. Comprehensive features do not help if the runtime is unreliable.

Best for: Teams who need Rust memory safety guarantees today and have the engineering capacity to debug framework issues as they arise. The one reason to bet on Moltis despite the instability: if Rust’s memory model is a hard requirement for your security posture and you cannot wait for the project to mature, Moltis is the only option that combines enterprise feature depth with zero unsafe code. Be prepared to contribute fixes upstream. Worth monitoring for everyone else; worth adopting only if Rust memory safety is a non-negotiable constraint and you have capacity to absorb framework bugs.

Honorable Mentions

PicoClaw is a Go-based framework at under 8MB, targeting IoT and embedded devices. If you need AI agents on $10 hardware — a Raspberry Pi running a monitoring agent, a sensor node making autonomous decisions — PicoClaw is purpose-built for that constraint. The footprint is roughly 8MB with under 10MB of RAM and one-second startup times. It lacks the formal security models of NanoClaw or ZeroClaw, which limits its applicability for compliance-sensitive use cases, but for embedded and edge scenarios where resource constraints dominate, nothing else in the ecosystem comes close.

IronClaw uses trusted execution environments (TEE) for cryptographic verification of agent operations. Every action an agent takes can be cryptographically attested, which provides provable execution integrity that no other framework offers. This matters for scenarios involving financial transactions, legal document processing, or any workflow where you need to prove that a specific agent performed a specific action at a specific time. The adoption footprint is small, and the TEE requirement limits deployment options, but for organizations where verifiable execution is a regulatory mandate, IronClaw is the only option purpose-built for it.

TrustClaw is a managed cloud platform. No infrastructure management, no self-hosting, no server configuration. Good for teams that want a turnkey solution and are comfortable with the tradeoffs of managed platforms — namely, that your agents and data run on someone else’s infrastructure.

Nanobot is a lightweight Python agent framework with roughly 4,000 lines of code. It is educational and approachable, with faster startup and lower memory than OpenClaw. Nanobot works well as a learning tool or for simple agent prototypes, but it is not enterprise-grade and lacks the security architecture of NanoClaw, ZeroClaw, or NemoClaw.

Three-panel technical diagram comparing security architectures: wrapper layer, container isolation, and compact single-unit approaches

Side-by-Side Comparison

Framework Language Footprint RAM Security Model Self-Hosted Best For
OpenClaw TypeScript ~28MB 1GB+ DM pairing, allowlists Yes Largest ecosystem, most integrations
NemoClaw Python + TS Wrapper 1GB+ (OC base) Kernel sandbox, YAML policy, privacy router Yes Hardening existing OpenClaw
NanoClaw TypeScript ~700 LOC ~50MB Container isolation, mandatory permissions, audit log Yes Regulated industries (compliance-first)
ZeroClaw Rust 3.4MB <5MB Deny-by-default, allowlists, encrypted secrets Yes Edge/IoT, minimal attack surface
Moltworker TypeScript Serverless Managed Cloudflare security stack, DDoS built-in No Zero infrastructure management
Moltis Rust ~150K LOC Moderate Rust memory safety, zero unsafe blocks Yes Enterprise Rust (if stability improves)

Security posture spectrum visualization showing the gradient from permissive default configurations to deny-by-default architectures for AI agent frameworks

Technology professional sketching a decision framework for choosing an AI agent security platform with holographic visualization overlay

How to Choose: A Decision Framework

Comparison tables are useful for reference. They are less useful for making decisions. Every enterprise has different constraints — compliance requirements, existing infrastructure, team expertise, hardware budgets, integration needs. The framework below maps specific enterprise requirements to specific recommendations, based on what we have seen working with clients evaluating these options.

If you already run OpenClaw and need to harden it: NemoClaw. It wraps your existing deployment with kernel-level sandboxing and policy controls. No migration, no ecosystem loss. The risk is that NemoClaw is brand new, so you are adopting enterprise security tooling that has not been production-tested at scale.

If you are in a regulated industry: NanoClaw. Container isolation, mandatory permission gates, and built-in audit logs are the three things compliance teams ask for first. The tradeoff is a smaller ecosystem and Claude-only LLM support.

If you need minimal footprint or deploy at the edge: ZeroClaw. A 3.4MB binary with under 5MB RAM usage runs on hardware that cannot support OpenClaw or NanoClaw. The deny-by-default model means more configuration upfront, which is either a feature or a burden depending on your team’s tolerance.

If you do not want to manage infrastructure: Moltworker. Cloudflare handles servers, scaling, security, and availability. You give up self-hosting and fine-grained control. For teams where infrastructure management is the problem they are trying to solve, that is the right tradeoff.

If you need enterprise Rust features and can tolerate instability: Moltis. The architecture is sound. The execution is rough. Monitor it, do not commit to it for production workloads today.

Questions to Ask Before Choosing

These are the questions that separate productive framework evaluations from ones that waste a quarter:

  • Do you need self-hosting? If yes, Moltworker is off the table. If no, Moltworker removes your biggest operational headache.
  • What is your compliance regime? HIPAA, SOC 2, or FedRAMP requirements push you toward NanoClaw’s audit infrastructure. If you can answer “none” honestly, your options open up significantly.
  • Do you have container and DevOps expertise? NanoClaw assumes you do. ZeroClaw is a single binary that a developer can deploy in an afternoon.
  • What is your hardware budget? ZeroClaw runs on a Raspberry Pi. OpenClaw needs a proper server with at least 1GB of RAM. NemoClaw adds overhead on top of that.
  • How many messaging integrations do you need? OpenClaw supports 10+ channels. Most alternatives support fewer. If your agents need to operate across Discord, Slack, WhatsApp, and Telegram simultaneously, the ecosystem size matters.
  • Do you already have an OpenClaw deployment? NemoClaw preserves that investment. Everything else requires migration of varying difficulty.
  • What is your team’s security expertise? ZeroClaw’s deny-by-default model requires understanding exactly what permissions each agent needs. OpenClaw with NemoClaw is more forgiving — the wrapper adds security without requiring you to define every permission from scratch.

What We Are Watching

We run OpenClaw because, as of today, nothing else matches its combination of ecosystem depth, messaging integrations, and skill library. Our managed autonomous AI agents operate on it daily, and the security measures we described above keep us comfortable with that choice. If you want OpenClaw’s ecosystem with enterprise-grade security but don’t want to build and maintain the hardening layer yourself, that’s exactly what our managed service provides — we handle the infrastructure, the security patching, the monitoring, and the operational burden so you can focus on what your agents do, not how they stay safe.

We will update this article as we test NemoClaw and as the alternative landscape evolves. If you want current findings, this page is where we publish them.

That said, we are watching NemoClaw closely. If the sandbox proves stable in production and the policy engine handles the edge cases that real-world agent workloads generate, NemoClaw becomes the path forward for our deployments. It addresses our biggest concerns without requiring migration.

Specifically, we would test NemoClaw against our most demanding agent patterns: Scott’s 9-workflow weekly schedule with simultaneous web scraping and API calls, Aria’s WordPress REST API publishing pipeline with credential isolation, and Kai’s GA4 data retrieval with cross-agent coordination. These workflows involve concurrent file system access, API authentication, tool execution chains, and inter-agent messaging — the exact scenarios where a security wrapper either proves itself or breaks down.

NanoClaw would be compelling if it added multi-LLM support. We run different models for different tasks (research gets one model, writing gets another, review gets a third). Claude-only is a constraint we cannot work around.

ZeroClaw’s efficiency numbers are impressive, but the ecosystem gap is real. When we need an agent to coordinate across Discord, file systems, web search, and WordPress publishing in a single workflow, the tool and integration library matters as much as the runtime security model. Our content pipeline alone involves 15+ tool integrations per agent — web scraping, REST APIs, file management, semantic search, image generation, messaging, and browser automation. Rebuilding that integration surface on a newer framework is not a weekend project.

We would not switch to anything that sacrifices the skill ecosystem or messaging integrations we depend on. Those are operational requirements, not preferences.

NemoClaw is eight days old. The architecture looks right and the backing is serious, but nobody knows yet whether it holds up under the load patterns that production agent teams generate. We will publish our findings when we do. In the meantime, our recommendation for teams evaluating OpenClaw alternatives today: pick the framework that matches your primary constraint, harden it properly, and build your security posture deliberately rather than relying on defaults.

Elegant wireframe fountain with cascading data particles representing secure AI agent platform architecture

Frequently Asked Questions

Is OpenClaw safe to use in 2026?

OpenClaw is safe with proper hardening: firewall restrictions, agent scoping, dependency review, secrets management, and keeping versions current. The default deployment posture is not safe for regulated or high-security environments. If you run defaults on a public-facing server, you have a problem. See the “What We Actually Run” section above for the specific hardening measures we apply in our production deployment.

What is the most secure OpenClaw alternative?

The most secure OpenClaw alternative for compliance-driven organizations is NanoClaw, with mandatory container isolation and a 700-line auditable codebase. ZeroClaw’s deny-by-default model is more restrictive at the permissions level but requires more manual configuration. NemoClaw adds the most security to existing OpenClaw deployments without requiring migration. The right choice depends on whether you need to start fresh (NanoClaw or ZeroClaw) or harden what you already run (NemoClaw).

Can I migrate from OpenClaw to NanoClaw or ZeroClaw without starting over?

ZeroClaw supports importing OpenClaw SOUL.md and IDENTITY.md files, which reduces migration effort for agent configurations. NanoClaw requires restructuring your deployment around containers. Neither is a drop-in replacement for the full OpenClaw skill and integration ecosystem. Plan on rebuilding custom skills and testing all messaging integrations — the agent logic ports over, but the tooling around it does not.

Is NemoClaw only for NVIDIA hardware?

No. NemoClaw is fully open source and hardware-agnostic at the infrastructure level. It runs on AWS, Azure, GCP, bare metal, or your own data center — NVIDIA built it, but it does not require NVIDIA GPUs. Two caveats: the current release is Linux-only (no Windows or macOS support), and the privacy router’s local inference is optimized for NVIDIA’s Nemotron model family. GPU acceleration helps but is not required; CPU-only servers work.

Which OpenClaw alternative works best for WhatsApp, Telegram, and Slack?

OpenClaw still has the broadest messaging channel support (10+ platforms). NanoClaw supports WhatsApp through Baileys. ZeroClaw supports 8+ channels. Moltworker inherits OpenClaw’s channel support through the Cloudflare Workers adaptation. If messaging breadth is critical, OpenClaw with NemoClaw hardening is the practical choice.

How much does it cost to run these alternatives?

The frameworks themselves are free and open source (except Moltworker, which uses Cloudflare’s pricing). The primary cost is LLM API usage, which runs roughly $80 to $120 per month for active agents regardless of framework. Infrastructure costs vary significantly: ZeroClaw runs on a $5/month VPS or a Raspberry Pi, OpenClaw and NemoClaw need a proper server (typically $20-80/month for a VPS with adequate RAM), and NanoClaw needs container infrastructure that adds overhead. For a breakdown of agent economics including model costs per task, see our AI agent cost calculator.

Can I use multiple alternatives together?

In theory, you could run NemoClaw-wrapped OpenClaw agents alongside ZeroClaw agents on different tasks. In practice, managing multiple agent frameworks increases operational complexity — different update cycles, different configuration formats, different debugging workflows, different security audit processes. Pick the one that fits your primary requirements and standardize on it. The overhead of maintaining two parallel frameworks almost always outweighs the benefits of mixing features.

What happened to Moltbot and Clawdbot?

Both were early forks that either merged back into the OpenClaw mainline or were abandoned as the ecosystem consolidated around the alternatives listed here. If you see references to either in older comparison articles, they are outdated. The six frameworks covered in this article represent the current state of the market as of March 2026.

Claude: We Need to Talk About Message Limits

“You’ve reached 75% of your usage limit for this week.” must be familiar to quite a few people now.

The promise vs. the reality, especially when subscriptions start at $20/month is frustrating, to say the least.

Now don’t get me wrong, i still do think that Claude is a great tool, and it has helped me a lot in building a website. But the message limits make me hesitant about renewing my subscription at this point.

The “just switch to another model” argument doesn’t hold up.
“Hit the limit? No problem — here’s a lighter model to keep you going.”

Sure. Except that the lighter model doesn’t have the context of the last 40 messages you just built up ?

It doesn’t know you already ruled out Solution B or that you’re on Node 18, not 20. So you either start over, re-paste everything, or accept dramatically degraded output quality.

The limit doesn’t hit the casual user who fires off five prompts a week. It hits the person who has made AI a core part of their production workflow — the exact user these subscriptions were designed to attract.

Moreover, you never really know exactly where you stand until you’re blocked.
No progress bar. No “you’ve used 30% of your weekly allowance” warning. Just a hard stop at the worst possible moment. For anyone managing a deadline, this is genuinely disruptive.
Basic usage transparency shouldn’t be a premium feature.

“Just upgrade to the enterprise tier”

Some will say: pay more, get more. Fair enough in principle.
But the jump from individual to enterprise pricing isn’t a gradual scale — it’s a cliff.

The pricing architecture seems deliberately designed to push anyone with serious usage needs into an enterprise contract, rather than offering a middle tier that actually fits solo builders and small teams.
For developers bootstrapping products on their own, that’s a non-starter.

I’m not arguing that AI companies should run at a loss to serve unlimited queries. Compute costs are real. But i just think there’s a reasonable middle ground that needs to be found:
∙ Visible usage tracking — show me how much I’ve consumed in real time
∙ Rollover credits — unused capacity this week shouldn’t just evaporate
∙ Graceful degradation warnings — tell me I’m approaching the limit before I’m cut off mid-session
∙ Session continuity: if I do hit a cap, preserve context so I can resume without starting from scratch
None of these are technically impossible. They’re product decisions.

We’re paying for infrastructure. We deserve more clarity about what we’re actually buying.

I Built a PDF Splitter That Never Touches Your Files — Here’s How

Why another PDF tool? Because privacy shouldn’t be a premium feature.

We’ve all been there. You have a 40-page PDF report, your client needs pages 12–18, and the only tools you can find either slap a watermark on the output, cap your file size, or — most troublingly — upload your document to some server you’ve never heard of before “processing” it.
That last part should bother you more than it does.
I built iHatePDF’s Split PDF tool to solve exactly this problem. It’s fast, it’s free, it has no file size limit, and — most importantly — your files never leave your device. Not a single byte.
Here’s the full story.

The Problem with Most Online PDF Tools
Online PDF utilities are everywhere. But most of them share an uncomfortable architecture: you upload your file, it travels to a remote server, gets processed, and then gets sent back to you. Along the way, your document — which might contain contracts, medical records, financial data, or intellectual property — passes through infrastructure you don’t control and likely don’t understand.
Some tools are upfront about this. Many are not. And even the honest ones that promise to “delete your file after 1 hour” are asking you to take their word for it.
There’s a better way.

The Core Idea: Keep Everything in the Browser
Modern browsers are incredibly capable. Thanks to APIs like the File API, Web Workers, and libraries like pdf-lib, you can do serious PDF manipulation entirely on the client side — no server required.
This is exactly what the Split PDF tool does. When you upload a PDF:

It’s read into memory using the browser’s FileReader API as an ArrayBuffer.
pdf-lib parses the document and counts the pages.
When you hit “Split PDF,” the library creates new PDF documents, copies the relevant pages over, and generates downloadable byte arrays.
Those byte arrays are handed directly to your browser’s download mechanism.

At no point does the file travel over a network. The “server” is your own CPU.
javascriptconst buffer = await readFileAsArrayBuffer(file);
const { PDFDocument } = window.PDFLib;
const sourcePdf = await PDFDocument.load(buffer);
Three lines. That’s the entire “upload” step — and it never left your machine.

Two Ways to Split
The tool offers two splitting modes, designed to cover the most common real-world scenarios.

  1. By Page Ranges
    This is the power-user mode. You type something like 1-5, 10-15, 20 and the tool produces three separate PDF files — one for each range. It’s perfect for:

Breaking a book into chapters
Extracting a specific section of a report to share with stakeholders
Separating a combined invoice document into individual invoices

The range parser handles both ranges (1-5) and single pages (20) in the same input string, separated by commas. Clean and flexible.
javascriptconst parseRanges = (rangeStr) => {
const result = [];
for (const part of rangeStr.split(“,”).map((s) => s.trim())) {
if (part.includes(“-“)) {
const [start, end] = part.split(“-“).map((n) => parseInt(n.trim()));
if (!isNaN(start) && !isNaN(end) && start <= end)
result.push({ start: start – 1, end: end – 1 });
} else {
const num = parseInt(part);
if (!isNaN(num)) result.push({ start: num – 1, end: num – 1 });
}
}
return result;
};
Notice the – 1 offsets — PDF page indices are zero-based internally, but humans count from 1. Small detail, big UX impact.

  1. Individual Pages
    One click, and every page becomes its own PDF file. A 20-page document turns into 20 separate downloads. This is ideal for distributing slides, archiving scanned documents page by page, or just giving someone exactly the one page they asked for.
    To avoid overwhelming the browser’s download manager, individual page downloads are staggered with a 100ms delay between each one — a tiny but important UX consideration.

Handling Downloads Across Every Browser
Cross-browser file downloads sound trivial until you try to support Safari on iOS. The tool uses a layered download helper that tries progressively more compatible approaches:

A custom window.download function if available
The legacy msSaveOrOpenBlob for old Edge/IE
A programmatically clicked tag (the standard modern approach)
As a last resort, window.open() with a blob URL, with a prompt to allow pop-ups

iOS Safari gets a special callout UI element that reminds users to check their Files app → Downloads folder, since the native Safari download behavior differs from desktop browsers.
javascriptconst isIOSSafari = () => {
const ua = window.navigator.userAgent;
return (
(!!ua.match(/iPad/i) || !!ua.match(/iPhone/i)) &&
!!ua.match(/WebKit/i) &&
!ua.match(/CriOS/i)
);
};
Small touches like this are what separate a tool people actually use from a tool people abandon in frustration.

Local History Without a Backend
The tool tracks your recent splits using a hybrid storage strategy:

Metadata (filename, tool used, timestamp, size) goes into localStorage — lightweight and fast.
The actual PDF bytes go into IndexedDB — the browser’s structured data store, capable of handling large binary blobs.

This means you can revisit recent files without re-uploading anything, and it all works offline. No accounts. No sync. No data leaving your device.
javascriptconst addToHistory = async (pdfData) => {
const history = JSON.parse(localStorage.getItem(HISTORY_KEY) || “[]”);
const newEntry = { id: Date.now(), name: pdfData.name, tool: pdfData.tool, … };
if (pdfData.bytes) {
await dbSet(pdf_${newEntry.id}, pdfData.bytes); // IndexedDB
}
history.unshift(newEntry);
localStorage.setItem(HISTORY_KEY, JSON.stringify(history.slice(0, 50)));
};
The history is capped at 50 entries to keep storage usage reasonable. Pragmatic, not precious.

Quality Is Never Compromised
One concern people often have with PDF tools is quality degradation. This tool sidesteps the issue entirely — because there is no re-rendering happening.
pdf-lib doesn’t rasterize your pages into images and repack them. It copies the raw PDF page objects from the source document into the new document. The text stays as text. The vector graphics stay as vectors. The embedded fonts stay embedded. You get a byte-perfect extraction, not a screenshot of a page.

The Bigger Picture
This tool is part of a broader philosophy: your files are yours. The browser has become powerful enough that the reflexive “upload to server → process → download” pipeline is often unnecessary, and increasingly, it’s irresponsible.
Client-side PDF processing is just one example. The same principle applies to image compression, document conversion, data parsing, and dozens of other utility tasks that millions of people outsource to servers every day when they don’t have to.
As developers, we have a responsibility to ask: does this actually need to leave the user’s device? More often than the current ecosystem suggests, the answer is no.

Try It
If you’ve ever needed to split a PDF — and who hasn’t — give it a try. Upload a file, split it, and notice what doesn’t happen: no spinner while a server “processes” it, no email confirmation, no account wall, no watermark on the output.
Just your PDF, split the way you want it, in seconds, entirely on your machine.
That’s what PDF tools should have been all along.

Built with React, pdf-lib, and a deep distrust of unnecessary server round-trips. All processing happens locally in your browser — always.

Why UltrafastSecp256k1?

https://github.com/shrec/UltrafastSecp256k1
A detailed look at what sets this library apart — not just in speed, but in engineering discipline, audit culture, and verified correctness.

1. Audit-First Engineering Culture

Most high-performance cryptographic libraries ship fast code and trust that it is correct.
UltrafastSecp256k1 ships fast code and then systematically tries to break it.

The internal self-audit system is not a layer of unit tests bolted on after the fact —
it was designed in parallel with the cryptographic implementation, as a first-class engineering artifact.

The underlying philosophy is Bitcoin-style: don’t trust, verify. The project does
not center its trust model on a one-time PDF artifact written by someone else at a
fixed moment in the past. Instead, it tries to make assurance continuously rerunnable:
every important claim should be tied to code, tests, CI artifacts, benchmark logs, or
traceable documentation that another engineer can reproduce on demand.

This is why the audit framework keeps expanding with the codebase. The repository ships
not only tests, but also reviewer-facing infrastructure: structured audit artifacts,
threat-model docs, adversarial exploit tests, differential checks, and a repo-local
SQLite source graph that makes the codebase searchable as an audit surface rather than
just a pile of files.

These top-level differentiators are claim-keyed in the ledger: exploit-audit surface A-005, graph-assisted review A-006, self-audit transparency A-007, and benchmark reproducibility A-004 in docs/ASSURANCE_LEDGER.md.

What the Audit Infrastructure Covers

Area What is Tested Assertion Count
Field arithmetic (𝔽ₚ) Commutativity, associativity, distributivity, canonical form, carry propagation, batch inverse, sqrt 264,622
Scalar arithmetic (ℤ_n) Reduction mod n, overflow, GLV decomposition, negation, edge cases (0, 1, n−1) 93,215
Point operations Infinity handling, Jacobian↔Affine round-trip, scalar multiplication, 100K stress 116,124
Constant-time layer No secret-dependent branches, no secret-dependent memory access, formal CT verification 120,652
Exploit PoC tests 86 dedicated adversarial PoC tests across 14 coverage areas (audit/test_exploit_*.cpp) 86 test files, 0 failures
Fuzz / adversarial libFuzzer harnesses + 530K deterministic corpus adversarial checks ~530,000+
Wycheproof vectors Google’s cryptographic test vectors for ECDSA and ECDH Hundreds of vectors
Fiat-Crypto linkage Cross-validates field arithmetic against formally-verified Fiat-Crypto reference Full suite
FROST / MuSig2 KAT Protocol-level Known Answer Tests per BIP-327 and FROST spec Full suite
Fault injection Tests behaviour under simulated hardware faults (bit flips, counter skips) Full suite
ABI gate FFI round-trip stability, C ABI regression detection Full suite
Performance regression Automated micro-benchmark gate — fails CI if throughput regresses Every push
Nightly differential Random round-trip differential tests against reference implementations ~1,300,000+/night
Total (audit runner) unified_audit_runner across 55 modules plus standalone audit surfaces ~1,000,000+
Total (exploit PoC tests) 86 exploit-style PoC tests across 14 coverage areas, all in audit/test_exploit_*.cpp 86 tests, 0 failures

All 55 audit modules across all tested platforms return AUDIT-READY. Zero failures.
All 86 exploit PoC tests pass. Zero failures across all 14 coverage areas.

Self-Audit Documents

Document Purpose
AUDIT_GUIDE.md Navigation guide for external auditors — build steps, source layout, test commands
AUDIT_REPORT.md Historical formal audit report (v3.9.0): 641,194 checks, 0 failures
AUDIT_COVERAGE.md Current coverage matrix by module and section
THREAT_MODEL.md Layer-by-layer risk analysis — what is in scope and out of scope
SECURITY.md Vulnerability disclosure policy and contact
docs/CT_VERIFICATION.md Constant-time formal verification evidence and methodology
audit/AUDIT_TEST_PLAN.md Detailed test plan covering all 8 audit sections
audit/platform-reports/ Per-platform audit run results and logs
tools/source_graph_kit/source_graph.py SQLite-backed repository graph for fast impact tracing, audit scoping, and reproducible review
docs/ASSURANCE_LEDGER.md Canonical claim-to-evidence ledger for public trust statements
docs/AI_AUDIT_PROTOCOL.md Formal protocol for AI-assisted auditor/attacker review loops
docs/FORTRESS_ROADMAP.md Gap-closing roadmap for fortress-grade self-audit

2. CI/CD Pipeline — 24 Automated Workflows

The continuous integration pipeline is not a basic build-and-test gate.
It is a multi-layer quality enforcement system with 24 GitHub Actions workflows
covering security, correctness, performance, supply chain, and formal analysis.

It is also only one part of the assurance model. The repository is routinely reviewed
through external-style passes as if by auditors, attackers, and bug bounty hunters,
including LLM-assisted review loops that help surface edge cases, exploit ideas, and
documentation gaps. Those passes are not treated as magic or as a replacement for
deterministic tests; they are useful because they feed new cases back into the same
reproducible audit framework.

Workflow Index (selected)

Workflow What It Does Trigger
ci.yml Core build + full test suite across 17 configurations × 7 architectures × 5 OSes Every push / PR
preflight.yml Fast pre-merge smoke check — blocks merge on basic failures Every PR
nightly.yml Nightly stress: 1.3M+ differential checks, extended fuzz, full sanitizer run Nightly
security-audit.yml Runs the full unified_audit_runner (55 modules, ~1M assertions) plus sanitizer and warning gates Every push
audit-report.yml Generates and archives structured audit report artifacts On release / manual
ct-arm64.yml Constant-time verification on native ARM64 hardware Every push
ct-verif.yml Formal constant-time verification pass Every push
valgrind-ct.yml Valgrind memcheck + CT analysis on Linux x64 Every push
bench-regression.yml Performance regression gate — CI fails if throughput drops Every push
benchmark.yml Full benchmark suite — results published to live dashboard On push to dev/main
codeql.yml GitHub CodeQL static analysis (C++) Every push
clang-tidy.yml Clang-Tidy lint pass with project-specific rules Every push
cppcheck.yml CPPCheck static analysis Every push
sonarcloud.yml SonarCloud code quality and security rating Every push
mutation.yml Mutation testing — verifies test suite kills injected faults Scheduled
cflite.yml ClusterFuzz-Lite continuous fuzzing integration Every push
bindings.yml Tests all 12 language bindings (Python, Rust, Node, Go, C#, Java, Swift, …) Every push
dependency-review.yml Scans dependency changes for known vulnerabilities Every PR
scorecard.yml OpenSSF Scorecard supply-chain security scan Weekly
valgrind-ct.yml Valgrind constant-time path analysis Every push
docs.yml Docs build and deployment validation Every push
packaging.yml NuGet, vcpkg, Conan, Swift Package, CocoaPods packaging validation On release
release.yml Full release pipeline: build, sign, attest, publish On tag

Build Matrix Scale

Dimension Coverage
Configurations 17 (Release, Debug, ASan+UBSan, TSan, Valgrind, coverage, LTO, PGO, …)
Architectures 7 (x86-64, ARM64, RISC-V, WASM, Android ARM64, iOS ARM64, ROCm)
Operating systems 5 (Linux, Windows, macOS, Android, iOS)
Compilers GCC 13, Clang 17, Clang 21, MSVC 2022, AppleClang, NDK Clang

3. Static Analysis & Sanitizer Stack

Every commit is checked by multiple independent static and dynamic analysis layers:

Tool What It Catches
CodeQL Semantic security vulnerabilities, data-flow bugs
SonarCloud Code quality, security hotspots, cognitive complexity
Clang-Tidy Style violations, anti-patterns, performance issues
CPPCheck Memory errors, null dereferences, buffer overflows
ASan + UBSan Memory errors, undefined behaviour in CT paths
TSan Data races and threading issues
Valgrind memcheck Heap errors, uninitialized reads
Valgrind CT Constant-time path analysis via shadow value propagation
libFuzzer Corpus-driven bug finding in field, scalar, and point arithmetic
ClusterFuzz-Lite Continuous fuzzing integrated into CI

The -Werror flag is enforced — warnings are build failures.

4. Supply Chain Security

Cryptographic libraries are high-value supply chain targets.
UltrafastSecp256k1 applies the OpenSSF supply-chain hardening model:

  • OpenSSF Scorecard — automated weekly supply-chain health score
  • OpenSSF Best Practices badge — verified against the CII/OpenSSF criteria
  • Pinned GitHub Actions — all third-party actions pinned to commit SHA, not floating tags
  • Dependency Review — automated PR-level scan for vulnerable dependencies
  • Harden-runner — runtime monitoring of CI runner behaviour
  • Reproducible builds — Dockerfile.reproducible for bit-for-bit build verification
  • SBOM — software bill of materials generated on release
  • Artifact attestation — GitHub Artifact Attestation on release builds

5. Formal Verification Layers

Layer Method Status
Field arithmetic correctness Fiat-Crypto cross-validation (differential testing against formally-verified reference) Active
Constant-time (field/scalar) ct-verif tool + ARM64 hardware CI Active
Constant-time (point ops) Dedicated ct-arm64.yml pipeline + Valgrind shadow analysis Active
Wycheproof ECDSA/ECDH Google’s adversarial test vector suite Active
Fault injection Simulated hardware faults in signing/verification paths Active
Cross-libsecp256k1 Differential round-trip against Bitcoin Core’s libsecp256k1 Active

6. Performance — Verified, Not Just Claimed

Every benchmark number in this project is:

  • Produced by a pinned compiler version with exact flags documented
  • Reproducible via a published command in docs/BENCHMARKS.md
  • Gated by an automated performance regression check in CI (bench-regression.yml)
  • Published to a live dashboard on pushes to dev/main

Sample verified numbers (RTX 5060 Ti, CUDA 12):

Operation Throughput
ECDSA sign 4.88 M/s
ECDSA verify 4.05 M/s
Schnorr sign (BIP-340) 3.66 M/s
Schnorr verify (BIP-340) 5.38 M/s
FROST partial verify 1.34 M/s

Sample verified numbers (x86-64 rerun, i5-14400F, Clang 19):

Operation Latency
Generator multiplication (kG) 5.9 µs
Scalar multiplication (kP) 16.0 µs
ECDSA sign 7.8 µs
ECDSA verify 20.2 µs

7. What “Not Paid-Externally Audited” Actually Means Here

UltrafastSecp256k1 has not yet undergone a paid third-party professional audit.
That is a factual status note, not the center of the project’s security philosophy.
The project is open to external audit and continuously prepares evidence so outside reviewers can audit it at any time.
At the same time, it does not wait for a third party to begin strengthening correctness and security, and it does not outsource trust to a single PDF milestone.

However, “not externally audited” does not mean “unverified.” The internal quality infrastructure described in this document represents a systematic, multi-layer correctness assurance program that most open-source cryptographic libraries do not have:

  • Over 1,000,000 internal audit assertions executed on every build
  • 24 CI/CD workflows enforcing correctness, security, and performance on every push/PR plus scheduled assurance runs
  • Formal constant-time verification on two independent platforms
  • Supply-chain hardening at the OpenSSF standard
  • Nightly differential testing at 1.3M+ additional random checks per night

The honest summary:

This library does not rely on a paid-audit badge as its primary trust story.
It does rely on open self-audit, reproducible evidence, graph-assisted review, and reviewer-friendly verification so anyone can inspect and challenge the implementation.
External audit is welcomed, but assurance work already happens continuously through internal audit on every build, every push/PR gate, and every nightly extended run.

Summary Table

Quality Dimension Evidence
Mathematical correctness 473,961 audit assertions (field + scalar + point)
Constant-time guarantees ct-verif, ARM64 CI, Valgrind CT, 120K CT assertions
Adversarial resilience Wycheproof, fault injection, 530K+ fuzz corpus
Protocol correctness FROST/MuSig2 KAT, cross-libsecp256k1 differential
Memory safety ASan, TSan, Valgrind — every commit
Static analysis CodeQL, SonarCloud, Clang-Tidy, CPPCheck
Supply chain OpenSSF Scorecard, pinned actions, SBOM, artifact attestation
Performance regression Automated gate on every push
Build reproducibility Dockerfile.reproducible + pinned toolchains
Self-audit documentation AUDIT_GUIDE, AUDIT_REPORT, AUDIT_COVERAGE, THREAT_MODEL

https://github.com/shrec/UltrafastSecp256k1

Video Friday: Beep! Beep! Roadrunner Bipedal Bot Breaks the Mold

Video Friday is your weekly selection of awesome robotics videos, collected by your friends at IEEE Spectrum robotics. We also post a weekly calendar of upcoming robotics events for the next few months. Please send us your events for inclusion.

ICRA 2026: 1–5 June 2026, VIENNA
RSS 2026: 13–17 July 2026, SYDNEY
Summer School on Multi-Robot Systems: 29 July–4 August 2026, PRAGUE

Enjoy today’s videos!

“Roadrunner” is a new bipedal wheeled robot prototype designed for multi-modal locomotion. It weighs around 15 kg (33 lb) and can seamlessly switch between its side-by-side and in-line wheel modes and stepping configurations depending on what is required for navigating its environment. The robot’s legs are entirely symmetric, allowing it to point its knees forward or backward, which can be used to avoid obstacles or manage specific movements. A single control policy was trained to handle both side-by-side and in-line driving. Several behaviors, including standing up from various ground configurations and balancing on one wheel, were successfully deployed zero-shot on the hardware.

[ Robotics and AI Institute ]

Incredibly (INCREDIBLY!) NASA says that this is actually happening.

NASA’s SkyFall mission will build on the success of the Ingenuity Mars helicopter, which achieved the first powered, controlled flight on another planet. Using a daring mid-air deployment, SkyFall will deliver a team of next-gen Mars helicopters to scout human landing sites and map subsurface water ice.

[ NASA ]

NASA’s MoonFall mission will blaze a path for future Artemis missions by sending four highly mobile drones to survey the lunar surface around the Moon’s South Pole ahead of astronauts’ arrival there. MoonFall is built on the legacy of NASA’s Ingenuity Mars Helicopter. The drones will be launched together and released during descent to the surface. They will land and operate independently over the course of a lunar day (14 Earth days) and will be able to explore hard-to-reach areas, including permanently shadowed regions (PSRs), surveying terrain with high-definition optical cameras and other potential instruments.

For what it’s worth, Moon landings have a success rate well under 50%. So let’s send some robots there to land over and over!

[ NASA ]

In Science Robotics, researchers from the Tangible Media group led by Professor Hiroshi Ishii, together with colleagues from Politecnico di Bari, present Electrofluidic Fiber Muscles: a new class of artificial muscle fibers for robots and wearables. Unlike the rigid servo motors used in most robots, these fiber-shaped muscles are soft and flexible. They combine electrohydrodynamic (EHD) fiber pumps — slender tubes that move liquid using electric fields to generate pressure silently, with no moving parts — with fluid-filled fiber actuators. These artificial muscles could enable more agile untethered robots, as well as wearable assistive systems with compact actuation integrated directly into textiles.

[ MIT Media Lab ]

In this study, we developed MEVIUS2, an open-source quadruped robot. It is comparable in size to Boston Dynamics Spot, equipped with two LiDARs and a C1 camera, and can freely climb stairs and steep slopes! All hardware, software, and learning environments are released as open source.

[ MEVIUS2 ]

Thanks, Kento!

What goes into preparing for a live performance? Arun highlights the reliability testing that goes into trying a new behavior for Spot.

[ Boston Dynamics ]

In this work, a multi-robot planning and control framework is presented and demonstrated with a team of 40 indoor robots, including both ground and aerial robots.

That soundtrack though.

[ GitHub ]

Thanks, Keisuke!

Quadrupedal robots can navigate cluttered environments like their animal counterparts, but their floating-base configuration makes them vulnerable to real-world uncertainties. Controllers that rely only on proprioception (body sensing) must physically collide with obstacles to detect them. Those that add exteroception (vision) need precisely modeled terrain maps that are hard to maintain in the wild. DreamWaQ++ bridges this gap by fusing both modalities through a resilient multi-modal reinforcement learning framework. The result: a single controller that handles rough terrains, steep slopes, and high-rise stairs—while gracefully recovering from sensor failures and situations it has never seen before.

That cliff behavior is slightly uncanny.

[ DreamWaQ++ ]

I take issue with this from iRobot:

While the pyramid exploration that iRobot did was very cool, they did it with a custom made robot designed for a very specific environment. Cleaning your floors is way, way harder. Here’s a bit more detail on the pyramids thing:

[ iRobot ]

More robots in circus please!

[ Daniel Simu ]

MIT engineers have designed a wristband that lets wearers control a robotic hand with their own movements. By moving their hands and fingers, users can direct a robot to perform specific tasks, or they can manipulate objects in a virtual environment with high-dexterity control.

[ MIT ]

At NVIDIA GTC 2026, we showcased how AI is moving into the physical world. Visitors interacted with robots using voice commands, watching them interpret intent and act in real time — powered by our KinetIQ AI brain.

[ Humanoid ]

Props to Sony for their continued support and updates for Aibo!

[ Aibo ]

This robot looks like it could be a little curvier than normal?

[ LimX Dynamics ]

Developed by Zhejiang Humanoid Robot Innovation Center Co., Ltd., the Naviai Robot is an intelligent cooking device. It can autonomously process ingredients, perform cooking tasks with high accuracy, adjust smart kitchen equipment in real time, and complete post-cooking cleaning. Equipped with multi-modal perception technology, it adapts to daily kitchen environments and ensures safe and stable operation.

That 7x is doing some heavy lifting.

[ Zhejiang Lab ]

This CMU RI Seminar is by Hadas Kress-Gazit from Cornell, on “Formal Methods for Robotics in the Age of Big Data.”

Formal methods – mathematical techniques for describing systems, capturing requirements, and providing guarantees – have been used to synthesize robot control from high-level specification, and to verify robot behavior. Given the recent advances in robot learning and data-driven models, what role can, and should, formal methods play in advancing robotics? In this talk I will give a few examples for what we can do with formal methods, discuss their promise and challenges, and describe the synergies I see with data-driven approaches.

[ Carnegie Mellon University Robotics Institute ]

Why I Ripped stream.pipe() Out of My Node.js API Gateway

Terminal screenshot showing 18 Jest network tests passing flawlessly in 2.7 seconds.

When I started building Torus, a multi-core Layer 7 Edge API Gateway from scratch in Node.js, I handled incoming network requests the way I had always seen it done in standard web applications:

TypeScript

let body = '';
req.on('data', (chunk: Buffer) => {
  body += chunk.toString();
});
req.on('end', () => {
  forwardToBackend(body);
});

It worked perfectly for lightweight tests. But as I started pushing concurrent loads and larger payloads through the proxy, my server began to choke. CPU usage spiked to 100%, the event loop lagged, and memory consumption grew uncontrollably until the process crashed.

I had fallen into a classic architectural trap: I was dragging raw TCP payload bytes directly into the V8 JavaScript engine’s memory heap.

Because the V8 heap has a strict memory limit, pulling massive payloads into user-space memory forces the Node.js Garbage Collector (GC) to work overtime. The GC halts the single-threaded event loop to clean up the allocated memory, effectively stalling every other active network connection in the proxy.

I learned a fundamental rule of proxy engineering the hard way:

Proxies shouldn’t read data; they should just move it.

To build a production-grade gateway, I realized I had to bypass the V8 heap entirely. I needed to keep the data in raw C++ memory blocks and move it to the Operating System level. But as I refactored my routing logic to achieve this, I stumbled into a silent, catastrophic flaw in the standard Node.js stream API that brought my entire test suite to a halt.

The First Evolution: Bypassing V8 with .pipe()

The architectural fix required a fundamental shift in how I viewed the data. I had to stop treating payloads as static variables and start treating them as flowing water.

I didn’t need to load an entire 50MB file into memory before forwarding it. I only needed to hold a few kilobytes in a temporary buffer, flush it to the destination, and reuse that memory space.

In Node.js, this is exactly what the node:stream module and Buffer objects are designed for.

A Buffer in Node.js allocates memory outside the V8 JavaScript engine. It utilizes raw C++ memory blocks mapped directly to the OS. By keeping the network chunks as raw Buffers, the payload never enters the JavaScript heap. Because it never enters the heap, the V8 Garbage Collector completely ignores it, leaving the event loop free to handle other connections.

To wire this up, I utilized the native .pipe() method to connect the readable client stream to the writable backend stream:

TypeScript

// Connects the incoming ReadableStream directly to the outgoing WritableStream
clientReq.pipe(proxyReq);

This single line of code acts as an OS-level plumbing system. It takes the incoming TCP stream, reads the raw C++ buffers, automatically manages the backpressure (ensuring a fast client doesn’t overwhelm a slow backend connection), and pushes the bytes directly out to the routing pool.

My CPU usage plummeted. The memory footprint stayed flat, regardless of how large the incoming payloads were. It felt like I had solved the scaling problem entirely.

But .pipe() was hiding a massive, silent vulnerability.

The Plot Twist: The Silent Socket Leak

I thought I had engineered the perfect solution. The proxy was fast, the CPU was idle, and the memory footprint stayed completely flat, regardless of payload size.

Then I ran my integration test suite.

All the assertions passed. I got the green checkmarks. But the terminal just froze. Jest refused to exit, eventually spitting out that infuriating warning: “Jest did not exit one second after the test run has completed.”

My initial reaction was to treat it like a standard web app bug. I meticulously checked my teardown logic, making sure proxyServer.close() was being called and my Redis clients were fully disconnected. I ran the tests again. It still hung.

I had to drop down to the OS level to understand what was actually happening. The Node.js event loop is mathematically programmed to never exit as long as there is an active I/O handle (like a net.Socket) in its queue. Something was keeping a socket alive.

The culprit was .pipe().

When my Jest test fired a dummy request through the proxy and then disconnected, the client-side socket closed gracefully. But I learned a lesson about Node.js streams: .pipe() blindly pushes data; it does not propagate lifecycle events.

When the client dropped, .pipe() did not send an error or close event to the destination stream. It left the backend connection completely open. The proxy was sitting there holding a dead connection to the backend, waiting for network bytes that would never arrive.

I had built a machine that generated half-open sockets. In a production environment, this would silently exhaust the Operating System’s File Descriptors (FDs). Every dropped client connection would permanently lock up an FD until the OS hit its limit and violently crash the Node process with an EMFILE error.

The Fix: stream.pipeline()

The Node.js core maintainers knew .pipe() was dangerously naive for production infrastructure. That is exactly why they introduced stream.pipeline().

Instead of blindly shoving data from one socket to another, .pipeline() acts as a unified state machine that monitors the entire stream chain. It pushes the responsibility of socket teardown back to the Node.js core networking stack where it belongs.

If any stream in the pipeline fails, throws an error, or abruptly closes (like a client dropping off with an ECONNRESET), .pipeline() automatically intercepts it. It destroys all other connected streams in that specific chain and bubbles up a single error for you to catch.

I removed every instance of .pipe() and the dozens of lines of manual .on('error') spaghetti I had written. Because raw TCP proxying requires bidirectional data flow, I replaced it with two parallel, sequential pipelines:

TypeScript

try {
  await Promise.all([
    pipeline(clientSocket, backendSocket),
    pipeline(backendSocket, clientSocket)
  ]);
} catch (err: any) {
  // If either side drops, the pipeline throws, and we clean up natively.
  clientSocket.destroy();
  backendSocket.destroy();
}

The moment I swapped to this architecture and ran my integration suite, the terminal didn’t hang. Jest executed all 18 network tests and exited flawlessly in 2.7 seconds. The event loop was instantly cleared. The silent socket leak was completely eradicated.

Terminal screenshot showing 18 Jest network tests passing flawlessly in 2.7 seconds.

Conclusion: Trust Nothing, Understand Everything

Building a multi-core Edge Gateway from scratch taught me that I cannot blindly trust high-level abstractions.

stream.pipe() looks elegant in a standard web tutorial, but in the trenches of raw TCP networking, it is a massive liability. If you are building infrastructure that handles thousands of concurrent connections, you must understand the Operating System-level lifecycle of your File Descriptors and your sockets. If you don’t, your system will slowly bleed to death under load, and logs won’t even tell you why.

If you want to see the exact implementation of this bidirectional TCP routing, you can check out the raw source code for Torus Proxy on my GitHub.