惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Help Net Security
T
ThreatConnect
SecWiki News
SecWiki News
F
Future of Privacy Forum
AWS News Blog
AWS News Blog
C
Cisco Blogs
A
Arctic Wolf
Vercel News
Vercel News
The GitHub Blog
The GitHub Blog
Scott Helme
Scott Helme
V
V2EX
博客园 - 叶小钗
阮一峰的网络日志
阮一峰的网络日志
K
Kaspersky official blog
G
Google Developers Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
P
Privacy International News Feed
C
Cyber Attacks, Cyber Crime and Cyber Security
N
News | PayPal Newsroom
Schneier on Security
Schneier on Security
NISL@THU
NISL@THU
Microsoft Azure Blog
Microsoft Azure Blog
量子位
The Hacker News
The Hacker News
Stack Overflow Blog
Stack Overflow Blog
Security Latest
Security Latest
M
Microsoft Research Blog - Microsoft Research
Google Online Security Blog
Google Online Security Blog
博客园_首页
C
CXSECURITY Database RSS Feed - CXSecurity.com
I
InfoQ
Google DeepMind News
Google DeepMind News
Y
Y Combinator Blog
The Cloudflare Blog
Microsoft Security Blog
Microsoft Security Blog
Martin Fowler
Martin Fowler
Cisco Talos Blog
Cisco Talos Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Troy Hunt's Blog
F
Fox-IT International blog
S
Security @ Cisco Blogs
博客园 - 司徒正美
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
C
Comments on: Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
L
LINUX DO - 最新话题
GbyAI
GbyAI
Project Zero
Project Zero
腾讯CDC
T
Tailwind CSS Blog

DEV Community

Espressif Reveals CoreBoard and Korvo Dev Kits for ESP32-S31 My CKA Cheat Sheet: Commands, Aliases, and Documentation Tricks I Used During the Exam Frontend Engineering Beyond Pixels: The Architecture of Digital Accessibility VLA or IL? A Controlled Dataset for Testing Whether Finetuning Turns Your VLA into a Fancy Imitation Learner Fabric AI Functions Turn GenAI Into a Data Pipeline Step The Treasure Hunt Engine That Broke Before the Traffic Did Reset Windows Update: The Definitive MSP Guide to RWU Your Resume Was Never Built for This AI Writes 46% of Code Now: What Snap's Layoffs Mean for Developers in 2026 From Chatbot to Agent — Tool Calling with NVIDIA NIM Fatigue and Fracture Mechanics: Why Parts Break Below Their Yield Strength I built a token-level debugger for comparing two LLMs VCP-Virtual Private Cloud Embedding sing-box in an iOS messenger to bypass Russian DPI (no VPN) Microsoft Copilot just exfiltrated a company's files. The attack was one email. Here's the mechanism. RAG 시스템 실전 구축 (v42) copilot cloud agent is becoming an automation api Cx Dev Log — 2026-04-23 Why Tesla Is Becoming the AI Enterprise Case Study Every Leader Should Understand ORA-00214 오류 원인과 해결 방법 완벽 가이드 SpecAgnt v2.0: The Agent Lifecycle Framework for AI-Native Engineering Optimizing Signal Latency and Weight Allocations in Algorithmic Pipelines SSH Under the Hood: Protocols, Mechanisms, and the Full Technical Story دليل بوابات الدفع للتاجر العربي في 2026 (وكيف تختار المناسبة لمتجرك) Cómo Mi Configuración de Docker Me Salvó de un Ataque de Supply Chain (Y Por Qué la Tuya Debería Hacerlo También) How My Docker Setup Saved Me From a Supply Chain Attack (And Why Yours Should Too) Astro: The epitome of SEO Technical Update I Gave My AI Agent the Ability to Research Before It Writes — Here’s What Changed Kubernetes sem Cloud Provider (Parte 2): Criando Operators em Go para automação e self-service de plataforma AI Memory Needs an Authority Policy, Not Just More Context You've done tutorial after tutorial. Your GitHub is still empty. (Free 1‑page PDF, no signup) TypeScript 7.0: The Go Compiler That Makes TS 10x Faster Connecting Wallets the Right Way: wagmi v2 and EIP-6963 The 5-Layer Architecture Every Production Multi-Agent System Needs (And Why Most Skip Layers 4 and 5) CSS Scroll-Driven Animations: No JavaScript Required Vite 8 + Rolldown: Rust-Powered Builds That Are 10–30x Faster Core Architectural Components of Azure My Skills How I Use AI as a Senior Engineer Construí um motor ATS determinístico porque estava cansado de adivinhar por que meu currículo era rejeitado SCS-Lab1 — CloudTrail: Trail + S3 + KMS + Log Validation LuisCore MCP server — daily syndication · 2026-05-25 Cursor vs JetBrains Rider for C#/.NET in 2026: which to pay for I built a local-first movie recommender with Corrective-RAG (cited explanations, hybrid retrieval, runs entirely on Ollama) Scaling to 1 Million Users : Load Balancing & Caching Strategies How the Events Table That Looked Right Killed Our Queue Three Failures My AI Memory System Caught — And the Flaw It Revealed in Itself dotnet Framework life cycle tool LangGraph 워크플로우 템플릿 (v41) I built a free image compression API — no signup, just curl Designing TikTok from Scratch — A System Design Deep Dive PREDICTION-20260525-0007: boredom-with-asymmetric-leverage [2026-Q3 through 2027-Q3] [Boost] How to integrate the QuickBooks Invoice API in 2026 How I Cut My Anthropic API Bill by 50% With a Local Python Tool Vibe Coding Problems: 7 Visual Bugs AI Code Generators Always Ship Chinese AI Models 2026: The Agentic Revolution, Hardware Independence, and What It Means for Global Developers The Quiet AI War Inside Your Browser The 12-Line Anti-Bot Trick That Saved Our Airdrop Snapshot From Sybil Farms Building a production-ready SaaS dashboard in Next.js 16 — Recharts, TanStack Table, dark mode, and collapsible sidebar Why 2026 Belongs to Agentic AI (And How to Build Your First Local Agent) It Was 2024 When We Tried to Outsmart the Treasure Hunt Engine RAG 시스템 실전 구축 (v40) I Found a Tool That Generates a Complete .NET 8 or Java Spring Boot API From SQL Schema in 30 Seconds I Added a 4th Agent That Audits My Other Agents. It Caught My Strategist Procrastinating for 3 Weeks. Streaming LLM responses to the browser in Go (Server-Sent Events) How We Publish and Manage Educational Admission Updates at Scale on DailyAxom A prompt is not a conversation. It's a component contract. How to Pass the EAA 2025 Accessibility Audit — A Step-by-Step WCAG Checklist Building an Autonomous MCP Lead Generation System with Hermes Agent LangGraph 워크플로우 템플릿 (v40) How I Built 100 Browser-Based Image Tools With No Server (FFmpeg WASM, PDF-lib, AI Background Removal) Nginx CVE-2026-9256, AI Prompt Injection Defenses, and Claude AI Data Leak Demo Scaling RAG for 10M+ Docs, .md Agent Memory, & Claude Code for Motion Graphics Diagram as Code with draw.io DuckDB Delta, PostgreSQL 17 Migration, & SQLite Optimization Deep Dives Windows 11 Microsoft Account Login Recovery During Internet Restrictions The Linux Commands You Forgot Exist (And Why AI Workflows Make Them Relevant Again) Spec-Driven Development Without an IDE: I Generated NestJS, Go, Spring Boot, Laravel, and Rust Apps From a Single PRD File Components are states Edge SEO y Middleware: Cómo Interceptar a Googlebot y LLMs antes de llegar a tu Servidor Context window exceeded at turn 23. Here's how I track token usage without a tokenizer. My Hermes agent spent $3 before I noticed. Now it can't. My Hermes agent's stop condition was a 40-line if/elif chain. I replaced it with 3 lines. My agent kept hitting context limits. This one function fixed it. Create and configure Azure Firewall Your Hermes agent's audit log is leaking customer emails. Here's a 100-line lib that fixes that. My agent kept forgetting what it was doing. A scratchpad fixed it. I replaced 200 lines of ad-hoc state management in my Hermes agent with one object. Per-Key Rate Limiting for Agent Tool Calls: Stop One User From Breaking Everything Composable Output Guardrails: Filter Agent Responses Before They Reach Users Sanitize Your LLM Message Lists Before Every API Call Thread a Run ID Through Every Agent Call So You Can Debug Anything Normalize Provider Error JSON So Your Agent Can Actually Handle Failures Priority Queue for Agent Sub-Tasks: Stop Processing Low-Priority Work First Static Lint Rules for Your LLM Prompts (Before They Hit Production) tool-call-budgets: Stop Runaway Agent Loops Before They Hit Your Invoice Step Through Your Agent's Failures Like a Debugger The Simplest Stop Condition: A Hard Cap on Agent Loop Iterations
Proximate vs Ultimate: The Bug Is Never Just the Bug
ignacio.medi · 2026-05-26 · via DEV Community

Evolutionary Adaptation and Software Design

I was reading about species adaptation when I stumbled on a concept that wouldn't leave me alone: Proximate and Ultimate Causation. Wikipedia defines it as:

A proximate cause is an event which is closer to (more immediately responsible for) causing some observed result. This exists in contrast to a higher-level ultimate (or distal) cause, which acts less directly through the proximate cause.

Ernst Mayr popularized these concepts in Cause and Effect in Biology (1961). The short version:

Ultimate causation asks why a trait exists at all. The evolutionary reason something is there. Natural selection, adaptation, history.

Proximate causation asks how something works right now. Physiology, genetics, development, immediate environment.

Classic Example: Birdsong in Spring

Question: Why does the bird sing?

  • Proximate: Increasing day length triggers hormonal changes; vocal muscles activate.
  • Ultimate: Singing attracts mates and defends territory. More singing, more offspring.

Example: Human Hunger

Question: Why do we feel hungry?

  • Proximate: Low blood glucose hits the hypothalamus, ghrelin gets released.
  • Ultimate: The ancestors who went looking for food when energy dropped are the ones who made it.

Why This Distinction Actually Matters

A classic example of confusing the two::

"Humans have religious beliefs because the temporal lobe produces spiritual experiences."

That's proximate. It explains the mechanism, not the origin. The ultimate question is different: maybe religious belief enhanced group cohesion, and groups that cohered survived better. Two completely different questions wearing the same label.

You see this all the time in evolutionary psychology:

  • Proximate: "Men prefer young partners because testosterone influences mate selection."
  • Ultimate: "Male ancestors who preferred fertile partners had more offspring."

Neither answer is wrong. They just aren't competing.

Applying This to Software

Bug-Fix Scenario

You get a 500. The stack trace points to a null check missing on customer_number. Unhandled AttributeError. That's proximate and yes, it's the code.

But ask yourself why that code existed: the team was sprinting hard on features, no one owned error handling, and the PR got waved through. That's ultimate. Fix the null check and the next unreviewed PR will introduce a different unhandled edge case. You treated the symptom.

Feature Request

We need a POST /trademark-identifier endpoint because the client requires reverse image search to identify sales related to a particular brand.

  • Proximate: The client needs reverse image search for branding identification.
  • Ultimate: Our competitor shipped visual search last quarter and we're losing RFQs to them.

The proximate is the ticket. The ultimate is why the ticket exists at all. If you only read the ticket, you might build the minimum. If you understand the pressure, you scope it differently.

Architecture Decision

We're extracting the auth service from the CRM because the monolith is too coupled and deployment takes 20 minutes.

The proximate answer is right there in the sentence. But the ultimate is messier: the company hired three more backend engineers, the PR queue is a graveyard, and features are taking two weeks to ship. Conway's Law isn't just a fun observation here. It's the actual selection pressure. The org outgrew the architecture, and the architecture is fighting back.

The Dangerous Pattern: Mistaking Proximate for Ultimate

In my experience as Software Architect, postmortems and design docs are full of this:

"The microservice split fixed our deployment time issue."
"We decluttered the database by partitioning large tables."

Both statements are probably true. And both are proximate. The deployment was slow because the monolith was coupled; the database was slow because it was bloated. Fine. But neither statement touches why the coupling existed or how the data got that way.

In the deployment case, the ultimate cause is usually this: the team grew faster than the domain was ever modeled. No one drew boundaries early because there was no pressure to, two engineers sharing a codebase don't need bounded contexts. By the time there were ten engineers, the coupling was load-bearing and painful to remove. The microservice split relieved the pain. It did not fix the underlying habit of building without domain boundaries.

In the database case, the ultimate cause is almost always ownership. No team owned the schema. Feature work landed wherever it fit. Partitioning cleans it up, but the next six months of features will re-create the mess if no one changes how data decisions get made.

Fix only the proximate like split the service and partition the database, and in six months you'll be back here. The new architecture will re-develop the same patterns, because the pressure that created the original problem is still active. That's software evolutionary convergence: systems drift toward the shape their environment selects for, regardless of how you restructure them.

The ultimate cause point isn't the coupling. It isn't the team size. It's that no mechanism was ever put in place to maintain domain boundaries as the team grew. Coupling is the symptom. Missing governance is the cause.

A Framework for Teams

When your team is about to implement something, ask two questions out loud:

Before implementation:

  • Proximate: What exactly are we changing?
  • Ultimate: What pressure is forcing this change? (Competition? Team growth? User feedback? Accumulated debt?)

After the first implementation:

  • Proximate: Did it work?
  • Ultimate: Is the pressure still there, or did we just treat the symptom?

The microservice deployment example again: time drops, the board is happy. But if the monolith was coupled because the team shared a database and never drew domain boundaries, that coupling pressure is still live. The system will pull itself back together. You bought time, not a solution.

Don't Fall for the "Just a Ticket" Trap

Consider the following scenario: No staging env for a service. Only dev and prod.

  • Proximate: No staging env exists.
  • Ultimate: The team went from 2 to 8 engineers, and the "ship to prod, test there" workflow that worked fine at 2 people is catastrophically risky at 8. The infrastructure didn't grow with the team.

Build the staging env, it's the right call. But the ultimate cause here isn't a missing environment; it's that no one owns the relationship between team size and process maturity. At 2 engineers, that gap is invisible. At 8, it's a staging env. At 15, it'll be the deployment pipeline. At 25, it'll be the on-call rotation falling apart at 3am.

So yes, build the env. And then name the real ticket: "as we grow, what process reviews do we run to catch the next thing our infrastructure isn't ready for?" That ticket probably doesn't exist. That's the one worth opening.

The ultimate cause point here is the absence of a feedback loop between team size and infrastructure maturity. Every team encounters these gaps. Most just build whatever env is on fire today and call it done. The adaptation is a recurring review — not a one-time build.

A practical technique:

  1. Write down the proximate cause. Something short that the room agrees on. If it's large, split it.
  2. For each proximate cause, ask "why was that true?" three more times, using the previous answer as the starting point.
  3. You'll land on the ultimate cause, or close enough to name it.

This is a rougher version of the Five Whys. What makes it useful here is naming the levels explicitly, proximate versus ultimate, so the team can't pretend the patch is the solution.

Stop at proximate and you shipped a patch. Address both, and you've actually adapted.