AI 资讯
Stop Shipping AI Slop: Build an Anti-Slop Harness Around Your LLM
"AI slop" is not a model problem. It's an engineering problem you decided not to solve. The slop is the bland, off-voice, half-hallucinated, occasionally-just-an-error-message text that your LLM emits maybe 5% of the time — and that 5% is the part users screenshot. The instinct is to fix it in the prompt: add three more sentences of "be concise, be accurate, match my tone." That treats a stochastic system as if it were deterministic. It isn't. You cannot prompt your way to a guarantee. What actually works is treating the model like any other unreliable upstream dependency: wrap it in a harness that validates, rejects, and retries before anything reaches a user. The model proposes; the harness disposes. Here's how to build one. Slop is a systems problem, not a prompt problem Every production LLM feature I've shipped converged on the same shape: the model is one stage in a pipeline, not the pipeline itself. You don't trust raw generation any more than you'd trust raw user input. You parse it, you validate it against constraints you can express in code, and you reject anything that fails — automatically, before a human ever sees it. The key insight is that most slop is detectable . Empty output, a leaked stack trace, the wrong language, a 900-word answer when you asked for 200, a banned phrase like "in today's fast-paced world" — these are all checkable with deterministic code. You don't need a judge model to catch them (though a judge model has its place at the end). You need a gate that runs on every generation, costs microseconds, and never gets tired. Think of it as five layers, each rejecting a different class of failure. Layer 1: Structured output, not freeform text The single biggest reduction in slop comes from refusing to accept prose where you can demand structure. If you ask for a JSON object with named fields and a schema, the failure modes collapse from "infinite" to "a handful you can enumerate." Use the provider's native structured-output / tool-calling
AI 资讯
The Same AI Model Can Perform 6x Better: Here's Why
A Stanford and Tsinghua paper ran a controlled experiment earlier this year. Same model. Same task. Different harness architecture. The result: a 6x performance gap driven entirely by the system built around the model. Not the model itself. This is not a prompt engineering insight. It is a systems architecture insight, and it changes where developers should invest their time when building agentic systems. The 6x Gap Meta-Harness tested Claude Opus 4.6 across two harness configurations on TerminalBench-2. The only variable was the scaffold: the code that manages tool calls, context windows, error recovery, and state persistence. One version scored at baseline. The other, with structured tool orchestration and context management, scored 18.4 points higher. Same inference cost. Same model. Different architecture. This pattern replicates across multiple independent studies: LangChain DeepAgents (2026): Same GPT-5.2-Codex model. Harness-only changes moved it from Top 30 to Top 5. That is a 13.7-point gain. Can Bölük (Hashline, 2026): Same model, same task. Changed the edit tool format. Performance went from 6.7% to 68.3%. That is a 10x improvement with 61% fewer tokens. Vercel's d0 agent : A production agent had 16 tools. Removing 14 of them (leaving only bash) took success rate from 80% to 100%. The bottleneck was not capability. It was decision surface. Why This Matters Practically The cheapest Haiku call with an optimised harness (37.6% on TerminalBench-2) outperformed the most expensive Opus call with a default harness (58.0%). That is at 1/50th the inference cost. Most teams are optimising at the wrong layer. They swap models, tune prompts, add retrieval. The structural leverage is in how the system manages tool calls, handles state, and recovers from failure. What Changes The practical takeaway for anyone building with AI agents: Audit your tool surface. Every tool your agent can call is a decision it must make. Vercel found 16→1 tool reduction improved everything.
AI 资讯
C_STD : A Leak-Free, Cross-Platform Standard Library for Modern C
c_std: A Leak-Free, Cross-Platform Standard Library for Modern C Bringing the comfort of the C++ STL and Python's standard library to C17 — without leaving C A technical white paper. Executive summary C is still the substrate of the computing world — kernels, databases, language runtimes, embedded firmware, and the inner loops of nearly everything else. Yet the moment you step away from the kernel and try to write ordinary application code in C, you feel the gap: no growable vector, no hash map, no JSON parser, no string type that doesn't invite a buffer overflow. You either pull in a grab-bag of mismatched third-party libraries, each with its own conventions and failure modes, or you re-implement the same dynamic array for the hundredth time. c_std is an attempt to close that gap deliberately and coherently. It is a single, consistent library — written in pure C17 — that reimplements a large slice of the C++ Standard Library (containers, algorithms, smart pointers) alongside many Python-style conveniences ( json , regex , random , statistics , csv , config , even turtle graphics). It targets Windows and Linux from one source tree, compiles cleanly under -Wall -Wextra , and — this is the part I care about most — is verified leak-free under Valgrind , module by module, example by example. This paper explains the design philosophy, the architecture, and the engineering discipline that makes a library like this trustworthy enough to build on. 1. The problem: C's missing middle Every C programmer knows the two extremes. At the bottom, the language itself: pointers, malloc , memcpy , raw arrays. At the top, whatever the platform hands you — <windows.h> or POSIX, OpenSSL, a JSON library someone wrapped a decade ago. The middle — the layer the C++ STL and Python's batteries-included standard library occupy — is missing. That missing middle has a real cost. It shows up as: Re-invention. Teams write their own vector, their own string builder, their own linked list, each subt
AI 资讯
Append-only doesn't mean what you'd hope
Event sourcing gets sold on immutability. You don't update, you don't delete, you only append, so the history is permanent. It mostly isn't. The events are immutable because your code agrees not to touch them, not because anything actually stops it. Underneath they're still rows in Postgres, and rows have a DBA with write access. A migration that "cleans up" old data. A 2 a.m. query run against the wrong connection. A backup restored with slightly different bytes in it. Change one of those rows and a replay won't blink. The aggregate rebuilds, the projections rebuild, everything looks fine. Usually the first person to notice is a customer whose balance is off, and by then the trail is cold. Chain each event into the next The trick is small. Give every row two extra columns: a hash of its contents, and the hash of the row before it. #1 AccountOpened prev=00000… hash=70be4f… │ ▼ #2 AmountDeposited prev=70be4f… hash=796018… │ ▼ #3 AmountWithdrawn prev=796018… hash=6a0260… The hash is SHA-256(previousHash || json(payload)) . Nothing exotic. The point is that each hash depends on the one before it. Edit a payload and its hash stops matching. Rewrite that hash to cover for the edit, and now the next row's pointer is wrong. You can't fix one without breaking the next. About forty lines of it Appending an event hashes it together with the previous one: public HashChainedEntry Append ( object payload ) { var previousHash = _entries . Count == 0 ? GenesisHash : _entries [^ 1 ]. Hash ; var hash = ComputeHash ( previousHash , payload ); var entry = new HashChainedEntry ( _entries . Count + 1 , payload , previousHash , hash ); _entries . Add ( entry ); return entry ; } internal static byte [] ComputeHash ( byte [] previousHash , object payload ) { var payloadJson = JsonSerializer . SerializeToUtf8Bytes ( payload , payload . GetType ()); var combined = new byte [ previousHash . Length + payloadJson . Length ]; Buffer . BlockCopy ( previousHash , 0 , combined , 0 , previousHash .
AI 资讯
Why my single Next.js app runs 4 different domains (and how the proxy.ts decides who sees what)
> TL;DR — I run four different domains off one Next.js codebase: a marketing site at pagestrike.com , an authenticated app at app.pagestrike.com, a public publishing domain at pagestrike.app, and customer-owned domains. The trick isn't deploying four apps — it's a single proxy.ts that reads the host and rewrites/redirects/passes-through per-request. This post walks through why I chose this shape, the parts I got wrong, and the cookie-domain trick that makes it all stick. Stack: Next.js 16 App Router , Supabase , Vercel , one proxy.ts file (~370 lines). This is the second post in my build-in-public series on PageStrike . Last week I wrote about the 6-CTA architecture — modeling conversion intent as a discriminated union so one launch could be a checkout, a COD form, or a calendar booking. This post is about a different primitive: modeling host as routing context so one codebase can serve four very different audiences. Why four domains, not one Most SaaS apps live at one domain — say myapp.com with /dashboard under it. That works until you grow into edge cases that don't fit: Marketing pages get spammed by your own dashboard headers. Your marketing nav says "Sign in / Pricing / Blog". Your dashboard nav says "Launches / Contacts / Settings". You either A/B them with conditional logic everywhere or you live with the noise. Public user-generated pages share your domain reputation. When a customer publishes a landing page at myapp.com/p/[slug] , every spammy LP from a free-tier user drags down myapp.com 's sender reputation, search trust, and ad-account standing. Google and Meta penalize the host, not the path. Custom domains don't route cleanly. A customer who buys acmewidgets.com and points it at your app expects their LP at acmewidgets.com/ — not myapp.com/p/acme-widgets . You need a rewrite that's transparent to the visitor, doesn't 404 on _next/static/* , and survives RSC prefetches. I split PageStrike — a free AI landing page builder — across four hosts to solve al
AI 资讯
Stop Using LLMs to Audit Other LLMs: You Are Bricking Your Production Latency
Look at your modern Agentic AI stack. An agent wants to execute a tool, trigger a deployment, access a database, or call an external API. Because nobody fully trusts a probabilistic black box, many teams now use a second probabilistic black box to validate the first one. Think about what is actually happening. You are running hundreds of billions of parameters, consuming tokens, burning GPU resources, and adding hundreds or thousands of milliseconds of latency just to answer a simple operational question: PASS HOLD RED Or in plain English: Continue Verify Stop For many production systems, that's the only decision that matters. Yet we often spend orders of magnitude more compute determining whether an action should execute than executing the action itself. That feels dangerously close to architectural bankruptcy. The Illusion of Prompt-Based Safety We've all done it. You create a prompt: "You are a security validator. If the action appears unsafe, return RED." Then reality arrives. Prompt injections appear. Edge cases appear. Different model versions behave differently. The same input occasionally produces different outputs. And your cloud bill keeps growing. At some point, a difficult architectural question emerges: Can a probabilistic system reliably govern another probabilistic system? Many teams assume the answer is yes. I'm not convinced. The Problem Isn't Intelligence This is where I think the industry may be looking at the problem incorrectly. The challenge is not intelligence. The challenge is governance. LLMs are exceptional at: Reasoning Summarization Code generation Natural language interaction But governance is a different problem. Governance is not asking: "What is the best answer?" Governance is asking: "Should this action be allowed to proceed?" Those are fundamentally different questions. A Different Architecture While exploring this problem, we ended up building a separate deterministic governance layer internally. Instead of generating text, it perf
AI 资讯
The Ghost in the Veltrix: Why Our Treasure Hunt Engine Was Sending Operators Down the Wrong Rabbit Hole
In November 2023 we ran our first global Hytale servers on Google Kubernetes Engine using Veltrix 3.2 as our configuration orchestrator. The Treasure Hunt Engine—a service that fans spawn to claim event loot—started crashing every time search volume exceeded 12 k RPM. Grafana showed a steady climb of 503 errors on /hunt/claim until the autoscaler maxed out at 32 G1 CPU cores and still couldnt keep up. Operators kept filing tickets that boiled down to one sentence: We click the map, nothing happens. We never saw the actual error because the ingress controller was swallowing it and returning a generic Too many requests. What we tried first (and why it failed) Our first move was to crank up the nginx-ingress-controller replicas from 3 to 12 and switch the load-balancer tier from GKE Standard to Premium. The 503 rate dropped to 8 k RPM, but now the p99 latency on claims spiked from 80 ms to 420 ms. The culprit was a recursive call in the hunt service: every claim required a round trip to the player-profile service to validate tier eligibility, and that service was on a shared Postgres 15.4 cluster with 3 k TPS of unrelated traffic. The error stack in Jaeger was literally tracing_id=7f3a1c8… server=profile-db pool_timeout . We tried adding connection pooling with PgBouncer, but the hunt service was using raw libpq and refused to reuse connections—no matter how many times we told it. The Architecture Decision We ripped the validation out of the synchronous path and made the hunt engine publish an event called HuntTierCheckRequired to a dedicated Kafka topic player-events-tier . The hunt service would respond to the client with a 202 Accepted immediately, then the loot-claim worker would listen to that topic and, if the tier passed, publish HuntLootReady . The worker ran in the same pod but on a separate goroutine with a 60-second TTL so we didnt leak memory if the tier service hung. We moved the player-profile service to an SSD-backed CloudSQL instance and gave it 32 GB R
AI 资讯
Google Cloud Suspends Railway's Production Account, Causing Eight-Hour Platform-Wide Outage
Google Cloud's automated systems suspended Railway's production account without notice, triggering an eight-hour platform-wide outage affecting 3 million users. The cascade took down workloads across all providers including AWS and bare metal because Railway's control plane was hosted on GCP. Railway is demoting GCP to backup-only status. By Steef-Jan Wiggers
AI 资讯
When Two Containers on the Same Host Are Shouting Through a Load Balancer
Building a Unix-Domain-Socket IPC server for ECS-on-EC2 services that need to talk fast, cheap, and reliably A while back I was looking at a flamegraph of a service that, on paper, should not have been having any performance problems. The producer and the consumer were the same Docker image's worth of trouble — colocated on the same EC2 host, in the same ECS cluster, sharing the same instance type, the same kernel, the same RAM. By every reasonable measure they were neighbours. And yet every event was making a round trip that looked roughly like this: producer → kernel TCP stack → ENI on the producer task → AWS VPC → internal load balancer → ENI on the consumer task → kernel TCP stack → consumer. TLS handshake. HTTP framing. JSON over the wire. Connection pool. Retry policy. The whole circus. I wasn't doing anything wrong. This is what the platform funnels you toward. ECS with awsvpc networking gives every task its own ENI. The default story for "service A talks to service B" is "give B a DNS name, put a load balancer in front of it, configure a security group, point A at the LB." Even if A and B are physically on the same box, the bytes are still leaving the kernel, traversing the VPC, and coming back. There's a fix for this. It's been a fix for fifty-something years. It just hasn't been the default fix, because cloud-native architecture grew up assuming services would be scattered across hosts and the network was the abstraction that mattered. This article is about building a proper IPC server using Unix Domain Sockets, deployed as a sidecar pattern on ECS-on-EC2, with a wire protocol robust enough to ship in production. We're going to design it from scratch — the transport choice, the wire format, the backpressure model, the failure modes, the deployment topology. I'll show you real pseudo-code from the implementation and call out the small number of places where, if you get it wrong, you'll spend a weekend debugging it. The intended outcome is something you coul
AI 资讯
Stop Paying a Streaming Bus to Carry Bytes That Live for Ninety Seconds
How a shared filesystem became the cheapest, fastest outbox I've ever built — and why FSx for OpenZFS is the version of that idea that finally scales I was staring at an AWS bill last quarter where a single Kinesis Data Streams line item was costing more than the entire S3 footprint sitting behind it. The events on that stream had a useful lifetime of about ninety seconds. They were written by one service, read by another, processed, and dropped. We were paying full streaming-bus price for bytes that barely outlived a TCP timeout. That bill is what got me thinking about transitional data as a category that deserves its own architecture, and about why every "use the right tool" instinct I had — Kinesis, Kafka, MSK — was the wrong tool for this particular shape of work. The right tool, it turns out, is a filesystem. Specifically, AWS FSx for OpenZFS, used as an outbox between producers and consumers, with only a tiny pointer message traveling through whatever messaging bus you already have. This article is the case for that pattern. It's also the design, the failure modes, the code, the cost math, and the honest list of when not to do it. I'll walk you through the architecture from first principles, show you the safe-write protocol that makes it correct under crashes and concurrent retries, compare the cost against Kinesis, MSK and EFS at a realistic petabyte-class workload, and explain why the recent addition of FSx Intelligent-Tiering changes the cost story in a way that makes the pattern attractive even for teams that don't ingest petabytes. If you've ever felt the queasy sensation of paying twice for the same bytes — once to land on a stream, again to land in storage — this is for you. What "transitional data" actually means Most data falls into one of two cleanly shaped buckets. Durable data is the stuff you keep — user records, orders, financial events, audit trails. It needs to live for years; you pay storage costs for those years and you get value over those y
AI 资讯
The Real Sovereign OS - OnemanBSD updated!
I lost more than 60 days but I made a huge update All OnemanBSD OS is now 64 bits. I also removed all bloat like Rust, Wayland and Qt dependencies from all app ports used in the system. (mpv was changed to gnome-mplayer because of that). New apps included (+ fixed source code of everything): audacity (audio editor) godot (game editor) deadbeef (mp3 player) ted (word processor) Also some bug fixes. Here is the link again: http://bialamusic.com/onemanBSD/ Here are my thoughts: I feel that we as humans are loosing control over technology that was created by humans. This is rising some serious and strange questions. I think we now need tools to power the individual so we can fight back. Not corporations. Not governments. Not organizations. Consider this my bullet in this battle. It is now in your hands so you can be active developers not just passive users.
AI 资讯
Fragments May 27: on-the-loop with Claude Code, 2h of endurance, and NHS closing repos
Martin Fowler's May 27 Fragments brings together four arguments with direct implications for teams working with AI agents. All four are worth covering. Ian Johnson: build quality gates before releasing the agent Ian Johnson published a series about restructuring a gnarly codebase: three months, 258 commits, moving from a Laravel monolith with no tests to an application with automated quality gates and an AI agent shipping production code with minimal supervision. The insight Fowler highlights is about the transition from in-the-loop to on-the-loop: "For the first two months of this project, I used Claude Code with auto-approve turned off. Every file edit, every terminal command, every change… I reviewed it before it executed. The results were good. The code was clean. But I was doing most of the thinking and half the typing. The agent was a fancy autocomplete with better suggestions." Ian Johnson Manual review of every change is not how you build trust in the agent. Trust comes from building the structure that ensures the agent will do the right thing, then stepping back. The sequence: characterization tests first, static analysis, architectural patterns that make things flow correctly. Fowler notes this is exactly the sequence he would use himself. Adam Tornhill: roughly 2 hours of cognitive endurance Adam Tornhill observes that agentic work has a decision density that is mentally more expensive than it appears. The estimate is roughly two hours as a sustainable limit, not a full day of work. The implication: adding more parallel agents does not solve the problem, because the bottleneck is the coordinating engineer's cognitive capacity, not available processing volume. The solutions are smaller tasks, automation, and verification mechanisms, not more parallelism. NHS: closing open source repositories NHS (UK National Health Service) closed open source repositories citing LLM threats to code security. The UK Government Data Services countered directly: making code p
AI 资讯
GitHub Slashes Agent Workflow Token Spend up to 62% with Daily Audits and MCP Pruning
GitHub reports cutting token costs in agentic CI workflows by up to 62% by pruning unused MCP tools, swapping some MCP calls for gh CLI, and running daily “auditor” and “optimizer” agents. A token-usage.jsonl artefact and an Effective Tokens metric help track spend across models and spot regressions. By Mark Silvester
AI 资讯
The Day Our Treasure Hunt Engine Blew Up at 3 AM (And How We Rebuilt It Right)
The Problem We Were Actually Solving Our event platform at Veltrix ran a treasure hunt game that gave users real-world rewards. It started as a simple Rails app with a PostgreSQL counter column for each hunt. By 3 AM on Black Friday, that counter column became a single point of failure. Every leaderboard update blocked the entire leaderboard query because PostgreSQL row-level locks escalated to table-level for SERIAL columns. Our error rate jumped from 0.2% to 18% under 2000 concurrent writes. The system didnt just slow down; it started failing writes with could not serialize access due to concurrent update deadlocks. We lost $47K in rewards payouts before we could scale up the database. What We Tried First (And Why It Failed) Our first fix was to shard the PostgreSQL counter by hunt ID, splitting the hot row into 1024 partitions. That reduced the lock contention, but introduced new problems. Each hunt now needed its own sequence, and our Rails code had to route writes to the correct shard. The shard routing introduced 400ms extra latency on leaderboard queries because we had to union results across 1024 tables. Meanwhile, PostgreSQL sequences had gaps up to 1024 when nodes restarted, so our reward payouts were off by thousands on high-traffic hunts. Our Redis cache didnt help because the leaderboard queries were point lookups against 1024 tables, and Redis couldnt pipeline those efficiently. The Architecture Decision We ripped out the PostgreSQL counter and replaced it with a Kafka Streams-based event sourcing system called HuntStream. Every hunt action (point earned, reward claimed) became an immutable event in a Kafka topic. We built a materialized view on top of RocksDB that consumed the topic and maintained the current leaderboard state in memory. The materialized view was partitioned by hunt ID, which meant leaderboard queries only hit one RocksDB partition per hunt. We used RocksDBs built-in caching to keep hot leaderboards in memory, and fall back to disk fo
AI 资讯
How to Integrate AI and LLMs into Production Web Apps (Lessons from the Field)
Everyone is adding AI to their product right now. Most of them are doing it wrong. Not because they chose the wrong model. Not because they used the wrong library. But because they treated AI integration like a regular feature and skipped all the engineering discipline that production systems require. I have integrated LLMs into multiple production applications. This is what I wish I had known before I started. The Mental Model Shift You Need First A traditional API call is deterministic. You send a request, you get a predictable response. You can write tests against it. You can cache it. You can reason about it. An LLM call is not deterministic. The same input can produce different outputs on different runs. The model can refuse, hallucinate, or return output in a format you did not expect. Your system needs to be designed around this reality, not in spite of it. This means defensive parsing, fallback logic, output validation, and graceful degradation are not optional extras. They are the core of the feature. Choosing the Right Model for the Right Job The biggest LLMs are not always the right choice. I learned this building EditDeck Pro, an AI creative platform for music. Some tasks needed a large frontier model for nuanced creative output. Others needed a fast, cheap model that could run many times per session without accumulating significant latency or cost. The pattern that works: Use a lighter model for classification, extraction, and short structured outputs. Use a larger model for generation tasks where quality matters more than speed. Route dynamically between them based on the task type. This can reduce your inference costs by 60 to 80 percent on workloads that mix simple and complex tasks. Prompt Engineering Is Software Engineering Prompts are code. They should be versioned, tested, and reviewed like code. I store prompts in a dedicated module with version numbers. When I change a prompt I run it against a fixed evaluation set of inputs and compare the out
AI 资讯
The Fallacies of GenAI Development
In 1994, Peter Deutsch published the Fallacies of Distributed Computing — eight assumptions that every developer building distributed systems makes, discovers are wrong, and pays for in production. The network is reliable. Latency is zero. Bandwidth is infinite. Each assumption sounds true. Each leads to system failures that could have been avoided. Thirty years later, we're making the same category of mistakes with generative AI. The trough of disillusionment for AI-assisted development has begun. Byron Cook, VP and Distinguished Scientist at Amazon, founder of AWS's Automated Reasoning Group (300+ scientists, 15+ teams), says it plainly: "Generative AI is sliding into the trough of disillusionment." The headlines are shifting. The "summer of vibe coding" is over. The disillusionment isn't caused by AI being useless. AI-assisted coding delivers real productivity gains. The disillusionment is caused by false assumptions about WHERE the gains come from and WHAT changes when generation gets fast. Teams expected 10x engineering. They got 10x code generation and 1x everything else. The gap between expectation and reality is the trough. This series names the eight assumptions, explains why each one fails, and presents the resolution — not from theory, but from domains that hit the same wall and climbed out. The Eight Fallacies 1. Faster code generation means faster engineering. You made one sub-system 10x faster. Seven others didn't change. The system doesn't get faster — it breaks at the interfaces. The CPU-memory wall tells you exactly what happens and what fixes it. 2. If the output looks correct, it is correct. AI-generated code is optimized for plausibility, not correctness. It compiles, passes tests, and reads well — while violating properties nobody tested. Plausible is not correct. The gap is where production failures live. 3. You can verify AI output with another AI. Guardrails, LLM-as-judge, AI code review — the verifier has the same failure modes as the thing
AI 资讯
The Platform Team Became a Finance Team
Platform team sprint planning in 2026 begins with budget allocation, not architecture review. The first question is no longer "what do we need to build?" — it's "what can we afford to run?" This is not FinOps adoption. This is authority displacement. The platform team became a finance team because the control plane for infrastructure decisions migrated from architecture governance to budget governance. Cost constraints don't inform architectural decisions anymore — they dictate them. And when financial systems gain veto authority over technical systems, resilience becomes the variable that adjusts. Platform team cost governance is now the primary control surface. Architecture is secondary. How We Got Here The timeline is sharper than most organizations admit. 2018–2022 was the cloud adoption phase. Platform teams built for scale. Multi-region resilience was standard. Observability was deep. Auto-scaling was elastic. Architectural requirements shaped cost models. The budget followed the design. 2023–2024 brought FinOps as a cost visibility layer. Teams could finally see where money was going. Dashboards got built. Anomaly detection got configured. Attribution models got refined. But visibility was still separate from authority. The FinOps team reported. The platform team decided. 2025–2026 is when cost governance moved from reporting to gating. The turning point: platform teams stopped asking "can we build this?" and started asking "can we afford this?" Engineering roadmaps became cost roadmaps. Feature requests now come with budget allocation approvals. Architecture reviews now include CFO sign-off gates. This shift introduced Budget-Normalized Architecture — systems designed around predictable monthly spend targets instead of operational resilience targets. The architecture no longer optimizes for failure domains, latency requirements, or recovery objectives. It optimizes for staying under the cost ceiling. Cost governance expanded because engineering governance fa
AI 资讯
Article: Stragglers, Not Failures: How Adaptive Hedged Requests Reduce p99 Latency by 74 Percent
n fan-out microservice architectures, slow-but-completing requests accumulate across services and drive p99 latency far higher than per-service metrics suggest. This article presents an adaptive hedging mechanism that uses DDSketch for real-time quantile estimation, windowed rotation to handle distribution drift, and a token-bucket budget to prevent load amplification. By Prathamesh Bhope
AI 资讯
Six Contradictions Behind Cognitive Debt in AI Assisted Development
The conversation about cognitive debt in AI-assisted development has been framed as a tradeoff: you can go fast, or you can understand your system, but not both. The proposed mitigations — pair programming, code reviews, requiring a human to understand each change — are braking mechanisms. They trade speed for comprehension. TRIZ (Theory of Inventive Problem Solving) says braking is a compromise, not a resolution. A resolved contradiction eliminates the conflict. You don't choose between speed and understanding. You restructure the system so they don't conflict. There are six root causes of cognitive debt in AI-augmented development. Each one is a contradiction. Each one has a TRIZ resolution that doesn't involve slowing down. Root Cause 1: The Velocity-Comprehension Gap AI generates complex logic in seconds that would take a human hours to write. The human never spends the time typing the code during creation. The theory of the program is never fully formed. The Contradiction Technical contradiction: Improving development speed (AI generates code faster) worsens depth of understanding (human doesn't internalize the logic). Physical contradiction: The development process must be simultaneously FAST (to capture AI's productivity gains) and SLOW (to allow human assimilation of the system's behavior). Resolution: Separation in Space (Principle 2 — Extraction + Principle 1 — Segmentation) The contradiction assumes that the thing being understood IS the code. Extract the understanding target from the code and put it somewhere else — a smaller, slower-moving, human-readable artifact that captures what the code must satisfy, not how it works. Segment the system's theory into independent, composable units. Each unit is one property: "this service must never accept unauthenticated requests," "this data pipeline must preserve ordering," "this retry loop must terminate within 30 seconds." Each property is 1-3 sentences in natural language or 3-10 lines in a predicate language.
AI 资讯
Read-Modify-Write isolation in NoSQL: the distributed-lock hell.
In part 1 , the single-document case was easy. In part 2 , two documents brought Write Skew, and we saw that even a native ACID transaction — snapshot isolation — lets it through. So teams reach for the reflex fix: a distributed lock — Redis-based, often a Redlock-style implementation. Acquire a lock on a key, do your Read → Modify → Write, release. On paper, you've finally serialized the critical section — operationally, at least. In practice, you've stepped on three mines. 1. Network latency Every guarded transaction now makes extra round-trips to Redis — before and after hitting your NoSQL store. You've doubled your coordination surface and taken a hard dependency on a second system being up, reachable, and fast on the hot path of every write. The "fast" database is now gated by the lock service. And the coupling bites harder than the average latency suggests: every Redis tail-latency spike becomes your write-latency spike — your p99 inherits Redis's p99 — and if Redis fails over mid-transaction, the lock you think you're holding can effectively vanish on the new primary, dropping you straight into the corruption case below. 2. Deadlock You can dodge deadlock entirely with a single coarse lock — but then every writer serializes on it, and you've thrown away the very concurrency you reached for NoSQL to get. So to keep throughput you go fine-grained, one lock per resource — and the moment an invariant touches more than one key (across this series, it always does), deadlock is back on the table: Transaction A locks key X, then needs Y. Transaction B locks Y, then needs X. Both block until timeout or intervention. The textbook cure — real deadlock detection, maintaining a wait-for graph across every lock holder and breaking cycles as they form — is a distributed-systems project in its own right: not something you bolt onto a cache you reached for precisely to save engineering time. So nobody builds it. Instead teams impose a standing discipline: always acquire locks