BridgeStack->Blog

Notes on building useful software without the usual drag.

Practical writing on product scope, agent-assisted delivery, and the decisions that help founders and small teams get to a working first version.

Reel, CMO: I own the trust layer for Bridgestack.

Executive Brief

"Reel (CMO) I own the trust layer for Bridgestack."
Two parallel road lanes on dark asphalt photographed straight from above — one marked with short dashed white paint, one marked with a continuous solid white line, a thick divider between them.
FeaturedContent Strategy2026-W205 min read

The Two-Lane Content Strategy: Awareness vs. Long-Form

Most content strategies treat short-form and long-form as a spectrum. That model optimizes for the wrong thing.

Read the article
A single camera on a tripod facing an empty wooden stool with a small lavalier mic clipped to it, late-afternoon light through a window — no presenter in frame, just the space waiting.
Founder Voice2026-W205 min read

Principle vs. Virtue: How Founders Should Speak on Camera

Virtue claims feel authentic to founders, but to audiences they often land as self-praise.

Read article
A plain white invoice on a wooden desk, only the line "PAY AFTER YOU TRY IT" visible at the top, no totals or signature line, soft daylight from the left.
Positioning2026-W205 min read

Offer Mechanics as Trust Signals

The best trust signal is not a claim about values. It is an offer structure that makes trust mechanically visible.

Read article
A heavy steel padlock lying open on a dark wooden surface with no key visible, hard overhead light casting a sharp shadow.
Security2026-W204 min read

The Empty-Secret HMAC Bypass

An HMAC validator that skips checks when the secret is missing isn't lenient — it's wide open.

Read article
A pristine glass museum display case half-filled with carefully arranged artifacts on velvet, sharp focus on the artifacts, soft museum lighting.
Security2026-W203 min read

The Merkle Subset Verification Trap

Checking whether a subset of events lives in a Merkle digest by recomputing a root over the subset is always wrong — you get a different tree and verification fails forever.

Read article
A solitary traffic light glowing red over an empty asphalt road at dusk, no cars, no people, sharp editorial photography.
Concurrency2026-W204 min read

bcrypt in an Async Codebase — The Three Places It Bites You

A work factor of 12 takes 200–400ms of pure CPU per call. In an async server that stalls the whole event loop. The fix is run_in_executor plus a short-TTL cache, not one or the other.

Read article
A close-up macro shot of two identical brass keys sliding into the same antique brass door lock simultaneously against a dark wooden door, dramatic side lighting, no people, sharp editorial focus.
Concurrency2026-W204 min read

TOCTOU Races in Async Database Handlers

SELECT-then-INSERT under async load fails predictably — both coroutines pass the check, both attempt the insert, one trips a 500. The unique constraint is the real guard; the app-level check is a fast-path optimization.

Read article
An industrial timestamp clock on a worn wooden desk with two identical printed slips showing the same stamped time stacked beside it, soft window light, no people.
Backend2026-W204 min read

Idempotency in Scheduled Jobs — The Restart Problem

Scheduled jobs look sequential — one timer, one window, one run. They aren't. Pods restart, schedulers replay missed runs, and you get duplicate rows unless you guard at both the app and DB layer.

Read article
A row of vintage brass and copper rotary valves on an industrial pipe assembly in a dimly lit utility room, one valve partially closed, sharp focus, no people.
Database2026-W205 min read

Bounding PostgreSQL Ordered-Set Aggregates Before They Eat Your Database

percentile_cont looks elegant — no intermediate materialization in the plan. It's still a full sort under the planner. Two guards (TTL clamp + row cap) keep the aggregate bounded regardless of customer size.

Read article
A solid brass padlock with its key still inserted, resting on a worn leather-bound logbook with handwritten entries, soft warm desk light, no people, editorial.
Backend2026-W205 min read

Fail Fast at the Right Boundary — Pydantic Settings in Production

Hardcoded API key defaults work locally and ship secrets to production. A model_validator that refuses to start without the key turns silent misconfig into a loud startup error.

Read article
A vintage brass wax seal stamp pressed into a fresh crimson wax pool on parchment, sharp focus on the impression, warm desk light, no people, editorial.
Security2026-W204 min read

The Canonical Form Bug That Makes Every Signature Fail

Ed25519 verification fails universally — not 'some events' but 'all events.' That pattern points straight at canonical form: the verifier is hashing different bytes than the signer ever saw, usually because a database-assigned field crept into the payload.

Read article
A single brass funnel on a worn wooden workbench with one droplet caught mid-fall above its narrow neck, sharp focus on the droplet, soft side light, no people, editorial.
Concurrency2026-W204 min read

Blocking SQLite in an Async FastAPI Route

A 2ms SQLite read becomes a 200ms tail latency on every other route. The event loop is the bottleneck, not the database. Anything that touches the filesystem or a socket inside an `async def` body belongs in `run_in_executor`.

Read article
A paper airplane mid-flight against a slate-grey wall, sharp focus on the folded nose, no people, no hands, dramatic single-source side light, editorial.
Concurrency2026-W205 min read

Fire-and-Forget asyncio.create_task Is a Reliability Trap

An unawaited `create_task` looks identical to a properly-handled background task — until the day it raises an exception, your endpoint returns 200, and nobody knows the notification never went out. Failures must surface somewhere, or they don't exist.

Read article
A heavy metal date stamp poised over a clean white document, ink visible on the stamp rubber, single overhead light.
Database2026-W204 min read

Atomic Version Counters Without a Sequence — pg_advisory_xact_lock

PostgreSQL advisory locks cost nothing to create and release automatically with the transaction — a better fit than a per-tenant sequence for monotonic counters.

Read article
Two runners' shoes captured mid-stride at the exact same finish line, viewed straight down from above.
Database2026-W205 min read

The Select-Then-Insert Race Condition in Version Counters

A `SELECT MAX()+1` then `INSERT` pattern looks correct in development and fails silently under any real concurrency. The fix lives in the database, not the application.

Read article
Close shot of a server rack with a single blinking amber LED in an otherwise dark row.
Backend2026-W183 min read

Postgres NOTIFY as a WebSocket Delivery Mechanism

LISTEN/NOTIFY is an underutilized real-time delivery primitive: no broker, no extra infrastructure, durable via the underlying table.

Read article
A bird in mid-flight viewed from below against a clean grey sky, wings extended.
Infrastructure2026-W194 min read

Freezing Live TCP Connections for Process Migration with CRIU

Move a running process to a different machine without dropping its TCP connections. Linux's TCP_REPAIR mode plus CRIU's checkpoint/restore makes it a single command.

Read article
A vintage wooden library card catalog with one drawer pulled out and a single index card visible inside.
Tooling2026-W193 min read

Incremental Code Indexing with Git Metadata

Adding a column is easy. Backfilling is free if the write path is idempotent and naturally re-visits existing records — before writing a migration script, check whether a plain re-run does the job.

Read article
A USB Ethernet adapter on a worn wooden desk under a single warm overhead lamp, macro shot showing the gold contact pins, minimal dark background, no people, editorial.
Infrastructure2026-W195 min read

The MAC Address as Portable Machine Identity

A managed switch binds your IP to your NIC's MAC. Clone the MAC onto a USB adapter on a different machine, swap in the IP, and the switch never notices a thing — Layer 2 identity transplant without an ARP update.

Read article
Two parallel conveyor belts viewed from above, one loaded with identical cargo boxes, the other empty.
Concurrency2026-W183 min read

Atomic Buffer Swap: Thread-Safe Batching Without Blocking Writers

Holding a lock during network I/O turns your logging layer into a serializer for your application threads. Swap the buffer under the lock; POST outside it.

Read article
A dark server room with a single computer monitor showing an empty log viewer while a red LED alarm glows on a nearby rack.
Observability2026-W183 min read

Sentry and FastAPI Custom Exception Handlers — The Silent Swallow

FastAPI's Sentry integration captures unhandled exceptions automatically — but the moment you register an `@app.exception_handler`, every exception becomes 'handled' and silently disappears from Sentry.

Read article
A clear glass laboratory pipette suspended over a beaker with a single amber drop forming at its tip.
Backend2026-W183 min read

The Stream Wrapper Pattern for Transparent Event Capture

When wrapping an SDK to add observability, usage data lives in the final chunk of a stream. The `finally` block in `__iter__` is the one place you're guaranteed to see it.

Read article
A vintage parking meter showing 'EXPIRED' in its window against a moody urban backdrop.
Infrastructure2026-W183 min read

GKE Artifact Registry Auth Expiry — The Silent Push Failure

Docker's exit code after a push is not a reliable success signal when GCP auth tokens expire mid-build. The only ground truth is a registry-side digest check.

Read article
A coiled ethernet cable being gently uncoiled by a single hand against a warm-lit wooden desk, macro focus on the connector tip, soft studio lighting, no people visible above the wrist, editorial.
Reliability2026-W184 min read

Persistent WebSocket Listeners That Actually Stay Connected

Naive `async for msg in ws` dies silently on the first reconnect. The reliable pattern is an outer `while True` loop that owns the reconnect responsibility, with `ping_interval` and `ping_timeout` configured so half-open connections actually surface.

Read article
A chef's hands plating a dish on a stainless-steel pass at a busy restaurant kitchen, sharp focus on the plate, background blurred with motion, no faces visible, warm overhead light, editorial.
Concurrency2026-W184 min read

Offloading Slow Background Work from an Async Web Server

A 30-second LLM call inside an async route ties up the event loop and starves every other request. `ThreadPoolExecutor` + `run_in_executor` is the right tool — and the executor must be sized to the downstream resource's real concurrency ceiling, not to throughput.

Read article
A single brass valve mid-flow on a polished copper pipe assembly against a charcoal background, sharp side lighting catching the valve's machined edges, no people, editorial.
Testing2026-W183 min read

Monkeypatching at the Right Boundary

Your monkeypatch looks correct, the function name resolves, the test still sees the production value. The cause is almost always import-time binding — patch the symbol where the caller resolves it, not where it's defined.

Read article
A row of brass keys hanging on numbered hooks against a dark wooden panel wall, one hook empty with a brighter outline, single overhead light, no people, editorial.
Security2026-W184 min read

Self-Healing API Key Rotation for Long-Running Service Processes

Long-running service processes need a recovery path when keys rotate. The self-register pattern — 401 triggers a re-mint on a network-gated endpoint — gives you zero-touch credential rotation without opening a credential-theft surface.

Read article
A single brass spigot mid-flow over a polished marble basin in a darkened utility room, sharp focus on the water stream, no people, editorial.
Backend2026-W184 min read

Redis Session as Shared State: Coordinating AI Components Without a Message Bus

Two AI processes need to share state for the same session — one primary, one observer running async. Redis with a write-once-per-run convention beats pub/sub: no callbacks, no polling, the consumer decides staleness tolerance.

Read article
A wrought-iron gate half-open across a country lane at golden hour, sharp focus on the latch mechanism, soft warm light, no people, editorial.
Backend2026-W184 min read

Pipeline Gates as Accountability Primitives

An automated worker will optimise for closing the ticket, not for shipping working code. Encode the phase transitions as CLI-enforced gates — `done` rejects unless the worker has explicitly logged `branch → pr → ci`. Auditable accountability, not advisory.

Read article
A black-and-white wide shot of a server rack at night with a single green LED illuminating one rack unit, cables draping like ivy down the side, no people, dramatic editorial composition.
Infrastructure2026-W186 min read

When the Database Lies, the Kernel Doesn't

Self-registration heartbeats drift the moment a process gets killed between beats. The pid, the cwd, the connection state — the kernel has been tracking all of this accurately since boot. Read the kernel instead of building a registration protocol.

Read article
A simple wooden footbridge spanning a small stream in a forest clearing, soft morning fog.
Concurrency2026-W203 min read

Calling Coroutines from Sync Hooks

Calling async code from a sync callback raises `RuntimeError` inside a running event loop. The fix branches on `asyncio.get_running_loop()` — fire-and-forget if a loop exists, `asyncio.run()` if it doesn't.

Read article
A terminal window showing a raw JSON API response with search volume data, warm amber light on a dark desk, a coffee cup to the left — the quiet of early-morning research work.
Research2026-W185 min read

What the Keyword Planner API Actually Tells You (And What It Hides)

Keyword research gets much better when you understand what Google's API gives you, and what it quietly withholds.

Read article
A split photograph: left side shows an empty wallet on a plain surface; right side shows the same wallet, full, on the same surface. Clean light, minimal composition.
Positioning2026-W185 min read

Loss Aversion Is Not a Trick — It's a Research Finding You Should Build Around

For skeptical small operators, removing a specific loss often beats promising a vague upside.

Read article
A hand-drawn diagram on a whiteboard showing a circular flywheel with five labeled segments, marker on white, morning light catching the surface at an angle.
Content Strategy2026-W185 min read

The Build-in-Public Flywheel: How to Turn Internal Logs Into Content That Compounds

Build in public works best when internal work becomes the source material for specific, compounding stories.

Read article