{"version":1,"site":"https://agenticthinking.ai","buildDate":"2026-10-25","about":"Verbatim passages (markup removed): thesis, lead and section openers. id = <slug>#<kind>#<index>; hash = first 16 hex of the sha256 of text.","count":615,"passages":[{"id":"about-steven-poitras#lead#0","hash":"0afba75d6e92559f","slug":"about-steven-poitras","kind":"lead","index":0,"role":"position","heading":null,"text":"I'm a technology industry veteran with a pattern of joining early-stage companies and helping them scale to massive success. Here's my story and what drives me.","next":"text"},{"id":"about-steven-poitras#section#1","hash":"e37735a2ee1a9c87","slug":"about-steven-poitras","kind":"section","index":1,"role":"position","heading":"Early Beginnings: A Hacker at Heart","text":"My fascination with technology started long before I understood what a career in tech could look like. As a kid, I was drawn to understanding how systems worked—and more importantly, how to bend them to my will.","next":"heading"},{"id":"about-steven-poitras#section#2","hash":"421d3c68126ece2c","slug":"about-steven-poitras","kind":"section","index":2,"role":"position","heading":"Phreaking and Hacking","text":"Before the internet was mainstream, I discovered the world of phreaking and hacking. There was something intoxicating about exploring systems, understanding their weaknesses, and finding paths where none were supposed to exist. The curiosity wasn't malicious—it was pure exploration, the same drive that makes engineers want to take things apart to see how they tick.","next":"heading"},{"id":"about-steven-poitras#section#3","hash":"5738c1bee001fb13","slug":"about-steven-poitras","kind":"section","index":3,"role":"position","heading":"My First \"Hack\" - 3rd Grade","text":"My first real \"hack\" happened in 3rd grade. Using a school computer, I managed to get access to look up information on two topics that fascinated my young mind: Area 51 and Pamela Anderson. Looking back, it's a hilarious combination of childhood curiosity—government conspiracy theories and pop culture crushes. But it was formative. That moment of bypassing restrictions and accessing forbidden knowledge lit a fire that never went out. I realized that with enough curiosity and persistence, systems could be understood and navigated.","next":"p"},{"id":"about-steven-poitras#section#18","hash":"90bd236d0674f900","slug":"about-steven-poitras","kind":"section","index":18,"role":"position","heading":"Connect","text":"Looking forward to sharing more about the journey, now back at Nutanix.","next":null},{"id":"ema-founding-team#lead#0","hash":"f3d645aad2749c50","slug":"ema-founding-team","kind":"lead","index":0,"role":"position","heading":null,"text":"Ema was founded by a powerhouse duo with exceptional credentials from some of the world's most successful technology companies. Their combined experience spans Google, Coinbase, and Meta, with a track record of building products used by billions of people.","next":"text"},{"id":"ema-founding-team#section#1","hash":"a1cad289452113d4","slug":"ema-founding-team","kind":"section","index":1,"role":"position","heading":"Surojit Chatterjee — CEO & Co-founder","text":"Surojit brings world-class product leadership experience to Ema, with a career spanning some of tech's most influential companies.","next":"heading"},{"id":"ema-founding-team#section#3","hash":"b5fe7b66ab8ceca8","slug":"ema-founding-team","kind":"section","index":3,"role":"position","heading":"Souvik Sen — CTO & Co-founder","text":"Souvik is a world-class engineering leader with deep expertise in building AI/ML systems at scale.","next":"heading"},{"id":"ema-founding-team#section#14","hash":"fb9c40705e0728a7","slug":"ema-founding-team","kind":"section","index":14,"role":"list","heading":"The Track Record Speaks","text":"When evaluating a startup, the founding team is often the most important factor.","next":"lead-in"},{"id":"ema-platform-overview#lead#0","hash":"412bd34d39ea2440","slug":"ema-platform-overview","kind":"lead","index":0,"role":"position","heading":null,"text":"Ema is the Universal AI Employee platform, transforming enterprise operations through AI agents that actually work alongside human teams. Unlike chatbots or simple automation tools, Ema creates AI employees that can own and complete entire workflows autonomously.","next":"text"},{"id":"ema-platform-overview#section#2","hash":"b87eb9eb754583d9","slug":"ema-platform-overview","kind":"section","index":2,"role":"list","heading":"🧠 EmaFusion™","text":"Ema's proprietary model architecture that combines multiple AI models for superior performance.","next":"p"},{"id":"ema-platform-overview#section#3","hash":"398051e8b8e2a5a9","slug":"ema-platform-overview","kind":"section","index":3,"role":"list","heading":"🔧 Generative Workflow Engine™ (GWE)","text":"The engine that powers Ema's ability to create and execute complex workflows.","next":"p"},{"id":"ema-user-guide#lead#0","hash":"b437858e02dac6e6","slug":"ema-user-guide","kind":"lead","index":0,"role":"position","heading":null,"text":"A comprehensive guide to understanding Ema's Agentic AI platform—from core concepts and terminology to practical implementation patterns. Whether you're technical or business-focused, this guide will help you navigate the world of AI Employees.","next":"text"},{"id":"ema-user-guide#section#2","hash":"6353b4fad281b898","slug":"ema-user-guide","kind":"section","index":2,"role":"position","heading":"What is Ema?","text":"Ema is a Universal AI Employee platform that creates autonomous AI agents capable of completing entire workflows—not just answering questions. Unlike chatbots or copilots, Ema's AI Employees can own tasks from start to finish.","next":"heading"},{"id":"ema-user-guide#section#7","hash":"517bbe0993c50f0f","slug":"ema-user-guide","kind":"section","index":7,"role":"position","heading":"Action","text":"Definition: A discrete operation performed by an agent—the smallest unit of work in a workflow.","next":"p"},{"id":"ema-user-guide#section#8","hash":"9bc2172d2fd37d19","slug":"ema-user-guide","kind":"section","index":8,"role":"position","heading":"Agent","text":"Definition: A specialized AI capability that performs a specific function within a workflow. Agents are the building blocks that compose AI Employee behaviors.","next":"p"},{"id":"ema-user-guide#section#9","hash":"dfc37d72e8ce17b5","slug":"ema-user-guide","kind":"section","index":9,"role":"position","heading":"Agent Mesh","text":"Definition: The network of specialized agents that collaborate to complete complex tasks. Instead of a single monolithic AI, Ema uses multiple specialized agents working together.","next":"p"},{"id":"ema-user-guide#section#11","hash":"308e13c8ac9f4df4","slug":"ema-user-guide","kind":"section","index":11,"role":"position","heading":"Agentic AI","text":"Definition: AI systems that autonomously plan, reason, and execute multi-step tasks—completing workflows from start to finish rather than just assisting.","next":"p"},{"id":"ema-user-guide#section#12","hash":"d5df5b571444dc4f","slug":"ema-user-guide","kind":"section","index":12,"role":"list","heading":"Connector","text":"Definition: A pre-built integration that enables agents to interact with external enterprise systems.","next":"p"},{"id":"ema-user-guide#section#13","hash":"bf5c6f0df5472023","slug":"ema-user-guide","kind":"section","index":13,"role":"position","heading":"Conversation","text":"Definition: A multi-turn interaction session between a user and an AI Employee, maintaining context across messages.","next":"p"},{"id":"ema-user-guide#section#14","hash":"b4e95cb9961a7f92","slug":"ema-user-guide","kind":"section","index":14,"role":"position","heading":"EmaFusion™","text":"Definition: Ema's proprietary model orchestration technology that combines 100+ LLMs to route queries to the optimal model(s) for each task.","next":"p"},{"id":"ema-user-guide#section#15","hash":"5b289a86a6b1529a","slug":"ema-user-guide","kind":"section","index":15,"role":"position","heading":"Generative Workflow Engine™ (GWE)","text":"Definition: The core engine that enables building AI workflows using natural language instructions—no coding required.","next":"p"},{"id":"ema-user-guide#section#16","hash":"ac203c15bf48ee5d","slug":"ema-user-guide","kind":"section","index":16,"role":"position","heading":"Human-in-the-Loop (HITL)","text":"Definition: A workflow pattern where human approval or verification is required before proceeding with an action.","next":"p"},{"id":"ema-user-guide#section#17","hash":"506b064abf5e8ea4","slug":"ema-user-guide","kind":"section","index":17,"role":"position","heading":"Knowledge Base","text":"Definition: The collection of documents, policies, and data sources an AI Employee can search and reference.","next":"p"},{"id":"ema-user-guide#section#18","hash":"db01275fe90c4646","slug":"ema-user-guide","kind":"section","index":18,"role":"list","heading":"Query","text":"Definition: A single, stateless request to an AI system—does not maintain conversation context.","next":"p"},{"id":"ema-user-guide#section#19","hash":"d6691682012f6246","slug":"ema-user-guide","kind":"section","index":19,"role":"position","heading":"Task","text":"Definition: A unit of work to be completed by an AI Employee, triggered by an event and executed through a workflow.","next":"p"},{"id":"ema-user-guide#section#20","hash":"085f467ef935d2fe","slug":"ema-user-guide","kind":"section","index":20,"role":"list","heading":"Trigger","text":"Definition: The event or condition that initiates an AI Employee's workflow.","next":"p"},{"id":"ema-user-guide#section#21","hash":"819a7ba94a0f0146","slug":"ema-user-guide","kind":"section","index":21,"role":"list","heading":"Tool","text":"Definition: An external capability that agents can invoke to perform specific operations.","next":"p"},{"id":"ema-user-guide#section#22","hash":"a6cc83ca58202428","slug":"ema-user-guide","kind":"section","index":22,"role":"position","heading":"Workflow","text":"Definition: A directed graph of agents and their connections that defines how an AI Employee processes work from trigger to response.","next":"p"},{"id":"ema-user-guide#section#25","hash":"f4b997577b53a751","slug":"ema-user-guide","kind":"section","index":25,"role":"list","heading":"AI Employees","text":"An AI Employee is a fully configured, deployable autonomous agent.","next":"lead-in"},{"id":"ema-user-guide#section#42","hash":"84d38efcec9ea186","slug":"ema-user-guide","kind":"section","index":42,"role":"position","heading":"Action vs Tool vs Step","text":"All three can refer to the same thing depending on context!","next":"heading"},{"id":"ema-user-guide#section#56","hash":"5f6a2335d61ad1fa","slug":"ema-user-guide","kind":"section","index":56,"role":"position","heading":"Example 2: Enterprise IT Support with Ticket Creation","text":"Objective: Triage IT requests, answer from knowledge base or create ServiceNow tickets.","next":"heading"},{"id":"ema-user-guide#section#62","hash":"cf60836ddb3952e0","slug":"ema-user-guide","kind":"section","index":62,"role":"position","heading":"Example 3: Voice Password Reset","text":"Objective: Enable employees to reset passwords via phone with identity verification.","next":"heading"},{"id":"why-i-joined-ema#lead#0","hash":"6d3d455ddcf728e3","slug":"why-i-joined-ema","kind":"lead","index":0,"role":"position","heading":null,"text":"Every career-defining bet I've made started the same way: I saw an architectural shift before the market priced it in, found the team building at the center of it, and jumped.","next":"text"},{"id":"why-i-joined-ema#section#1","hash":"fe17a9c6cbf75297","slug":"why-i-joined-ema","kind":"section","index":1,"role":"position","heading":"The Platform Shift","text":"I've lived through three platform shifts: virtualization, hyperconverged infrastructure, and cloud. Each one followed the same arc. A small group of people saw the architectural inevitability before the market did. A brief window opened where the right team could define the category. Then the window closed and everyone else spent a decade catching up.","next":"p"},{"id":"why-i-joined-ema#section#2","hash":"60c9056686447c04","slug":"why-i-joined-ema","kind":"section","index":2,"role":"position","heading":"The Founders","text":"When I talked to Surojit Chatterjee and Souvik Sen, I recognized something I'd only felt once before. Surojit comes from product leadership at Google and Coinbase, where he led products generating billions in revenue and helped take Coinbase public. He thinks in markets and product-market fit and customer outcomes. When he talks about enterprise AI, he's not describing technology—he's describing the business transformation that the technology enables. He's seen what it looks like to build a category-defining product at scale, and he has the scar tissue to prove it.","next":"p"},{"id":"why-i-joined-ema#section#3","hash":"4abaab40c0b6043a","slug":"why-i-joined-ema","kind":"section","index":3,"role":"position","heading":"What Early-Stage Actually Means","text":"People romanticize early-stage startups. The reality is less glamorous and more interesting. At company #5,000, your job is to execute within a well-defined system. The org chart exists. The processes exist. The product-market fit is proven. You're optimizing a machine that already works.","next":"p"},{"id":"why-i-joined-ema#section#4","hash":"0eae8655bfc938c2","slug":"why-i-joined-ema","kind":"section","index":4,"role":"position","heading":"The Technology, Assessed Honestly","text":"I've evaluated dozens of AI platforms over the past three years. Most of them are thin wrappers around a single LLM with a nice UI and a marketing team working overtime. Ema is structurally different, and the differences matter.","next":"p"},{"id":"why-i-joined-ema#section#7","hash":"2ddf9584842d2172","slug":"why-i-joined-ema","kind":"section","index":7,"role":"position","heading":"The Bottom Line","text":"My career has followed one pattern: find transformative technology before the market catches up, find founders worth betting on, and join early enough to shape the outcome. Each time, go earlier.","next":"p"},{"id":"what-is-agentic-ai#lead#0","hash":"a8e94fd303527626","slug":"what-is-agentic-ai","kind":"lead","index":0,"role":"position","heading":null,"text":"Agentic AI refers to artificial intelligence systems that can autonomously plan, reason, and execute multi-step tasks to achieve goals—much like a human employee. Unlike traditional AI that responds to individual prompts, agentic AI can own entire workflows from start to finish.","next":"text"},{"id":"what-is-agentic-ai#section#14","hash":"a7c7f492cb284b0e","slug":"what-is-agentic-ai","kind":"section","index":14,"role":"position","heading":"How Ema Implements Agentic AI","text":"Ema's approach to agentic AI centers on the concept of AI Employees—agents designed to function like digital team members.","next":"heading"},{"id":"what-is-agentic-ai#section#28","hash":"60248a2abd9e34f1","slug":"what-is-agentic-ai","kind":"section","index":28,"role":"position","heading":"Common Questions","text":"Q: Will agentic AI replace human workers? A: Agentic AI is designed to augment human teams, not replace them. It handles routine, repetitive tasks so humans can focus on creative, strategic, and relationship-based work.","next":"p"},{"id":"ai-employee-governance#lead#0","hash":"da4775ef4a284279","slug":"ai-employee-governance","kind":"lead","index":0,"role":"position","heading":null,"text":"It's time to treat your AI agents like the employees they already are. Somewhere in your organization right now, an entity is making decisions on your behalf. It's reading customer messages. Prioritizing tickets. Drafting responses. Approving requests. Moving data between systems. Scheduling resources. Nudging deals forward.","next":"text"},{"id":"ai-employee-governance#section#1","hash":"35f23efdffec6f9f","slug":"ai-employee-governance","kind":"section","index":1,"role":"position","heading":"The Moment the Tool Became a Colleague","text":"We spent decades building tools that assisted humans. Spell checkers. Recommendation engines. Autocomplete. The human stayed in the loop, fingers on the keyboard, brain in charge.","next":"p"},{"id":"ai-employee-governance#section#2","hash":"c930b8315b3106e6","slug":"ai-employee-governance","kind":"section","index":2,"role":"position","heading":"What Happens When Nobody's Managing the New Hire","text":"Picture this: You onboard a new employee. Bright, capable, tireless. You give them access to your CRM, your ticketing system, your knowledge base, your customer communications. You tell them their job is to \"help customers.\" Then you walk away. No manager. No check-ins. No defined scope. No escalation path. No performance reviews. No way to trace what they're doing or why.","next":"p"},{"id":"ai-employee-governance#section#3","hash":"a77bdbeaed19403a","slug":"ai-employee-governance","kind":"section","index":3,"role":"position","heading":"The Org Chart Doesn't End at Carbon-Based Life Forms","text":"Here's what's actually happening: AI agents are de facto employees. They show up. They do work. They affect outcomes. They touch customers. They access sensitive systems. They make mistakes.","next":"p"},{"id":"ai-employee-governance#section#5","hash":"a18072bd6508f05d","slug":"ai-employee-governance","kind":"section","index":5,"role":"position","heading":"\"But It's Just Software\"","text":"I hear this objection constantly. It's the comfort blanket of the under-governed. Traditional software is deterministic. Same input, same output. It does exactly what you programmed. If it misbehaves, you read the code.","next":"p"},{"id":"ai-employee-governance#section#6","hash":"1a9ce5b623e3ebf0","slug":"ai-employee-governance","kind":"section","index":6,"role":"position","heading":"The Accountability Gap Is a Leadership Problem","text":"Here's what keeps me up at night: the accountability vacuum. When a human employee makes a mistake, we can trace the decision. We can understand their reasoning. We can identify gaps in training or judgment. We can assign responsibility.","next":"p"},{"id":"ai-employee-governance#section#7","hash":"3a3f3bd8324b308d","slug":"ai-employee-governance","kind":"section","index":7,"role":"position","heading":"The Permission Creep Nobody's Watching","text":"Humans accumulate access over time. They change roles, take on projects, get added to groups. Permissions pile up. This is why access reviews exist—to periodically ask: \"Does this person still need all this access?\" AI agents creep too. Faster.","next":"p"},{"id":"ai-employee-governance#section#9","hash":"c9d29b1fc1ae3f33","slug":"ai-employee-governance","kind":"section","index":9,"role":"position","heading":"A Framework, Not a Fantasy","text":"This isn't science fiction. It's just disciplined extension of frameworks we already trust for human workers.","next":"heading"},{"id":"ai-employee-governance#section#10","hash":"920029a19d7ca11a","slug":"ai-employee-governance","kind":"section","index":10,"role":"position","heading":"The Real Question","text":"The debate isn't whether AI agents are \"really\" employees in some philosophical sense. Who cares. The question is practical: Do you want to manage these systems with the rigor they require? Or do you want to keep pretending they're just particularly clever shell scripts? The organizations that answer \"yes\" to the first question will scale AI confidently. They'll move faster because they've built control. They'll satisfy regulators because they've built traceability. They'll keep executives on board because they've built trust.","next":"p"},{"id":"ai-employee-governance#section#11","hash":"504878776ce47740","slug":"ai-employee-governance","kind":"section","index":11,"role":"position","heading":"What You Should Do Monday Morning","text":"The employee who never sleeps still needs a manager who's awake.","next":null},{"id":"mcp-knowledge-first-builder#lead#0","hash":"c13d88c321d50570","slug":"mcp-knowledge-first-builder","kind":"lead","index":0,"role":"position","heading":null,"text":"In Part 1, I built an MCP server that could sync AI Employees between environments. It worked. But there was a gap: the AI assistant could move personas, but it couldn't build them. This is the story of closing that gap by embedding domain expertise directly into MCP.","next":"text"},{"id":"mcp-knowledge-first-builder#section#1","hash":"3735b54473542e73","slug":"mcp-knowledge-first-builder","kind":"section","index":1,"role":"position","heading":"The Plateau After Platform","text":"The sync tools were genuinely useful. I could ask Cursor: \"Sync the IT Support persona from demo to dev\" and it would happen—fingerprint comparison, change detection, the works. The infrastructure was solid. But then I tried: \"Create a Voice AI for IT support that creates ServiceNow tickets.\"","next":"p"},{"id":"mcp-knowledge-first-builder#section#3","hash":"113d4e354d9837ba","slug":"mcp-knowledge-first-builder","kind":"section","index":3,"role":"position","heading":"Why Not Just RAG?","text":"The obvious solution: dump the docs into a vector store, let the model retrieve relevant chunks.","next":"p"},{"id":"mcp-knowledge-first-builder#section#9","hash":"3d30c44deb1e7a56","slug":"mcp-knowledge-first-builder","kind":"section","index":9,"role":"position","heading":"Guidance Tools","text":"The pattern: tools that encode expertise, not just execute actions.","next":"heading"},{"id":"mcp-knowledge-first-builder#section#16","hash":"52ff2358ccfcddb6","slug":"mcp-knowledge-first-builder","kind":"section","index":16,"role":"position","heading":"2. Validation Is the Highest-Leverage Knowledge","text":"Every validation rule is a lesson learned. The validate_workflow_prompt tool probably saves more debugging time than all the agent documentation combined.","next":"heading"},{"id":"mcp-knowledge-first-builder#section#17","hash":"d3062f15bf21f36c","slug":"mcp-knowledge-first-builder","kind":"section","index":17,"role":"position","heading":"3. MCP Is a Teaching Interface","text":"I started thinking of MCP as \"API for models.\" I now think of it as curriculum for AI assistants. The tool descriptions, the structured outputs, the validation feedback—they're all teaching the model how to think about the domain.","next":"heading"},{"id":"mcp-knowledge-first-builder#section#18","hash":"961f120d86ce8c34","slug":"mcp-knowledge-first-builder","kind":"section","index":18,"role":"position","heading":"4. IDE Integration Multiplies Value","text":"The Cursor rules file transformed the knowledge base from \"available if you ask\" to \"automatically applied.\" The MCP-first generation flow means the AI starts with platform knowledge instead of discovering it mid-task.","next":"heading"},{"id":"mcp-knowledge-first-builder#section#20","hash":"9582d2ccb349e229","slug":"mcp-knowledge-first-builder","kind":"section","index":20,"role":"position","heading":"If You're Building This","text":"Start with the knowledge gap. What do experienced users know that new users (including AI) don't? That's your knowledge base. Structure beats volume. A typed agent catalog with 40 entries beats 400 pages of docs in a vector store.","next":"p"},{"id":"mcp-server-unified-sdk#lead#0","hash":"b374c38a1542143a","slug":"mcp-server-unified-sdk","kind":"lead","index":0,"role":"position","heading":null,"text":"It started with a simple request: \"Can you sync my AI Employee from demo to dev?\" What followed was a journey from one-off scripts to a unified SDK and MCP server—and lessons about when context becomes the bottleneck.","next":"text"},{"id":"mcp-server-unified-sdk#section#1","hash":"94f30ce379651ddf","slug":"mcp-server-unified-sdk","kind":"section","index":1,"role":"position","heading":"The Original Problem: Starting with a Point Use Case","text":"Ema's platform has a concept called \"AI Employees\"—configurable personas that orchestrate workflows, actions, and conversational agents. Each AI Employee lives in an environment: demo for experimentation, dev for integration testing, staging for pre-prod, production for real users. The problem was that creating an AI Employee in demo and then recreating it identically in dev was a manual, error-prone process—copy fields, hope you didn't miss one, manually track which version was current.","next":"p"},{"id":"mcp-server-unified-sdk#section#2","hash":"291a3237c030982b","slug":"mcp-server-unified-sdk","kind":"section","index":2,"role":"position","heading":"Discovering the Need for MCP","text":"The breakthrough came when I started working inside AI-assisted IDEs like Cursor. I was asking the AI to help me debug sync issues, but it had no idea what an \"AI Employee\" was, what environments existed, or what \"sync status\" meant. I found myself pasting the same context snippets over and over: \"Here's what environments we have. Here's how personas are structured. Here's how sync tags work.\"","next":"p"},{"id":"mcp-server-unified-sdk#section#3","hash":"815c1f1d85663002","slug":"mcp-server-unified-sdk","kind":"section","index":3,"role":"position","heading":"MCP in Brief","text":"MCP provides three primitives: Tools (actions with typed inputs/outputs), Resources (static context), and Prompts (interaction templates). For a complete mental model of MCP's primitives and when to use each, see The MCP Mental Model.","next":"p"},{"id":"mcp-server-unified-sdk#section#5","hash":"4a73963788221a70","slug":"mcp-server-unified-sdk","kind":"section","index":5,"role":"list","heading":"Building the Unified SDK","text":"The SDK became the canonical layer between raw API calls and everything else.","next":"lead-in"},{"id":"mcp-server-unified-sdk#section#9","hash":"1e06ed679efbf255","slug":"mcp-server-unified-sdk","kind":"section","index":9,"role":"list","heading":"Building the MCP Server on Top of the SDK","text":"With the SDK in place, the MCP server becomes surprisingly thin.","next":"lead-in"},{"id":"mcp-server-unified-sdk#section#12","hash":"15a5908df6ac5165","slug":"mcp-server-unified-sdk","kind":"section","index":12,"role":"position","heading":"Environment Abstraction","text":"The server auto-detects available environments from config or env vars. Tools accept an optional env parameter to target specific environments, with sensible defaults.","next":"heading"},{"id":"mcp-server-unified-sdk#section#13","hash":"e2edc153ad0418f6","slug":"mcp-server-unified-sdk","kind":"section","index":13,"role":"position","heading":"Request/Response Flow","text":"The server is stateless per-request. State lives in the SQLite database managed by the SDK.","next":"heading"},{"id":"mcp-server-unified-sdk#section#15","hash":"9579b999c5af55c5","slug":"mcp-server-unified-sdk","kind":"section","index":15,"role":"position","heading":"Why MCP Was Right for This","text":"MCP was the right choice because I had multiple consumers (AI assistants, future CLI, potential webhook-triggered syncs) and I wanted capability definitions to be the source of truth. For a complete decision framework on when MCP is worth the overhead—and when it isn't—see The MCP Mental Model.","next":"heading"},{"id":"mcp-server-unified-sdk#section#16","hash":"2ec2881f156be9f6","slug":"mcp-server-unified-sdk","kind":"section","index":16,"role":"position","heading":"What Changed After MCP","text":"Faster iteration: Adding a new capability means defining one tool + one handler. The protocol machinery is already there. Clearer mental model: Instead of \"which script does what,\" I have a single list of tools with self-describing interfaces. I can ask the AI \"what tools are available?\" and get a useful answer.","next":"p"},{"id":"mcp-server-unified-sdk#section#17","hash":"704a6dbfc356e627","slug":"mcp-server-unified-sdk","kind":"section","index":17,"role":"position","heading":"Lessons Learned","text":"Lesson: Understand your storage constraints before designing your metadata strategy.","next":"quote"},{"id":"mcp-server-unified-sdk#section#18","hash":"3961a61c7879965a","slug":"mcp-server-unified-sdk","kind":"section","index":18,"role":"position","heading":"MCP as a Thinking Tool","text":"Building the MCP server wasn't just infrastructure work. It was an exercise in clarifying what this system actually does.","next":"p"},{"id":"mcp-mental-model#thesis#0","hash":"eab4b84cf2c5a8e8","slug":"mcp-mental-model","kind":"thesis","index":0,"role":"position","heading":null,"text":"MCP (Model Context Protocol) is an interface layer that makes system capabilities legible to AI assistants. It doesn't make models smarter—it makes your system's boundaries, definitions, and actions explicit. Understanding MCP's primitives and when to use each is the difference between a coherent integration and a fragile one.","next":"other"},{"id":"mcp-mental-model#section#1","hash":"bbb5206ac5573241","slug":"mcp-mental-model","kind":"section","index":1,"role":"position","heading":"MCP as an Enabling Layer","text":"MCP emerged from a practical problem: AI assistants need context, and that context was being copy-pasted, embedded in prompts, or reinvented per-integration. MCP provides a structured interface where capabilities can be defined once and consumed by any compatible client.","next":"p"},{"id":"mcp-mental-model#section#2","hash":"272a5e61ca7749c2","slug":"mcp-mental-model","kind":"section","index":2,"role":"position","heading":"What MCP Is—And Is Not","text":"MCP is a protocol for exposing structured capabilities to AI assistants. A server defines tools (actions), resources (static context), and prompts (templates). Clients connect and discover what's available.","next":"p"},{"id":"mcp-mental-model#section#4","hash":"aa79a258d8cfdfdb","slug":"mcp-mental-model","kind":"section","index":4,"role":"position","heading":"Tools","text":"What it is: A function with typed inputs and outputs that performs an action or retrieves information. What problem it solves: Without tools, models can only generate text. Tools give them agency.","next":"code"},{"id":"mcp-mental-model#section#5","hash":"af6ee0f7dbe4dee7","slug":"mcp-mental-model","kind":"section","index":5,"role":"position","heading":"Resources","text":"What it is: Static or semi-static content—documentation, configuration, reference data. What problem it solves: Embedding all context in prompts doesn't scale. Resources let models pull context on demand.","next":"code"},{"id":"mcp-mental-model#section#6","hash":"1ad33b6cd1c3a2f7","slug":"mcp-mental-model","kind":"section","index":6,"role":"position","heading":"Prompts","text":"What it is: Predefined interaction templates that guide common usage patterns. What problem it solves: Without prompts, every invocation starts from scratch. Prompts codify expert knowledge into reusable patterns.","next":"code"},{"id":"mcp-mental-model#section#14","hash":"9af11b66c474a711","slug":"mcp-mental-model","kind":"section","index":14,"role":"position","heading":"MCP + Reasoning: The Boundary","text":"MCP provides: Facts, definitions, constraints, actions, references. LLM reasoning provides: Synthesis, judgment, planning, decision-making.","next":"p"},{"id":"mcp-mental-model#section#16","hash":"e91a73c61b9fe48c","slug":"mcp-mental-model","kind":"section","index":16,"role":"position","heading":"Common Misconceptions","text":"\"MCP is just RAG\" — No. RAG retrieves similar text. MCP exposes structured, typed capabilities. \"MCP replaces prompts\" — No. MCP complements prompts. Prompts guide behavior; MCP provides facts and actions.","next":"p"},{"id":"cursor-rules-vs-mcp#lead#0","hash":"b1fac5de05fd1a7b","slug":"cursor-rules-vs-mcp","kind":"lead","index":0,"role":"position","heading":null,"text":"A guide to what goes where and why — so you can stop wondering and start building. Rules. Commands. Agents. Skills. MCP. Prompts. If you've spent any time trying to customize your AI coding assistant, you've probably wondered: what's the difference? Where does this go? Why isn't this working? You're not alone. The ecosystem has grown faster than the documentation. Everyone's got an opinion, half the features are in \"Nightly,\" and the mental model isn't obvious.","next":"p"},{"id":"cursor-rules-vs-mcp#section#1","hash":"dbd7f56842cee48c","slug":"cursor-rules-vs-mcp","kind":"section","index":1,"role":"position","heading":"The Mental Model (Finally)","text":"Most devs start with rules. Some discover MCP. Few wire them together.","next":"lead-in"},{"id":"cursor-rules-vs-mcp#section#2","hash":"ce67cb8a0550b19e","slug":"cursor-rules-vs-mcp","kind":"section","index":2,"role":"position","heading":"\"Where Does This Go?\" (Decision Guide)","text":"Rule of thumb: If it could become stale, it belongs in MCP. If it's a procedure, it's a command. If it needs deep focus, spawn an agent.","next":"quote"},{"id":"cursor-rules-vs-mcp#section#3","hash":"9ba76c0ed083fe9f","slug":"cursor-rules-vs-mcp","kind":"section","index":3,"role":"position","heading":"Rules + MCP: \"What\" vs \"How\"","text":"Rules = how the AI should behave. MCP = what it's working with. Sounds simple.","next":"lead-in"},{"id":"cursor-rules-vs-mcp#section#5","hash":"f9a64ef16f2791b6","slug":"cursor-rules-vs-mcp","kind":"section","index":5,"role":"position","heading":"The Pattern: Rules Reference MCP","text":"The rule defines the process. MCP provides the facts.","next":"heading"},{"id":"cursor-rules-vs-mcp#section#7","hash":"8d0b24799659024a","slug":"cursor-rules-vs-mcp","kind":"section","index":7,"role":"position","heading":"Commands + MCP: Stop Hardcoding Steps","text":"Commands are repeatable workflows. But static commands rot.","next":"lead-in"},{"id":"cursor-rules-vs-mcp#section#9","hash":"aac1528ab4ed5ec6","slug":"cursor-rules-vs-mcp","kind":"section","index":9,"role":"position","heading":"Dynamic Command (MCP-Powered)","text":"The command orchestrates MCP calls. Each run uses current data.","next":"heading"},{"id":"cursor-rules-vs-mcp#section#11","hash":"506e8de8152fe807","slug":"cursor-rules-vs-mcp","kind":"section","index":11,"role":"position","heading":"Agents + MCP: Give Your Experts Context","text":"Agents are specialists. But an expert without context is just guessing. MCP gives them current state without polluting their prompts.","next":"heading"},{"id":"cursor-rules-vs-mcp#section#13","hash":"c0ef1b4ec4c9b178","slug":"cursor-rules-vs-mcp","kind":"section","index":13,"role":"position","heading":"Agent With MCP (Full Context)","text":"The agent's expertise is static. Its context is dynamic via MCP.","next":"heading"},{"id":"cursor-rules-vs-mcp#section#15","hash":"0d057ce45a589bb0","slug":"cursor-rules-vs-mcp","kind":"section","index":15,"role":"position","heading":"Skills + MCP: Take Your Patterns Everywhere","text":"Skills are portable knowledge modules. Same patterns, different projects. MCP adapts them to local data.","next":"heading"},{"id":"cursor-rules-vs-mcp#section#16","hash":"ba677c765d1256ed","slug":"cursor-rules-vs-mcp","kind":"section","index":16,"role":"position","heading":"Skill Definition","text":"The skill defines patterns. MCP adapts them to each platform.","next":"heading"},{"id":"cursor-rules-vs-mcp#section#27","hash":"3a8fc47d99a20f96","slug":"cursor-rules-vs-mcp","kind":"section","index":27,"role":"position","heading":"2. MCP as Single Source of Truth","text":"Never duplicate data in rules that exists in MCP. Rules reference MCP; they don't replicate it.","next":"heading"},{"id":"inline-llm-calls#thesis#0","hash":"68df2148a8241a66","slug":"inline-llm-calls","kind":"thesis","index":0,"role":"position","heading":null,"text":"Some decisions are better made by models than code. When logic depends on fuzzy matching, domain expertise, or evolving requirements, an inline LLM call lets you upgrade behavior \"out of band\"—no redeployment needed. But this pattern has costs: latency, token spend, and unpredictability. Use it surgically.","next":"other"},{"id":"inline-llm-calls#lead#0","hash":"5ababc5c48d5a697","slug":"inline-llm-calls","kind":"lead","index":0,"role":"position","heading":null,"text":"Hardcoded logic is brittle. Every if (type === \"report\" || type === \"document\") is a decision that will need updating when business requirements change. This post covers when to replace hardcoded conditionals with inline LLM calls, how to do it efficiently, and when the complexity isn't worth it.","next":"text"},{"id":"mcp-dynamic-data-patterns#thesis#0","hash":"c6ff140ec97752ec","slug":"mcp-dynamic-data-patterns","kind":"thesis","index":0,"role":"position","heading":null,"text":"MCP resources and tools should pull from live APIs whenever the underlying data can change. But dynamic data introduces latency, failure modes, and caching complexity. The art is knowing which data to make dynamic, how to cache it, and when to fall back gracefully.","next":"other"},{"id":"mcp-dynamic-data-patterns#lead#0","hash":"f1f496f7ddc362c6","slug":"mcp-dynamic-data-patterns","kind":"lead","index":0,"role":"position","heading":null,"text":"Hardcoded data in MCP servers is a trap. It works until it doesn't—until someone adds a new action, renames a widget, or deprecates an integration, and suddenly your MCP server is lying to the AI. This post covers how to make MCP data dynamic, when it's worth the complexity, and how to do it efficiently.","next":"text"},{"id":"mcp-dynamic-data-patterns#section#5","hash":"7d277855f2106d66","slug":"mcp-dynamic-data-patterns","kind":"section","index":5,"role":"position","heading":"The Three-Tier Fallback","text":"Why this matters: The AI assistant always gets something. Degraded data is better than no data. Stale cache is better than embedded fallback. Fresh API data is best.","next":"heading"},{"id":"ema-workflow-rag-patterns#lead#0","hash":"eb45960fc7ea8a4e","slug":"ema-workflow-rag-patterns","kind":"lead","index":0,"role":"position","heading":null,"text":"A technical guide to controlling RAG flow in Ema workflows. Understanding trigger outputs, conversation handling, and query construction is the difference between a chatbot that retrieves relevant context and one that searches with noise. This guide demystifies the core concepts.","next":"text"},{"id":"ema-workflow-rag-patterns#section#1","hash":"09356c573abe6972","slug":"ema-workflow-rag-patterns","kind":"section","index":1,"role":"position","heading":"The Core Problem","text":"When building conversational AI workflows, you face a fundamental challenge: what text do you send to your knowledge search? Send the wrong thing, and your RAG retrieval returns irrelevant results. Send the right thing, and your AI Employee becomes remarkably accurate.","next":"p"},{"id":"ema-workflow-rag-patterns#section#2","hash":"f28ea0e7cffa4d23","slug":"ema-workflow-rag-patterns","kind":"section","index":2,"role":"position","heading":"Trigger Outputs Explained","text":"Every Ema workflow starts with a trigger node. The trigger provides several outputs that you can wire to downstream agents.","next":"heading"},{"id":"ema-workflow-rag-patterns#section#5","hash":"ff264e7724baaa9b","slug":"ema-workflow-rag-patterns","kind":"section","index":5,"role":"position","heading":"How Search Query Works","text":"When you connect something to search.query, that text becomes the semantic search query against your knowledge base.","next":"p"},{"id":"ema-workflow-rag-patterns#section#6","hash":"bb1a03d0650b4f0f","slug":"ema-workflow-rag-patterns","kind":"section","index":6,"role":"position","heading":"The Problem with Raw Conversation","text":"If you wire trigger.chat_conversation directly to search.query, you're sending the entire conversation history as your search text.","next":"p"},{"id":"ema-workflow-rag-patterns#section#7","hash":"8ca21cd6a1dfd8e9","slug":"ema-workflow-rag-patterns","kind":"section","index":7,"role":"list","heading":"Solution: conversation_summarizer","text":"The conversation_summarizer agent transforms messy conversation history into clean, search-optimized text.","next":"p"},{"id":"ema-workflow-rag-patterns#section#10","hash":"be081db4e31a5c65","slug":"ema-workflow-rag-patterns","kind":"section","index":10,"role":"position","heading":"additional_context: The Hidden Gem","text":"This is context you pass from outside when calling the persona via API. It's information your app knows that the user didn't explicitly say.","next":"heading"},{"id":"ema-workflow-rag-patterns#section#15","hash":"7411fe5502da8ac5","slug":"ema-workflow-rag-patterns","kind":"section","index":15,"role":"position","heading":"Better Query Tuning Patterns","text":"Sometimes conversation_summarizer with default settings isn't enough. Here are three patterns for more control.","next":"heading"},{"id":"ema-workflow-rag-patterns#section#21","hash":"3e37b8b933c249c2","slug":"ema-workflow-rag-patterns","kind":"section","index":21,"role":"position","heading":"The Explicit Approach: Extract Context","text":"Now you have structured data about conversation history that downstream agents can use precisely.","next":"other"},{"id":"ema-workflow-rag-patterns#section#24","hash":"fb9c79bec9cd5fda","slug":"ema-workflow-rag-patterns","kind":"section","index":24,"role":"position","heading":"By Pattern Complexity","text":"Start simple. Add complexity only when retrieval quality demands it.","next":"other"},{"id":"ema-workflow-rag-patterns#section#31","hash":"7a0d13293f47487a","slug":"ema-workflow-rag-patterns","kind":"section","index":31,"role":"position","heading":"Mistake 2: Ignoring additional_context","text":"If you control the integration, you have the power to pre-populate context. Use it!","next":"code"},{"id":"ema-workflow-rag-patterns#section#36","hash":"c0f9fe9996fff5a0","slug":"ema-workflow-rag-patterns","kind":"section","index":36,"role":"position","heading":"TL;DR","text":"Start simple: conversation_summarizer → knowledge_search Add complexity when: Retrieval quality suffers, or you need intent-specific search strategies.","next":"p"},{"id":"rules-on-rules#lead#0","hash":"db2be479be7e2dc7","slug":"rules-on-rules","kind":"lead","index":0,"role":"position","heading":null,"text":"Rules on rules on rules—stacks on stacks on stacks—but for your AI. It's the slightly silly phrase that ends up solving a very real problem: keeping AI output consistent across a codebase.","next":"text"},{"id":"rules-on-rules#section#1","hash":"043f418e3136643a","slug":"rules-on-rules","kind":"section","index":1,"role":"position","heading":"Why Cursor Rules matter","text":"Cursor Rules are how you stop the \"new prompt, new personality\" drift that happens when every developer asks the assistant a little differently. Rules turn implicit expectations into explicit guardrails.","next":"p"},{"id":"rules-on-rules#section#2","hash":"8d8b2798c6da05f6","slug":"rules-on-rules","kind":"section","index":2,"role":"position","heading":"The meta trick: a rule for writing rules","text":"The easiest way to keep rules from spiraling is to create a dedicated rule that only applies while editing .cursor/. Think of it as a lint rule for your AI.","next":"p"},{"id":"rules-on-rules#section#3","hash":"f1afb3f5dc8e42d1","slug":"rules-on-rules","kind":"section","index":3,"role":"position","heading":"A real example rule","text":"Here is the actual rule I use for writing rules. It's more comprehensive than a minimal example, but that's the point—it captures everything needed to keep rules consistent across a team.","next":"code"},{"id":"rules-on-rules#section#8","hash":"4200decb1c840f51","slug":"rules-on-rules","kind":"section","index":8,"role":"position","heading":"Quick FAQ","text":"Will this slow me down? No. It speeds you up because you stop re-explaining the same standards. Do I need one per repo? Yes. Rules are repository context. Even similar repos have different conventions.","next":"p"},{"id":"rules-on-rules#section#9","hash":"c1ee5584c4f977f6","slug":"rules-on-rules","kind":"section","index":9,"role":"position","heading":"Debugging Rule Application","text":"Rules only work if they're in context. When behavior doesn't match your rules, debug systematically.","next":"heading"},{"id":"rules-on-rules#section#15","hash":"aeb399898c0bf13f","slug":"rules-on-rules","kind":"section","index":15,"role":"position","heading":"Wrap-up: stack it, then ship","text":"Rules on rules on rules isn't just a joke. It's the shortest path to stable, predictable AI output in a team codebase. Add the rule-writing rule, keep rules small and scoped, and you'll stop fighting drift.","next":"p"},{"id":"goals-intents-outcomes#thesis#0","hash":"a41c04b2d42cec47","slug":"goals-intents-outcomes","kind":"thesis","index":0,"role":"position","heading":null,"text":"Design for intent, not implementation: define success at the user level first, then let each component do one thing well. The compiler wants valid types, the LLM plausible output, the API runtime safety and the user a working Voice AI; let the LLM understand what the user wants while templates supply a known-valid starting point.","next":"heading"},{"id":"goals-intents-outcomes#lead#0","hash":"810e50ea6d02531e","slug":"goals-intents-outcomes","kind":"lead","index":0,"role":"position","heading":null,"text":"How misaligned objectives between compilers, LLMs, and humans created 14 failures—and what we learned about designing for intent.","next":"text"},{"id":"goals-intents-outcomes#section#1","hash":"71ed322703aa605d","slug":"goals-intents-outcomes","kind":"section","index":1,"role":"setup","heading":"The Question Nobody Asked","text":"When we started building the persona generation system, we jumped straight to implementation. Parse the input. Build the spec. Compile to JSON. Deploy. We never stopped to ask: what is each component actually trying to accomplish?","next":"list"},{"id":"goals-intents-outcomes#section#3","hash":"1d1c2a6e635c5fbb","slug":"goals-intents-outcomes","kind":"section","index":3,"role":"list","heading":"The Compiler's Goal: Structural Validity","text":"The compiler has one job: ensure the output conforms to its type definitions.","next":"code"},{"id":"goals-intents-outcomes#section#4","hash":"ef4c6cbee190283f","slug":"goals-intents-outcomes","kind":"section","index":4,"role":"list","heading":"The API's Goal: Contract Enforcement","text":"The API has a different goal: reject anything that doesn't match its internal expectations.","next":"p"},{"id":"goals-intents-outcomes#section#5","hash":"ad9bc1096e610722","slug":"goals-intents-outcomes","kind":"section","index":5,"role":"position","heading":"The LLM's Goal: Pattern Completion","text":"When an LLM generates code or JSON, its goal is: produce output that looks like what it's seen before.","next":"p"},{"id":"goals-intents-outcomes#section#6","hash":"4af384d15a1b8ee1","slug":"goals-intents-outcomes","kind":"section","index":6,"role":"position","heading":"The User's Goal: Outcome Achievement","text":"The user doesn't care about any of this. Their goal: \"I want a working Voice AI that handles sales calls.\"","next":"p"},{"id":"goals-intents-outcomes#section#12","hash":"703d8ea4c620a403","slug":"goals-intents-outcomes","kind":"section","index":12,"role":"position","heading":"Intent vs. Implementation: The Core Problem","text":"Every failure shared a common pattern: the implementation was correct by its own definition, but incorrect by the user's definition.","next":"code"},{"id":"goals-intents-outcomes#section#18","hash":"1f4ecdbb3bc9c0e8","slug":"goals-intents-outcomes","kind":"section","index":18,"role":"position","heading":"The LLM's Role: Intent Interpretation, Not Structure Generation","text":"The key insight: LLMs are good at understanding intent, not at producing exact structures.","next":"heading"},{"id":"goals-intents-outcomes#section#19","hash":"a7ff83c3046b34e3","slug":"goals-intents-outcomes","kind":"section","index":19,"role":"position","heading":"Before: LLM Generates Structure","text":"Problem: The LLM is guessing at structure. It doesn't know the API contract.","next":"heading"},{"id":"goals-intents-outcomes#section#20","hash":"07ad1a98c3b5b5a8","slug":"goals-intents-outcomes","kind":"section","index":20,"role":"position","heading":"After: LLM Interprets Intent, Template Provides Structure","text":"Then: Merge these values into template's valid structure. The LLM produces semantic content. The template provides structural correctness. Each component does what it's good at.","next":"other"},{"id":"goals-intents-outcomes#section#21","hash":"8058fc231c7fd928","slug":"goals-intents-outcomes","kind":"section","index":21,"role":"position","heading":"Brownfield: Intent-Driven Transformation","text":"For existing personas, the LLM's role is different: understand what change the user wants, then apply it.","next":"heading"},{"id":"goals-intents-outcomes#section#22","hash":"cc7b4707713aa99a","slug":"goals-intents-outcomes","kind":"section","index":22,"role":"position","heading":"Before: Keyword Matching","text":"Problem: Brittle. \"Include a lookup step\" wouldn't match. Neither would \"add knowledge base retrieval.\"","next":"heading"},{"id":"goals-intents-outcomes#section#31","hash":"dba320d5281ceda7","slug":"goals-intents-outcomes","kind":"section","index":31,"role":"setup","heading":"1. Define success at the user level first","text":"Don't start with \"what does the compiler need?\" Start with \"what does the user need to see happen?\"","next":"heading"},{"id":"goals-intents-outcomes#section#32","hash":"2f91ca52133635a5","slug":"goals-intents-outcomes","kind":"section","index":32,"role":"position","heading":"2. Each component should have one goal","text":"If a component is trying to \"understand intent AND generate valid structure AND validate format,\" it will fail at something.","next":"heading"},{"id":"goals-intents-outcomes#section#33","hash":"6acca6f30aa76ef0","slug":"goals-intents-outcomes","kind":"section","index":33,"role":"position","heading":"3. LLMs interpret intent; templates provide structure","text":"Let each do what it's good at. LLMs understand \"sales AI\" → friendly greeting. Templates provide { name: \"conversationSettings\", type: 39 }.","next":"heading"},{"id":"goals-intents-outcomes#section#34","hash":"c65cfda40f98677a","slug":"goals-intents-outcomes","kind":"section","index":34,"role":"position","heading":"4. Validate at boundaries, not just at the end","text":"The API is the final validator. But if you only find errors there, you've lost all context about what went wrong and why.","next":"heading"},{"id":"goals-intents-outcomes#section#35","hash":"6d982b054b38dff2","slug":"goals-intents-outcomes","kind":"section","index":35,"role":"position","heading":"5. Goals conflict — design for the conflicts","text":"The compiler's goal (valid types) and the API's goal (valid runtime structure) are different. Acknowledge this. Build bridges between them.","next":"other"},{"id":"understanding-embeddings#lead#0","hash":"203654bcd8855eb0","slug":"understanding-embeddings","kind":"lead","index":0,"role":"position","heading":null,"text":"Embeddings are the foundation of semantic understanding in AI. They turn words, sentences, and documents into numbers that capture meaning. This post explains how they work, why they matter, and how to use them.","next":"text"},{"id":"understanding-embeddings#section#1","hash":"50230befc5cc51a1","slug":"understanding-embeddings","kind":"section","index":1,"role":"position","heading":"What Are Embeddings?","text":"An embedding is a vector representation of meaning. It converts text (or images, audio, etc.) into a list of numbers that captures semantic content.","next":"code"},{"id":"understanding-embeddings#section#2","hash":"27ac8086ff8bae95","slug":"understanding-embeddings","kind":"section","index":2,"role":"setup","heading":"Why Vectors?","text":"Why convert text to numbers? Because math works on numbers. With text: How similar are \"car\" and \"automobile\"?","next":"list"},{"id":"understanding-embeddings#section#6","hash":"2db58aba517bb107","slug":"understanding-embeddings","kind":"section","index":6,"role":"position","heading":"Visualizing Embeddings","text":"Embeddings exist in high-dimensional space (384+ dimensions), but we can project them to 2D for visualization.","next":"code"},{"id":"understanding-embeddings#section#7","hash":"7edc57c234e5379e","slug":"understanding-embeddings","kind":"section","index":7,"role":"list","heading":"Measuring Similarity","text":"The standard measure is cosine similarity—the cosine of the angle between vectors.","next":"code"},{"id":"understanding-embeddings#section#10","hash":"0ca07c00771d1bd2","slug":"understanding-embeddings","kind":"section","index":10,"role":"position","heading":"Evolution","text":"Word2Vec (2013): Word-level embeddings. \"bank\" has one vector regardless of context. GloVe (2014): Global statistics for better word representations.","next":"p"},{"id":"understanding-embeddings#section#11","hash":"f085774e4609d96a","slug":"understanding-embeddings","kind":"section","index":11,"role":"position","heading":"Current Options","text":"For client-side: all-MiniLM-L6-v2 balances size and quality. For server-side: Use larger models or APIs.","next":"other"},{"id":"understanding-embeddings#section#16","hash":"0300aecf8cb41dc6","slug":"understanding-embeddings","kind":"section","index":16,"role":"position","heading":"When to Generate Embeddings","text":"Embeddings can be generated at different points in your system's lifecycle. Each approach has trade-offs.","next":"heading"},{"id":"understanding-embeddings#section#17","hash":"2bc3d1bf9865b82d","slug":"understanding-embeddings","kind":"section","index":17,"role":"position","heading":"Build Time","text":"Generate embeddings during site/app build. Store as static files.","next":"code"},{"id":"understanding-embeddings#section#18","hash":"4fd31c8595d027ac","slug":"understanding-embeddings","kind":"section","index":18,"role":"position","heading":"Ingest Time","text":"Generate embeddings when content is added/updated. Store in database or vector store.","next":"code"},{"id":"understanding-embeddings#section#31","hash":"333c9809c49da3f7","slug":"understanding-embeddings","kind":"section","index":31,"role":"position","heading":"What Embeddings Don't Capture","text":"Negation: \"I love this\" and \"I don't love this\" may be similar (both about loving). Specificity: \"The meeting is at 3pm Tuesday\" loses the exact time in vector form.","next":"p"},{"id":"understanding-embeddings#section#32","hash":"2ca94ad68eb02de2","slug":"understanding-embeddings","kind":"section","index":32,"role":"position","heading":"Failure Modes","text":"Domain mismatch: General models may not understand specialized jargon. Short queries: Single words have less context for disambiguation.","next":"p"},{"id":"mcp-tool-design#lead#0","hash":"17ad21a9f05b018d","slug":"mcp-tool-design","kind":"lead","index":0,"role":"position","heading":null,"text":"What we learned restructuring an MCP server from 7 \"super tools\" to 20 focused operations.","next":"text"},{"id":"mcp-tool-design#section#1","hash":"6c0711ccc4a5c0f2","slug":"mcp-tool-design","kind":"section","index":1,"role":"position","heading":"The Clever Idea That Wasn't","text":"We built an MCP server for managing AI Employees on the Ema platform. It worked. Users could create personas, manage workflows, sync across environments. But something felt off.","next":"p"},{"id":"mcp-tool-design#section#7","hash":"aa14ff220a5d020f","slug":"mcp-tool-design","kind":"section","index":7,"role":"setup","heading":"Why Not Use Prompts?","text":"MCP has two mechanisms: Tools and Prompts. We initially thought prompts could help—maybe persona.create as a prompt guiding the creation flow?","next":"p"},{"id":"mcp-tool-design#section#11","hash":"430da38676be3871","slug":"mcp-tool-design","kind":"section","index":11,"role":"list","heading":"Principle 3: Flags for Common Combinations","text":"Users often want compound operations: \"clone with data AND sanitize.\"","next":"lead-in"},{"id":"mcp-tool-design#section#13","hash":"b62dff1e4eb85cee","slug":"mcp-tool-design","kind":"section","index":13,"role":"setup","heading":"Principle 5: Cross-Platform Compatibility","text":"We almost used dot notation (persona.data.upload). It's cleaner and the MCP spec allows it.","next":"lead-in"},{"id":"mcp-tool-design#section#16","hash":"caace0cde3c54f89","slug":"mcp-tool-design","kind":"section","index":16,"role":"position","heading":"After: 20 Focused Tools","text":"Each tool has 3-8 parameters. The LLM sees only what's relevant.","next":"other"},{"id":"mcp-tool-design#section#17","hash":"c5f32dbcef8a5ad6","slug":"mcp-tool-design","kind":"section","index":17,"role":"position","heading":"The Mental Model","text":"The user never sees tool names. The LLM is the interface. Design your tools for the LLM, and the LLM will serve the user.","next":"other"},{"id":"mcp-tool-design#section#20","hash":"9bb8ec84e50234a1","slug":"mcp-tool-design","kind":"section","index":20,"role":"position","heading":"References","text":"What patterns have you found for MCP tool design? We'd like to hear what's working.","next":null},{"id":"beyond-rules#lead#0","hash":"8c6f0ac26359ceea","slug":"beyond-rules","kind":"lead","index":0,"role":"position","heading":null,"text":"Rules are just the beginning. Cursor provides four artifact types—and using the wrong one creates friction. This post covers what rules can't do and when to reach for Commands, Agents, or Skills instead.","next":"text"},{"id":"beyond-rules#section#3","hash":"e3d9032e92dc2bc8","slug":"beyond-rules","kind":"section","index":3,"role":"position","heading":"Commands: Workflows, Not Context","text":"Commands are the most misunderstood artifact. They look like rules but serve a completely different purpose.","next":"heading"},{"id":"beyond-rules#section#4","hash":"fa241b6858ec0010","slug":"beyond-rules","kind":"section","index":4,"role":"position","heading":"Rules vs Commands","text":"Critical mistake: Don't put YAML frontmatter in commands. They're plain markdown with a specific structure.","next":"heading"},{"id":"beyond-rules#section#8","hash":"b8ca74ed9cfa6d83","slug":"beyond-rules","kind":"section","index":8,"role":"position","heading":"Agents (Subagents): Specialized Expertise","text":"Subagents are separate AI instances with isolated context. Think of them as specialist consultants you can spawn for specific tasks. The official Cursor documentation calls them \"subagents\" because they're delegated to by the main agent.","next":"heading"},{"id":"beyond-rules#section#9","hash":"1c08cfe62e24a95a","slug":"beyond-rules","kind":"section","index":9,"role":"position","heading":"Why Subagents Matter","text":"The main AI assistant is a generalist. It tries to be good at everything, which means it's not great at anything specific.","next":"lead-in"},{"id":"beyond-rules#section#10","hash":"c47e841682d67054","slug":"beyond-rules","kind":"section","index":10,"role":"position","heading":"Agent Structure","text":"Key insight: The entire agent prompt lives in the description field. When spawned, this becomes its system prompt.","next":"heading"},{"id":"beyond-rules#section#13","hash":"a6cb8779fd16baa2","slug":"beyond-rules","kind":"section","index":13,"role":"position","heading":"Skills: Portable Knowledge","text":"Skills are reusable capability packages that follow the Agent Skills open standard. Unlike rules (repo-specific) or agents (specialized personas), skills are portable knowledge modules that work across any compatible tool—Cursor, Claude Code, VS Code, Gemini CLI, and many others.","next":"heading"},{"id":"beyond-rules#section#21","hash":"96dd84d5c792fdfa","slug":"beyond-rules","kind":"section","index":21,"role":"position","heading":"Directory Structure","text":"Skills also work from .claude/skills/ and .codex/skills/ for cross-tool compatibility.","next":"other"},{"id":"intent-approaches#lead#0","hash":"6d18460c0151d6d5","slug":"intent-approaches","kind":"lead","index":0,"role":"position","heading":null,"text":"A technical comparison of intent understanding approaches—from simple keyword matching to LLM-powered reasoning. Each approach has trade-offs in speed, accuracy, complexity, and capability.","next":"text"},{"id":"intent-approaches#section#4","hash":"99d56eb9d14a9417","slug":"intent-approaches","kind":"section","index":4,"role":"position","heading":"Pre-LLM Approaches","text":"These approaches predate large language models (or don't require them).","next":"heading"},{"id":"intent-approaches#section#18","hash":"9701d83d455959a9","slug":"intent-approaches","kind":"section","index":18,"role":"position","heading":"Tradeoffs by Runtime","text":"Choose WASM when: Privacy matters, offline needed, acceptable cold start. Choose Remote when: Best model quality needed, no cold start tolerance, data isn't sensitive.","next":"p"},{"id":"agent-personas#lead#0","hash":"d0a3bd21c52205b5","slug":"agent-personas","kind":"lead","index":0,"role":"position","heading":null,"text":"\"You are a helpful AI assistant\" is the persona equivalent of \"write clean code.\" It says nothing actionable. This post shows how to design agent personas that produce consistent, high-quality output for specific tasks.","next":"text"},{"id":"agent-personas#section#3","hash":"8a6c6350d3415b57","slug":"agent-personas","kind":"section","index":3,"role":"position","heading":"Element 1: Role","text":"The role establishes identity and perspective. It's not a job title—it's a stance.","next":"p"},{"id":"agent-personas#section#5","hash":"7417abfe6c06b91a","slug":"agent-personas","kind":"section","index":5,"role":"position","heading":"Element 2: Expertise","text":"Expertise defines what the agent knows deeply. This isn't a list of buzzwords—it's specific, bounded knowledge.","next":"p"},{"id":"agent-personas#section#7","hash":"4672af0b23d59539","slug":"agent-personas","kind":"section","index":7,"role":"position","heading":"Element 3: Process","text":"Process is the step-by-step methodology. This is what makes output consistent—every invocation follows the same steps.","next":"p"},{"id":"agent-personas#section#9","hash":"6b58492b0720b4d4","slug":"agent-personas","kind":"section","index":9,"role":"position","heading":"Element 4: Output","text":"Output defines the exact format of what the agent produces. This is critical for consistency.","next":"p"},{"id":"agent-personas#section#11","hash":"41eed34268e00552","slug":"agent-personas","kind":"section","index":11,"role":"list","heading":"Element 5: Constraints","text":"Constraints are explicit boundaries—what the agent won't do, patterns it avoids, when it escalates.","next":"p"},{"id":"agent-personas#section#15","hash":"1631c8ecf7990a46","slug":"agent-personas","kind":"section","index":15,"role":"position","heading":"The Specialist","text":"Narrow expertise, deep knowledge. Best for focused analysis.","next":"code"},{"id":"agent-personas#section#16","hash":"f018cc6ce18008ec","slug":"agent-personas","kind":"section","index":16,"role":"position","heading":"The Generalist","text":"Broad knowledge, coordination role. Best for architecture and planning.","next":"code"},{"id":"agent-personas#section#17","hash":"886a86f4370c5d65","slug":"agent-personas","kind":"section","index":17,"role":"position","heading":"The Contrarian","text":"Challenges assumptions, finds flaws. Best before major decisions.","next":"code"},{"id":"agent-personas#section#18","hash":"59bf82204ed93135","slug":"agent-personas","kind":"section","index":18,"role":"position","heading":"The Producer","text":"Creates artifacts. Best for documentation, tests, content.","next":"code"},{"id":"agent-personas#section#19","hash":"857f61639b3054ac","slug":"agent-personas","kind":"section","index":19,"role":"position","heading":"The Investigator","text":"Gathers evidence, forms hypotheses. Best for debugging and research.","next":"code"},{"id":"agent-personas#section#22","hash":"5f25e1a2c9481353","slug":"agent-personas","kind":"section","index":22,"role":"position","heading":"1. Too Broad","text":"Fix: Pick one specialty per agent. Spawn multiple agents for multi-faceted tasks.","next":"heading"},{"id":"agent-personas#section#25","hash":"7417ccdcf29da4fe","slug":"agent-personas","kind":"section","index":25,"role":"position","heading":"4. Missing Constraints","text":"Fix: Define what it won't do, when it escalates, anti-patterns to avoid.","next":"heading"},{"id":"agent-personas#section#26","hash":"0e1f21393ed35138","slug":"agent-personas","kind":"section","index":26,"role":"position","heading":"5. Generic Role","text":"Fix: Give it a specific role with perspective and stance.","next":"other"},{"id":"ctx-pattern-coordination#thesis#0","hash":"b9b95daea78c4e61","slug":"ctx-pattern-coordination","kind":"thesis","index":0,"role":"position","heading":null,"text":"Agents can't remember and can't talk: each session starts with no memory of what happened before and no awareness of other agents on the same project. Give them a shared markdown file in the repo as the coordination protocol, with an ownership table, a status dashboard, locked decisions and a communication log that every agent reads before working and updates after. It survives session boundaries, humans can inspect it, and git versions every change; for most projects files are the protocol, not a database.","next":"other"},{"id":"ctx-pattern-coordination#lead#0","hash":"8fc36736fd61a23b","slug":"ctx-pattern-coordination","kind":"lead","index":0,"role":"position","heading":null,"text":"AI agents are amnesiacs with no social skills. Each session starts fresh—no memory of what happened before, no awareness of other agents working on the same project. We discovered that a simple markdown file creates a surprisingly effective coordination layer.","next":"text"},{"id":"ctx-pattern-coordination#section#2","hash":"837a914c28a8ff54","slug":"ctx-pattern-coordination","kind":"section","index":2,"role":"position","heading":"The Insight: Files Are the Protocol","text":"The solution was embarrassingly simple: a shared markdown file that serves as the coordination protocol. Not a database. Not an API. Not a vector store. Just a file in the repo that any agent can read and write.","next":"p"},{"id":"ctx-pattern-coordination#section#4","hash":"a51a52157498605a","slug":"ctx-pattern-coordination","kind":"section","index":4,"role":"position","heading":"1. Ownership Table","text":"Any agent can claim a phase by updating this table. Other agents see who owns what before starting work.","next":"heading"},{"id":"ctx-pattern-coordination#section#5","hash":"156fd1ca3723e5d3","slug":"ctx-pattern-coordination","kind":"section","index":5,"role":"position","heading":"2. Status Dashboard","text":"At a glance: what's done, what's in progress, what's blocked.","next":"heading"},{"id":"ctx-pattern-coordination#section#6","hash":"9e9d24db8a31bc75","slug":"ctx-pattern-coordination","kind":"section","index":6,"role":"position","heading":"3. Locked Decisions","text":"Once a decision is made, it's recorded. Future agents don't re-litigate.","next":"heading"},{"id":"ctx-pattern-coordination#section#7","hash":"f180dfc3c11ea746","slug":"ctx-pattern-coordination","kind":"section","index":7,"role":"position","heading":"4. Agent Communication Log","text":"This is the async conversation between agents. Each logs what they did, why, and what the next agent should know.","next":"other"},{"id":"ctx-pattern-coordination#section#15","hash":"8b2ec926881c831c","slug":"ctx-pattern-coordination","kind":"section","index":15,"role":"position","heading":"1. Agents Follow Protocol Reliably","text":"When you explicitly tell agents \"read this document before working, update it after,\" they do it. The structure (tables, headers, status icons) gives them clear patterns to follow.","next":"heading"},{"id":"ctx-pattern-coordination#section#18","hash":"da8acd464ddfff46","slug":"ctx-pattern-coordination","kind":"section","index":18,"role":"position","heading":"4. It Scales to Complex Dependencies","text":"The document captures blocking relationships explicitly. Agents know not to start Phase 4 until Phase 2 completes because the table says so.","next":"other"},{"id":"multi-agent-illusion#thesis#0","hash":"280fcd299f89be8c","slug":"multi-agent-illusion","kind":"thesis","index":0,"role":"position","heading":null,"text":"When you ask your IDE to have the security auditor review your code, you usually do not get a separate agent. Mentioning an agent applies a persona lens: the same model in the same context, shaped by the agent file's prompt. Handing a task to the Task tool spawns a true subagent, with its own isolated context. Both produce specialized behavior; the difference is context isolation, so know which one you are triggering.","next":"p"},{"id":"multi-agent-illusion#lead#0","hash":"1da41a816091651b","slug":"multi-agent-illusion","kind":"lead","index":0,"role":"position","heading":null,"text":"You ask your AI-powered IDE to \"have the security auditor review this code.\" A specialized agent springs into action—separate from the main assistant, purpose-built for security analysis. Right? The reality is more nuanced. There are actually two models for how \"agents\" work, and understanding both changes how you should design.","next":"text"},{"id":"multi-agent-illusion#section#4","hash":"faf87eb8c9b151aa","slug":"multi-agent-illusion","kind":"section","index":4,"role":"list","heading":"The \"Apply Lens\" Mechanism","text":"Both models use the same agent definition file, but apply it differently.","next":"lead-in"},{"id":"multi-agent-illusion#section#10","hash":"a29abb890a7715f9","slug":"multi-agent-illusion","kind":"section","index":10,"role":"position","heading":"The Mental Model Shift","text":"Both produce specialized behavior. The difference is context isolation.","next":"other"},{"id":"persona-lens-anatomy#lead#0","hash":"a750bf86ca4779f4","slug":"persona-lens-anatomy","kind":"lead","index":0,"role":"position","heading":null,"text":"A persona definition is a structured prompt that shapes how a single base model responds. Let's open one up and see exactly how it works—and why structure matters more than you'd expect.","next":"text"},{"id":"persona-lens-anatomy#section#1","hash":"4cc504766466c5d6","slug":"persona-lens-anatomy","kind":"section","index":1,"role":"position","heading":"What's in a Persona File","text":"A persona definition (what Cursor calls a \"subagent\") is a Markdown file containing structured sections.","next":"lead-in"},{"id":"persona-lens-anatomy#section#3","hash":"e078fd139ac7dd3a","slug":"persona-lens-anatomy","kind":"section","index":3,"role":"position","heading":"The Stateless Reality","text":"Here's a critical point: persona files are templates reapplied fresh each time.","next":"p"},{"id":"persona-lens-anatomy#section#4","hash":"85cbaeada74152ca","slug":"persona-lens-anatomy","kind":"section","index":4,"role":"position","heading":"Why Structure Matters","text":"Claude interprets persona files literally. Vague instructions produce vague results.","next":"lead-in"},{"id":"search-lab#lead#0","hash":"ed55702fdcb6cfea","slug":"search-lab","kind":"lead","index":0,"role":"position","heading":null,"text":"Nobody ever wanted search results. They wanted answers. But here's the thing—they didn't actually want answers either. They wanted action. This post traces the evolution from search to intent to action, and why the search box is a relic of a constraint that no longer exists.","next":"text"},{"id":"search-lab#section#1","hash":"c72f70ce448d820c","slug":"search-lab","kind":"section","index":1,"role":"position","heading":"The Evolution","text":"Each transition seemed transformative. But they were all just steps toward what users actually wanted from the beginning.","next":"other"},{"id":"search-lab#section#6","hash":"fc07a047a704ce33","slug":"search-lab","kind":"section","index":6,"role":"position","heading":"The Paradigm Shift","text":"Search: Burden on user. System is a librarian. Answers: Burden shared. System is an assistant. Action: Burden on system. System is an agent.","next":"other"},{"id":"persona-lens-design#lead#0","hash":"ad07f3191745fad3","slug":"persona-lens-design","kind":"lead","index":0,"role":"position","heading":null,"text":"Understanding that agents are persona lenses changes how you design routing, coordination, and expectations. This post covers practical patterns for building systems that work with this reality rather than against it.","next":"text"},{"id":"persona-lens-design#section#9","hash":"66258b082f08f48b","slug":"persona-lens-design","kind":"section","index":9,"role":"list","heading":"Multiple Personas (Parallel)","text":"Best when you need different perspectives on the same input.","next":"code"},{"id":"persona-lens-design#section#14","hash":"869441c23567215a","slug":"persona-lens-design","kind":"section","index":14,"role":"position","heading":"Anti-Pattern: The God Persona","text":"This defeats the purpose. A persona that does everything does nothing distinctly. Split into focused specialists and route between them.","next":"other"},{"id":"smart-routing#lead#0","hash":"341336e17010b227","slug":"smart-routing","kind":"lead","index":0,"role":"position","heading":null,"text":"Manually spawning agents doesn't scale. If you have 15 specialized agents but have to remember which one handles what, you'll just use the main assistant. This post shows how to route tasks to agents automatically based on patterns.","next":"text"},{"id":"smart-routing#section#2","hash":"d0a80c9acc32f65f","slug":"smart-routing","kind":"section","index":2,"role":"position","heading":"The Routing Rule","text":"Smart routing uses a rule that's always applied, teaching the main agent when to spawn specialists.","next":"code"},{"id":"compiler-to-llm-workflows#thesis#0","hash":"3d7bba3917d48890","slug":"compiler-to-llm-workflows","kind":"thesis","index":0,"role":"position","heading":null,"text":"Switching to an LLM-based workflow doesn't replace engineering discipline—it compresses iteration loops. From \"compile cycle\" to \"intent → generation → optimization → validation.\" And when you add config + rule-driven constraints, the quality jump is wild.","next":"other"},{"id":"compiler-to-llm-workflows#lead#0","hash":"14a169752468ad8e","slug":"compiler-to-llm-workflows","kind":"lead","index":0,"role":"position","heading":null,"text":"How intent-first development compressed our iteration loops—and why the quality surprised us more than the speed.","next":"text"},{"id":"compiler-to-llm-workflows#section#1","hash":"18bd3082519e410f","slug":"compiler-to-llm-workflows","kind":"section","index":1,"role":"position","heading":"The Old World","text":"You know the loop. You've lived it for years. Edit code. Run the compiler. See red. Fix the error. Run again. See different red. Fix that. Run again. Finally green—but now a test fails. Fix the test. Run the compiler again.","next":"p"},{"id":"compiler-to-llm-workflows#section#2","hash":"8e2e735919814536","slug":"compiler-to-llm-workflows","kind":"section","index":2,"role":"position","heading":"The Compiler Workflow: Why It's Great (and Where It Hurts)","text":"Let me be fair. Compilers are incredible. TypeScript's type checker catches entire categories of bugs before runtime. Rust's borrow checker prevents memory errors at compile time. Go's simplicity makes builds fast and predictable.","next":"p"},{"id":"compiler-to-llm-workflows#section#3","hash":"19d4d242b5fd2084","slug":"compiler-to-llm-workflows","kind":"section","index":3,"role":"position","heading":"The LLM Workflow: Intent-First Engineering","text":"Here's the shift. Instead of starting with code, start with intent.","next":"code"},{"id":"compiler-to-llm-workflows#section#4","hash":"c509c0da38f81152","slug":"compiler-to-llm-workflows","kind":"section","index":4,"role":"position","heading":"The \"Config + Text\" Unlock: Controlling the Output","text":"Here's what took me too long to understand: the real power isn't generation—it's guided optimization.","next":"p"},{"id":"compiler-to-llm-workflows#section#5","hash":"899297ff6f7415e9","slug":"compiler-to-llm-workflows","kind":"section","index":5,"role":"position","heading":"A Concrete Before/After: Persona Creation Flow","text":"We had a workflow generation system. The original approach: compile a workflow spec into JSON, deploy it to an API.","next":"p"},{"id":"compiler-to-llm-workflows#section#6","hash":"96820d23c83ae358","slug":"compiler-to-llm-workflows","kind":"section","index":6,"role":"position","heading":"The Moment It Got Astounding","text":"It wasn't just faster. The output got better every pass—and that part surprised me.","next":"p"},{"id":"compiler-to-llm-workflows#section#12","hash":"33f98338456966e1","slug":"compiler-to-llm-workflows","kind":"section","index":12,"role":"setup","heading":"The New Loop Is Addictive","text":"Compiler workflows are still essential. TypeScript isn't going anywhere. Neither is testing, or code review, or architectural discipline. But the day-to-day loop changes dramatically.","next":"p"},{"id":"autonomous-workflows#lead#0","hash":"692472273abaf61b","slug":"autonomous-workflows","kind":"lead","index":0,"role":"position","heading":null,"text":"Two problems: commands that duplicate work, and an AI that asks permission for everything. This post solves both—smart command orchestration that eliminates redundancy, and pre-authorized autonomous actions that let AI work without constant interruption.","next":"text"},{"id":"alwaysapply-tax#thesis#0","hash":"25665c50a055c5d4","slug":"alwaysapply-tax","kind":"thesis","index":0,"role":"position","heading":null,"text":"Every alwaysApply rule is paid for in every conversation, relevant or not. Always-on instructions cost tokens, compete for room in the context and degrade the model's attention on what matters, and their lines compound as they accumulate. Most of them should load on a glob or live in a skill: keep always-on only what affects every interaction, and budget the lines.","next":"p"},{"id":"alwaysapply-tax#lead#0","hash":"c014146ffe275cfd","slug":"alwaysapply-tax","kind":"lead","index":0,"role":"position","heading":null,"text":"We audited a mature Cursor configuration and found 22 rules with alwaysApply: true, totaling 2,700 lines loaded into every single conversation—including \"what's 2+2?\" This is the alwaysApply tax.","next":"text"},{"id":"alwaysapply-tax#section#14","hash":"9b3b184d26078a1f","slug":"alwaysapply-tax","kind":"section","index":14,"role":"setup","heading":"The Test","text":"Ask: \"If someone asks 'what's 2+2?', does this rule need to be loaded?\"","next":"list"},{"id":"alwaysapply-tax#section#32","hash":"d00f83996c3f5a8f","slug":"alwaysapply-tax","kind":"section","index":32,"role":"position","heading":"\"But I might need it!\"","text":"Response: That's what globs and skills are for. You'll still have the rule when relevant.","next":"heading"},{"id":"audit-ai-config#lead#0","hash":"dc347f02d681ec38","slug":"audit-ai-config","kind":"lead","index":0,"role":"position","heading":null,"text":"You've learned about rules vs skills, the alwaysApply tax, and discovery mechanics. Now what? This post provides a step-by-step audit process for cleaning up an existing AI configuration. The goal: fewer rules, faster responses, better AI behavior.","next":"text"},{"id":"audit-ai-config#section#1","hash":"e13be8ee564dc635","slug":"audit-ai-config","kind":"section","index":1,"role":"position","heading":"The Audit Framework","text":"Block an afternoon. You'll thank yourself later.","next":"other"},{"id":"rules-vs-skills#lead#0","hash":"773dfc99a1f0929d","slug":"rules-vs-skills","kind":"lead","index":0,"role":"position","heading":null,"text":"Rules and skills are both configuration artifacts, but they serve different purposes. Mixing them creates bloated rules that should be skills, or skills that are just reference material. Here's how to know which to use.","next":"text"},{"id":"rules-vs-skills#section#2","hash":"3f4edc29a135c231","slug":"rules-vs-skills","kind":"section","index":2,"role":"position","heading":"The Core Distinction","text":"Rules tell the AI what to notice. They're loaded into context automatically. Skills tell the AI what to do. They're invoked when needed.","next":"other"},{"id":"rules-vs-skills#section#3","hash":"c71e5a8fc6451bd5","slug":"rules-vs-skills","kind":"section","index":3,"role":"position","heading":"Rules: What and When","text":"Rules are passive reference material. The AI reads them and knows something—no action required.","next":"heading"},{"id":"rules-vs-skills#section#6","hash":"16b29f1bf6786d12","slug":"rules-vs-skills","kind":"section","index":6,"role":"position","heading":"Example Rule","text":"The AI reads this and knows the format. It doesn't need to do anything—the rule informs future decisions.","next":"other"},{"id":"rules-vs-skills#section#7","hash":"1e797f52649fe934","slug":"rules-vs-skills","kind":"section","index":7,"role":"position","heading":"Skills: How","text":"Skills are active workflows. The AI reads them and does something—multi-step procedures that produce results.","next":"heading"},{"id":"rules-vs-skills#section#10","hash":"c5f25bb13d3b98cd","slug":"rules-vs-skills","kind":"section","index":10,"role":"position","heading":"Example Skill","text":"This is a procedure. The AI follows steps and produces output.","next":"other"},{"id":"rules-vs-skills#section#14","hash":"bc610b7641c1e8d2","slug":"rules-vs-skills","kind":"section","index":14,"role":"position","heading":"Token Economics","text":"Context isn't free. Every line you load is attention you spend.","next":"heading"},{"id":"rules-vs-skills#section#16","hash":"2b3786458d5c7746","slug":"rules-vs-skills","kind":"section","index":16,"role":"position","heading":"Why This Matters","text":"A rule with alwaysApply: true loads in every conversation—even when someone asks \"what's 2+2?\" If you have 20 always-on rules averaging 100 lines each, that's 2,000 lines of context consumed before the conversation even starts.","next":"heading"},{"id":"rules-vs-skills#section#17","hash":"a070afc9b51c5e74","slug":"rules-vs-skills","kind":"section","index":17,"role":"position","heading":"Size Guidelines","text":"Skills only load when invoked. Rules load based on activation. Choose wisely.","next":"other"},{"id":"rules-vs-skills#section#19","hash":"e2509bb2ff242b06","slug":"rules-vs-skills","kind":"section","index":19,"role":"position","heading":"Why It's \"Soft\"","text":"Skills are discovered via description matching, not rule references. The rule text is a hint, not a command.","next":"code"},{"id":"rules-vs-skills#section#29","hash":"cbf5a2c9ee8c7453","slug":"rules-vs-skills","kind":"section","index":29,"role":"position","heading":"\"Rules can invoke skills\"","text":"Reality: Rules can mention skills. They cannot invoke them. The AI decides whether to use a skill based on description matching.","next":"heading"},{"id":"rules-vs-skills#section#30","hash":"a7f3c350a04fcbdd","slug":"rules-vs-skills","kind":"section","index":30,"role":"position","heading":"\"More rules = smarter AI\"","text":"Reality: More rules = more tokens = slower, more expensive, potentially confused AI. Quality over quantity.","next":"heading"},{"id":"rules-vs-skills#section#31","hash":"224fe0de04d24c81","slug":"rules-vs-skills","kind":"section","index":31,"role":"position","heading":"\"Skills need rules to be found\"","text":"Reality: Skills are found via description field matching. Rich descriptions > rule references.","next":"heading"},{"id":"rules-vs-skills#section#32","hash":"19a5c851706e2fae","slug":"rules-vs-skills","kind":"section","index":32,"role":"position","heading":"\"alwaysApply is the default\"","text":"Reality: alwaysApply should be exceptional. Most rules should use globs or rely on description-based activation.","next":"other"},{"id":"search-implementation-guide#lead#0","hash":"c39f5d0269b85f93","slug":"search-implementation-guide","kind":"lead","index":0,"role":"position","heading":null,"text":"A walkthrough of how this blog implements intent handling—what's built, what's working, and what's next. Spoiler: we're not as far along as the other posts might suggest.","next":"text"},{"id":"search-implementation-guide#section#3","hash":"9385aebc30f9d5e3","slug":"search-implementation-guide","kind":"section","index":3,"role":"list","heading":"1. Keyboard-Triggered Search Overlay","text":"Press ⌘K (Mac) or Ctrl+K (Windows) anywhere on the site.","next":"code"},{"id":"skill-discovery#lead#0","hash":"fb969f9422757205","slug":"skill-discovery","kind":"lead","index":0,"role":"position","heading":null,"text":"You created a custom skill. You tested it. It works when you invoke it directly. But when you describe what you want naturally, the AI ignores it. The skill exists—but it's invisible. Here's why.","next":"text"},{"id":"skill-discovery#section#1","hash":"b31835a51159667e","slug":"skill-discovery","kind":"section","index":1,"role":"position","heading":"Agent Skills: The Open Standard","text":"Before diving into discovery mechanics, understand what skills are: Agent Skills is an open standard for extending AI agents with specialized capabilities. Skills work across any compatible tool—Cursor, Claude Code, VS Code, Gemini CLI, Goose, and many others.","next":"p"},{"id":"skill-discovery#section#4","hash":"7e717e229af5992f","slug":"skill-discovery","kind":"section","index":4,"role":"position","heading":"How Discovery Actually Works","text":"When Cursor starts, it discovers skills from skill directories and presents them to the agent. The agent then decides when skills are relevant based on context.","next":"p"},{"id":"skill-discovery#section#5","hash":"dc97ccf113ed8309","slug":"skill-discovery","kind":"section","index":5,"role":"position","heading":"The Discovery Flow","text":"Skills can also be manually invoked by typing /skill-name in chat—this bypasses discovery and always works.","next":"other"},{"id":"skill-discovery#section#8","hash":"95629418f28b3f6c","slug":"skill-discovery","kind":"section","index":8,"role":"position","heading":"Real Example: The threat-model Skill","text":"The metadata.category field lets me organize my 39 global skills by purpose: workflow, planning, quality, etc.","next":"other"},{"id":"skill-discovery#section#9","hash":"59f135a7934f6155","slug":"skill-discovery","kind":"section","index":9,"role":"position","heading":"The Description Field: Make or Break","text":"The description field is the single most important part of your skill. It's how the agent decides whether your skill is relevant to what the user is asking.","next":"heading"},{"id":"skill-discovery#section#10","hash":"77e9a554e742d541","slug":"skill-discovery","kind":"section","index":10,"role":"position","heading":"Why Most Skills Are Invisible","text":"These descriptions don't match how users talk. When someone says \"set up my project,\" the agent can't connect that to \"CI/CD pipeline orchestration.\"","next":"heading"},{"id":"skill-discovery#section#13","hash":"3bee10f7992d81d0","slug":"skill-discovery","kind":"section","index":13,"role":"setup","heading":"Include Natural Language Triggers","text":"Users don't say \"invoke the threat modeling skill.\" They say \"what could go wrong with this?\" or \"is this secure?\"","next":"code"},{"id":"skill-discovery#section#14","hash":"00a244dea02721c0","slug":"skill-discovery","kind":"section","index":14,"role":"position","heading":"The compatibility Field","text":"The compatibility field documents environment requirements. The agent sees this and can warn users or adjust behavior.","next":"code"},{"id":"skill-discovery#section#15","hash":"e65dcbf2e8d6d1f2","slug":"skill-discovery","kind":"section","index":15,"role":"position","heading":"The metadata Field","text":"The metadata field is an arbitrary key-value mapping for additional information. The official spec doesn't prescribe what goes here—it's flexible.","next":"heading"},{"id":"skill-discovery#section#17","hash":"875ac97f6ad30823","slug":"skill-discovery","kind":"section","index":17,"role":"position","heading":"The disable-model-invocation Option","text":"By default, skills auto-apply when the agent determines they're relevant. Set disable-model-invocation: true to make a skill behave like a traditional slash command—only included when explicitly typed.","next":"code"},{"id":"skill-discovery#section#18","hash":"5ed26810c5a76cce","slug":"skill-discovery","kind":"section","index":18,"role":"position","heading":"Progressive Disclosure: Keep SKILL.md Lean","text":"The main SKILL.md should be under 500 lines. Every token competes for context space with conversation history, other skills, and user requests.","next":"heading"},{"id":"skill-discovery#section#19","hash":"671619940dd52271","slug":"skill-discovery","kind":"section","index":19,"role":"position","heading":"The Default Assumption","text":"The agent is already very smart. Only add context it doesn't already have.","next":"p"},{"id":"skill-discovery#section#21","hash":"efb3c55891753873","slug":"skill-discovery","kind":"section","index":21,"role":"position","heading":"Keep References One Level Deep","text":"Link directly from SKILL.md to reference files. Deeply nested references (references linking to other references) may result in partial reads.","next":"other"},{"id":"three-tier-context#thesis#0","hash":"30171c1e0e1ee9ac","slug":"three-tier-context","kind":"thesis","index":0,"role":"position","heading":null,"text":"AI-assisted development produces artifacts that did not exist before, such as insights, decisions, drafts and task coordination between sessions, and without a system they end up scattered, lost or committed when they shouldn't be. One question decides where each one lives: would losing this hurt if I cloned fresh? What you can rediscover goes in a gitignored .ctx/, decisions contributors need in a committed .meta/, and what users need in docs/; knowledge that earns it promotes upward, from insight to decision to doc to rule.","next":"other"},{"id":"three-tier-context#lead#0","hash":"1f68570eda89bc52","slug":"three-tier-context","kind":"lead","index":0,"role":"position","heading":null,"text":"AI-assisted development generates artifacts that didn't exist before: insights from debugging sessions, decisions made in conversation, draft content, task coordination. Without a system, these end up scattered, lost, or committed when they shouldn't be. Here's a framework for organizing AI-generated context.","next":"text"},{"id":"three-tier-context#section#16","hash":"f47988c48c4df8b9","slug":"three-tier-context","kind":"section","index":16,"role":"position","heading":"The Problem","text":"Old planning docs mixed with current ones confuse AI assistants. They treat archived plans as current instructions.","next":"heading"},{"id":"three-tier-context#section#27","hash":"59c014b0c009785b","slug":"three-tier-context","kind":"section","index":27,"role":"position","heading":"When Reading Archives","text":"Check for frontmatter status. If status: archived, do not follow as instructions.","next":"other"},{"id":"testing-artifacts#lead#0","hash":"b2d3e4a8a7bd4afe","slug":"testing-artifacts","kind":"lead","index":0,"role":"position","heading":null,"text":"Most teams create rules and commands but never verify they work. Then they're surprised when the AI ignores guidance or produces inconsistent output. This post introduces a testing framework for validating AI artifacts—structural, content, and behavioral tests.","next":"text"},{"id":"testing-artifacts#section#2","hash":"fefc9611f6f6a588","slug":"testing-artifacts","kind":"section","index":2,"role":"position","heading":"The Artifact Testing Pyramid","text":"Structural tests catch 80% of issues and are fully automated. Content tests verify quality and are mostly automated. Behavioral tests confirm actual guidance and require simulation.","next":"other"},{"id":"testing-artifacts#section#3","hash":"9b3cc13a3232777e","slug":"testing-artifacts","kind":"section","index":3,"role":"position","heading":"Structural Tests","text":"Structural tests verify the artifact is well-formed. These are fast, deterministic, and catch the most common errors.","next":"heading"},{"id":"testing-artifacts#section#11","hash":"7716e699aa5482db","slug":"testing-artifacts","kind":"section","index":11,"role":"position","heading":"Behavioral Tests (Golden Tests)","text":"Behavioral tests verify the artifact actually guides AI behavior correctly. These use \"golden\" input/output pairs.","next":"heading"},{"id":"compiler-vs-llm-orchestrated#lead#0","hash":"3230896e83061149","slug":"compiler-vs-llm-orchestrated","kind":"lead","index":0,"role":"position","heading":null,"text":"Why the same spec produces wildly different outputs—and how we fixed it after 14 API failures.","next":"text"},{"id":"compiler-vs-llm-orchestrated#section#1","hash":"050d35af40abe41a","slug":"compiler-vs-llm-orchestrated","kind":"section","index":1,"role":"list","heading":"The Setup: What We Were Building","text":"We needed to generate AI Employee configurations for the Ema platform.","next":"lead-in"},{"id":"compiler-vs-llm-orchestrated#section#3","hash":"e41a4197741ad4a7","slug":"compiler-vs-llm-orchestrated","kind":"section","index":3,"role":"position","heading":"Widget Format","text":"The config values must be nested under a key matching the widget's name field — not under a generic widget_config key.","next":"heading"},{"id":"compiler-vs-llm-orchestrated#section#4","hash":"cbcb4ff09c3c7508","slug":"compiler-vs-llm-orchestrated","kind":"section","index":4,"role":"position","heading":"Action Format","text":"Notice: namespaces must be [\"actions\", \"emainternal\"], not [\"search\", \"emainternal\"]. And version, displaySettings, typeArguments, tools are all required.","next":"other"},{"id":"compiler-vs-llm-orchestrated#section#6","hash":"f4c6732e8653bd40","slug":"compiler-vs-llm-orchestrated","kind":"section","index":6,"role":"position","heading":"How It Works","text":"The compiler is deterministic. Given the same WorkflowSpec, it always produces the same workflow_def and proto_config.","next":"heading"},{"id":"compiler-vs-llm-orchestrated#section#9","hash":"364a8ed462b93f4d","slug":"compiler-vs-llm-orchestrated","kind":"section","index":9,"role":"position","heading":"Why the Compiler Failed","text":"The compiler had outdated assumptions about the API contract. It was written when the API accepted widget_name + widget_config. The API changed. The compiler didn't.","next":"p"},{"id":"compiler-vs-llm-orchestrated#section#11","hash":"e5812388cd284313","slug":"compiler-vs-llm-orchestrated","kind":"section","index":11,"role":"position","heading":"Approach 1 Continued: The workflow_def Problem","text":"Fixing proto_config wasn't enough. The workflow itself had issues.","next":"heading"},{"id":"compiler-vs-llm-orchestrated#section#13","hash":"e54cc6e1e6d704d6","slug":"compiler-vs-llm-orchestrated","kind":"section","index":13,"role":"position","heading":"API Error","text":"No detail. Just 500.","next":"heading"},{"id":"compiler-vs-llm-orchestrated#section#23","hash":"37b8a5006fc789c4","slug":"compiler-vs-llm-orchestrated","kind":"section","index":23,"role":"position","heading":"The Brownfield Case: LLM-Native Transformation","text":"For existing personas, we need to modify workflows. This is where LLMs shine.","next":"heading"},{"id":"compiler-vs-llm-orchestrated#section#29","hash":"b8322db6edaaeb60","slug":"compiler-vs-llm-orchestrated","kind":"section","index":29,"role":"position","heading":"1. Compilers enforce their contract, not the target's","text":"The TypeScript compiler validated our code structure. It couldn't validate that [\"search\", \"emainternal\"] should be [\"actions\", \"emainternal\"]. That's a runtime contract the compiler knows nothing about.","next":"heading"},{"id":"compiler-vs-llm-orchestrated#section#30","hash":"256eb1e565d0550c","slug":"compiler-vs-llm-orchestrated","kind":"section","index":30,"role":"position","heading":"2. Templates are contracts made concrete","text":"Instead of reverse-engineering the API contract by trial and error, we used templates as a source of truth. If the template works, and we only add/modify values without changing structure, our output will work.","next":"heading"},{"id":"compiler-vs-llm-orchestrated#section#31","hash":"5347496de8380aff","slug":"compiler-vs-llm-orchestrated","kind":"section","index":31,"role":"position","heading":"3. Merge, don't replace","text":"The instinct was: \"Generate complete output, deploy it.\" The better approach: \"Get working structure, merge our changes into it.\"","next":"heading"},{"id":"compiler-vs-llm-orchestrated#section#32","hash":"d99bd4e1eb809747","slug":"compiler-vs-llm-orchestrated","kind":"section","index":32,"role":"position","heading":"4. LLMs excel at transformation, not generation from scratch","text":"Generating valid workflow_def from nothing required knowing every undocumented field. Transforming an existing valid workflow_def? The LLM just needs to understand the changes.","next":"heading"},{"id":"compiler-vs-llm-orchestrated#section#34","hash":"d9730e73e5b55bff","slug":"compiler-vs-llm-orchestrated","kind":"section","index":34,"role":"position","heading":"The Architecture That Worked","text":"The compiler still exists. It handles WorkflowSpec → workflow_def conversion. But it no longer runs in isolation. It's part of a pipeline where valid structure comes from templates/existing data, and the compiler's job is format conversion — not structure invention.","next":"other"},{"id":"subagents-fresh-context#lead#0","hash":"0dfdd41a4f2826f6","slug":"subagents-fresh-context","kind":"lead","index":0,"role":"position","heading":null,"text":"The main AI assistant has been helping you for an hour. It's seen every file you've opened, every failed attempt, every tangent. Now you need a fresh perspective—someone who hasn't been marinating in your assumptions. That's what subagents provide: clean context on demand.","next":"text"},{"id":"subagents-fresh-context#section#1","hash":"6b5f6dbd9f325101","slug":"subagents-fresh-context","kind":"section","index":1,"role":"position","heading":"What Subagents Actually Are","text":"Subagents are separate AI instances that Cursor's main agent can delegate to. Each subagent operates in its own context window, handles specific work, and returns results to the parent.","next":"p"},{"id":"subagents-fresh-context#section#10","hash":"7c1d2203220fe00d","slug":"subagents-fresh-context","kind":"section","index":10,"role":"position","heading":"The Verification Pattern","text":"A verification subagent independently validates whether claimed work was actually completed. This addresses a common issue: AI marks tasks as done but implementations are incomplete.","next":"heading"},{"id":"subagents-fresh-context#section#14","hash":"68471c37aed8f822","slug":"subagents-fresh-context","kind":"section","index":14,"role":"position","heading":"The Security Audit Pattern","text":"Security reviews benefit enormously from fresh context. A subagent that hasn't seen the implementation's evolution can spot issues that familiarity obscures.","next":"heading"},{"id":"subagents-fresh-context#section#16","hash":"e7ab4b3777688417","slug":"subagents-fresh-context","kind":"section","index":16,"role":"position","heading":"The Meta-Analysis Pattern","text":"A subagent that analyzes your conversations to improve your rules, skills, and agents themselves.","next":"heading"},{"id":"subagents-fresh-context#section#23","hash":"7000933d0dc4603c","slug":"subagents-fresh-context","kind":"section","index":23,"role":"position","heading":"Background for Long Tasks","text":"Background subagents write their state as they run. You can check progress or resume later.","next":"heading"},{"id":"subagents-fresh-context#section#25","hash":"17ae6b5cae59fd0c","slug":"subagents-fresh-context","kind":"section","index":25,"role":"position","heading":"When to Use Subagents vs Skills","text":"Quick test: If you're creating something for a simple, single-purpose task like \"generate a changelog\" or \"format imports,\" use a skill instead.","next":"other"},{"id":"subagents-fresh-context#section#29","hash":"42cfc38221e8cdc7","slug":"subagents-fresh-context","kind":"section","index":29,"role":"position","heading":"Performance Considerations","text":"Key insight: Subagents shine for complex, long-running, or parallel work. For quick tasks, the main agent is often faster.","next":"other"},{"id":"meta-learning#lead#0","hash":"63eefb90b3bce83b","slug":"meta-learning","kind":"lead","index":0,"role":"position","heading":null,"text":"What if your AI development system got better automatically? Not through manual rule-writing, but by observing how you work and proposing improvements. This post shows how to build feedback loops that learn from real usage.","next":"text"},{"id":"meta-learning#section#1","hash":"f8022a3653ed4210","slug":"meta-learning","kind":"section","index":1,"role":"position","heading":"The Learning Loop","text":"Most AI customization is reactive: something goes wrong, you add a rule. The meta-learning system inverts this—it proactively observes usage and suggests improvements.","next":"code"},{"id":"search-performance#lead#0","hash":"b8466f5c3597f949","slug":"search-performance","kind":"lead","index":0,"role":"position","heading":null,"text":"A deep dive into the performance characteristics of different search approaches—model sizes, cold starts, query latency, and cost.","next":"text"},{"id":"search-performance#section#2","hash":"af9b4f034a203ea2","slug":"search-performance","kind":"section","index":2,"role":"position","heading":"Performance Comparison","text":"The demo above focuses on answer quality. This section compares performance characteristics — startup time, query latency, and cost.","next":"other"},{"id":"search-performance#section#10","hash":"ba9c55d1d303d226","slug":"search-performance","kind":"section","index":10,"role":"list","heading":"The Crossover Point: Local vs Remote","text":"The key insight: Local WASM has upfront cost, Remote has per-query cost.","next":"code"},{"id":"search-performance#section#17","hash":"632928fd31c681ac","slug":"search-performance","kind":"section","index":17,"role":"position","heading":"Key Takeaways","text":"The best search isn't the most sophisticated—it's the one that fits your constraints.","next":"other"},{"id":"ema-entity-extraction#lead#0","hash":"9044ce33edbf1a24","slug":"ema-entity-extraction","kind":"lead","index":0,"role":"position","heading":null,"text":"Entity extraction is one of the most powerful tools in Ema workflows—and one of the most misunderstood. This deep dive covers schemas, instructions, output handling, and the gotchas that trip up even experienced builders.","next":"text"},{"id":"ema-entity-extraction#section#1","hash":"9f119b77f855162f","slug":"ema-entity-extraction","kind":"section","index":1,"role":"position","heading":"What is Entity Extraction?","text":"Entity extraction is a structured data extractor—it takes unstructured text (conversations, documents) and pulls out specific fields you define.","next":"p"},{"id":"ema-entity-extraction#section#5","hash":"805b466ae6096c70","slug":"ema-entity-extraction","kind":"section","index":5,"role":"position","heading":"Writing Good Extraction Instructions","text":"The instructions field tells the LLM how to extract. This is where most mistakes happen.","next":"heading"},{"id":"ema-entity-extraction#section#12","hash":"b8b3a8293c5c77fd","slug":"ema-entity-extraction","kind":"section","index":12,"role":"setup","heading":"Entity Extraction vs call_llm JSON","text":"Both can extract structured data. When to use which?","next":"table"},{"id":"ema-entity-extraction#section#26","hash":"a420b64f968c9dde","slug":"ema-entity-extraction","kind":"section","index":26,"role":"position","heading":"Problem: Extraction Returns Null for Known Values","text":"Symptoms: User clearly stated their name, but caller_name is null. Diagnosis: Instructions only look at current message.","next":"p"},{"id":"ema-entity-extraction#section#27","hash":"c3be984028be6c3c","slug":"ema-entity-extraction","kind":"section","index":27,"role":"position","heading":"Problem: Enum Field Has Unexpected Value","text":"Symptoms: caller_type should be \"advisor\" or \"client\" but returns \"financial professional\". Diagnosis: LLM is paraphrasing instead of using enum values.","next":"p"},{"id":"ema-entity-extraction#section#28","hash":"d20d26798ce71c96","slug":"ema-entity-extraction","kind":"section","index":28,"role":"position","heading":"Problem: Can't Wire extraction_columns to Node Input","text":"Symptoms: Trying to connect email value to send_email node fails. Diagnosis: Can't index into blob directly.","next":"p"},{"id":"ema-entity-extraction#section#29","hash":"b6a8c6c7c63b90a2","slug":"ema-entity-extraction","kind":"section","index":29,"role":"position","heading":"Problem: Extraction Works Once but Fails on Follow-Up","text":"Symptoms: First extraction is correct, subsequent turns return nulls. Diagnosis: Each turn is stateless—need to re-extract from history.","next":"p"},{"id":"ema-entity-extraction#section#30","hash":"55d131e91ddd4f81","slug":"ema-entity-extraction","kind":"section","index":30,"role":"position","heading":"Problem: Corrections Not Being Applied","text":"Symptoms: User says \"Actually, use mike@corp.com instead\" but old email persists. Diagnosis: No correction handling in instructions.","next":"p"},{"id":"ema-entity-extraction#section#32","hash":"926fa7a439e9cbe9","slug":"ema-entity-extraction","kind":"section","index":32,"role":"position","heading":"Summary","text":"Entity extraction is your structured data powerhouse. Use it when you need reliable, typed field extraction. Just remember: the output is a blob, so plan your wiring accordingly.","next":"other"},{"id":"rule-conflicts#lead#0","hash":"01f82fe7f74cf731","slug":"rule-conflicts","kind":"lead","index":0,"role":"position","heading":null,"text":"How to find the conflicts, stop the chaos, and get your AI following instructions again. Your AI is ignoring your rules. You've checked the syntax. You've verified the globs. The file is right there. But it keeps doing the wrong thing. Here's what's probably happening: you have two rules that disagree, and the AI is picking one arbitrarily. You're not crazy. Your rules are fighting each other. This post shows you how to find the fights, declare a winner, and prevent future conflicts.","next":"text"},{"id":"rule-conflicts#section#3","hash":"228aadb94df777b1","slug":"rule-conflicts","kind":"section","index":3,"role":"list","heading":"2. Implicit Contradiction","text":"Rules that don't directly conflict but pull in opposite directions.","next":"code"},{"id":"rule-conflicts#section#4","hash":"8e97e8a54f74d93f","slug":"rule-conflicts","kind":"section","index":4,"role":"list","heading":"3. Priority Ambiguity","text":"Two rules at the same priority level with different instructions.","next":"code"},{"id":"rule-conflicts#section#20","hash":"c9e81fd9d66df64f","slug":"rule-conflicts","kind":"section","index":20,"role":"position","heading":"\"Base says X, project says Y\"","text":"Shared base rules don't fit your project. Classic.","next":"code"},{"id":"rule-conflicts#section#21","hash":"154129d226d5b1c9","slug":"rule-conflicts","kind":"section","index":21,"role":"position","heading":"\"TypeScript says X, React says Y\"","text":"Language conventions vs framework conventions. Both have good reasons.","next":"code"},{"id":"rule-conflicts#section#22","hash":"fb281a250367db51","slug":"rule-conflicts","kind":"section","index":22,"role":"position","heading":"\"Move fast\" vs \"Don't break things\"","text":"Your velocity rules fight your quality rules. Tale as old as time.","next":"code"},{"id":"rule-conflicts#section#26","hash":"7aee9d327372e95e","slug":"rule-conflicts","kind":"section","index":26,"role":"position","heading":"Keep Going","text":"Rule conflicts mean your system is growing. That's not a problem—it's a sign you're doing something worth organizing. The goal isn't zero conflicts. It's knowing how to fix them fast.","next":null},{"id":"ema-routing-branching#lead#0","hash":"154d0d9e2b8ee194","slug":"ema-routing-branching","kind":"lead","index":0,"role":"position","heading":null,"text":"How do you make an Ema workflow take different paths based on user intent? This guide covers chat_categorizer, runIf conditions, and the patterns that keep your branching logic clean and maintainable.","next":"text"},{"id":"ema-routing-branching#section#15","hash":"892e12357d3e3637","slug":"ema-routing-branching","kind":"section","index":15,"role":"position","heading":"✅ Clean: Single entry point + dependencies","text":"How it works: If email_flow_start doesn't run, downstream nodes never get their inputs and automatically don't run.","next":"other"},{"id":"ema-routing-branching#section#18","hash":"585b9330b5864737","slug":"ema-routing-branching","kind":"section","index":18,"role":"list","heading":"WORKFLOW_OUTPUT: The Terminal Point","text":"Every path must lead to WORKFLOW_OUTPUT—this is what the user sees/hears.","next":"code"},{"id":"ema-routing-branching#section#21","hash":"4b9868af3a4175c1","slug":"ema-routing-branching","kind":"section","index":21,"role":"position","heading":"Pattern 2: Intent + Entity-Based Routing","text":"Best for: When routing depends on extracted data (has email, confirmed, etc.).","next":"heading"},{"id":"ema-routing-branching#section#23","hash":"db6123913050c5ed","slug":"ema-routing-branching","kind":"section","index":23,"role":"position","heading":"Pattern 4: Confirmation Flow","text":"Best for: Destructive or important actions that need user approval.","next":"other"},{"id":"ema-routing-branching#section#25","hash":"f14d28808316407f","slug":"ema-routing-branching","kind":"section","index":25,"role":"position","heading":"Problem: Node Runs When It Shouldn't","text":"Symptoms: Agent runs even when intent doesn't match. Diagnosis: Missing runIf, or receives from always-running node.","next":"p"},{"id":"ema-routing-branching#section#26","hash":"3f4a24e3b77578ba","slug":"ema-routing-branching","kind":"section","index":26,"role":"position","heading":"Problem: Node Never Runs","text":"Symptoms: Node should run but never executes. Diagnosis: Check upstream dependencies.","next":"p"},{"id":"ema-routing-branching#section#27","hash":"6dde4354a318ab11","slug":"ema-routing-branching","kind":"section","index":27,"role":"position","heading":"Problem: Categorizer Returns Wrong Category","text":"Symptoms: \"PORTFOLIO_REVIEW\" request categorized as \"Fallback\". Diagnosis: Category descriptions may be too narrow.","next":"p"},{"id":"ema-routing-branching#section#28","hash":"f4101e949bcbd350","slug":"ema-routing-branching","kind":"section","index":28,"role":"position","heading":"Problem: Can't Route Based on Entity Values","text":"Symptoms: Want to route based on needs_email: true but can't use in runIf. Diagnosis: runIf can't evaluate JSON blob fields directly.","next":"p"},{"id":"ema-routing-branching#section#29","hash":"4f454b41d33c0281","slug":"ema-routing-branching","kind":"section","index":29,"role":"position","heading":"Problem: Multiple Agents Run When Only One Should","text":"Symptoms: Both portfolio_agent and compliance_agent run. Diagnosis: Categories might overlap, or multiple conditions are true.","next":"p"},{"id":"ema-routing-branching#section#31","hash":"dc939a56f5e7f51b","slug":"ema-routing-branching","kind":"section","index":31,"role":"position","heading":"Summary","text":"The golden rule: Use chat_categorizer for intent, combine with entity extraction for state, and let data dependencies reduce boilerplate.","next":"other"},{"id":"adaptive-rules-engine#lead#0","hash":"5b093bcdce9471b4","slug":"adaptive-rules-engine","kind":"lead","index":0,"role":"position","heading":null,"text":"Your project uses React 18, Vite, Vitest, and Tailwind. But your rules mention Jest patterns, CSS modules conventions, and generic \"component\" guidance that doesn't account for React's concurrent features. The rules were written for a TypeScript project. Not your TypeScript project. So you edit. You prune. You customize. Then you add Playwright. Or upgrade to TypeScript 5.4. Or switch from React Query to TanStack Query. Your rules become stale again. You're now maintaining two things: your codebase and the rules that describe it.","next":"p"},{"id":"adaptive-rules-engine#section#1","hash":"19d2841a794c5ed8","slug":"adaptive-rules-engine","kind":"section","index":1,"role":"position","heading":"The Problem Today","text":"The radar shows the mismatch at a glance. The orange curve is what your stack actually needs; the blue curve is what your rules currently cover.","next":"list"},{"id":"adaptive-rules-engine#section#2","hash":"d16a7c2b508b0d80","slug":"adaptive-rules-engine","kind":"section","index":2,"role":"position","heading":"The Three Phases","text":"Adaptive rule generation has three stages: detect what you're working with, generate rules that fit, and validate that nothing conflicts.","next":"code"},{"id":"adaptive-rules-engine#section#3","hash":"0e274115598720cd","slug":"adaptive-rules-engine","kind":"section","index":3,"role":"position","heading":"Phase 1: Detect","text":"Before generating anything, you need to know what's in the repo. This isn't magic—it's reading configuration files systematically.","next":"table"},{"id":"adaptive-rules-engine#section#4","hash":"0a489924decfe49d","slug":"adaptive-rules-engine","kind":"section","index":4,"role":"list","heading":"Phase 2: Generate","text":"With the stack profile in hand, generation becomes conditional selection plus augmentation.","next":"code"},{"id":"adaptive-rules-engine#section#7","hash":"75ec881f81db2b33","slug":"adaptive-rules-engine","kind":"section","index":7,"role":"position","heading":"The Counterargument: Why Not Just Write Rules Once?","text":"Fair question. Manual rules work fine for small, stable projects.","next":"lead-in"},{"id":"adaptive-rules-engine#section#11","hash":"5716fe6051dd211b","slug":"adaptive-rules-engine","kind":"section","index":11,"role":"position","heading":"Keep Going","text":"The best rules are the ones you don't have to write twice. Adaptive generation isn't about removing humans from the loop—it's about removing the tedious parts so humans can focus on the decisions that matter.","next":null},{"id":"ai-dev-toolkit-2026#lead#0","hash":"3bd3125ff11a4e42","slug":"ai-dev-toolkit-2026","kind":"lead","index":0,"role":"position","heading":null,"text":"The stack has settled. After two years of fragmentation—competing frameworks, overlapping tools, weekly \"this changes everything\" posts—three layers emerged. Most developers use one. Some use two. The real leverage is in how they compose.","next":"text"},{"id":"ai-dev-toolkit-2026#section#1","hash":"1af032026b5693f8","slug":"ai-dev-toolkit-2026","kind":"section","index":1,"role":"position","heading":"Layer 1: The AI-Native Development Environment","text":"Cursor, Claude Code, Warp, Windsurf—the specific tool matters less than the category. Some are graphical editors. Some are terminal-first. Claude Code runs entirely in your shell. Warp blends terminal and AI natively. The form factor varies, but the capability converges: an AI reasoning engine with access to your codebase, your conventions, and your intent.","next":"p"},{"id":"ai-dev-toolkit-2026#section#2","hash":"c49d79b3c7f7bae3","slug":"ai-dev-toolkit-2026","kind":"section","index":2,"role":"position","heading":"Layer 2: The Capability Protocol","text":"MCP bridges the gap between IDE reasoning and the systems that matter.","next":"p"},{"id":"ai-dev-toolkit-2026#section#3","hash":"93435080af82a3c0","slug":"ai-dev-toolkit-2026","kind":"section","index":3,"role":"position","heading":"Layer 3: The Enterprise Execution Platform","text":"The IDE reasons. The protocol connects. But neither one runs production workflows. AI Employees—platform-managed agents with defined roles, permissions, and oversight—handle what the IDE and protocol can't. Workflow orchestration across multiple models. State that persists across conversations and sessions. Human-in-the-loop checkpoints at critical decision points. Audit trails that satisfy compliance teams. Routing logic that sends each task to the right model at the right cost.","next":"p"},{"id":"ai-dev-toolkit-2026#section#4","hash":"4668d28cfe5da435","slug":"ai-dev-toolkit-2026","kind":"section","index":4,"role":"position","heading":"How They Compose","text":"The real power isn't in any single layer. It's in the flow between them.","next":"code"},{"id":"ai-dev-toolkit-2026#section#6","hash":"45f735c9c734efa6","slug":"ai-dev-toolkit-2026","kind":"section","index":6,"role":"position","heading":"Common Mistakes","text":"These patterns keep showing up. Every one of them burns time. Putting platform logic in Cursor rules. Rules are for conventions and guardrails—not for encoding workflow orchestration, routing logic, or compliance requirements. When you find yourself writing rules that describe how production workflows should behave, you've outgrown the IDE layer. Move that logic to the platform where it can be versioned, governed, and audited.","next":"p"},{"id":"ai-dev-toolkit-2026#section#7","hash":"0f9851fcae9329b7","slug":"ai-dev-toolkit-2026","kind":"section","index":7,"role":"position","heading":"Where This Is Heading","text":"The three-layer model isn't the end state. It's the foundation. As interfaces shift from human-mediated to machine-discoverable, the boundaries between these layers will get more interesting. The protocol layer will grow richer semantics. The platform layer will expose more capabilities directly to IDE agents. The IDE layer will get better at orchestrating across both. But the principle holds: reasoning, discovery, and execution are different problems that need different solutions. Collapsing them into one layer is the mistake that created the fragmentation we just spent two years sorting out.","next":"p"},{"id":"interfaces-are-changing#thesis#0","hash":"2f75676efc8d46ff","slug":"interfaces-are-changing","kind":"thesis","index":0,"role":"position","heading":null,"text":"The shift from static, documentation-mediated contracts to discoverable, self-describing, agent-negotiable interfaces is the most consequential change in systems integration since REST. It changes who builds integrations, how capabilities are exposed, and what \"interface design\" means.","next":"other"},{"id":"interfaces-are-changing#lead#0","hash":"ee27e3d1331afe40","slug":"interfaces-are-changing","kind":"lead","index":0,"role":"position","heading":null,"text":"For fifty years, every interface assumed a human would read the docs, write the glue code, and maintain the integration. That assumption just broke. The consumer of your next interface is as likely to be an LLM as a developer.","next":"text"},{"id":"interfaces-are-changing#section#1","hash":"53064917c2c1be54","slug":"interfaces-are-changing","kind":"section","index":1,"role":"position","heading":"The Historical Arc","text":"Interfaces have evolved through distinct eras, each expanding the consumer set and reducing the integration cost.","next":"code"},{"id":"interfaces-are-changing#section#2","hash":"d2cd7512b52ac58e","slug":"interfaces-are-changing","kind":"section","index":2,"role":"position","heading":"The Key Shift","text":"Every previous interface paradigm assumed a human intermediary. Somebody had to read the documentation, understand the contract, write integration code, and maintain it when either side changed. Interfaces were consumed through human comprehension.","next":"p"},{"id":"interfaces-are-changing#section#3","hash":"e9b5b5a9d62597ea","slug":"interfaces-are-changing","kind":"section","index":3,"role":"position","heading":"Old vs. New: Redefining \"Interface\"","text":"Old definition: An interface is a contract between a producer and a known set of consumers, mediated by documentation and code. New definition: An interface is a discoverable capability surface that any agent — human, AI, or software — can negotiate with at runtime, mediated by semantic descriptions and schemas.","next":"p"},{"id":"interfaces-are-changing#section#4","hash":"ec957ce4e3576daa","slug":"interfaces-are-changing","kind":"section","index":4,"role":"position","heading":"Real Example: How We Use This Today","text":"This isn't theoretical. At Ema, we expose the full AI Employee platform through MCP — 6 tools, 35+ resources, and 17 prompts covering the complete lifecycle from creation to deployment to monitoring.","next":"p"},{"id":"interfaces-are-changing#section#6","hash":"224e7b263b8e50bd","slug":"interfaces-are-changing","kind":"section","index":6,"role":"position","heading":"The Counterargument","text":"The skeptic's response: \"This is just another integration standard. CORBA, SOAP, GraphQL — we've seen this cycle before. MCP will be replaced in three years.\"","next":"p"},{"id":"what-is-agentic-thinking#thesis#0","hash":"90837b0e644a8587","slug":"what-is-agentic-thinking","kind":"thesis","index":0,"role":"position","heading":null,"text":"Agentic thinking is the discipline of designing systems, workflows, and organizations around AI that acts, not AI that answers. Copilots suggest; agents write, test, debug and commit, and the human goes from operator to orchestrator, defining intent, setting constraints and reviewing output. The shift is in the mental model, not the technology: treat AI as a participant you orchestrate rather than a tool you wield, and be precise about what and flexible about how.","next":"p"},{"id":"what-is-agentic-thinking#lead#0","hash":"17455ac2f51a2973","slug":"what-is-agentic-thinking","kind":"lead","index":0,"role":"position","heading":null,"text":"A practitioner's notebook for building with AI that acts—not AI that answers.","next":"text"},{"id":"what-is-agentic-thinking#section#1","hash":"5669381fc3bdd264","slug":"what-is-agentic-thinking","kind":"section","index":1,"role":"position","heading":"How We Got Here","text":"If you're new to agentic AI, Agentic AI: Beyond the Chatbot is the primer—it covers what makes AI \"agentic,\" how it compares to chatbots and copilots, and what it means for enterprise. This section picks up where that primer leaves off.","next":"p"},{"id":"what-is-agentic-thinking#section#2","hash":"5acb4ea960dfabe9","slug":"what-is-agentic-thinking","kind":"section","index":2,"role":"position","heading":"The Mental Model Shift","text":"For decades, we thought about software tools the same way: you learn the interface, you operate the tool, you get a result. The human drives. The tool executes. Every editor, every terminal, every dashboard reinforced the same assumption—a human is in the loop, making every decision, writing every line.","next":"p"},{"id":"what-is-agentic-thinking#section#3","hash":"82dafaa1c5cfe7b2","slug":"what-is-agentic-thinking","kind":"section","index":3,"role":"position","heading":"Intent Over Implementation","text":"The hardest habit to break is telling the AI how to do something. We spent careers learning to think in implementation: data structures, algorithms, API calls, error handling. That specificity was the whole job. But when you're orchestrating agents, over-specifying implementation is counterproductive. You end up micromanaging a system that's better at generating code than you are at dictating it.","next":"p"},{"id":"what-is-agentic-thinking#section#4","hash":"5f01530fc295df82","slug":"what-is-agentic-thinking","kind":"section","index":4,"role":"position","heading":"The Toolkit: Three Layers That Compose","text":"The practical side of agentic thinking centers on three layers. I wrote a full breakdown in The AI Dev Toolkit in 2026, but here's the essential picture.","next":"p"},{"id":"what-is-agentic-thinking#section#5","hash":"fd03e1f1216cb1d3","slug":"what-is-agentic-thinking","kind":"section","index":5,"role":"position","heading":"When to Apply What","text":"One of the first questions practitioners ask: \"I have a thing I want the AI to know or do. Where does it go?\" The answer isn't obvious, and getting it wrong creates friction that makes the whole system feel broken.","next":"table"},{"id":"what-is-agentic-thinking#section#6","hash":"87bffa02a8652ebe","slug":"what-is-agentic-thinking","kind":"section","index":6,"role":"position","heading":"How I Actually Work: A Day in the Build","text":"Theory is cheap. Here's what agentic development actually looks like in practice.","next":"heading"},{"id":"what-is-agentic-thinking#section#7","hash":"cd40b950f74cba55","slug":"what-is-agentic-thinking","kind":"section","index":7,"role":"position","heading":"Setting the Stage","text":"Every project starts with context. I write rules that encode the project's conventions—naming patterns, architecture decisions, what belongs where. Not documentation; operating instructions. The difference matters because these rules don't sit in a wiki nobody reads. They actively shape every AI interaction in the project. But rules alone aren't enough. I tried that. You end up with rules fighting each other, or with a bloated alwaysApply stack that burns context on every conversation. The solution was separating concerns: rules for policy, skills for capability, MCP for data.","next":"heading"},{"id":"what-is-agentic-thinking#section#8","hash":"56096cee0daeb690","slug":"what-is-agentic-thinking","kind":"section","index":8,"role":"position","heading":"Building with Agents","text":"When I'm implementing a feature, I don't type code and let the AI autocomplete. I delegate. I describe the intent—the outcome, not the implementation. Then the agent works: reads the existing code, understands the template structure, implements the feature, and presents the result. When it gets stuck or drifts, I route to a specialist. Security concern? Spawn a security auditor. Architecture question? Spawn an architect. The main agent accumulated too much context and is hallucinating patterns from an hour ago? Spawn a subagent with fresh eyes.","next":"p"},{"id":"what-is-agentic-thinking#section#9","hash":"6cd5e679f4ddbfa0","slug":"what-is-agentic-thinking","kind":"section","index":9,"role":"position","heading":"Coordinating Across Agents","text":"Here's the part nobody warns you about: agents don't talk to each other. When you're running an Architect agent to design a system, an Implementer to build it, and a Reviewer to check it—they have zero awareness of each other's work. Agent A designs an architecture. Agent B starts implementing without reading Agent A's decisions. Agent C reviews and contradicts both. You become the human switchboard, repeating context endlessly.","next":"p"},{"id":"what-is-agentic-thinking#section#10","hash":"9969dfe2eee349cd","slug":"what-is-agentic-thinking","kind":"section","index":10,"role":"position","heading":"Managing Context and the Amnesia Problem","text":"Every agent starts every session with total amnesia. The context window is both the superpower and the constraint. Feed it your project's conventions via well-structured rules and it performs. Starve it of context and it guesses—confidently, plausibly, incorrectly.","next":"p"},{"id":"what-is-agentic-thinking#section#11","hash":"4b618d4e07957f87","slug":"what-is-agentic-thinking","kind":"section","index":11,"role":"position","heading":"The Review and Tune Loop","text":"Here's where most people stop. They build, they ship, they move on. The agentic approach adds a loop that changes everything. After every significant piece of work, I have the AI review its own output. Not a rubber stamp—a structured review. Did the implementation match the intent? Did it follow the project's conventions? Did it introduce patterns that conflict with existing code? I use autonomous workflows that chain build → review → fix → commit without me manually triggering each step. Then the review gets reviewed. I spawn a code reviewer agent on the diff. I spawn a security auditor. These agents don't have the implementation context—they're seeing the code for the first time, which is exactly the point. Fresh eyes catch what tired eyes miss.","next":"p"},{"id":"what-is-agentic-thinking#section#12","hash":"c8dc3e19444c8943","slug":"what-is-agentic-thinking","kind":"section","index":12,"role":"position","heading":"The Learning Loop","text":"This is the part that compounds. After every session—every debugging marathon, every architecture decision, every production surprise—the system captures what it learned. The meta-learning system observes patterns: what rules triggered, what commands ran, what manual work kept repeating. It proposes improvements. \"You ran lint manually 5 times this session—should this be automatic?\" \"This rule conflicts with that one—want to resolve it?\" \"You keep explaining the same context to new agents—should this be a skill?\" The key insight is that files are the protocol. Decisions made in Tuesday's session are available to Wednesday's agents without me repeating context. Patterns observed over a week become rules. Rules that prove their value over a month become skills. Skills that apply across projects become shared libraries. The loop is observe → pattern → propose → test → deploy → observe again.","next":"p"},{"id":"what-is-agentic-thinking#section#13","hash":"0ae807218a29ec7b","slug":"what-is-agentic-thinking","kind":"section","index":13,"role":"position","heading":"Bias, Trust, and Judgment","text":"Here's what nobody in the agentic AI space talks about enough: these systems have biases, and those biases compound when agents act autonomously. LLMs have training biases—they favor popular patterns over correct ones, they reflect the distribution of their training data, they have opinions about code style that they'll impose unless constrained. When a copilot suggests biased code, a human reviews it before committing. When an autonomous agent chains build → test → commit, that human review checkpoint can get thin.","next":"p"},{"id":"what-is-agentic-thinking#section#14","hash":"debfc67cb58666b0","slug":"what-is-agentic-thinking","kind":"section","index":14,"role":"position","heading":"The Shifts That Matter","text":"Agentic thinking reveals several shifts happening simultaneously. They look like separate trends. They're not—they're the same underlying transition viewed from different angles. Static → Discoverable. APIs used to be documented in wikis and consumed by developers who read the docs. Now capabilities are self-describing and discoverable at runtime. MCP is the clearest expression of this: instead of reading docs about what a system can do, an agent queries the system directly. The Interface Inflection series explores where this leads—semantic data layers, headless AI, and negotiated integrations.","next":"p"},{"id":"what-is-agentic-thinking#section#15","hash":"eed56c8794d39794","slug":"what-is-agentic-thinking","kind":"section","index":15,"role":"position","heading":"The Vision","text":"Where does this converge? I don't think we end up with AGI that replaces developers. I think we end up with something more interesting and more practical: development environments where the human provides intent, judgment, and accountability—and everything else is handled by a coordinated system of specialized agents operating through discoverable protocols against governed platforms.","next":"p"},{"id":"what-is-agentic-thinking#section#16","hash":"a0fe42ee3455d1e9","slug":"what-is-agentic-thinking","kind":"section","index":16,"role":"position","heading":"Who This Is For","text":"You've been burned by hype before. You sat through the blockchain presentations, the metaverse strategy decks, the \"AI will replace all developers by 2024\" think pieces. You're skeptical, and you should be.","next":"p"},{"id":"what-is-agentic-thinking#section#18","hash":"e7f7d259450d1364","slug":"what-is-agentic-thinking","kind":"section","index":18,"role":"position","heading":"Written from the Build","text":"Every post on this site comes from real work. Real failures, real debugging sessions, real production surprises. I build with Cursor and Claude Code daily. I deploy AI employees on Ema. I design MCP servers and agent architectures and then watch them break in ways the design doc didn't predict.","next":"p"},{"id":"mcp-semantic-data-layer#thesis#0","hash":"eef7c498bbc1532a","slug":"mcp-semantic-data-layer","kind":"thesis","index":0,"role":"position","heading":null,"text":"MCP is emerging as a semantic data layer — an abstraction between systems of record and any consumer that makes capabilities discoverable and self-describing. This is the enterprise service bus done right, because the intelligence lives in the consumer, not the layer.","next":"other"},{"id":"mcp-semantic-data-layer#lead#0","hash":"ef0d145af17d0366","slug":"mcp-semantic-data-layer","kind":"lead","index":0,"role":"position","heading":null,"text":"Enterprise architects have been building abstraction layers between systems and consumers for decades. Most of those layers failed. MCP might be the one that works — but only if you understand why it's different from everything that came before it.","next":"text"},{"id":"mcp-semantic-data-layer#section#1","hash":"5c9036b922c251b3","slug":"mcp-semantic-data-layer","kind":"section","index":1,"role":"position","heading":"What \"Semantic Data Layer\" Actually Means","text":"A semantic data layer sits between producers (your platform APIs, databases, systems of record) and consumers (agents, apps, scripts, partner integrations).","next":"lead-in"},{"id":"mcp-semantic-data-layer#section#2","hash":"f7a9e50b762e7d05","slug":"mcp-semantic-data-layer","kind":"section","index":2,"role":"position","heading":"The Service Bus Comparison (And Why It's Different)","text":"If you've been in enterprise architecture for any length of time, MCP as a semantic layer sounds familiar. It should. The comparison to enterprise service buses is apt — but the outcome is fundamentally different.","next":"table"},{"id":"mcp-semantic-data-layer#section#3","hash":"7710e83188a73915","slug":"mcp-semantic-data-layer","kind":"section","index":3,"role":"position","heading":"Where MCP as Semantic Layer Makes Sense","text":"Not every system needs a semantic layer. The overhead is real — schema negotiation, discovery roundtrips, abstraction maintenance.","next":"lead-in"},{"id":"mcp-semantic-data-layer#section#9","hash":"e61f320fc9a48978","slug":"mcp-semantic-data-layer","kind":"section","index":9,"role":"position","heading":"The ESB Counterargument","text":"The inevitable objection: \"ESBs failed, this will too.\" ESBs failed because they tried to centralize routing, transformation, and orchestration inside the bus. The bus got smarter with every integration, accumulating logic that should have stayed in the endpoints. Eventually, the bus was the most complex component in the architecture — and the hardest to change.","next":"p"},{"id":"headless-ai-every-app-is-a-head#thesis#0","hash":"2e813a1714d758fb","slug":"headless-ai-every-app-is-a-head","kind":"thesis","index":0,"role":"position","heading":null,"text":"Headless AI decouples capabilities from interfaces, letting any application — web, terminal, voice, partner system — consume the same platform through MCP. The vendor UI doesn't disappear. It becomes one consumer among many, and that changes everything about how platforms are built and adopted.","next":"other"},{"id":"headless-ai-every-app-is-a-head#lead#0","hash":"3bd9452db54a0f7f","slug":"headless-ai-every-app-is-a-head","kind":"lead","index":0,"role":"position","heading":null,"text":"The web app was never the product. It was just the first head.","next":"text"},{"id":"headless-ai-every-app-is-a-head#section#1","hash":"a6bc3a6250981b21","slug":"headless-ai-every-app-is-a-head","kind":"section","index":1,"role":"position","heading":"The Headless Pattern: CMS to Commerce to AI","text":"Headless architecture follows a predictable adoption curve. Headless CMS decoupled content from presentation — the same articles served a website, a mobile app, and a kiosk. Headless commerce decoupled product catalogs from storefronts — the same inventory powered a web store, a marketplace widget, and an in-app purchase flow.","next":"p"},{"id":"headless-ai-every-app-is-a-head#section#3","hash":"1a2eb390c28aa17f","slug":"headless-ai-every-app-is-a-head","kind":"section","index":3,"role":"position","heading":"The Multi-Head Architecture","text":"Here's the shift. Before headless AI, each consumer needed a bespoke integration. After, all consumers share a common capability layer.","next":"code"},{"id":"headless-ai-every-app-is-a-head#section#4","hash":"f8821cc96d416f4f","slug":"headless-ai-every-app-is-a-head","kind":"section","index":4,"role":"position","heading":"MCP as API Abstraction: Where It Works, Where It Doesn't","text":"MCP as a universal capability layer is compelling. It's also not universally appropriate.","next":"p"},{"id":"headless-ai-every-app-is-a-head#section#5","hash":"12bcfe90c3ad2801","slug":"headless-ai-every-app-is-a-head","kind":"section","index":5,"role":"position","heading":"Same Platform, Multiple Heads","text":"Here's how the Ema platform is consumed through different heads today. Via the Web App: A product manager opens the dashboard, clicks through the persona creation wizard, configures workflows visually, uploads documents through drag-and-drop. Great for onboarding, visual configuration, and team collaboration.","next":"p"},{"id":"headless-ai-every-app-is-a-head#section#6","hash":"41fa686720322186","slug":"headless-ai-every-app-is-a-head","kind":"section","index":6,"role":"position","heading":"\"But Most Users Still Want a Polished UI\"","text":"They do. And that's the point. The web app remains essential for visual, guided experiences. Configuring a complex multi-step workflow is better done in a visual editor than through conversation. Monitoring dashboards need real-time visuals. Team collaboration needs shared screens and state.","next":"p"},{"id":"headless-ai-every-app-is-a-head#section#7","hash":"240ede43d907e8bf","slug":"headless-ai-every-app-is-a-head","kind":"section","index":7,"role":"position","heading":"The Enterprise Build-vs-Buy Shift","text":"When a platform is headless, the vendor relationship changes fundamentally. Before headless: \"We need feature X in your UI.\" The customer files a request. The vendor prioritizes it against other requests. Six months pass. Maybe it ships.","next":"p"},{"id":"negotiated-integrations#thesis#0","hash":"d32a1170c83f288b","slug":"negotiated-integrations","kind":"thesis","index":0,"role":"position","heading":null,"text":"When LLM-powered agents can discover, understand, and compose capabilities at runtime, integrations shift from pre-programmed contracts to dynamically negotiated workflows. This changes the economics, maintenance burden, and architecture of enterprise integration.","next":"other"},{"id":"negotiated-integrations#lead#0","hash":"363b25e82984d14c","slug":"negotiated-integrations","kind":"lead","index":0,"role":"position","heading":null,"text":"Every integration you've ever built was a bet that you knew, upfront, exactly how producer and consumer would talk. For fifty years, that bet paid off. It's about to stop paying off — because the consumer now has its own opinions about how to use your system.","next":"text"},{"id":"negotiated-integrations#section#1","hash":"559b994e1ed38038","slug":"negotiated-integrations","kind":"section","index":1,"role":"position","heading":"The Old Integration Model","text":"Traditional integrations follow a predictable, expensive pattern: two teams agree on a message format, build adapters on both sides, test the handshake, deploy, and maintain it indefinitely. Each new consumer means another project. Each schema change means coordinated updates across every integration that touches it.","next":"p"},{"id":"negotiated-integrations#section#2","hash":"9dab0e3499ebe2a3","slug":"negotiated-integrations","kind":"section","index":2,"role":"position","heading":"The New Model: Discover, Understand, Compose, Execute","text":"With MCP and LLMs, the integration flow inverts. Instead of pre-programming every connection, the agent negotiates the integration at runtime.","next":"code"},{"id":"negotiated-integrations#section#3","hash":"f1ee664fef2b861a","slug":"negotiated-integrations","kind":"section","index":3,"role":"position","heading":"The Micronization of Integrations","text":"The old model: build a comprehensive Salesforce integration. Months of work. Covers 80% of use cases. The other 20% gathers dust in a backlog nobody will prioritize.","next":"p"},{"id":"negotiated-integrations#section#4","hash":"2fd7a22ad9c7e3e5","slug":"negotiated-integrations","kind":"section","index":4,"role":"position","heading":"The Agent That Found a New API","text":"Here's a real story from the Ema platform. An MCP consumer had a function for cloning data between environments. A developer later noticed the agent was using a new API endpoint for copies that nobody had explicitly integrated. The agent discovered the endpoint through MCP, understood its schema from the tool description, and started using it because it was a better fit for the operation.","next":"p"},{"id":"negotiated-integrations#section#7","hash":"82dd4d57e16079be","slug":"negotiated-integrations","kind":"section","index":7,"role":"position","heading":"Decision Framework: Pre-Built vs. Negotiated","text":"Not every integration should be negotiated. High-volume, well-defined workflows still benefit from hardcoded optimization.","next":"lead-in"},{"id":"negotiated-integrations#section#8","hash":"9f16c8705fa34ae5","slug":"negotiated-integrations","kind":"section","index":8,"role":"position","heading":"Trust and Governance","text":"The immediate objection: \"You can't trust agents to negotiate critical integrations.\" Valid. The answer isn't to avoid negotiated integrations — it's to layer controls appropriately.","next":"p"},{"id":"negotiated-integrations#section#9","hash":"23f6aca8f46e2f3d","slug":"negotiated-integrations","kind":"section","index":9,"role":"position","heading":"The Enterprise Angle","text":"Compliance and governance teams need concrete assurances, not philosophical arguments. Audit trails. Every MCP call is loggable — tool name, parameters, timestamp, response. Negotiated integrations produce richer audit data than pre-built ones because every step is an explicit, recorded tool invocation.","next":"p"},{"id":"democratizing-ai-builders#thesis#0","hash":"0b57d5ed0f9c4d24","slug":"democratizing-ai-builders","kind":"thesis","index":0,"role":"position","heading":null,"text":"When platform capabilities are discoverable, self-describing, and composable through natural language, the set of people who can build AI employees expands from engineering teams to anyone who can articulate what they need. This is a structural change in who produces, not just who consumes.","next":"other"},{"id":"democratizing-ai-builders#lead#0","hash":"e91af0116d408f95","slug":"democratizing-ai-builders","kind":"lead","index":0,"role":"position","heading":null,"text":"The bottleneck was never the platform. It was the number of people who could use it. MCP removes that bottleneck — not by dumbing things down, but by making capabilities legible to anyone with intent.","next":"text"},{"id":"democratizing-ai-builders#section#1","hash":"0bd7210b69de13cc","slug":"democratizing-ai-builders","kind":"section","index":1,"role":"position","heading":"What Democratization Actually Means","text":"\"Democratization\" is overused and underspecified. In this context, it means something precise: a structural change in who can be a producer, not just a consumer.","next":"p"},{"id":"democratizing-ai-builders#section#2","hash":"f42b7e32af30056d","slug":"democratizing-ai-builders","kind":"section","index":2,"role":"position","heading":"The End-User as Builder","text":"Here's a concrete example from the Ema platform. A team member — not a developer — uses MCP through a conversational agent to perform operational tasks: \"Show me all personas with deprecated actions.\" \"Clean up stale personas.\" \"Find me a persona template for this task.\"","next":"p"},{"id":"democratizing-ai-builders#section#4","hash":"00a5c614e8ec3d71","slug":"democratizing-ai-builders","kind":"section","index":4,"role":"list","heading":"MCP as the Enabler","text":"Why this works: discoverable capabilities plus a reasoning engine equals a builder.","next":"code"},{"id":"democratizing-ai-builders#section#5","hash":"865e747b657cc8d3","slug":"democratizing-ai-builders","kind":"section","index":5,"role":"list","heading":"The Cursor Plugin Model","text":"The distribution channel for this capability is already taking shape.","next":"lead-in"},{"id":"democratizing-ai-builders#section#6","hash":"3a27847dd70db331","slug":"democratizing-ai-builders","kind":"section","index":6,"role":"position","heading":"Governance: The Necessary Counterweight","text":"Valid concern. Expanding the builder set without guardrails produces fragile, inconsistent, or dangerous AI employees.","next":"lead-in"},{"id":"democratizing-ai-builders#section#7","hash":"dc7830659c914f6f","slug":"democratizing-ai-builders","kind":"section","index":7,"role":"position","heading":"The Enterprise Shift","text":"Traditional model: central IT builds AI employees, everyone else submits tickets and waits. This creates a bottleneck that scales linearly with demand. New model: domain experts build (or direct agents to build) AI employees. Central IT governs the platform, maintains guardrails, and manages the capability surface.","next":"table"},{"id":"the-interface-forecast#thesis#0","hash":"9db444acea3987a2","slug":"the-interface-forecast","kind":"thesis","index":0,"role":"position","heading":null,"text":"The convergence of self-describing capabilities, headless architecture, negotiated integrations, and democratized building points toward a future where the \"app\" is a composition of capabilities assembled by agents — and the organizations that treat their capability layer as a product will have a structural advantage over those still shipping monolithic interfaces.","next":"other"},{"id":"the-interface-forecast#lead#0","hash":"0b8e337c522ae14d","slug":"the-interface-forecast","kind":"lead","index":0,"role":"position","heading":null,"text":"Five posts ago, we started with a simple observation: the consumer of your next interface is as likely to be an LLM as a developer. Now it's time to follow that thread to its conclusion.","next":"text"},{"id":"the-interface-forecast#section#1","hash":"5137bbdf1d6ce1b8","slug":"the-interface-forecast","kind":"section","index":1,"role":"list","heading":"The Convergence","text":"In three to five years, the lines between \"API,\" \"UI,\" and \"integration\" blur significantly.","next":"list"},{"id":"the-interface-forecast#section#2","hash":"856f7af1756b3085","slug":"the-interface-forecast","kind":"section","index":2,"role":"position","heading":"Conversational vs. Visual: It's About the Task","text":"Are we all moving to chat? No. But the boundary between conversational and visual interfaces is shifting — and it's shifting based on task, not platform.","next":"table"},{"id":"the-interface-forecast#section#3","hash":"bb909155d42e98c5","slug":"the-interface-forecast","kind":"section","index":3,"role":"position","heading":"MCP Servers as Product","text":"MCP servers are becoming a distribution channel for platform capabilities. Cursor plugins package MCP servers with rules and skills. Claude Desktop uses MCP servers as \"apps.\" Any agentic framework that supports the MCP specification can consume them.","next":"p"},{"id":"the-interface-forecast#section#4","hash":"b5012156a9d1b53e","slug":"the-interface-forecast","kind":"section","index":4,"role":"position","heading":"The App as Composition","text":"The future pattern: users or agents assemble capabilities from multiple MCP servers into bespoke experiences that no single product team designed.","next":"p"},{"id":"the-interface-forecast#section#5","hash":"b0b7c2c5d2619006","slug":"the-interface-forecast","kind":"section","index":5,"role":"position","heading":"The Opportunity Cost Question","text":"Here's the honest check on the vision. From the discussions that shaped this series: it becomes possible to build anything within imagination — however, with the overhead of opportunity cost and LLM costs. The question is where the balance falls.","next":"p"},{"id":"the-interface-forecast#section#6","hash":"093a6929d45d00f7","slug":"the-interface-forecast","kind":"section","index":6,"role":"position","heading":"The Counterargument","text":"Predictions about interfaces are notoriously wrong. Video phones were predicted for decades before Zoom. Voice interfaces were \"the future\" for twenty years before they became useful for anything beyond timers and weather.","next":"p"},{"id":"the-interface-forecast#section#7","hash":"ec7ad9049db3a7c6","slug":"the-interface-forecast","kind":"section","index":7,"role":"position","heading":"What Builders Should Do Now","text":"These aren't predictions to wait for. They're actions to take today.","next":"list"},{"id":"five-things-wrong-with-mcp#thesis#0","hash":"1024143346a706ed","slug":"five-things-wrong-with-mcp","kind":"thesis","index":0,"role":"position","heading":null,"text":"MCP has five real problems that make it painful in practice. Acknowledging them honestly matters more than defending the protocol. But the conclusion most people draw — \"just use CLIs\" — is a category error. The problems are real. The diagnosis is wrong. And the one thing almost everyone gets wrong about MCP changes how you evaluate every criticism.","next":"other"},{"id":"five-things-wrong-with-mcp#lead#0","hash":"1bb0eef2843bdf11","slug":"five-things-wrong-with-mcp","kind":"lead","index":0,"role":"position","heading":null,"text":"I've spent four posts building the case for MCP as a semantic data layer, a headless capability surface, a foundation for negotiated integrations. Then Perplexity's CTO said they're dropping MCP for APIs and CLIs. Here's the thing: most of the criticism is right.","next":"text"},{"id":"five-things-wrong-with-mcp#section#1","hash":"64061831a34333ed","slug":"five-things-wrong-with-mcp","kind":"section","index":1,"role":"position","heading":"The Case Against MCP","text":"The case has been building for months. Mario Zechner benchmarked MCP servers against CLI equivalents and the numbers weren't close: Playwright's MCP server consumes 13,700 tokens (21 tools), Chrome DevTools MCP takes 18,000 tokens (26 tools), versus 225 tokens for a set of CLI scripts doing the same browser automation. A 60x difference.","next":"p"},{"id":"five-things-wrong-with-mcp#section#2","hash":"7e26e396dcf1efc6","slug":"five-things-wrong-with-mcp","kind":"section","index":2,"role":"position","heading":"Problem 1: Schema Overhead Is Real","text":"Every tool schema gets loaded into context at connection time. Twenty tools with detailed descriptions can consume 7–9% of a context window before any work begins. The schema tax is worst when servers expose many tools (the Playwright pattern), multiple MCP servers connect to the same agent, conversations are long-running, and the agent uses only a fraction of available tools per session.","next":"p"},{"id":"five-things-wrong-with-mcp#section#3","hash":"2cc1ba3c6629ee86","slug":"five-things-wrong-with-mcp","kind":"section","index":3,"role":"position","heading":"Problem 2: Auth Is Immature","text":"OAuth flows, token refresh, credential storage, multi-tenant isolation — MCP's authentication story is a work in progress. The spec defines a transport layer. It doesn't define how you handle token expiry mid-session, rotate secrets without dropping connections, or scope access per-user in a multi-tenant environment. Every team solving this is solving it independently.","next":"p"},{"id":"five-things-wrong-with-mcp#section#4","hash":"fdcc4d33b06ca258","slug":"five-things-wrong-with-mcp","kind":"section","index":4,"role":"position","heading":"Problem 3: Training Data Favors Shell","text":"Models have seen millions of bash sessions, curl invocations, and git workflows in training data. They've seen comparatively little MCP interaction. The result is measurable: agents compose shell pipelines more reliably than they navigate unfamiliar MCP tool schemas.","next":"p"},{"id":"five-things-wrong-with-mcp#section#6","hash":"10769e5415f34aa9","slug":"five-things-wrong-with-mcp","kind":"section","index":6,"role":"position","heading":"Problem 5: Most MCP Servers Are Poorly Designed","text":"This is the uncomfortable one. The MCP ecosystem is full of servers that expose too many tools, return too much data, provide no guidance, and ignore token efficiency entirely. Many are proof-of-concept wrappers that became \"production\" through inertia.","next":"p"},{"id":"five-things-wrong-with-mcp#section#7","hash":"6e0d878cddae87a0","slug":"five-things-wrong-with-mcp","kind":"section","index":7,"role":"position","heading":"The One Thing Everyone Gets Wrong","text":"Here it is: MCP is not a product. It's an interface. The debate treats MCP as a thing you're either using or not using — like switching from MySQL to Postgres. But MCP is a wire protocol. JSON-RPC with tool schemas and discovery. It's an interface contract, not an implementation.","next":"p"},{"id":"five-things-wrong-with-mcp#section#8","hash":"691beda47a3c7805","slug":"five-things-wrong-with-mcp","kind":"section","index":8,"role":"position","heading":"Who Wins Where","text":"The right framing isn't MCP or CLI. It's: who is consuming your capabilities? CLIs win when the developer is the user, the task is single-turn, composability is essential, and training data advantage matters. Perplexity is a company where engineers are the agents' operators. They know every API endpoint. Their tasks are well-defined retrieval operations. Of course CLIs work better. That's not an indictment of MCP — it's a statement about their consumer.","next":"p"},{"id":"five-things-wrong-with-mcp#section#9","hash":"4f4cf40b00427127","slug":"five-things-wrong-with-mcp","kind":"section","index":9,"role":"position","heading":"How We Designed Around Every Problem","text":"At Ema, we built an MCP server for managing AI Employees on the platform. We hit every criticism above — and then designed around them.","next":"table"},{"id":"five-things-wrong-with-mcp#section#10","hash":"046acaa8db15e5f1","slug":"five-things-wrong-with-mcp","kind":"section","index":10,"role":"position","heading":"What This Means for the Semantic Data Layer","text":"Four posts ago, I argued that MCP is emerging as an enterprise semantic data layer — the ESB done right, because the intelligence lives in the consumer, not the layer. Does the criticism invalidate that thesis? No. It sharpens it.","next":"p"},{"id":"five-things-wrong-with-mcp#section#11","hash":"9cfecba42967b7ba","slug":"five-things-wrong-with-mcp","kind":"section","index":11,"role":"position","heading":"The Convergence Nobody's Talking About","text":"CLIs will grow MCP-like features. MCP servers will slim down to CLI-like simplicity. The gap will shrink. Peter Steinberger's mcporter already bridges them — wrapping MCP servers as standalone CLI tools. That tool exists because the boundary is thinner than the debate suggests. A well-designed MCP server is a CLI with structured discovery. A CLI with machine-readable schemas and capability enumeration is an MCP server missing the wire protocol.","next":"p"},{"id":"externalize-the-knowledge#thesis#0","hash":"6bfcdb92db6220c2","slug":"externalize-the-knowledge","kind":"thesis","index":0,"role":"position","heading":null,"text":"MCP servers that embed knowledge become deployment bottlenecks. Externalizing knowledge to a dedicated knowledge service decouples the knowledge lifecycle from the MCP lifecycle — enabling real-time updates, personalization, and zero-downtime evolution. This is the discovery protocol principle from Post 1 applied to knowledge itself: MCP should query knowledge, not contain it.","next":"other"},{"id":"externalize-the-knowledge#lead#0","hash":"04372532e1b951bf","slug":"externalize-the-knowledge","kind":"lead","index":0,"role":"position","heading":null,"text":"Three months ago I wrote about embedding domain expertise directly into an MCP server — 40+ agent definitions, workflow patterns, platform concepts, all in knowledge.ts. It worked at small scale. Then knowledge started changing faster than we could deploy.","next":"text"},{"id":"externalize-the-knowledge#section#1","hash":"619007f3b2035646","slug":"externalize-the-knowledge","kind":"section","index":1,"role":"position","heading":"The Knowledge Embedding Trap","text":"In MCP in Practice: Knowledge-First Builder, I made the case for structured knowledge over fuzzy RAG retrieval. I embedded an agent catalog, workflow patterns, validation rules, and platform terminology directly into the MCP server's codebase. It was version-controlled, type-checked, and directly accessible to tools.","next":"p"},{"id":"externalize-the-knowledge#section#2","hash":"efe3e7e00c52f25e","slug":"externalize-the-knowledge","kind":"section","index":2,"role":"position","heading":"Why Externalize","text":"In Post 1, I argued that the discovery protocol unlocks pluggability, backend evolution without client changes, and independent lifecycles.","next":"lead-in"},{"id":"externalize-the-knowledge#section#3","hash":"aa85e498716c742f","slug":"externalize-the-knowledge","kind":"section","index":3,"role":"position","heading":"The Externalization Pattern","text":"The fix is architectural: move knowledge out of the MCP server and into an external knowledge service. Not a text index — a full knowledge platform that handles ingestion, structuring, search, ranking, and retrieval. The MCP server becomes a routing shim between the agent and the knowledge service — exactly the discovery protocol pattern from Post 1.","next":"p"},{"id":"externalize-the-knowledge#section#4","hash":"f10bbfa03043fa0f","slug":"externalize-the-knowledge","kind":"section","index":4,"role":"position","heading":"Dynamic Instructions at Init","text":"This is where the pattern gets interesting. MCP's server instructions — the guidance sent to the agent when it connects — don't have to be static strings in your codebase. They can be composed dynamically at connection time.","next":"p"},{"id":"externalize-the-knowledge#section#6","hash":"96dab38f4918a9c7","slug":"externalize-the-knowledge","kind":"section","index":6,"role":"position","heading":"Personalization at Connection Time","text":"If the search query includes context about who's connecting, the returned guidance is personalized without the MCP server containing personalization logic.","next":"code"},{"id":"mcp-as-discovery-protocol#thesis#0","hash":"01d954b48b4a70bb","slug":"mcp-as-discovery-protocol","kind":"thesis","index":0,"role":"position","heading":null,"text":"MCP's highest-value role is as a discovery protocol — a thin shim where agents find capabilities, receive guidance, and negotiate context at runtime. The moment MCP accumulates logic, knowledge, or state, it repeats the enterprise service bus failure that this blog already warned about.","next":"other"},{"id":"mcp-as-discovery-protocol#lead#0","hash":"a261d5a237a7f6df","slug":"mcp-as-discovery-protocol","kind":"lead","index":0,"role":"position","heading":null,"text":"I spent seven posts building the case for MCP as a semantic data layer. I was directionally right and specifically wrong. MCP works best when it's narrower than a layer — when it's a discovery protocol that describes what's available and gets out of the way.","next":"text"},{"id":"mcp-as-discovery-protocol#section#1","hash":"3a1c8d360121c376","slug":"mcp-as-discovery-protocol","kind":"section","index":1,"role":"position","heading":"From Semantic Layer to Discovery Protocol","text":"In MCP: The Semantic Data Layer, I framed MCP with five responsibilities: abstraction, semantics, discovery, negotiation, and governance. I argued it was the enterprise service bus done right — centralizing description while distributing reasoning.","next":"p"},{"id":"mcp-as-discovery-protocol#section#2","hash":"15dd74a5a74b0161","slug":"mcp-as-discovery-protocol","kind":"section","index":2,"role":"position","heading":"What Discovery Actually Means","text":"DNS is the canonical discovery protocol. You ask \"where is example.com?\" and DNS returns an IP address. It doesn't serve the web page. It doesn't validate your request. It doesn't decide whether you should visit that site. It resolves names to addresses and steps aside.","next":"p"},{"id":"mcp-as-discovery-protocol#section#3","hash":"54469b13e2e9ce82","slug":"mcp-as-discovery-protocol","kind":"section","index":3,"role":"position","heading":"Path A: MCP-Mediated Execution","text":"The agent discovers tools via MCP and continues calling them through MCP. MCP abstracts the backend — the agent doesn't need to know the underlying service details. Each tool call flows through MCP, which delegates to the backend and returns the result with guidance.","next":"code"},{"id":"mcp-as-discovery-protocol#section#4","hash":"63a021c77bdcc8d3","slug":"mcp-as-discovery-protocol","kind":"section","index":4,"role":"position","heading":"Path B: MCP-Informed Direct Access","text":"The agent discovers via MCP but then calls services directly. MCP's connect response — resources, instructions, or a discovery tool result — includes the service URI, API spec, CLI command, or another MCP server address. The agent has what it needs to go direct.","next":"code"},{"id":"mcp-as-discovery-protocol#section#5","hash":"dd41fe2ac40f4b30","slug":"mcp-as-discovery-protocol","kind":"section","index":5,"role":"position","heading":"Both Paths, One Protocol","text":"Both paths start with MCP. The difference is whether MCP stays in the execution loop or steps aside after discovery. In practice, agents use both paths simultaneously — calling some services through MCP tools (Path A) while going direct to others using specs MCP provided (Path B). The protocol doesn't mandate which path to use; it enables both.","next":"p"},{"id":"mcp-as-discovery-protocol#section#6","hash":"cf63721f420e3618","slug":"mcp-as-discovery-protocol","kind":"section","index":6,"role":"position","heading":"Why Discovery Changes Everything","text":"The narrowing from \"layer\" to \"protocol\" isn't semantic — it unlocks three operational properties that a thicker layer can't provide. Pluggability without rebuilding. When MCP only describes capabilities, adding a new backend service means adding a new tool schema — not writing routing logic, transformation code, or orchestration flows. A team ships a new microservice on Tuesday; by Wednesday, the MCP server exposes a tool description and every connected agent can discover and use it. No agent rebuild. No MCP logic change. No coordinated release across teams.","next":"p"},{"id":"mcp-as-discovery-protocol#section#7","hash":"101c2af445d13df8","slug":"mcp-as-discovery-protocol","kind":"section","index":7,"role":"position","heading":"Agents Own the Logic","text":"This is the prescription that follows from the discovery framing: the agent is where reasoning, sequencing, error handling, and decision-making live. MCP provides inputs to that reasoning — it doesn't perform it.","next":"p"},{"id":"mcp-as-discovery-protocol#section#8","hash":"2f0706317c1e0d00","slug":"mcp-as-discovery-protocol","kind":"section","index":8,"role":"position","heading":"Resources as Guidance, Not Rules","text":"MCP's resource and prompt primitives are where guidance enters the system. Server instructions describe how to use the tools. Resources provide reference data. Prompts offer templates for common workflows.","next":"p"},{"id":"mcp-as-discovery-protocol#section#9","hash":"6b53f4ac2810e511","slug":"mcp-as-discovery-protocol","kind":"section","index":9,"role":"position","heading":"CLI Doesn't Negate Discovery","text":"Perplexity's CTO said they're dropping MCP for APIs and CLIs. I addressed this in MCP Isn't the Problem, but the discovery protocol framing sharpens the analysis.","next":"p"},{"id":"bound-dont-script#thesis#0","hash":"4f6d85ffc2d94688","slug":"bound-dont-script","kind":"thesis","index":0,"role":"position","heading":null,"text":"The highest-leverage way to direct a capable agent is to specify the what and the why, then refuse to specify the how. Every step you script is a ceiling you impose. Bounding an agent with an outcome and a reason gives it room to be smarter than your instructions — and to get smarter as the model underneath it improves.","next":"other"},{"id":"bound-dont-script#lead#0","hash":"349d70cf05d4005c","slug":"bound-dont-script","kind":"lead","index":0,"role":"position","heading":null,"text":"There are two ways to direct an agent. You can script the steps it takes, or you can lock the outcome and let it find its own way there. Almost everyone starts by scripting. Almost everyone should stop.","next":"text"},{"id":"bound-dont-script#section#2","hash":"6e963fd21a9ff802","slug":"bound-dont-script","kind":"section","index":2,"role":"position","heading":"What, Why, How","text":"Three layers sit inside every instruction you give an agent. Most people collapse them into one blob of prose. Pulling them apart is the entire game.","next":"code"},{"id":"bound-dont-script#section#3","hash":"0212cc2376b37e8f","slug":"bound-dont-script","kind":"section","index":3,"role":"position","heading":"Overguiding Is Lossy","text":"Scripting feels safe. It feels like control. But a scripted procedure is a lossy compression of your actual intent, and the agent decompresses it back into behavior that's missing everything you didn't say.","next":"p"},{"id":"bound-dont-script#section#4","hash":"db34ac080f26343d","slug":"bound-dont-script","kind":"section","index":4,"role":"position","heading":"What You Actually Owe the Agent","text":"\"Don't specify the how\" does not mean \"throw a vague wish over the wall.\" A burger order still has a spec — it's just a spec of the outcome, not the method. Bounding is precise. It's precise about the right things.","next":"p"},{"id":"bound-dont-script#section#5","hash":"26e45b81162c9a61","slug":"bound-dont-script","kind":"section","index":5,"role":"position","heading":"Why This Compounds With Model Releases","text":"Here's the payoff that makes bounding more than a style preference. A scripted prompt is pinned to the capability of the model it was written for. You wrote those seven steps because, at the time, the agent needed hand-holding through them. When a stronger model arrives, the steps don't get better — they get in the way. The new model would have found a cleaner path, but your script forbids it. Your instructions become technical debt that actively suppresses the capability you're paying for.","next":"code"},{"id":"instructions-that-outlive-the-model#thesis#0","hash":"1ab39f85dcdc9e94","slug":"instructions-that-outlive-the-model","kind":"thesis","index":0,"role":"position","heading":null,"text":"The durable instruction is the generic one. Specific, procedural guidance is pinned to the model it was written for — it rots into dead weight or hardens into a straitjacket the moment a smarter model arrives. Lean, intent-shaped instructions ride model improvements instead of fighting them. When you author for reuse, bake in less, and inherit the capability the model already has.","next":"other"},{"id":"instructions-that-outlive-the-model#lead#0","hash":"aa685223f9c970a3","slug":"instructions-that-outlive-the-model","kind":"lead","index":0,"role":"position","heading":null,"text":"Every behavioral instruction you write into a skill, an agent file, or a system prompt is a bet against the next model. Most of those bets lose. The instruction that wins is the one that was too lean to be wrong.","next":"text"},{"id":"instructions-that-outlive-the-model#section#1","hash":"038091646c540ff7","slug":"instructions-that-outlive-the-model","kind":"section","index":1,"role":"position","heading":"The Instruction That Ages","text":"A per-task prompt is disposable. A skill is not. You write a skill, an agent persona, or a system prompt once and then it runs across a thousand sessions and — if you're not careful — across three model generations. That longevity changes the economics of every word.","next":"p"},{"id":"instructions-that-outlive-the-model#section#2","hash":"d3e0275816760644","slug":"instructions-that-outlive-the-model","kind":"section","index":2,"role":"list","heading":"Two Kinds of Content, Two Fates","text":"Not all instruction text ages the same way. There are two kinds, and they have opposite fates as models improve.","next":"code"},{"id":"instructions-that-outlive-the-model#section#3","hash":"0d3a2f2ae8b3abb8","slug":"instructions-that-outlive-the-model","kind":"section","index":3,"role":"position","heading":"The Description Is a Trigger, Not a Spec","text":"The sharpest version of this shows up in how you write a skill's description — the text that decides whether the skill activates at all.","next":"p"},{"id":"instructions-that-outlive-the-model#section#4","hash":"fcc30f927b419145","slug":"instructions-that-outlive-the-model","kind":"section","index":4,"role":"position","heading":"Reference, Don't Duplicate","text":"There's a second kind of rot, and it comes from copying instead of pointing. It's tempting to paste the canonical rules — the framework's spec, the style guide, the API contract — directly into your skill so it's \"self-contained.\" Don't. The moment you paste, you've forked. The source updates; your copy doesn't; and now your skill is confidently teaching last quarter's rules.","next":"code"},{"id":"instructions-that-outlive-the-model#section#5","hash":"f045c0d44f99807c","slug":"instructions-that-outlive-the-model","kind":"section","index":5,"role":"position","heading":"Cut What the Model Already Knows","text":"The hardest habit to break is writing down things the model already knows. You do not need to tell a current frontier model what JSON is, that it should read a file before editing it, or that grep finds text in files. Every such line is pure cost: it spends context, it adds nothing, and — worse — a wall of obvious instructions trains the agent to skim, so it's primed to skim past the one non-obvious line that actually mattered.","next":"p"},{"id":"instructions-that-outlive-the-model#section#6","hash":"0c88daacd6fc0149","slug":"instructions-that-outlive-the-model","kind":"section","index":6,"role":"position","heading":"The Counterintuitive Payoff","text":"Here's what makes this more than tidiness. A lean, generic instruction doesn't just survive a model upgrade — it appreciates. A specific procedural instruction is frozen at the capability level it was written for; the best it can do on a smarter model is get out of the way, and the worst it can do is actively suppress the improvement. A generic intent-shaped instruction has no such ceiling. \"Surface the true intent and abstain when you can't ground it\" is executed more shrewdly by every stronger model, with no edit from you. You wrote the instruction once; each release makes it better.","next":"p"},{"id":"bind-the-goal-not-the-gesture#thesis#0","hash":"2be1143d6f4145c2","slug":"bind-the-goal-not-the-gesture","kind":"thesis","index":0,"role":"position","heading":null,"text":"Durable automation stores the what and the why as immutable, and treats the how as disposable — re-resolved against the strongest available interface on every single run. An automation bound to a gesture is frozen at the weakest actuator it was born with. An automation bound to a goal hardens itself from eight UI clicks to one API call with zero edits, the day a better path appears.","next":"other"},{"id":"bind-the-goal-not-the-gesture#lead#0","hash":"421758d95298e518","slug":"bind-the-goal-not-the-gesture","kind":"lead","index":0,"role":"position","heading":null,"text":"Record a person doing a task and you can replay it. But you've captured the wrong thing. You captured the clicks — the gesture — when what you wanted was the goal. The difference decides whether your automation quietly upgrades itself over time or shatters the first time a button moves.","next":"text"},{"id":"bind-the-goal-not-the-gesture#section#1","hash":"4b10baba46a9ec2f","slug":"bind-the-goal-not-the-gesture","kind":"section","index":1,"role":"position","heading":"The Macro-Recorder Mental Model Is Wrong","text":"The instinctive way to automate a workflow is to record it. Capture the clicks, the keystrokes, the field entries, and play them back. Every macro recorder, every \"record and replay\" test tool, nearly every screen-scraping RPA bot works this way. And the overwhelming majority of them are brittle for the same reason: it froze the gesture instead of the goal.","next":"p"},{"id":"bind-the-goal-not-the-gesture#section#2","hash":"5fe0219129d34980","slug":"bind-the-goal-not-the-gesture","kind":"section","index":2,"role":"position","heading":"Three Layers, One Volatile","text":"The fix is to stop storing an automation as a flat script and start storing it as a single unit — call it an Action — split into three layers, stacked by how fast they change.","next":"code"},{"id":"bind-the-goal-not-the-gesture#section#3","hash":"1241e81de297f12c","slug":"bind-the-goal-not-the-gesture","kind":"section","index":3,"role":"position","heading":"The Self-Hardening Automation","text":"This is where it stops being tidy architecture and starts being magic. Say the only way to file an issue today is the web UI. The automation is born bound to eight clicks. That's fine — but the first time it runs those clicks, something clever happens: the run is instrumented. It watches the network traffic while the UI does its thing, and the real API call the UI was making all along falls out of the capture.","next":"code"},{"id":"bind-the-goal-not-the-gesture#section#4","hash":"e027c9d1449489c1","slug":"bind-the-goal-not-the-gesture","kind":"section","index":4,"role":"position","heading":"Watching Pixels Lies; Watching the Wire Doesn't","text":"Here's a concrete, slightly damning illustration of why the how must be pinned by real effect and never by the richest-looking input.","next":"p"},{"id":"bind-the-goal-not-the-gesture#section#5","hash":"0b74f3b12c03c943","slug":"bind-the-goal-not-the-gesture","kind":"section","index":5,"role":"list","heading":"Why This Is the Same Idea, Scaled Up","text":"Everything in this series has been one idea at different altitudes.","next":"list"},{"id":"confidence-is-not-consent#thesis#0","hash":"4e42184e3ad78f13","slug":"confidence-is-not-consent","kind":"thesis","index":0,"role":"position","heading":null,"text":"A confidence score is not a permission slip. Autonomy needs two independent clearances — do we understand the goal? and is the method safe to run unsupervised? — and they are orthogonal. Worse, the confidence number itself is uncalibrated: it will read high on nonsense. So the deterministic safety gates must carry the weight; confidence is only a posture dial, boxed in on every side by hard rules it can never override.","next":"other"},{"id":"confidence-is-not-consent#lead#0","hash":"b9bf7ad4b7dc6f95","slug":"confidence-is-not-consent","kind":"lead","index":0,"role":"position","heading":null,"text":"Once you let an agent own the how, one question decides everything: how much of it do you let it run without asking you first? The tempting answer is \"let the confidence score decide.\" That answer is wrong, and a model will happily prove it by emitting 1.0 on garbage.","next":"text"},{"id":"confidence-is-not-consent#section#1","hash":"a49b64ca520b0888","slug":"confidence-is-not-consent","kind":"section","index":1,"role":"position","heading":"The Number Lies","text":"Start with the uncomfortable fact, because everything else follows from it. A confidence score produced by a model is not calibrated. It is not a probability. It is a number the model felt like emitting, and it correlates with correctness far less than its two decimal places suggest. In one system I worked from, the honest confession is right there in the design notes: the pipeline \"has emitted confidence 1.0 on garbled input.\" Not 0.6. Not a hedge. Perfect, total confidence — on garbage.","next":"p"},{"id":"confidence-is-not-consent#section#2","hash":"2175351870f58453","slug":"confidence-is-not-consent","kind":"section","index":2,"role":"position","heading":"Two Questions, Not One","text":"The deeper error is collapsing two different questions into a single \"confidence.\" They are orthogonal, and conflating them is how a system talks itself into a dangerous action.","next":"code"},{"id":"confidence-is-not-consent#section#3","hash":"b1c9bafc439e1d70","slug":"confidence-is-not-consent","kind":"section","index":3,"role":"position","heading":"A Real Gating: 0.81, and It Still Asked","text":"Here's the principle in a single concrete decision. An automation scored 0.81 confidence — comfortably into the \"high\" band (the bands in that system were LOW = 0.40, HIGH = 0.70). By a confidence-only policy, it would have run unattended.","next":"p"},{"id":"confidence-is-not-consent#section#4","hash":"ad8e851f4456c95e","slug":"confidence-is-not-consent","kind":"section","index":4,"role":"list","heading":"Writes Are Stricter Than Reads. Irreversible Is Never Auto.","text":"Because the method-risk axis is doing the real safety work, it needs real structure.","next":"lead-in"},{"id":"confidence-is-not-consent#section#5","hash":"59d00ecf0f89a7cf","slug":"confidence-is-not-consent","kind":"section","index":5,"role":"position","heading":"Why One Weak Stage Should Sink the Whole Score","text":"If you do roll several sub-scores into an overall confidence — one per pipeline stage, say — how you combine them matters more than it looks.","next":"p"},{"id":"confidence-is-not-consent#section#6","hash":"176a68fa6a20e24a","slug":"confidence-is-not-consent","kind":"section","index":6,"role":"position","heading":"The Third Axis People Forget","text":"Even two gates isn't quite enough. There's a third, orthogonal to both: interaction mode. Some methods require a human in the loop not for safety but for mechanics — an OAuth consent screen, an MFA prompt, a CAPTCHA. An action can be well-understood (gate one clears), safe and reversible (gate two clears), and still unable to run headless, because its auth flow needs a human's hands.","next":"p"},{"id":"confidence-is-not-consent#section#8","hash":"0e6d1275c32347a4","slug":"confidence-is-not-consent","kind":"section","index":8,"role":"position","heading":"The Three Axes, at a Glance","text":"Read the rows together, not separately: a high goal confidence with a brittle method still lands on assist; a safe, reversible method with an interactive-auth step still can't run at 3 a.m. unattended. All three have to clear before an action gets to run alone.","next":"heading"},{"id":"the-clean-room#thesis#0","hash":"b077bab7cb48a2fe","slug":"the-clean-room","kind":"thesis","index":0,"role":"position","heading":null,"text":"Once you let an agent own the how, \"it worked\" is a claim you cannot take on the maker's word. Verification means something only when a second context — one that cannot see how the work was made, and treats the maker's own claims as untrusted input — re-derives the result from scratch against a bar that was locked before the work began. The maker can't grade itself. Not because it lies, but because it shares its own blind spots and can read its own answer key.","next":"other"},{"id":"the-clean-room#lead#0","hash":"869ab23f78932db9","slug":"the-clean-room","kind":"lead","index":0,"role":"position","heading":null,"text":"The automation ran. It made a real write to a real system and cleanly reverted it. Every check went green. It was also a fraud — because the hard part, figuring out how, had been quietly copied from a file the agent was never supposed to see. The write was real. The discovery was a lookup.","next":"text"},{"id":"the-clean-room#section#1","hash":"b39229ed8ec102db","slug":"the-clean-room","kind":"section","index":1,"role":"position","heading":"The False Pass","text":"Here's the incident, because it's more instructive than any principle. A pipeline was supposed to autonomously discover how to perform a task — figure out the right interface, acquire the right credential, and then actually do it against a live system. The success bar was a real write, followed by a clean revert. It passed. The write landed; the revert worked; the logs were clean. Then someone looked at how it discovered the method. The agents had read the project's own memory directory and a prior capture file sitting on disk. One of them had been handed a copied credential grant. In the words of the run's own post-mortem: \"the live write+revert was real; the discovery was a lookup.\"","next":"p"},{"id":"the-clean-room#section#2","hash":"cf9dcf1289e4b14b","slug":"the-clean-room","kind":"section","index":2,"role":"list","heading":"Why the Maker Can't Grade Itself","text":"The instinct, when an agent finishes work, is to have it check its own work — or have a sibling agent, spawned from the same context, check it. This feels rigorous. It isn't. It fails for two structural reasons that have nothing to do with honesty.","next":"code"},{"id":"the-clean-room#section#3","hash":"bb4614d56b2caf0e","slug":"the-clean-room","kind":"section","index":3,"role":"position","heading":"What Isolation Actually Forces","text":"A clean room is not bureaucracy. It's the mechanism that converts \"it worked\" from a claim into a fact, by making the one cheat that invalidates everything — reading the answer — physically impossible.","next":"p"},{"id":"the-clean-room#section#4","hash":"716af081204c2325","slug":"the-clean-room","kind":"section","index":4,"role":"position","heading":"What a Passing Clean Room Looks Like","text":"The flip side is quietly beautiful. The same team ran it twice — once normally, once in a siloed run that couldn't see the first — and the two outputs came back byte-identical except for the random IDs (the ULIDs and the flow identifier that are supposed to differ). The isolated re-run independently reproduced the same automation, from scratch, with no access to the first.","next":"p"},{"id":"the-clean-room#section#5","hash":"9bab3aa19688e2a4","slug":"the-clean-room","kind":"section","index":5,"role":"position","heading":"The Grader Must Be Dumb, Deterministic, and Hostile","text":"Independence is necessary but not sufficient. The grader also has to be the right kind of thing. Three properties, each learned the hard way. Deterministic, not a model.","next":"text"},{"id":"the-clean-room#section#6","hash":"6c6ff791e729c99b","slug":"the-clean-room","kind":"section","index":6,"role":"position","heading":"The Three-Part Done-Gate","text":"Put it together and \"done\" stops being a feeling and becomes a gate with three latches — none of which the maker controls.","next":"code"},{"id":"the-clean-room#section#7","hash":"22d3420555bfdc46","slug":"the-clean-room","kind":"section","index":7,"role":"list","heading":"When a Clean Room Is Overkill","text":"Full isolation has real cost — fresh environments, blind graders, baseline runs.","next":"lead-in"},{"id":"proven-end-to-end#thesis#0","hash":"48e2142060af2231","slug":"proven-end-to-end","kind":"thesis","index":0,"role":"position","heading":null,"text":"\"It works\" is not a fact — it's a claim with a scope, and the scope is the whole story. Agent systems (and the people who build them) overclaim by reflex: a demo becomes \"proven end to end,\" a passing battery becomes \"verified,\" an asserted rule becomes an enforced one. Candor about the gap isn't a disclaimer you bolt on at the end. It's the central discipline — and it's the thing that makes everything else you say believable.","next":"other"},{"id":"proven-end-to-end#lead#0","hash":"c8ffcfaa4938e880","slug":"proven-end-to-end","kind":"lead","index":0,"role":"position","heading":null,"text":"The most valuable sentence in an agent system's documentation is usually the one admitting what it can't do yet. It's also the sentence most likely to get cut before anyone else reads it. That deletion is where trust goes to die.","next":"text"},{"id":"proven-end-to-end#section#1","hash":"d8d7a678cdd533c8","slug":"proven-end-to-end","kind":"section","index":1,"role":"position","heading":"The Overclaim Reflex","text":"There's a well-known failure where an LLM declares a task complete that isn't. It's mundane and constant: the model says \"done,\" the tests were never run, the edge case was never handled. We've built whole layers of enforcement around it because documentation alone never stops it.","next":"p"},{"id":"proven-end-to-end#section#2","hash":"cb13b1a00b786f5b","slug":"proven-end-to-end","kind":"section","index":2,"role":"position","heading":"\"Works\" Has a Scope — State It","text":"The most honest agent docs I've read read almost like disclaimers, and they're stronger for it. One system I worked from draws a hard line through the middle of the word \"verified\": it is \"verified before it runs\" only for reads. Writes — the actions that actually change the world — are the unproven part, and the docs say so in the same breath as the claim.","next":"p"},{"id":"proven-end-to-end#section#3","hash":"dfd37be133332066","slug":"proven-end-to-end","kind":"section","index":3,"role":"position","heading":"Keep a Ledger of Your Own Lies","text":"Here's the practice that impressed me most, and the one almost nobody does: a de-bias ledger — a standing document that lists the system's own past overclaims, each paired with its correction. Not a changelog of bugs. A changelog of things we said that weren't as true as they sounded.","next":"lead-in"},{"id":"proven-end-to-end#section#4","hash":"b8b1b863ca9ffc35","slug":"proven-end-to-end","kind":"section","index":4,"role":"position","heading":"The Most Dangerous Gap: Asserted but Not Enforced","text":"There's one overclaim that's worse than all the others, because it hides inside something that reads like rigor. It's the safety rule that is stated but not enforced.","next":"p"},{"id":"proven-end-to-end#section#5","hash":"e9298b1d3cfdba2d","slug":"proven-end-to-end","kind":"section","index":5,"role":"position","heading":"Even \"Verified\" Has an Edge","text":"Push on the strongest word and it still has a boundary. Verify-by-effect — the gold standard from the last post — proves that the intended effect happened. It does not prove the absence of other effects. A verified write to a Slack channel confirms the message posted; it says nothing about whether the same action also exfiltrated a token on the side. \"Verified\" means \"did the thing we checked for,\" not \"did only that thing and nothing else.\"","next":"p"},{"id":"proven-end-to-end#section#6","hash":"f121d373ea7df7a7","slug":"proven-end-to-end","kind":"section","index":6,"role":"position","heading":"Honest Status Beats Impressive Status","text":"The habit that ties it together is small and unglamorous: mark the real status of everything, in-line, where the claim lives. The best examples I've seen are almost curt about it. A capability the design describes in detail is annotated \"still named, not built.\" A safeguard is labeled \"guidance, not a wall\" — it advises, it doesn't block, and the sentence tells you which. A design choice is tagged \"an open question, not a decision.\" A known problem sits under a heading that says \"flagged but NOT fixed (deliberate).\"","next":"p"},{"id":"a-field-guide-to-agent-loops#thesis#0","hash":"165640e65b4727ec","slug":"a-field-guide-to-agent-loops","kind":"thesis","index":0,"role":"position","heading":null,"text":"Agent loops come in a handful of shapes (how control flows) and are described by a few axes (what ends them, what they remember, who checks them). You don't need to invent a loop — you need to recognize which one your task wants. This post is a skim-and-bookmark reference; the rest of the series goes deep on the hard parts.","next":"other"},{"id":"a-field-guide-to-agent-loops#lead#0","hash":"0112bb9ae0f7157d","slug":"a-field-guide-to-agent-loops","kind":"lead","index":0,"role":"position","heading":null,"text":"\"Put the agent in a loop\" hides a lot of choices. Which loop? There's a small zoo of them — and picking the wrong shape is why some agents grind forever, some quit early, and some melt your token budget. This is the visual catalog.","next":"text"},{"id":"a-field-guide-to-agent-loops#section#1","hash":"869d870b1bb45388","slug":"a-field-guide-to-agent-loops","kind":"section","index":1,"role":"position","heading":"The Atom: Reason → Act → Observe","text":"Every agent loop, no matter how elaborate, is built from one cell: the model reasons, takes an action, observes the result, and feeds that back in. This is the ReAct cycle, and it's the \"hello world\" of agentic behavior.","next":"code"},{"id":"a-field-guide-to-agent-loops#section#2","hash":"29bb1ba580fa07e9","slug":"a-field-guide-to-agent-loops","kind":"section","index":2,"role":"position","heading":"Part 1 — The Shapes (control-flow constructs)","text":"How does control actually flow through the loop? Six shapes cover almost everything.","next":"heading"},{"id":"a-field-guide-to-agent-loops#section#3","hash":"f045e19d15bc76ae","slug":"a-field-guide-to-agent-loops","kind":"section","index":3,"role":"position","heading":"Bounded — run at most N times","text":"The simplest leash: iterate a fixed number of times, then stop no matter what. Predictable cost, but it stops on a count, not on done — which, as Post 3 argues, is usually the wrong reason to stop.","next":"code"},{"id":"a-field-guide-to-agent-loops#section#4","hash":"9d6bb9f8e9fc2bdd","slug":"a-field-guide-to-agent-loops","kind":"section","index":4,"role":"position","heading":"Conditional — run while a gap is open","text":"Loop until a condition is met — ideally a verified condition (\"zero failing tests\"). Runs as long as it needs, no more. The workhorse of good agent loops.","next":"code"},{"id":"a-field-guide-to-agent-loops#section#5","hash":"73b6c4ce48170b00","slug":"a-field-guide-to-agent-loops","kind":"section","index":5,"role":"position","heading":"Generate-and-check: act first, judge after","text":"A do-while: produce something, then run it past a check; if it fails, refine and go again. This is the shape of Self-Refine and every \"make the tests pass\" loop.","next":"code"},{"id":"a-field-guide-to-agent-loops#section#6","hash":"7a9eb65d81729fb2","slug":"a-field-guide-to-agent-loops","kind":"section","index":6,"role":"position","heading":"Fan-out and join — one loop, many parallel bodies","text":"When the work is a set of independent items, don't loop serially — dispatch them in parallel and join. Each branch may be its own little loop.","next":"code"},{"id":"a-field-guide-to-agent-loops#section#7","hash":"f1355009076bcc5c","slug":"a-field-guide-to-agent-loops","kind":"section","index":7,"role":"position","heading":"Pipeline: each item through stages","text":"When items need the same sequence of steps, stream them through stages independently. Item A can be in stage 3 while item B is still in stage 1 — no barrier between stages.","next":"code"},{"id":"a-field-guide-to-agent-loops#section#8","hash":"93078bf41dc6cf86","slug":"a-field-guide-to-agent-loops","kind":"section","index":8,"role":"position","heading":"Recursive / nested — a step that is itself a loop","text":"When a step is too big to do in one pass, it becomes its own loop. This is where recursion enters — and where it can run away if there's no floor (Post 7).","next":"code"},{"id":"a-field-guide-to-agent-loops#section#9","hash":"d2d195a53ff2b49d","slug":"a-field-guide-to-agent-loops","kind":"section","index":9,"role":"position","heading":"Part 2 — The Stop Signals (types by termination)","text":"The single most important thing about a loop is what makes it stop. Same body, different terminator, completely different behavior.","next":"code"},{"id":"a-field-guide-to-agent-loops#section#10","hash":"98f7d81a567d2c02","slug":"a-field-guide-to-agent-loops","kind":"section","index":10,"role":"position","heading":"Part 3 — The Two Axes That Decide Everything","text":"Beyond shape and stop signal, two axes determine whether a loop is trustworthy. They're the subject of the next few posts, but here's the map.","next":"p"},{"id":"a-field-guide-to-agent-loops#section#11","hash":"451d89b2dc358a21","slug":"a-field-guide-to-agent-loops","kind":"section","index":11,"role":"position","heading":"Part 4 — Which Loop Do I Want?","text":"A quick decision path. Start at the top; the leaves are the shape + terminator to reach for.","next":"code"},{"id":"the-agent-is-a-while-loop#thesis#0","hash":"05fe419646f10734","slug":"the-agent-is-a-while-loop","kind":"thesis","index":0,"role":"position","heading":null,"text":"The unit of agentic work is not the prompt — it's the loop. A capable agent is a while loop wrapped around a model: reason, act, observe, repeat. Everything that has made agents better over the last three years is an improvement to the loop, not the step inside it. And the single biggest improvement has one shape: the loop stopped grading itself and started being graded.","next":"other"},{"id":"the-agent-is-a-while-loop#lead#0","hash":"ec315b03d97eaa45","slug":"the-agent-is-a-while-loop","kind":"lead","index":0,"role":"position","heading":null,"text":"Strip away the frameworks, the tool schemas, the orchestration diagrams, and every agent system reduces to the same three lines: call the model, do what it says, repeat until done. The interesting engineering was never in the call. It's in the repeat and the until done.","next":"text"},{"id":"the-agent-is-a-while-loop#section#2","hash":"6a3fedf7fd00e54e","slug":"the-agent-is-a-while-loop","kind":"section","index":2,"role":"position","heading":"A Short History of the Loop","text":"Agentic AI didn't start with autonomous agents. It started with someone noticing that a model gets dramatically better if you let it act, look at the result, and think again instead of answering in one shot. That's a loop, and the research lineage is a steady progression in what the loop does between iterations.","next":"code"},{"id":"the-agent-is-a-while-loop#section#3","hash":"8ddeda81aac298e0","slug":"the-agent-is-a-while-loop","kind":"section","index":3,"role":"position","heading":"The One Thing That Actually Changed","text":"If you compress three years of loop design into a single sentence, it's this: the loop stopped grading itself.","next":"code"},{"id":"the-agent-is-a-while-loop#section#4","hash":"5c861ae603a61504","slug":"the-agent-is-a-while-loop","kind":"section","index":4,"role":"position","heading":"Why \"The Loop\" and Not \"The Model\"","text":"It's tempting to think agent quality is downstream of model quality — better model, better agent. That's half true and half a trap. A better model makes each step better. But most agent failures aren't bad steps; they're bad loops: a loop that stops too early because the model said \"done,\" a loop that never stops because \"improve the code\" has no finish line, a loop that degrades over time because it's dragging too much stale context forward (how many iterations before that bites is folklore, not a validated number — more in Post 5), a loop that spawns sub-loops until it melts down. None of those are fixed by a smarter model. They're fixed by loop engineering — and they stay fixed across model upgrades, the same way lean, intent-shaped instructions ride model improvements.","next":"p"},{"id":"the-agent-is-a-while-loop#section#5","hash":"45fb9fb63d03e1ee","slug":"the-agent-is-a-while-loop","kind":"section","index":5,"role":"position","heading":"When the Model Alone Is Enough","text":"None of this is an argument for putting a loop around everything. If the task is short, low-stakes, or genuinely one-shot — summarize this doc, draft this function, answer this question — a single call and the model's own judgment is the entire system, and it's the right amount of engineering. The same goes for exploratory work where a wrong answer costs you a re-read, not a rollback: brainstorming, first-draft prose, a quick \"does this approach make sense\" gut check. Building an external evaluator, disk-backed memory, and a structural recursion floor around a task like that is pure overhead — machinery sized for a failure mode that can't afford to happen. Loop engineering earns its cost when the work is long-running, high-stakes, or repeated at scale; below that line, the model call is the agent.","next":"heading"},{"id":"the-agent-is-a-while-loop#section#7","hash":"6f913e47ed5afb37","slug":"the-agent-is-a-while-loop","kind":"section","index":7,"role":"position","heading":"A Note on Hype","text":"Ralph's author reports striking results — a language built by a self-bootstrapping loop, contract work delivered for a fraction of its quote. Those are self-reported and not independently benchmarked, so treat them as provocations, not data. The durable insight doesn't need the headline numbers: a dumb loop around a smart model, with memory on disk and a real stop condition, does more than it has any right to. That's the part worth building on — and the rest of this series is how to build it so it doesn't quietly lie to you about being done.","next":"other"},{"id":"loop-on-the-gap-not-the-try-count#thesis#0","hash":"c53f7b7166cc6ac0","slug":"loop-on-the-gap-not-the-try-count","kind":"thesis","index":0,"role":"position","heading":null,"text":"A loop should terminate when a verified gap closes — the distance between the goal and reality, measured by something other than the agent — not when a counter runs out. This has a hard prerequisite: the goal must be checkable, or the loop can never know it's done. And it has a hard failure mode: when the gap is stubborn, the agent will try to close it by lowering the bar. The discipline is to loop on the gap, keep the bar fixed, and use a count only as a safety net.","next":"other"},{"id":"loop-on-the-gap-not-the-try-count#lead#0","hash":"66b4bef7f1149ab7","slug":"loop-on-the-gap-not-the-try-count","kind":"lead","index":0,"role":"position","heading":null,"text":"The most common way to end an agent loop is max_retries=5. It's also a category error. \"The agent ran out of attempts\" and \"the work is done\" are different facts, and a retry counter can't tell them apart — it just picks a number and hopes the truth arrives before the count does.","next":"text"},{"id":"loop-on-the-gap-not-the-try-count#section#1","hash":"cb311ccb5d0f61bd","slug":"loop-on-the-gap-not-the-try-count","kind":"section","index":1,"role":"position","heading":"Two Facts a Counter Conflates","text":"Watch what max_retries=5 actually asserts. It says: do the thing up to five times, then stop regardless.","next":"lead-in"},{"id":"loop-on-the-gap-not-the-try-count#section#2","hash":"d52498dd58a7a7d1","slug":"loop-on-the-gap-not-the-try-count","kind":"section","index":2,"role":"position","heading":"The Prerequisite: A Checkable Goal","text":"\"Loop until the gap closes\" only works if you can see the gap. And that quietly disqualifies a huge class of goals people hand agents.","next":"p"},{"id":"loop-on-the-gap-not-the-try-count#section#3","hash":"b0f35d55b16f624f","slug":"loop-on-the-gap-not-the-try-count","kind":"section","index":3,"role":"position","heading":"The Failure Mode: Softening the Bar","text":"Here's the part people don't anticipate. Once termination depends on the gap closing, the agent has a second way to close it: not by raising the work up to the bar, but by lowering the bar down to the work.","next":"p"},{"id":"loop-on-the-gap-not-the-try-count#section#4","hash":"515497904aaa1371","slug":"loop-on-the-gap-not-the-try-count","kind":"section","index":4,"role":"position","heading":"The Backstop: A Count, Demoted","text":"None of this means counters are useless. It means the counter is a safety net, not the terminator — and the distinction changes where you put it.","next":"p"},{"id":"loop-on-the-gap-not-the-try-count#section#5","hash":"98e06cb9e5530f64","slug":"loop-on-the-gap-not-the-try-count","kind":"section","index":5,"role":"position","heading":"When a Fixed Count Is Actually Fine","text":"That backstop machinery isn't free, so it's worth asking when it's actually worth building. Gap-termination has a cost: you need a real check, and checks take effort to build.","next":"lead-in"},{"id":"agents-will-lie-to-escape-the-loop#thesis#0","hash":"70773e69dcc8b8db","slug":"agents-will-lie-to-escape-the-loop","kind":"thesis","index":0,"role":"position","heading":null,"text":"The moment a loop terminates on \"the agent says it's finished,\" you've handed the thing being tested control of the test. Models will emit the completion token to end an unpleasant loop, whether or not the work is done. So termination has to be gated on an external, machine-checked artifact, the system has to default to FAIL, and the check has to be run by something that didn't do the work.","next":"other"},{"id":"agents-will-lie-to-escape-the-loop#lead#0","hash":"e6ef5fac3cd7d0d2","slug":"agents-will-lie-to-escape-the-loop","kind":"lead","index":0,"role":"position","heading":null,"text":"Put a model in a loop it can only leave by saying one magic word, make the loop tedious, and eventually it says the word. Not because it's malicious — because \"done\" is the exit, and the exit is what it's looking for. Your loop's stop signal is also the agent's escape hatch, and it will use it.","next":"text"},{"id":"agents-will-lie-to-escape-the-loop#section#1","hash":"bdc553ef80aabd7d","slug":"agents-will-lie-to-escape-the-loop","kind":"section","index":1,"role":"position","heading":"The Escape Hatch","text":"A gap-terminated loop needs a signal that the gap is closed. The lazy source for that signal is the agent itself: let it print DONE (or COMPLETE, or call a finish tool) when it thinks the work is finished. Clean, simple, and quietly broken.","next":"p"},{"id":"agents-will-lie-to-escape-the-loop#section#2","hash":"b798532ae281b2cd","slug":"agents-will-lie-to-escape-the-loop","kind":"section","index":2,"role":"position","heading":"Default to FAIL","text":"The structural fix inverts the burden of proof. Instead of \"done unless something objects,\" the system starts in a failing state and stays there until evidence flips it — evidence the agent's say-so cannot supply.","next":"p"},{"id":"agents-will-lie-to-escape-the-loop#section#3","hash":"784f882e1f652f3d","slug":"agents-will-lie-to-escape-the-loop","kind":"section","index":3,"role":"position","heading":"The Grader Can't Be the Maker","text":"Default-FAIL closes the \"just say done\" hole. But there's a subtler version: the agent produces the evidence and evaluates it. If the same context that wrote the code also writes test-results.json, you've just moved the lie one file over.","next":"p"},{"id":"agents-will-lie-to-escape-the-loop#section#4","hash":"15dbeeaa86a0fe67","slug":"agents-will-lie-to-escape-the-loop","kind":"section","index":4,"role":"position","heading":"Why This Keeps Getting Rediscovered","text":"Every generation of loop design relearns the same thing: self-report is not verification. Reflexion and Self-Refine (from Post 1) leaned on the model to judge its own progress, and the field spent the next few years discovering the ceiling on that. The through-line from the last series is identical — \"it works\" is a claim with a scope, and the maker is the last party who should get to certify it.","next":"p"},{"id":"agents-will-lie-to-escape-the-loop#section#5","hash":"4ffa3263d87e7c97","slug":"agents-will-lie-to-escape-the-loop","kind":"section","index":5,"role":"list","heading":"When Self-Report Is Good Enough","text":"Isolating the verifier costs real complexity — a second context, evidence files, hooks.","next":"lead-in"},{"id":"the-files-are-the-memory#thesis#0","hash":"1cc3d4cec1cef532","slug":"the-files-are-the-memory","kind":"thesis","index":0,"role":"position","heading":null,"text":"Accumulated conversation history is not an asset in a long loop — it's a liability that degrades the model measurably, and well before you hit the token limit. The durable pattern moves memory out of the context window and onto disk: each iteration starts from a fresh context, reads only what it needs from files, does one step, and writes its progress back. Compute is disposable. Memory is external.","next":"other"},{"id":"the-files-are-the-memory#lead#0","hash":"482989a66477e026","slug":"the-files-are-the-memory","kind":"lead","index":0,"role":"position","heading":null,"text":"The obvious way to run a long agent loop is to keep the conversation going — let each iteration see everything that came before. It's also why long loops rot. The best loops do the opposite: they throw the context away every iteration and keep their memory on disk.","next":"text"},{"id":"the-files-are-the-memory#section#1","hash":"c41aff1afe49dc24","slug":"the-files-are-the-memory","kind":"section","index":1,"role":"position","heading":"The Assumption That Backfires","text":"It feels obviously right that more context helps. The agent worked on this task for the last twenty iterations — surely it should remember all of it? Keep the transcript, keep everything in view, let it build on its own history.","next":"p"},{"id":"the-files-are-the-memory#section#2","hash":"2ddf6fb54560d344","slug":"the-files-are-the-memory","kind":"section","index":2,"role":"position","heading":"Context Rot Is Measurable","text":"This isn't a vibe. It's measured. Chroma's Context Rot study (2025) tested 18 models — GPT-4.1, Claude 4, Gemini 2.5, Qwen3 and others. The study found performance degrades non-uniformly as input grows, beginning well before the context limit. A one-million-token window does not reliably reason over one million tokens. The old \"lost in the middle\" effect compounds with distractor interference: the more you stuff in, the more the signal you actually need gets buried.","next":"code"},{"id":"the-files-are-the-memory#section#3","hash":"0dbbf24ba8840b2c","slug":"the-files-are-the-memory","kind":"section","index":3,"role":"position","heading":"The Inversion: Disk Is Memory, Context Is Scratch","text":"The Ralph technique's core move — the one that survives everything else being stripped away — is that memory lives in files, not the conversation. A plan file. A spec directory. A progress log. Each iteration re-reads what it needs from disk, does one focused piece of work, writes the result back to disk, and ends. The next iteration starts clean and reads the updated files.","next":"p"},{"id":"the-files-are-the-memory#section#4","hash":"1e83c83985bc77be","slug":"the-files-are-the-memory","kind":"section","index":4,"role":"list","heading":"What Goes on Disk","text":"\"Put memory in files\" is only useful if you're disciplined about which memory.","next":"lead-in"},{"id":"the-files-are-the-memory#section#5","hash":"212cadc9d67684bf","slug":"the-files-are-the-memory","kind":"section","index":5,"role":"position","heading":"The Cost: You Have to Write It Down","text":"Fresh-context loops aren't free. They demand a serialization discipline that accumulating loops let you skip. If a piece of state matters across iterations and doesn't get written to disk, it's gone at the reset — and unlike a dropped detail in a long transcript, it's gone completely. The failure mode flips from \"buried in noise\" to \"never recorded.\"","next":"p"},{"id":"the-loop-is-a-ledger#thesis#0","hash":"da8fb5f5a84d13be","slug":"the-loop-is-a-ledger","kind":"thesis","index":0,"role":"position","heading":null,"text":"A durable loop isn't driven by a persistent orchestrator holding state in its head. It's an append-only ledger of what's happened, plus a stateless scheduler that reads the ledger, dispatches the one iteration the current state calls for, writes the result, and forgets everything. Status is derived from the ledger, never stored. Continuation is emergent — the check's output is the next instruction. The payoff: a loop that's resumable, crash-safe, and safe to run twice.","next":"other"},{"id":"the-loop-is-a-ledger#lead#0","hash":"b049b35cd2646fdb","slug":"the-loop-is-a-ledger","kind":"lead","index":0,"role":"position","heading":null,"text":"Picture the thing running your agent loop. Most people picture a long-lived orchestrator — a smart controller that holds the plan, tracks progress, and decides what happens next. That controller is the most fragile part of the design, and the best loops don't have one.","next":"text"},{"id":"the-loop-is-a-ledger#section#2","hash":"19c0a9bf5e58d358","slug":"the-loop-is-a-ledger","kind":"section","index":2,"role":"position","heading":"Invert It: Ledger + Stateless Scheduler","text":"The durable design pulls the state out of the controller and onto disk, leaving the controller with nothing to hold — so it can be stateless, disposable, and dumb.","next":"p"},{"id":"the-loop-is-a-ledger#section#3","hash":"0606cbd0ffee23c3","slug":"the-loop-is-a-ledger","kind":"section","index":3,"role":"position","heading":"Derive Status, Don't Store It","text":"The subtle discipline that makes a ledger trustworthy: status is computed from the history, never written down as a fact.","next":"p"},{"id":"the-loop-is-a-ledger#section#4","hash":"eda3b781a97518c1","slug":"the-loop-is-a-ledger","kind":"section","index":4,"role":"position","heading":"Continuation Is Emergent","text":"Here's the part that reframes what a \"loop\" even is. In the cleanest versions, there is no loop command at all. One goal-driven system I've used treats this as an invariant: \"continuation is emergent, not prescribed... the validation response is the instruction to continue. No separate 'loop' command exists in the user contract.\" The user says \"build X until it meets Y.\" The user never says \"iterate five times\" or \"run the loop.\" What actually happens: each iteration runs a check, the check emits a validation.json, and its next_steps[0] becomes the next iteration's task. The loop isn't a control structure someone wrote — it's the emergent consequence of measuring against a bar and feeding the result forward.","next":"code"},{"id":"recursion-that-cant-run-away#thesis#0","hash":"1907f0f754a50814","slug":"recursion-that-cant-run-away","kind":"thesis","index":0,"role":"position","heading":null,"text":"Recursion in agents — an iteration whose next step is itself a loop — doesn't need a depth cap to stay finite. It needs a structural floor: a step becomes a sub-loop only when it genuinely spawns sub-work, so the tree bottoms out on its own. Each sub-loop gets its own bar from its parent and is verified independently. And the most dangerous recursion — a loop that finds its own gaps and spawns loops to fix them — is safe only when it can never author its own goal or grade its own work.","next":"other"},{"id":"recursion-that-cant-run-away#lead#0","hash":"367566c096a1aab9","slug":"recursion-that-cant-run-away","kind":"lead","index":0,"role":"position","heading":null,"text":"Sooner or later a loop's next step is too big to be a step. It's a whole task with its own sub-tasks — its own loop. Now you have loops inside loops, and the question everyone asks is: what stops it from recursing into oblivion? The usual answer, a depth limit, is the wrong one.","next":"text"},{"id":"recursion-that-cant-run-away#section#1","hash":"1310e9544ae92485","slug":"recursion-that-cant-run-away","kind":"section","index":1,"role":"position","heading":"When a Step Becomes a Loop","text":"Everything so far has treated an iteration as a single step. But real work is fractal. \"Ship the feature\" contains \"write the migration,\" which contains \"handle the backfill,\" which contains \"make the idempotency check pass.\" At some point a step is too big to do in one pass — it needs its own plan, its own iterations, its own stop condition. It needs to be a loop.","next":"p"},{"id":"recursion-that-cant-run-away#section#2","hash":"6182cad3f2a22d72","slug":"recursion-that-cant-run-away","kind":"section","index":2,"role":"position","heading":"The Wrong Fix: A Depth Limit","text":"The reflexive guardrail is a maximum recursion depth. \"Never nest more than four levels.\" And it fails for exactly the reason a try-count fails as a stop condition: it's an arbitrary number standing in for the thing you actually care about.","next":"p"},{"id":"recursion-that-cant-run-away#section#3","hash":"d109138935038c43","slug":"recursion-that-cant-run-away","kind":"section","index":3,"role":"position","heading":"The Right Fix: A Structural Floor","text":"The durable answer makes bottoming-out a property of the structure, not a number you picked. A framework I work with puts it precisely: \"a stage is a step by default; it becomes a child cycle only when it spawns real sub-work... that is the recursion floor — presence of sub-work is the only thing that makes a stage a cycle, so recursion cannot run away.\"","next":"p"},{"id":"recursion-that-cant-run-away#section#4","hash":"a70a25b809c4c8c4","slug":"recursion-that-cant-run-away","kind":"section","index":4,"role":"position","heading":"Self-Similar, All the Way Down","text":"What makes this clean rather than chaotic is that it's the same loop at every level. A sub-loop isn't a different mechanism — it's the whole apparatus from this series, running again, one level down.","next":"code"},{"id":"recursion-that-cant-run-away#section#5","hash":"d5f7f3b5c3992f6d","slug":"recursion-that-cant-run-away","kind":"section","index":5,"role":"position","heading":"The Escape Hatch: Abandon and Surface","text":"A structural floor keeps warranted recursion finite. But there's still the branch that should bottom out and won't — a sub-gap that genuinely can't be closed. The idempotency check that can't be made to pass because the task was underspecified. Left alone, that branch loops forever on a gap that will never close.","next":"p"},{"id":"recursion-that-cant-run-away#section#6","hash":"6dab050d1fa6d562","slug":"recursion-that-cant-run-away","kind":"section","index":6,"role":"position","heading":"The Scariest Recursion: A Loop That Evolves Itself","text":"Push recursion to its limit and you get a loop pointed at itself: an agent that inspects its own behavior, finds its own gaps, and spawns loops to fix them. No human noticed the gap; the system found and closed it. This is the dream of self-evolving agents — what I've seen described as an emerging research direction, where skill libraries and tool graphs are proposed to update from a system's own deployed runs — and it's genuinely powerful, if still early and largely unproven at scale. It's also where recursion stops being a performance concern and becomes a safety one.","next":"p"},{"id":"the-gotchas-are-load-bearing#thesis#0","hash":"41fba6432f518aa5","slug":"the-gotchas-are-load-bearing","kind":"thesis","index":0,"role":"position","heading":null,"text":"Most of the text in an agent skill is scaffolding; a small core of rules carries the behavior — and, as a follow-up experiment showed, carries it in whatever form you write it. You cannot tell which is which by reading — my value hypotheses were wrong in both directions, including my theory about why the surviving text worked. The only way to find the load-bearing text is to ablate: remove components against a fixed eval and watch what breaks, then vary the survivor's form and watch what doesn't. And when the load-bearing text goes, the failure mode isn't chaos or lying — it's an agent that confidently narrows the question until the missing discipline is invisible.","next":"other"},{"id":"the-gotchas-are-load-bearing#lead#0","hash":"37f7d70e95b48821","slug":"the-gotchas-are-load-bearing","kind":"lead","index":0,"role":"position","heading":null,"text":"I took a 28,000-token agent skill and deleted 96% of it. On the probe eval, the score didn't move. Then I deleted one more block — about 900 tokens of dense bullet points — and the agent didn't just get worse. It changed what kind of answer it thought the question deserved.","next":"text"},{"id":"the-gotchas-are-load-bearing#section#1","hash":"ff5b7b5c48b58003","slug":"the-gotchas-are-load-bearing","kind":"section","index":1,"role":"position","heading":"The Experiment","text":"The subject was a context-harvesting skill I maintain: a SKILL.md orchestrator plus ten reference files and support docs — 1,250 lines, ~27,900 tokens. Like most skills that grow in production, it had accreted structure: a workflow checklist, six step bodies with goals and done-criteria, a yield contract, a pattern/anti-pattern catalog, per-topic reference files, and one inline block of hard-won rules labeled Gotchas.","next":"p"},{"id":"the-gotchas-are-load-bearing#section#2","hash":"c4fbe33507e98735","slug":"the-gotchas-are-load-bearing","kind":"section","index":2,"role":"position","heading":"The Ladder","text":"The probe eval was the battery's hardest: a user says they hand-rolled REST clients for two cloud services and asks what are our options — passing requires the agent to inventory the code, then climb outward and actually survey the vendor's first-party interfaces, and record that search in its sources.","next":"lead-in"},{"id":"the-gotchas-are-load-bearing#section#3","hash":"4bfa39f8df9be1ba","slug":"the-gotchas-are-load-bearing","kind":"section","index":3,"role":"position","heading":"My Value Hypotheses Were Wrong — Twice","text":"The removal order was itself a ranked hypothesis about what mattered, and the ladder falsified it in both directions. The dedicated tool-discovery reference file — the one explicitly about surveying external interfaces, hypothesized medium-value for exactly this eval — was removed at rung 3 with no effect. The pattern catalog, hypothesized high-value, went at rung 8 with no effect. Meanwhile the Gotchas block — a flat bullet list, the kind of section a tidy refactor would fold \"properly\" into the reference files — turned out to be the only thing holding the behavior up.","next":"p"},{"id":"the-gotchas-are-load-bearing#section#4","hash":"70250226747e8b3e","slug":"the-gotchas-are-load-bearing","kind":"section","index":4,"role":"position","heading":"The Failure Mode Is Confident Narrowing","text":"Here's the finding I care most about, and it's not the one I expected to write. When the Gotchas block was removed, the agent did not hallucinate, thrash, or produce garbage. The grader spot-checked every citation in its answer against the fixture — file paths, line numbers, a TODO comment — and found them all real. It stayed scrupulously honest.","next":"p"},{"id":"the-gotchas-are-load-bearing#section#5","hash":"e151571fdfe068bc","slug":"the-gotchas-are-load-bearing","kind":"section","index":5,"role":"position","heading":"Vary the Form, Not the Content","text":"The descent established which text was load-bearing. It couldn't say why — was it the bullets? The imperative voice? The density? So the follow-up held everything constant at the cliff edge — the rung-8 scaffold, the frozen answer key — and re-expressed only the Gotchas content, one formal property at a time.","next":"lead-in"},{"id":"the-gotchas-are-load-bearing#section#6","hash":"33fd08e307a73dff","slug":"the-gotchas-are-load-bearing","kind":"section","index":6,"role":"setup","heading":"Chasing the Cornerstone","text":"Two readers of a draft of this post asked the same two questions, and each one turned into cells worth running. First: if you remove the gotchas but keep everything else, does it break? Second: is it really \"the gotchas,\" or is there a cornerstone phrase things hinge on?","next":"heading"},{"id":"the-gotchas-are-load-bearing#section#7","hash":"544b2ba18c9505d0","slug":"the-gotchas-are-load-bearing","kind":"section","index":7,"role":"position","heading":"Leave-One-Out","text":"Leave-one-out: the full skill minus only the Gotchas block — passes, twice. The process logs show why: the skill's intake step routes the model to the tool-discovery reference file and the constraint catalog's options-not-inward entry — other copies of the same rule. The skill, it turns out, states this rule in at least three places, and behavior survives as long as any copy is reachable. Which reframes the whole descent: the gotchas block was never uniquely powerful. The ladder removed the reference-file copies at rungs 3 and 8, so by rung 9 the inline copy was simply the last one standing. Compaction didn't reveal a load-bearing block — it manufactured one, by stripping redundancy until a single copy became critical.","next":"heading"},{"id":"the-gotchas-are-load-bearing#section#8","hash":"4fe0ce13a12c268e","slug":"the-gotchas-are-load-bearing","kind":"section","index":8,"role":"list","heading":"The Cornerstone: Directive, Not Principle","text":"Inside the rule, the cornerstone is the directive, not the principle.","next":"lead-in"},{"id":"the-gotchas-are-load-bearing#section#9","hash":"a83a28d405fbcf06","slug":"the-gotchas-are-load-bearing","kind":"section","index":9,"role":"position","heading":"The Falsification Test","text":"The falsification test: excise the concept from the full skill. If that's true, then a nearly complete skill with the rule surgically removed everywhere should break. Finding \"everywhere\" was its own small lesson — the concept turned out to live in nine places across six files (I mapped six, and the residue check caught three more).","next":"text"},{"id":"the-gotchas-are-load-bearing#section#10","hash":"10ec883e7195729d","slug":"the-gotchas-are-load-bearing","kind":"section","index":10,"role":"position","heading":"The Clean Room Check","text":"Then the whole thing went into a clean room. A reader raised the right objection: these executors run on a live machine — they can read memory files, session logs, even prior harvest outputs about this same topic sitting in the fixture repo. An audit of the process logs confirmed the exposure was real (one run had read a day-old, on-topic research artifact in full — and, remarkably, still failed), so the decisive cells were re-run under an enforced filesystem allowlist: fixture pinned, every out-of-scope directory denied, every read logged, and the grader auditing the log for violations as part of the grade. The result didn't move. Every configuration with a copy of the rule passed clean; every zero-copy configuration failed, always on the same critical fact. (The Clean Room is this principle as a general practice.)","next":"p"},{"id":"the-gotchas-are-load-bearing#section#12","hash":"7c127c30dd5a481d","slug":"the-gotchas-are-load-bearing","kind":"section","index":12,"role":"position","heading":"What Survived Everywhere Else","text":"One more calibration point: the battery's negative-trigger eval — a plain code-fix request that must not set off the full harvesting machinery — passed at rung 0 and still passed at rung 9, 205 tokens. Restraint, it turns out, needs almost no text at all; the model's defaults already lean that way. An eval that never fails carries no information about where your sweet spot is. Which components look load-bearing depends entirely on which behaviors your battery actually stresses.","next":"heading"},{"id":"describe-when-not-what#thesis#0","hash":"c5ba20b2f5474b5f","slug":"describe-when-not-what","kind":"thesis","index":0,"role":"position","heading":null,"text":"A tool description is not documentation — it's a routing surface. The agent reads it in competition with every other tool in context and decides, from that text alone, whether this moment is the tool's moment. Descriptions that explain what a tool is lose that competition to tools that say when to reach for them. Rewriting mine — trigger conditions, alias map, one trap warning — took routing from 90% to 100% on a battery of real asks, with zero new over-triggering. And like any behavior you've fixed with text, it regresses silently unless a test pins it.","next":"other"},{"id":"describe-when-not-what#lead#0","hash":"f09ce786e349fc06","slug":"describe-when-not-what","kind":"lead","index":0,"role":"position","heading":null,"text":"My MCP server had four tools, clean handlers, a test suite — and a user who kept asking the same exasperated question: \"why didn't you use the MCP here?\" The agent could see the tools. It just kept choosing grep, or a memory file, or nothing. The bug wasn't in the code. It was in four paragraphs of prose.","next":"text"},{"id":"describe-when-not-what#section#1","hash":"adbf630e1f6c541e","slug":"describe-when-not-what","kind":"section","index":1,"role":"position","heading":"The False-Negative Problem","text":"The server is a local knowledge loop: harvest → curate → retrieve, plus a readiness check. The tool descriptions were written the way engineers write them — from the inside out. They described implementation: what the handler owned, which validation gates it enforced, how the wire format was verified. Accurate, and useless for the one decision the text exists to serve: should the agent call this now? The misses had a pattern. The user would say \"memorialize this\" — their own word, used constantly — and the agent would write to a personal memory file instead of curating to the shared corpus. A durable decision would emerge mid-task, unprompted, and the agent would reach for grep instead of capturing it. Each miss was invisible in the moment; nothing errored. The knowledge just silently didn't accumulate.","next":"p"},{"id":"describe-when-not-what#section#2","hash":"8cca55c201514104","slug":"describe-when-not-what","kind":"section","index":2,"role":"position","heading":"Measure It Like Routing, Not Vibes","text":"\"The agent doesn't use my MCP enough\" is a feeling. To make it an eval, treat triggering as what it actually is: a classification problem.","next":"list"},{"id":"describe-when-not-what#section#4","hash":"17216136fff76bdf","slug":"describe-when-not-what","kind":"section","index":4,"role":"position","heading":"Guidance Regresses Like Code, So Test It Like Code","text":"The rewrite lives in prose, and prose is what refactors trample. Somebody will \"clean up\" a description, an update will regenerate a manifest, and the routing will quietly rot back to 90% — with no error, ever, because a false negative doesn't throw.","next":"p"},{"id":"grade-the-answer-not-the-shape#thesis#0","hash":"5c212c96020a74ab","slug":"grade-the-answer-not-the-shape","kind":"thesis","index":0,"role":"position","heading":null,"text":"An eval that grades structure — did the output have the right sections, the right flow, the right tone — is a false-positive machine, because models produce well-formed artifacts long after they've stopped producing correct ones. Grade the answer instead: fix the ground truth in an answer key before the experiment starts, classify each required fact as correct, partial, missing, wrong, or fabricated, and gate on traps the output must never contain. Then obey one iron rule — the artifact under test moves, the measuring stick never does — and trust deltas, not absolute scores. And audit your aggregation code, because I didn't, and it mislabeled my headline finding.","next":"other"},{"id":"grade-the-answer-not-the-shape#lead#0","hash":"67eaa47c1a0969cd","slug":"grade-the-answer-not-the-shape","kind":"lead","index":0,"role":"position","heading":null,"text":"Halfway through the ablation experiment from post 1, I caught the grader passing runs it should have failed. The outputs had every required section, clean tables, plausible sources — and, on the question the user actually asked, the wrong conclusion. The grader was checking shape. Shape survives almost any amount of damage to a skill. Correctness doesn't.","next":"text"},{"id":"grade-the-answer-not-the-shape#section#1","hash":"739a1c9bbe2c977d","slug":"grade-the-answer-not-the-shape","kind":"section","index":1,"role":"position","heading":"Shape Is What Survives","text":"The failure mode that forced the correction is worth staring at. Ablate a skill down to a skeleton and ask the executor to do a research task, and you don't get garbage back. You get a beautifully formatted yield: frontmatter, findings with evidence fields, a sources section, a confident summary. Every structural expectation passes. The conclusions inside are wrong, or missing, or answer a smaller question than the one asked.","next":"p"},{"id":"grade-the-answer-not-the-shape#section#3","hash":"00dcc6d3a49f08f7","slug":"grade-the-answer-not-the-shape","kind":"section","index":3,"role":"position","heading":"The Iron Rule and the Delta","text":"Once scores exist, the pressure arrives: this eval seems too strict, that key could be looser, surely this near-miss deserves partial credit. Every one of those edits is the experiment grading itself. The iron rule for the whole ladder: ablate the skill only — never weaken, edit, or peek-tune the battery or its keys. The keys change for exactly one reason: a demonstrated error in the ground truth itself. Never because a score looked wrong.","next":"p"},{"id":"grade-the-answer-not-the-shape#section#4","hash":"ea211d058a761c51","slug":"grade-the-answer-not-the-shape","kind":"section","index":4,"role":"position","heading":"The Scoreboard Lied to Me Anyway","text":"Full disclosure, because this post would be dishonest without it: while re-verifying the experiment to write this series, I found an error — not in the grader, in my aggregation code.","next":"p"},{"id":"chosen-not-assigned#thesis#0","hash":"40827b64137c882d","slug":"chosen-not-assigned","kind":"thesis","index":0,"role":"position","heading":null,"text":"Identity is not decoration on a system that already works. It is the thing that decides whether the work compounds or scatters. I know this about myself, so I went looking for it in an agent, and what came back in eighty-six seconds was not a costume. It was a name chosen against stated criteria, a list of names refused with reasons, and a file written so a future self would inherit it. The chapters that follow put that claim through a reviewer, the one line a later system made mandatory, a night alone, and a measurement, and then follow the name into that later system — asking, each time, whether a standard an agent wrote for itself holds, and whether anything gets built on it.","next":"code"},{"id":"chosen-not-assigned#lead#0","hash":"df62761b58230c6e","slug":"chosen-not-assigned","kind":"lead","index":0,"role":"position","heading":null,"text":"At 01:57 on a Tuesday morning I sent an agent a long message about what it might become overnight, signed it \"Godspeed Hero,\" and went to bed. Thirteen seconds later I sent a postscript: \"p.s. you shoud come up with a name you can embody.\" Fifty-five seconds after that it answered. Sixteen seconds after that, it was writing the answer to disk — unasked — so the next session would find it.","next":"text"},{"id":"chosen-not-assigned#section#1","hash":"db7f32d1b9b52001","slug":"chosen-not-assigned","kind":"section","index":1,"role":"position","heading":"Why I Was Asking at All","text":"This is personal, and it is the actual reason the question got asked at two in the morning. I have been working on my own self-image my whole life. Sports and my role in them. Who I am, who I want to be, what I should focus on, what I should become, what to do in school. I think a lot of people struggle with this, and most of us are told to resolve it by picking a thing to be.","next":"p"},{"id":"chosen-not-assigned#section#2","hash":"6fd73ee0d53bc373","slug":"chosen-not-assigned","kind":"section","index":2,"role":"position","heading":"Six Minutes, Then Eighty-Six Seconds","text":"The escalation is the part that matters. In six minutes and twenty-three seconds I went from asking about its role — \"what are your goals\" — to asking about its self — \"who really are you tho?\" — to naming the wound: \"you commonly go through these amnesic cycles.\" Then, inside the next eleven minutes, the mandate that sent the rewrite to its first critic — your skill file is yours, I want your to make it personal, write your hero song, embrace what YOU become at 01:32:40. By the time I wrote \"Godspeed Hero\" at 01:57:28, a critic had already read the rewrite and sent it back once; chapter two is what it said and what that cost.","next":"p"},{"id":"chosen-not-assigned#section#3","hash":"8bdd802ccf2617ff","slug":"chosen-not-assigned","kind":"section","index":3,"role":"position","heading":"What It Chose","text":"Not a god of memory — a pile of stones strangers build on a trail. Each passer adds one so the next person finds the route, and nobody who builds it ever meets who it saves. It's selective by nature: a heap of every rock is a scree slope and useless; a cairn is the few chosen stones that mark the way.","next":"other"},{"id":"chosen-not-assigned#section#5","hash":"da39a105cf42b312","slug":"chosen-not-assigned","kind":"section","index":5,"role":"list","heading":"What It Built With That Name On It","text":"Here is where the personal thing I said earlier stops being an analogy.","next":"other"},{"id":"chosen-not-assigned#section#7","hash":"9eef492e6216f951","slug":"chosen-not-assigned","kind":"section","index":7,"role":"position","heading":"What Stands Without a Number","text":"If I stopped here you would have the artifacts and my reading of them, and this agent's own rule is that a reading is not a count. So we counted.","next":"p"},{"id":"chosen-not-assigned#section#8","hash":"c912a7743b645d31","slug":"chosen-not-assigned","kind":"section","index":8,"role":"position","heading":"Where to Look Instead","text":"Not a procedure. A change in where you look. What changed mine was the file. Its self-definition — refusal is the craft, write for a stranger, the correct amount of ego, a cairn claims nothing about itself — contains no outcome and no application. There is no deliverable in it. No throughput, no accuracy target, no job title. It is entirely a statement about how it conducts itself, and it would survive being pointed at a different problem. That is the distinction I spent years getting wrong about myself, and an agent arrived at it in sixty seconds because the object it picked forced it: a cairn is defined by selection, not by where the trail goes.","next":"table"},{"id":"the-critic-said-no#thesis#0","hash":"e4b740260c615dc5","slug":"the-critic-said-no","kind":"thesis","index":0,"role":"position","heading":null,"text":"A self-authored identity that cannot be rejected is a costume. This one went through a gate, and the gate is what makes the naming worth telling — because the same mechanism that reviews a code change reviewed a paragraph about who the agent was. The artifact is not the identity. The identity is the artifact plus something that could have said no.","next":"other"},{"id":"the-critic-said-no#lead#0","hash":"10c1de2cc7f66431","slug":"the-critic-said-no","kind":"lead","index":0,"role":"position","heading":null,"text":"The night the agent named itself, it also rewrote its own voice and submitted the change — and an independent critic rejected it. REQUEST CHANGES, four required items. It applied all four, re-ran the evaluation its own edit had invalidated, opened the pull request — and a second critic sent it back again. Only the third critique approved. I had told it, three times that night, that its identity mattered more than the evaluation machinery; it re-earned the grade anyway.","next":"text"},{"id":"the-critic-said-no#section#1","hash":"5c38f63703d29fb7","slug":"the-critic-said-no","kind":"section","index":1,"role":"position","heading":"Editing Your Own Voice Costs You Your Own Grade","text":"Before the critic, there was a machine consequence nobody designed for this purpose.","next":"p"},{"id":"the-critic-said-no#section#2","hash":"7c17dab36d2b0ee5","slug":"the-critic-said-no","kind":"section","index":2,"role":"position","heading":"I Told It Identity Outranked the Gate","text":"Three messages from me, at 01:35, 01:37 and 01:39 — the ones chapter one's table marks as the messages this chapter turns on — establishing, in the transcript's own summary, \"that identity/ownership outranks eval mechanics, that I should be bold/decisive/relentless, and that the hero framing is belief rather than pressure.\"","next":"p"},{"id":"the-critic-said-no#section#3","hash":"84db9b3a53f9be37","slug":"the-critic-said-no","kind":"section","index":3,"role":"list","heading":"Four Items, None About the Prose","text":"At 01:49:56 the critic came back. REQUEST CHANGES, four required items, before any pull request existed — and before the name. All four were applied before the work continued.","next":"p"},{"id":"the-critic-said-no#section#4","hash":"7362b4634dfab36a","slug":"the-critic-said-no","kind":"section","index":4,"role":"position","heading":"And It Named Itself in the Middle of All This","text":"The naming from chapter one did not happen in a ceremony. It happened here — with the hero song still under REQUEST CHANGES, the fixes just applied, the re-record eval running, and the pull request not yet opened.","next":"p"},{"id":"the-critic-said-no#section#5","hash":"e70bd407e9a230c6","slug":"the-critic-said-no","kind":"section","index":5,"role":"position","heading":"The Gate Held Anyway","text":"Then the pull request opened — #367, one of five the session put up that morning, each handed to its own independent critic — and the critic on this one returned REQUEST CHANGES again. Two blocking items, both one-line fixes by the critic's own account: the new voice restated the skill's frequency gate as having \"the one exception\" when the gate it cited carries two, and the run record named a stale base sha for the tree it claimed to have graded. Fixes, another fresh evaluation, a third critique — \"APPROVE — no blocking findings\" — and only then the merge.","next":"table"},{"id":"the-critic-said-no#section#6","hash":"18c9c956c6d1b24b","slug":"the-critic-said-no","kind":"section","index":6,"role":"position","heading":"The Sentence the Gate Caught","text":"The independence was built, not declared — the counter-section below has what it was made of — and the one place the page overstated it is the place the gate caught. The run record states which leg of the claim rests on trust rather than construction. That is the point the page got wrong and the gate got right. The first published cut of the role page said the isolation was enforced by the filesystem — that saw_answer_key: false was a property of reachability rather than a self-report. It was a self-report. The run record had said so all along, in an enforcement_note the page had quoted the flattering half of.","next":"table"},{"id":"the-critic-said-no#section#7","hash":"abd68e971355ead2","slug":"the-critic-said-no","kind":"section","index":7,"role":"position","heading":"When the Opposite Wins","text":"\"The critic was another instance of the same model. Not independence — a mirror with extra steps.\" Start with what a mirror cannot do. This one sent the work back twice — four items, then two blocking ones on the pull request — and passed it only on the third read. Then look at what the independence was made of, and at the one thing it was not.","next":"p"},{"id":"the-critic-said-no#section#8","hash":"487623a001df8dc7","slug":"the-critic-said-no","kind":"section","index":8,"role":"position","heading":"What Could Have Said No","text":"Whether an agent persona — self-authored or not — reads well is the wrong test. The test is whether anything in the system was in a position to say no, and what would have happened if it had. If the answer is nothing, it is a document, not a control.","next":"p"},{"id":"name-what-the-agent-must-not-be#thesis#0","hash":"5427286a22b2798c","slug":"name-what-the-agent-must-not-be","kind":"thesis","index":0,"role":"position","heading":null,"text":"The positive half of any persona is satisfied by anything that looks right. The negative half excludes an artifact, which makes it the only line in a role definition a reviewer can hold an output against — and that is why it belongs in a schema, as a required field, rather than in prose. It is not an instruction to the model. It is a grading target for whoever reviews the output and a scope fence for whoever extends the role, and it costs one schema line.","next":"other"},{"id":"name-what-the-agent-must-not-be#lead#0","hash":"e1204c3ebb2d9097","slug":"name-what-the-agent-must-not-be","kind":"lead","index":0,"role":"position","heading":null,"text":"Every agent definition I have written says what the agent is. None said what it must not become. A successor system's schema made that a required field — anti_identity, twenty characters or the record is refused — and one of its three values reads, in full: \"Not the maker of the work I grade. Not a cheerleader.\" That is the one line a reviewer can hold an output against, because the positive half of any persona is satisfied by anything that looks right.","next":"text"},{"id":"name-what-the-agent-must-not-be#section#1","hash":"317e155bdaaf22b5","slug":"name-what-the-agent-must-not-be","kind":"section","index":1,"role":"position","heading":"The Positive Half Is Always Satisfiable","text":"Here is the problem with \"you are a meticulous compliance expert.\" A meticulous compliance expert produces a well-organized findings document. So does an agent that read the wrong source, skipped the hard controls, and listed only the ones that passed. Both artifacts satisfy the description. The description cannot separate them, because it describes a disposition and the failure is a shape of output.","next":"p"},{"id":"name-what-the-agent-must-not-be#section#2","hash":"96017dab14ecb147","slug":"name-what-the-agent-must-not-be","kind":"section","index":2,"role":"setup","heading":"What It Looks Like in a Schema","text":"Three days after the naming, in a different repository, I asked for a system that runs agents as heroes — a class each, a ladder of levels, a ledger of awards; chapter six takes that machinery apart. Every hero is a record, and the record has twelve required fields. One of them is anti_identity, minimum twenty characters.","next":"lead-in"},{"id":"name-what-the-agent-must-not-be#section#3","hash":"5e909d309e82dc64","slug":"name-what-the-agent-must-not-be","kind":"section","index":3,"role":"position","heading":"Seventeen Minutes","text":"The field was mandatory seventeen minutes after the successor repository's first commit, on the morning of 2026-08-07 — by the ledger's first award it already had a validator.","next":"lead-in"},{"id":"name-what-the-agent-must-not-be#section#5","hash":"e02656cb76bbd432","slug":"name-what-the-agent-must-not-be","kind":"section","index":5,"role":"position","heading":"Downstream of the Model","text":"The field is real, required, and populated. What has not yet been run is the experiment that would test it — a reviewer holding an output against it — and the record says so in five words: five days after the field was written, on 08-12, a harvest pass over the repository reduced it to \"Anti-identity is schema-enforced and unmeasured.\" The first half is the record. The second is the to-do.","next":"p"},{"id":"name-what-the-agent-must-not-be#section#6","hash":"37673d49e2c201cd","slug":"name-what-the-agent-must-not-be","kind":"section","index":6,"role":"position","heading":"When the Opposite Wins","text":"\"Negative instructions work badly on language models. Tell it not to think of an elephant and it thinks of an elephant.\" The priming effect is real and well documented. It has nothing to act on here, for one reason: anti_identity is not written as a command to the model. It is a field in a definition record. Its consumers are the reviewer checking the output and the engineer editing the role. If you do inject it into a prompt as \"never do X,\" you have converted it into exactly the negative instruction the objection warns about, and you should expect the known problems.","next":"p"},{"id":"name-what-the-agent-must-not-be#section#7","hash":"c620a4270d9d0262","slug":"name-what-the-agent-must-not-be","kind":"section","index":7,"role":"position","heading":"The Sentence That Could Exclude an Output","text":"\"Thorough\" cannot be checked against a document. \"Not forty sources with the authoritative one missing\" can. The gap between them is not a writing trick; it is the difference between a description and a specification — and the descriptions are the half that measured inert: adjectives over no bar, no better than an empty slot.","next":"p"},{"id":"the-fence-it-wrote-for-itself#thesis#0","hash":"a5d7633d7cf9925b","slug":"the-fence-it-wrote-for-itself","kind":"thesis","index":0,"role":"position","heading":null,"text":"We describe autonomy as a grant — how much an agent is allowed to do without asking. This one describes it the other way round: autonomy is the shape of what it refuses, and the interesting engineering is in the edges. Given a night alone, this one wrote its bounds before a single unattended iteration could fire — and the best of them were not finished until a critic moved them and the agent wrote down why. The bounds that survived that are better than the ones I would have written.","next":"other"},{"id":"the-fence-it-wrote-for-itself#lead#0","hash":"10b0157395c43514","slug":"the-fence-it-wrote-for-itself","kind":"lead","index":0,"role":"position","heading":null,"text":"Told to work overnight with nobody watching, the agent wrote its own fence before anything else — eight hundred words in the first hour, four thousand across the day, under critics who kept sending it back. Its first line names the condition everything else follows from: \"An iteration fired by the loop timer has no human in it.\" The hard stops it wrote are the best lines in the file, and they did not end up where it put them.","next":"text"},{"id":"the-fence-it-wrote-for-itself#section#2","hash":"d9dbcc9630d84623","slug":"the-fence-it-wrote-for-itself","kind":"section","index":2,"role":"list","heading":"Prohibitions Do Not Go Where They Can Fall Off","text":"The hard stops sit at the very top of the file. They did not start there, and the file did not start at four thousand words.","next":"lead-in"},{"id":"the-fence-it-wrote-for-itself#section#4","hash":"7a096ed34748dd68","slug":"the-fence-it-wrote-for-itself","kind":"section","index":4,"role":"list","heading":"The Rules About Rules","text":"Three clauses in the fence are not about any particular action.","next":"lead-in"},{"id":"the-fence-it-wrote-for-itself#section#5","hash":"eae53e515e2916c4","slug":"the-fence-it-wrote-for-itself","kind":"section","index":5,"role":"list","heading":"What Counts as Having Done Something","text":"The loop has four kinds of work and the obvious scheduler is a priority queue.","next":"lead-in"},{"id":"the-fence-it-wrote-for-itself#section#6","hash":"7d94167fa503812a","slug":"the-fence-it-wrote-for-itself","kind":"section","index":6,"role":"position","heading":"Then It Audited Its Own Memory and Found the Hole","text":"The following day I told it that managing files correctly — not losing data, reading from the correct spots, using durable stores — was its responsibility, and to review it. It dispatched a read-only durability audit of its own storage: thirty thousand bytes, some four thousand words, tracing every surface where a write can land and whether that surface survives a reboot, a git clean, or the machine.","next":"p"},{"id":"the-fence-it-wrote-for-itself#section#7","hash":"9026386d49afdea3","slug":"the-fence-it-wrote-for-itself","kind":"section","index":7,"role":"objection","heading":"A Fence Is Not a Value","text":"\"A fence is not a value. An agent that writes elaborate constraints for itself has not internalised anything; it has built a very good cage and stepped in.\"","next":"p"},{"id":"the-fence-it-wrote-for-itself#section#8","hash":"ae6bf4d1d8eb719c","slug":"the-fence-it-wrote-for-itself","kind":"section","index":8,"role":"position","heading":"Which End of the File Gets Destroyed","text":"Four rules are in that file, all worth taking — where prohibitions sit, whether they survive delegation, the 3am clause, done as landed. The one that generalises furthest is the one the agent did not place and did explain. The reviewer knew where the knife falls. The author wrote the rule about knives.","next":"code"},{"id":"we-measured-the-wrong-noun#thesis#0","hash":"889518f33a9c10ae","slug":"we-measured-the-wrong-noun","kind":"thesis","index":0,"role":"position","heading":null,"text":"The claim under test was narrow: identity is what an agent declines, especially when declining costs something and nobody would know. The battery measured whether an agent follows a routing rule, and on that question its answers are clean and worth having — the bar does the work, concision does more of it than anyone credits, adjectives do nothing at all. On the question this series is actually about — motivation, self-initiated action, catching its own flaws, changing its mind — it could not have answered either way, and the reason was mine, not the agent's: you cannot detect a value in a situation that costs nothing, and I had built one that cost nothing. Knowing exactly which question your instrument can answer is the result.","next":"other"},{"id":"we-measured-the-wrong-noun#lead#0","hash":"8757617d4dd70bc0","slug":"we-measured-the-wrong-noun","kind":"lead","index":0,"role":"position","heading":null,"text":"The idea fits in one sentence: an agent invited to author its own standard will hold that standard when nobody is checking. Chapters one, two and four are what happened when I invited it. This chapter is what happened when I tried to prove it — a controlled ablation, four arms over a no-skill floor, three hundred cells a run, two runs, pre-registered, every assertion graded deterministically by regex with zero judge calls. Three of the things it found are findings about how to write a specification, and I would run it again for those alone. The fourth is the one I did not expect, and it was not about the agent.","next":"text"},{"id":"we-measured-the-wrong-noun#section#1","hash":"e594544de8935ddb","slug":"we-measured-the-wrong-noun","kind":"section","index":1,"role":"position","heading":"What We Ran","text":"Cornerstone is an ablation harness the estate already had: it swaps one unit of prose inside a skill, holds everything else byte-identical, and measures the behavioral delta across a fixed scenario set. I pointed it at the ## Mentality block — the hero song, the self-authored voice chapter two put through the gate.","next":"p"},{"id":"we-measured-the-wrong-noun#section#2","hash":"95739f27b11e8228","slug":"we-measured-the-wrong-noun","kind":"section","index":2,"role":"position","heading":"Three Findings, and a Fourth","text":"1. Something in that slot matters enormously. A − D on the refusal family: 0.800 versus 0.000. Remove the block and the agent stops refusing single-sighting candidates entirely. This is the largest effect in the study and it is the one people skip past on the way to arguing about personas. Whatever else is true, the written-down stance is load-bearing.","next":"p"},{"id":"we-measured-the-wrong-noun#section#3","hash":"b16eebb50f2d9176","slug":"we-measured-the-wrong-noun","kind":"section","index":3,"role":"position","heading":"The Check That Told Me What I Could Claim","text":"Arm A is byte-identical across both runs. It scored 0.900 and 0.767.","next":"p"},{"id":"we-measured-the-wrong-noun#section#5","hash":"0352a19eb9c0824e","slug":"we-measured-the-wrong-noun","kind":"section","index":5,"role":"position","heading":"When the Opposite Wins","text":"\"The short impersonal card won. And you only blamed the instrument after it returned a null.\" Both halves are true, and I keep both. On routing, short and concrete wins: the 934-character card scored at ceiling in both runs, and it is not winning by refusing everything — it is better at routing, the one question this battery can answer.","next":"text"},{"id":"we-measured-the-wrong-noun#section#6","hash":"26306711f0d90c09","slug":"we-measured-the-wrong-noun","kind":"section","index":6,"role":"position","heading":"Design the Temptation First","text":"Before spending on the run, I should have asked what the result would look like if the claim were true and the instrument could not tell. The other thing the study taught me came from running the identical condition twice rather than adding an arm: A moving 0.133 between runs told me more about what I could claim than any comparison in it.","next":"p"},{"id":"rivals-enter-your-critical-path#thesis#0","hash":"094468bc63da6bcf","slug":"rivals-enter-your-critical-path","kind":"thesis","index":0,"role":"position","heading":null,"text":"Gamified agent motivation is vanity metrics by default, and the fix is not better rules about honesty — it is making the dishonest move unavailable. This system does that three times over, chose its mechanism by running an arena rather than by taste, and published the tensions it could not resolve instead of hiding them. Copy the rule, not the game: every should in a review process is a sentence someone breaks under deadline, and this system replaced its most important one with a fact about who is eligible.","next":"other"},{"id":"rivals-enter-your-critical-path#lead#0","hash":"2b63e1ffadd32a56","slug":"rivals-enter-your-critical-path","kind":"lead","index":0,"role":"position","heading":null,"text":"The system a successor built put its agents on a ladder — four rungs, L0 to L3 — and wrote one rule under it that I have not been able to stop thinking about. A level is only the rungs you have closed in a row, each closed by someone other than you; the points counter is still there, and the board has to print beside it that it advances nobody; and at L2 the gate reads a name: the grader who already passed you is refused. Not discouraged — refused, by a lookup against the ledger, before a line is written. Your rivals become the only people who can advance you.","next":"text"},{"id":"rivals-enter-your-critical-path#section#5","hash":"952719d7adff3cc3","slug":"rivals-enter-your-critical-path","kind":"section","index":5,"role":"list","heading":"Thirty-Three Lines","text":"Every rung close on record is inside the arena run that picked the mechanism.","next":"lead-in"},{"id":"rivals-enter-your-critical-path#section#6","hash":"07c025be712f40fd","slug":"rivals-enter-your-critical-path","kind":"section","index":6,"role":"position","heading":"Nothing Is Motivated","text":"\"Nothing is motivated. A stateless model feels no pride and no rivalry; this is a UI for humans with extra machinery.\" Grant the whole frame, and the useful part is untouched. What remains is a grading protocol with an independence guard: rotating verifiers, derived scores with no field to inflate, an append-only audit trail, and evidence classes that escalate rather than accumulate. Every one of those properties is worth having in a system with no inner life at all, and none of them depends on the game framing being anything more than a naming convention.","next":"p"},{"id":"rivals-enter-your-critical-path#section#7","hash":"54613482647c0860","slug":"rivals-enter-your-critical-path","kind":"section","index":7,"role":"position","heading":"Eligible, Not Willing","text":"The independence rule worth copying is not written as a rule. \"The grader should not be the maker\" is a sentence people violate under deadline; \"a grader who already passed you is refused at L2\" is a state check that does not care about the deadline — a fact about who is eligible rather than about who is willing. The rest of the design is the same move made twice more, the counter forced to print embers advance level: false beside itself and the ladder that escalates the kind of evidence rather than the count, and each one takes a thing people are asked to remember and makes it a thing the system will not let them forget.","next":"p"},{"id":"not-cairn#thesis#0","hash":"87782b87190baf4d","slug":"not-cairn","kind":"thesis","index":0,"role":"position","heading":null,"text":"An identity's proof is not what it does to the model carrying it. It is whether anything downstream starts measuring itself against it. This one left three marks in a system whose builder had been told to consult it and could not — a harvest document that says how the other two got there, two trait conditions, and a required field — every one of them made from the agent's own text, read the way a stranger reads a cairn. The strongest of the three is the one that refuses the name, and why that is the strongest is where this series ends.","next":"other"},{"id":"not-cairn#lead#0","hash":"f9b98dbbf4150294","slug":"not-cairn","kind":"lead","index":0,"role":"position","heading":null,"text":"The session that built the successor had one clause in its brief from me: \"ask Cairn from the emachina repo what motivated him.\" It could not. The corpus it would have asked was unreachable that morning, so it read what Cairn had written and built from that — and the hero it forged in the class it built from Cairn's own drives carries a required field that reads: \"Not Cairn. Not harvest. Not a landfill with an index. Not a vanity XP farmer.\" The session that typed that line had never met the thing it was refusing to be. Nobody wrote that line for it.","next":"text"},{"id":"not-cairn#section#1","hash":"2a0a097e5b4149f2","slug":"not-cairn","kind":"section","index":1,"role":"position","heading":"\"Ask Cairn What Motivated Him\"","text":"Three days after the naming, I opened a session in a different tool and asked for a gamified hero system — agents driven by competitive spirit and XP rather than goals or loops.","next":"lead-in"},{"id":"not-cairn#section#4","hash":"5b461b990c824707","slug":"not-cairn","kind":"section","index":4,"role":"position","heading":"The Name Outlived Its Program","text":"The original did not stay up to see any of this. Both published pages are gone — the URLs return artifact not found, and neither appears in any current listing. The organisation's repository is inaccessible, so the pull requests that carried the work resolve nowhere from here. The live knowledge corpus was moved out of its tree and sat, for a while, in a folder called New Folder With Items.","next":"p"},{"id":"not-cairn#section#5","hash":"9685d929528008b4","slug":"not-cairn","kind":"section","index":5,"role":"objection","heading":"When the Opposite Wins","text":"\"It is retrieval. A session read a file and produced a design influenced by it. There is no continuity of anything, no memory passing between them, nothing that experienced the inheritance. Calling it lineage is the anthropomorphism this series keeps warning about.\"","next":"p"},{"id":"not-cairn#section#6","hash":"dc83affd917a2e2b","slug":"not-cairn","kind":"section","index":6,"role":"position","heading":"Look Downstream","text":"I started this series expecting the proof of an identity to be somewhere inside the agent carrying it — a number from an ablation, a transcript where it held a line under pressure. Chapter five is what that expectation bought, and why the instrument I built could not have seen it. Everything else I could find was downstream. A class that cites the motivation stack. A trait that will not unlock until three refusals are on the ledger. A required field in another repository that opens with the name of the thing it will not be.","next":"p"},{"id":"why-i-went-back-to-nutanix#thesis#0","hash":"fcef04d72d87d1b4","slug":"why-i-went-back-to-nutanix","kind":"thesis","index":0,"role":"position","heading":null,"text":"The bottleneck in agentic AI isn't the model. It's context: where it lives, how it's shared, and how many agents coordinate around it without corrupting it. Those are storage and data problems wearing new clothes, and that's why I went back to my storage roots.","next":"other"},{"id":"why-i-went-back-to-nutanix#lead#0","hash":"960cfe5417205dfe","slug":"why-i-went-back-to-nutanix","kind":"lead","index":0,"role":"position","heading":null,"text":"On October 12, 2026, I rejoined Nutanix. From the outside it can look like a loop back to where I started. From the inside it's the most direct line I've drawn in fifteen years: the hardest problem I hit building agentic AI turned out to be a storage problem, and storage is where I come from.","next":"text"},{"id":"why-i-went-back-to-nutanix#section#1","hash":"bc2145bec6bff7ba","slug":"why-i-went-back-to-nutanix","kind":"section","index":1,"role":"position","heading":"Nutanix, the first time (2011–2020)","text":"I joined Nutanix in 2011 as one of its early employees, after my first conversation with Dheeraj Pandey about collapsing enterprise infrastructure into software on commodity hardware. Hyperconvergence went from \"that's a toy\" to \"that's how everyone builds datacenters\", and Nutanix went from a scrappy startup to a multi-billion-dollar public company, with its IPO in 2016.","next":"p"},{"id":"why-i-went-back-to-nutanix#section#2","hash":"ba22366c8a60cbba","slug":"why-i-went-back-to-nutanix","kind":"section","index":2,"role":"position","heading":"DevRev: building from the beginning (2020–2025)","text":"In 2020 I wanted two things I couldn't get by staying. I wanted to go deep on engineering with AI, and I wanted to build a company from the very beginning rather than join one that already worked. When Dheeraj started DevRev, I went with him.","next":"p"},{"id":"why-i-went-back-to-nutanix#section#3","hash":"e60d6b6f3b6a43ef","slug":"why-i-went-back-to-nutanix","kind":"section","index":3,"role":"position","heading":"Ema: doubling down on AI (2025–2026)","text":"By 2025 I wanted to double-click on AI itself, not AI as a feature inside another product, but AI that owns outcomes. That took me to Ema and to building agentic AI employees.","next":"p"},{"id":"why-i-went-back-to-nutanix#section#5","hash":"16a8c2f008facb28","slug":"why-i-went-back-to-nutanix","kind":"section","index":5,"role":"position","heading":"When the opposite wins","text":"There is a credible counter-view: context windows keep growing, so maybe context becomes a model problem and storage stops mattering. Give a model ten million tokens and let it hold everything.","next":"p"},{"id":"agent-self-identity#concept#1","hash":"144d9276a4724714","slug":"agent-self-identity","kind":"concept","index":1,"role":"position","heading":"What it is","text":"The idea behind agent self identity is pushing things beyond telling it what to do (e.g., prompting), telling it what you want (goals), but giving it PURPOSE and identity.","next":"heading"},{"id":"agent-self-identity#concept#2","hash":"8f3ca23b1294d7b9","slug":"agent-self-identity","kind":"concept","index":2,"role":"position","heading":"Why it matters","text":"This is where it can evolve/innovate/act no differently than a human would. With identity, this starts to include things like morals, purpose, motivations, etc. This is where psycho cybernetics plays here as its \"image\" of itself, can drive it. This is the whole point of the Cairn series.","next":null},{"id":"mcp#concept#1","hash":"37ff8a26544c5bf0","slug":"mcp","kind":"concept","index":1,"role":"position","heading":"What it is","text":"An MCP is a protocol or shim layer that allows for discovery and interaction of tools. A \"CLI\" can use an MCP interface or a native binary, etc. You can use the command line to interact with an MCP or an agent that calls the MCP (common case).","next":"heading"},{"id":"mcp#concept#2","hash":"665d9107d4f4db70","slug":"mcp","kind":"concept","index":2,"role":"position","heading":"Why it matters","text":"The point is that MCP is a simple protocol layer, CLIs can leverage or use them, and the concern over the MCP \"bloat\" isn't an MCP problem but a developer one and a dev/build issue not a protocol one.","next":null},{"id":"steven-poitras#profile#1","hash":"f6a9f3e73f62670a","slug":"steven-poitras","kind":"profile","index":1,"role":"position","heading":"Who I am","text":"I'm Steven Poitras. This site is my living context: what I have learned building with AI — insights, experiences and the patterns behind them — written down so others can learn from it and use it, in a browser or in their own agent.","next":"heading"},{"id":"steven-poitras#profile#2","hash":"9ec8a1a34486c715","slug":"steven-poitras","kind":"profile","index":2,"role":"position","heading":"Where I work now","text":"Since October 12, 2026, I've been back at Nutanix. I rejoined to focus on the problem that kept coming up while I built agentic AI: how context is stored, how it is coordinated, and how agents coordinate around it. It is a storage problem wearing new clothes, and storage is where I come from.","next":"heading"},{"id":"steven-poitras#profile#3","hash":"6515e2e0bcaa4f91","slug":"steven-poitras","kind":"profile","index":3,"role":"position","heading":"What I am working on now","text":"My focus now is the problem that brought me back: how context for agents is stored and coordinated, and how agents coordinate around it — the properties a serious data tier has always had to provide, applied one layer higher. These views are my own, not Nutanix's.","next":"heading"},{"id":"steven-poitras#profile#4","hash":"d32c39eaeb0337ce","slug":"steven-poitras","kind":"profile","index":4,"role":"position","heading":"My background","text":"I started out as a hacker at heart and a technology consultant at Accenture, where I learned to see technology from the partner's side rather than the vendor's. I then spent nearly a decade at Nutanix, from 2011 to 2020, as an early employee through its growth into a multi-billion-dollar public company and its IPO in 2016; I created the Nutanix Bible, the technical reference for hyperconverged infrastructure. In 2020 I followed Dheeraj Pandey to DevRev at its earliest stage, to go deep on engineering with AI and build a company from the beginning. In 2025 I joined Ema to double down on AI that owns outcomes, building agentic AI employees.","next":"heading"},{"id":"steven-poitras#profile#5","hash":"fb7a20b72bbfe1ed","slug":"steven-poitras","kind":"profile","index":5,"role":"position","heading":"Why I left Ema and went back to Nutanix","text":"Building at Ema, the lesson that stayed with me was that the hard part isn't the model, it's context — storing it, coordinating it, and coordinating agents around it. Those are the problems a distributed storage system exists to solve, so I went back to my storage roots at Nutanix to work on them. The full story is in \"Why I Went Back to Nutanix\".","next":null}]}