/Blog

Blog

Content about design, technology, and the weird stuff in between.

7 min readJohnny UnarJohnny Unar

Your AI Helpdesk Bot Has an Account Takeover Vector You Designed In

Meta's 2026 chatbot password reset exploit wasn't an infra bug. It was an interaction design failure, and your SaaS assistant probably has the same one.

Read more
7 min readJohnny UnarJohnny Unar

Context Rot Is Not a Context Window Problem

Bigger context windows don't fix agent drift. Your long-running agent loses the plot because of context rot, and no amount of tokens saves you.

7 min readJohnny UnarJohnny Unar

Your Agent Eval Sandbox Is the Attack Surface

The AISI July incident wasn't about frontier model danger. It was about containment design nobody actually does. Here's a checklist to fix that.

9 min readJohnny UnarJohnny Unar

The Review Queue Is Now Your Deployment Bottleneck

Agents open more PRs in a day than your team used to see in a month. Your 2023 review process can't keep up. Time to redesign it.

7 min readJohnny UnarJohnny Unar

The debug and chalk Hijack Was a Maintainer Identity Failure, Not a North Korea Story

Amazon tied the September 2025 npm hijack of debug and chalk to the same North Korean crew behind the axios compromise. The scary part isn't the attacker. It's the model.

8 min readJohnny UnarJohnny Unar

The CRA 24-Hour Clock Starts September 11 and Your Dependency Graph Is the Liability

Article 14 of the EU Cyber Resilience Act lands on your codebase, not your legal team. Here is what the 24-hour reporting rule actually demands from engineering.

8 min readJohnny UnarJohnny Unar

Your LLM Gateway Is a Credential Vault, and the LiteLLM Breach Proved It

The March 2026 LiteLLM supply chain attack showed why your AI proxy is the highest-value target in your stack, and why most teams still treat it like a utility library.

7 min readJohnny UnarJohnny Unar

Prompt Injection Is a Code Execution Primitive Now

Microsoft's CVE-2026-25592 showed a single injected prompt driving host-level RCE. Your threat model still treats it like a content problem. That's the bug.

8 min readJohnny UnarJohnny Unar

Stop Constraining Agents With Prompts, Constrain Them With Infrastructure

Stripe's Minions ship 1,300 zero-human PRs a week against a trillion-dollar codebase. The trick isn't a smarter model, it's making the sandbox the permission system.

6 min readJohnny UnarJohnny Unar

The Axios Postinstall Hook Was the Whole Attack

Sapphire Sleet published axios@1.14.1 with a RAT in a postinstall hook. OIDC Trusted Publishing didn't save anyone. Here's the misconfiguration that actually let it happen.

7 min readJohnny UnarJohnny Unar

AI Is Rewriting Your IAM Layer and Nobody Reviews the Diff

A hands-on audit playbook for the overly broad permissions that LLM-generated backend code quietly bakes into your codebase on every PR.

9 min readJohnny UnarJohnny Unar

Server Actions Are Public Endpoints, Treat Them Like It

Every exported Server Action is a callable HTTP endpoint with no auth, no rate limiting, no validation. Here's the hardening checklist we run on every Next.js project.

6 min readJohnny UnarJohnny Unar

The Homogenization Trap: Why Every AI-Designed UI Looks Identical

72% of designers now use generative AI, and the result is a sea of interchangeable SaaS dashboards. Tactile brutalism is the engineering answer.

8 min readJohnny UnarJohnny Unar

AI Code Passes CI and Breaks Production Anyway

Your CI was built for deterministic human code. AI output is probabilistic and context-sensitive, and your validation pipeline has no primitives for catching where it fails.

6 min readJohnny UnarJohnny Unar

You Are Paying for AI to Write the Bugs It Will Charge You to Fix

Velocity numbers measuring code written instead of value delivered are how engineering leaders are quietly fooling their own boards in 2026.

7 min readJohnny UnarJohnny Unar

Your Tests Passed and Production Still Broke: The AI Verification Gap Nobody Wants to Name

81% of tech leaders report more production failures from AI code even with 92% pre-deploy confidence. The gap isn't volume, it's the pipeline itself.

9 min readJohnny UnarJohnny Unar

The Vercel Breach Is a Template for How OAuth Sprawl Kills You

A hands-on audit guide for finding the silent OAuth grants, stale tokens, and unencrypted env vars that turn one phished laptop into a full breach.

7 min readJohnny UnarJohnny Unar

Your AI Dev Toolchain Is the Attack Surface

The June 2026 Microsoft GitHub compromise targeted developers running Claude Code and Gemini CLI. Your AppSec posture was never built for this.

8 min readJohnny UnarJohnny Unar

Your AI Coding Budget Is Buying the Illusion of Speed

84% of developers use AI tools, but org-wide productivity is stuck at 10-30%. Here's where the ROI actually disappears and what to do about it.

8 min readJohnny UnarJohnny Unar

SLSA Provenance Did Not Save TanStack

84 malicious package versions shipped with valid SLSA Build Level 3 attestations. The attacker hijacked the pipeline, not the credentials. Provenance signed the malware.

6 min readJohnny UnarJohnny Unar

The METR Productivity Illusion in Real Engineering Work

METR found senior devs were 19% slower with AI but felt 20% faster. That 39-point gap should change how you measure AI tooling.

9 min readJohnny UnarJohnny Unar

Structured Outputs Guarantee Syntax, Not Sanity

GPT-4o's JSON mode gives you valid JSON. It doesn't give you correct data. Here's why that distinction is destroying pipelines.

10 min readJohnny UnarJohnny Unar

Postgres + pgvector 0.8 Is Probably Enough for Your Embeddings

Before you spin up Pinecone or Qdrant, read this. We benchmarked pgvector 0.8 HNSW against Qdrant 1.13 and the results will bore you in the best way.

12 min readJohnny UnarJohnny Unar

Tool Calls Are Not Actions: Build an Approval Queue First

The gap between an LLM returning a tool-call and actually running it against live data is where AI features go wrong. Here's the concrete pattern.

8 min readJohnny UnarJohnny Unar

Structured Outputs Guarantee Shape, Not Semantics

JSON mode doesn't mean your LLM output is safe to use. Here's why you need a schema contract layer on top of it.

9 min readJohnny UnarJohnny Unar

Structured Outputs Don't Mean Your LLM Data Is Correct

Schema conformance is trivially easy. Semantic correctness is where LLM pipelines actually fall apart, and most teams never notice until production.

9 min readJohnny UnarJohnny Unar

Stop mocking your database: Postgres 17 makes it unnecessary

Mocking your DB keeps tests green and production broken. Here's how transaction savepoints and schema isolation fix that.

9 min readJohnny UnarJohnny Unar

Your AI Feature Ships Fast and Rots Faster

Shipping a GPT-4o integration takes a weekend. Maintaining it takes a policy. Here's the one-page lifecycle template we actually use.

9 min readJohnny UnarJohnny Unar

Postgres Outbox Beats RabbitMQ for Webhook Ingestion Under 5k RPM

Before you bolt on SQS for webhook reliability, read this. A Postgres outbox table and a Go worker will serve most startups better.

9 min readJohnny UnarJohnny Unar

Postgres RLS Is Your Real Tenant Isolation Layer, Not Django

Manual WHERE clauses in your ORM will eventually leak tenant data. Here's how to wire Postgres 17 RLS into Django 6.x properly.

12 min readJohnny UnarJohnny Unar

Stop warming pools: adaptive CPU-bursting that actually saves money

Warm pools feel like a win until the AWS bill arrives. Here's a concrete pattern with Go worker pools, Redis token buckets, and KEDA that gets you sub-200ms p95 without paying for idle CPUs.

12 min readJohnny UnarJohnny Unar

Edge for delivery, Go for domain

A strict partitioning recipe for Next.js 15 and Go 1.22, with auth, SSR streaming, flags, observability, and none of the hand-wavy edge hype.

10 min readJohnny UnarJohnny Unar

One npm package nearly owned our Next.js 15 app

A postinstall hook, a remote loader, and a few ugly hours in CI. The fixes were simple once we stopped pretending JavaScript supply chain risk was theoretical.

10 min readJohnny UnarJohnny Unar

Stop Paginating in the Client, Let Next.js 16 Do It

Client-side pagination burns memory, inflates TTFB, and makes UX flaky. Cursor APIs plus route-segment caching fix the mess without a rewrite.

10 min readJohnny UnarJohnny Unar

A sane monorepo needs hard boundaries

Monorepos work fine in 2026, if you treat boundaries as code and automate enforcement. Our setup is boring on purpose, and that’s why it holds.

10 min readJohnny UnarJohnny Unar

Swap Encoders Without Torching Retrieval

Embedding model upgrades break search in quiet, expensive ways. This is the rollout playbook we use to ship encoder changes without wrecking retrieval.

11 min readJohnny UnarJohnny Unar

Edge observability is mostly a telemetry problem

Next.js 15 edge functions and Go 1.22 services need different observability than long-lived servers. Trace cold starts, collect sampled flamegraphs, and tail-sample hard.

10 min readJohnny UnarJohnny Unar

Don’t ship agent chains to SMB customers

Agentic tool orchestration looks clever in demos and turns ugly in production. Use typed function calls, deterministic proxies, and explicit fallbacks instead.

10 min readJohnny UnarJohnny Unar

Stop shipping business logic in Next.js edge

Use Edge for fast decisions, keep stateful work in Go. This split fixes correctness bugs, retries, and observability holes that keep showing up in SaaS systems.

10 min readJohnny UnarJohnny Unar

Kill the GraphQL gateway at 12 services

Federation adds a governance tax most mid-stage startups can't afford. Typed OpenAPI and consumer-driven contracts bring back speed and make failures obvious.

9 min readJohnny UnarJohnny Unar

Zero-Downtime Django Postgres Migrations Need Multi-Step Plans

Safe schema changes in a Django monolith come from staged rollouts, backfills, and boring operational discipline. Squashed migrations won't save you.

14 min readJohnny UnarJohnny Unar

Multi-tenant Postgres 16: pick RLS unless proven otherwise

Most SaaS teams should default to Row Level Security in Postgres 16. The hard part isn't SQL, it's pooling, migrations, and operational discipline.

10 min readJohnny UnarJohnny Unar

Stop Forcing Analytics Through Django ORM

Reporting code packed into chained QuerySets gets slow, fragile, and unreadable. Put heavy analytics back in SQL, where Postgres can actually help you.

9 min readJohnny UnarJohnny Unar

Ship prompts like code, or expect regressions

Production LLM features rot quietly. Version prompts, test them in CI, canary against shadow traffic, and make rollback boring.

9 min readJohnny UnarJohnny Unar

Ship one correct admin workflow

Config panels feel like product progress until they turn your SMB app into a support machine. Pick one strong admin path and defend it.

10 min readJohnny UnarJohnny Unar

Treat hallucinations like system failures

Hallucinations leave fingerprints. Instrument token probabilities, track evidence provenance, and gate actions with cheap verifiers before anything touches production.

9 min readJohnny UnarJohnny Unar

GPU, API, or CPU batching for AI inference

Most startup AI infra decisions get made on vibes. Use throughput, tail latency, token volume, and ops burden to pick the least painful option.

11 min readJohnny UnarJohnny Unar

Bill compute, kill per-request pricing

Per-request billing punishes automation and rewards waste. Meter compute instead, and your SaaS economics stop behaving like a bug.

11 min readJohnny UnarJohnny Unar

API rewrites are governance failures

Most API rewrites happen because teams skipped contracts, versioning, and deprecation discipline. A small amount of governance fixes that without slowing delivery.

10 min readJohnny UnarJohnny Unar

Embedding drift will quietly wreck your retrieval

Vector search degrades slowly, then all at once. Measure drift before recall collapses and model upgrades torch production.