AI 资讯
How Datadog Used Claude and Cursor for Test-Driven Production Migration
In a recent article, Datadog engineer Arnold Wakim shared what worked, what didn't, and the lessons they learned while evolving a critical production system using AI to overcome hard limits in its storage backend and significantly improve performance. By Sergio De Simone
AI 资讯
Claude Code vs. Codex: Which AI Coding Assistant Is Better?
Artificial intelligence has transformed software development. Instead of simply generating code snippets, modern coding assistants can understand entire codebases, refactor applications, write tests, debug issues, and even execute development workflows. Among the most capable tools available today are Claude Code and Codex. While both are designed to accelerate software development, they take different approaches to coding assistance. This article compares their strengths, weaknesses, and ideal use cases. What Is Claude Code? Claude Code is Anthropic's command-line coding assistant built around the Claude family of language models. Rather than functioning as a traditional autocomplete tool, Claude Code works as an AI development agent that can inspect projects, edit files, explain code, write tests, fix bugs, and help developers navigate large repositories. Its workflow is centered around natural language. Developers describe what they want, and Claude Code performs the necessary steps while keeping the developer involved throughout the process. Key features Deep understanding of large codebases Multi-file editing Test generation Refactoring assistance Terminal-based workflow Strong reasoning for complex programming tasks Excellent documentation generation What Is Codex? Codex is OpenAI's AI coding agent designed to help developers write, understand, and modify software. Unlike the original Codex model introduced in 2021, today's Codex operates as a software engineering agent capable of working across repositories, generating code, fixing bugs, creating pull requests, running tests, and assisting with development workflows. Codex integrates closely with OpenAI's ecosystem and focuses on turning natural language instructions into production-ready code while maintaining awareness of project context. Key features Repository-aware coding Autonomous task execution Code generation Bug fixing Test writing Pull request assistance Integration with modern development workflow
AI 资讯
Anyone else noticing Claude being more stubborn, lying to you with high confidence that things the way he says to find out it's complete non sense?
AI 资讯
How to Create a Skill in Claude Code
This is a cross-post — the original (and any updates) live at broke2builtai.com . The first time I watched Claude Code reach for a skill I hadn't told it to use — read a folder, run the script inside it, and hand back the finished thing — the difference from a slash command finally landed. A slash command waits for you to type it. A skill waits for the situation . Claude decides. That one shift is the whole feature, and building one takes about five minutes once you know where the file goes. Here's the entire thing end to end, including the one gotcha that decides whether your skill ever actually fires. What a Skill actually is A Skill is a folder with a SKILL.md file inside it. The Markdown holds instructions; the YAML frontmatter at the top holds a name and a description . That description is doing the most important job in the whole file: Claude reads it to decide, on its own, whether the current task warrants invoking the skill. Nothing else you write matters if the description doesn't get you picked. That's the mental model to hold onto: a custom slash command is a prompt you trigger by typing /name ; a skill is a procedure Claude triggers when the context matches. Same reusable-instructions idea, opposite trigger. Where the file goes Two locations register, exactly like commands and subagents : Project skill — .claude/skills/<skill-name>/SKILL.md inside the repo. Committed, so your whole team gets it. Personal skill — ~/.claude/skills/<skill-name>/SKILL.md in your home directory. Follows you across every project on your machine. Each skill is its own folder, and the folder name should match the name in the frontmatter. A loose SKILL.md sitting somewhere else won't be picked up. The minimum viable skill Create the folder and the file: .claude/skills/pytest-runner/SKILL.md Then write the two-part file — frontmatter, then body: --- name : pytest-runner description : " Run, generate, or debug pytest tests for this project. Use when the user asks to run the test su
AI 资讯
Anthropic Wants You to Pay Up for Claude Fable 5
Claude subscribers must soon pay usage-based fees to access Anthropic’s best consumer AI model—a sign that the golden era of AI subscriptions is ending.
AI 资讯
RLS recursion infinite loop: why I gave up policies and bet everything on a JWT custom claims hook
Episode 1/4 — 3 incidents, one root: default GRANTs open more than you think — [CANONICAL URL EPISODE 1: fill in after push] Episode 2/4 — await mutation() lies when nobody opens the { error } envelope — [CANONICAL URL EPISODE 2: fill in after push] The morning Françoise sees zero rows, again It's a Tuesday in April 2026. I've just added the agent_readonly role to the authenticated membership — a one-liner, meant to share a GRANT for a reporting job. First SELECT on cours , Sentry receives infinite recursion detected in policy for relation "user_roles" , code 42P17 . From the office next door, Françoise is already on the phone with the Maisons-Laffitte branch: "So they can't see anything over there — is that normal?" Foreman tone, not really a question. I read the error on my screen. The difference from episode 1: this time Postgres is talking. What came out of Sentry was no longer a silent empty set — it was an explicit error. That difference saved me two days. When Postgres shouts, you listen. The trap is that what it says isn't where you're looking. I won't pretend this is obscure. A policy on user_roles that queries user_roles to decide who can read user_roles is a loop. You avoid it, you work around it with SECURITY DEFINER , you move on. The problem: my user_roles policy didn't reference user_roles . I had already cleaned it up three weeks earlier. The recursion was coming from somewhere else. The diagnostic that targets the wrong object First reflex: re-read the user_roles policy. It's clean, reads auth.email() , never calls itself. Second reflex: disable policies one by one to find the culprit. Wrong angle. -- supabase/migrations/20260420_admin_write_cours_v1.sql -- "Admin write cours" policy — original version that loops CREATE POLICY "Admin write cours" ON public . cours FOR ALL TO authenticated USING ( EXISTS ( SELECT 1 FROM public . user_roles WHERE email = auth . email () AND role IN ( 'admin' , 'super_admin' ) ) ); The recursion doesn't come from a fau
AI 资讯
The PostgREST query that silently ORDER BY ctid: a Supabase week, distilled
The fourth call of the week Catherine calls from the Maisons-Laffitte site on a Tuesday afternoon in early May. "It's broken, but it's a quick fix." That's her line — I know it, and she's usually right. She describes it in three sentences: the newsletter export for the enrolled-students segment comes back with ninety-two names, the planning view shows ninety-two active courses, but the counter page shows eighty-nine. Three enrolled students missing. She'd checked the database directly — they're all there. "Why three steps for that?" She's not asking for my benefit. She's asking for herself. Except this time, hanging up, I realize it's the fourth time this week I've hung up thinking the same thing. Four Supabase incidents, four fixes, four closed tickets. And not a single exception raised by the database. I reopen the three previous ones and lay all four side by side on screen. This isn't four bugs. It's one failure mode, declinated four times. The first three Episode 1 was about the default GRANT s Supabase places on functions and policies. A SQL function created without an explicit REVOKE inherits anon access that nobody wrote in the migration, and that nobody caught in review because the diff doesn't show it. The function works. It's just callable from outside. [CANONICAL URL EPISODE 1: to fill in after publication of #48 — "3 Supabase security incidents, one shared root cause: SECURITY DEFINER inherits EXECUTE TO PUBLIC"] Episode 2, an ON DELETE SET NULL cascade coupled with a CHECK NOT NULL on the target column. The parent DELETE attempts the SET NULL , the CHECK rejects it, and the transaction surfaces an error we read as a deletion failure — while it actually masks a consistency assumption we'd held for three months. The query fails loudly, which is more charitable than the other three cases, but the diagnosis heads in the wrong direction because nobody had declared that the two constraints lived in tension. [CANONICAL URL EPISODE 2: to fill in after publicati
AI 资讯
Why your agent over-engineers your simplest request (and the 3 prompts that stop it)
The request was eight words Monday morning. I open the outgoing email queue: six hundred and forty-seven drafts waiting, six hundred and seventy-two sent. Nobody clicks Send . First-contact emails are prepared by a pipeline and they sleep, because the last step assumes a human. That human, I had stopped believing she would have the time. I state the decision: automate sending . The response comes in seconds. Three levels of automation. Four channels. Three risk thresholds. All correct, all fit for a half-day architecture workshop. I had not asked for a workshop. Pauline walks behind me, glances at the screen, says nothing. Three timed reframes First reframe , brief: too strange, let's simplify . The agent drops two axes, keeps four residual layers, progressive warm-up over three weeks, deterministic anti-replay hash, configuration table in the database, manual Phase 1 followed by an automated Phase 2 to validate after two weeks of measurement. The target stays the same, that an email leaves without a human click. The path has grown accordingly. Second reframe , drier: simple, three safeguards, a kill-switch, we do this in one day . The agent re-architects, accepts the one-day target, keeps the three safeguards. But slips in three prostheses it calls industry standard : real-time dashboard, exponential retry, structured audit log in a new table. Each justifiable in isolation. None of them requested. Third reframe , shorter still: I don't understand why you're adding this . An opening line almost embarrassed, which I had never read from it before: "you're right, I'm over-engineering without necessity." And the version that should have arrived on the first round. A function that takes the draft record, checks three conditions, calls the send engine, returns. // lib/email-outbox.ts — generateFirstContactDraft (commit 3756e63) if ( ! EMAIL_REGEX . test ( input . email )) { return { success : false , error : ' email_invalide ' } } if ( BLACKLIST_EMAILS . has ( input . ema
AI 资讯
Anthropic’s new Claude feature is quietly selling you on AI
Claude’s new Reflect dashboard doesn’t just visualize how you use AI. It also subtly reinforces how much of your daily work now depends on Anthropic’s chatbot.
AI 资讯
LED Strip Tetris: Zero-Code Hardware Game with TuyaOpen + Claude Code Tutorial
I built an LED Strip Tetris game — without writing a single line of code. No keyboard mashing. No debugging at 2 AM. No reading 500 pages of datasheets. Just natural language prompts, an AI agent, and a Tuya T5 AI Core board. Here's the full breakdown of how it works 👇 🧩 What Is LED Strip Tetris? LED Strip Tetris is a DIY hardware game built entirely through natural language prompts using TuyaOpen IDE and Claude Code. It runs on a Tuya T5 AI Core development board with a WS2812 LED strip (72 LEDs) and three color-matched buttons — red, green, and blue. Colored LEDs fall from the top of the strip; players press the matching button to shoot a colored LED upward and eliminate the falling one on contact. The entire game — firmware, game logic, hardware wiring, sound effects, compilation, and flashing — was generated by AI. Zero manual coding. 🔌 The Hardware (Ridiculously Simple) Component Role Tuya T5 AI Core Board Main MCU — runs game logic, drives LED strip and buttons WS2812 LED Strip (72 LEDs) Display — colored LEDs fall and get eliminated 3 Push Buttons (Red / Green / Blue) Input — shoot matching color upward to clear falling LEDs Speaker Sound effects on button press That's it. No custom PCB. No complex wiring harness. Just four components plugged into a dev board. 🤔 Why This Is a Big Deal Here's what building a hardware game normally looks like: Step Traditional Approach Vibe Coding with TuyaOpen IDE Dev environment setup Install toolchain, configure SDK, fight dependencies Copy a workflow link, paste into Claude Code, click confirm Game logic Write C code from scratch, design state machines Describe the game in one sentence, AI generates the code Hardware config Read datasheets, look up GPIO mappings, manually configure Tell AI which pins you're using, it handles the rest Sound effects Write audio decoding code, integrate codecs Give AI the file path, it decodes and compiles Debugging Serial logs, oscilloscope, hours of trial and error AI self-diagnoses compile
AI 资讯
Anthropic Shipped @Claude For Slack. My Team Runs On
Anthropic Shipped @claude for Slack. My Team Runs on Telegram. Anthropic just shipped @Claude inside Slack channels. Tag the bot, it reads the thread, does work async, posts back. Nice product. Except roughly 95% of small businesses don't live in Slack — they run on WhatsApp, Telegram, and Gmail. If you're a solopreneur or a 1-to-10-person team, here's the exact four-part recipe I use to run the same pattern in Telegram for under $12/month. What Anthropic actually shipped (and who it's for) Anthropic shipped an enterprise distribution deal wearing a product launch t-shirt. @Claude for Slack lets you tag the bot in a channel or thread, gives it channel memory, connects to your other apps, and returns work asynchronously — but only on Slack Team and Enterprise plans. That's the punchline: it lives where the annual contracts live. Look at the raw user counts. Slack's own reporting puts it around 35–40 million weekly active users globally. WhatsApp is over 2 billion. Telegram is over 900 million. Gmail sits around 1.8 billion. In the 1-to-10-employee segment outside US tech, Slack penetration is single digits. Small teams in Europe, LATAM, and most of Asia coordinate in WhatsApp groups and run pipeline out of Gmail. They are not about to add Slack seats at $15/user/month just to get an @Claude mention. That's a rational call for Anthropic — Slack is where the enterprise procurement motion already exists. It's just not a product for the operator segment. And the pattern they productized is trivially replicable on any messenger with a bot API. Platform Weekly/monthly active users Bot API Cost to run a mention-bot Slack ~35–40M WAU Yes, paid plan $15/user/mo + API Telegram ~900M MAU Yes, free ~$5–12/mo API only WhatsApp Business ~2B MAU Yes, metered $0.005–0.08/conversation + API Gmail ~1.8B MAU Pub/Sub push Free tier + API The four-part recipe (works in any messenger) Every mention-bot is the same four moving parts: a webhook that fires on mention, a context store that ho
AI 资讯
Keeping context and decisions consistent across parallel AI agents
You start the morning with four Claude Code agents running, each in its own git worktree, each on a separate task. By mid-afternoon something is off. One agent has re-implemented a helper another already wrote. A second built against an interface that a third changed an hour ago. A fourth made a naming choice that contradicts a decision you made — out loud, to yourself — at 9am. Every diff is reasonable on its own. The system they add up to is not. This is the failure mode that shows up the moment you go from one agent to several. The code each agent produces is fine. What drifts is everything between the agents: the decisions, the conventions, the current shape of the interfaces they all depend on. Running the agents in parallel is the easy part. Keeping them coherent is the hard part, and it's a different problem. Why parallel agents drift An agent's context is per-session. Each Claude Code instance has its own context window, populated by what it has read and done in that session. Nothing about that window is shared with the agent running in the next worktree. There is no common memory they all write to and read from. So when agent A decides "we use the repository pattern for data access," that decision exists in exactly two places: agent A's context, and your head. Agent B never hears about it. Three kinds of state cause the drift, and they're worth separating because they need different handling: Decisions already made. Architecture, naming, conventions, the approach you settled on for a cross-cutting concern. These are durable — once made, they should bind every agent, including ones you spawn tomorrow. The current contract. The shape of the interfaces, types, and APIs that agents share. This changes during the work: agent A edits a signature, and agents B and C are now building against a version that no longer exists. What's in flight. Who is touching which files right now. Two agents editing the same module in separate worktrees won't see each other until th
AI 资讯
Claude Cowork expands to mobile and web
With this update, users can start a task from their desk, get status updates on their phone, and pick up the finished output later — even if their laptop is closed.
AI 资讯
Shut Those Laptops! Anthropic Puts Its Claude Cowork Agent on Your Phone
Claude Cowork now keeps working on tasks even after you close your laptop. It’s part of a larger push toward smartphone-controlled agents.
AI 资讯
Why AI code review hallucinates — and the two gates that fix it
CCA-Audit — open source (MIT) AI code review has a trust problem, and it's not that it misses bugs. It's that it invents them. If you've run an LLM over a diff, you've seen it: a "possible null dereference" on a value that's guarded three lines up. A "SQL injection" your ORM already parameterizes. A "race condition" that can't happen. And then — worse — it confidently rewrites working code to "fix" the thing that was never broken. The real bug, meanwhile, sits quietly in the noise. The problem isn't intelligence. It's that most AI reviewers report their first impression as a verdict. A model reads a diff, pattern-matches "this looks like X," and emits a finding — without ever going back to check whether X is actually reachable in this code. Humans do a second pass ("wait, is price validated upstream?"). Most AI-review pipelines skip it. Here are two gates that add that second pass — and a stress test showing what they catch. Gate 1: verify findings before you fix (anti-hallucination) The idea is simple: no finding is allowed into the fix plan until a separate step re-checks it against the real code. After the auditors produce findings, a verification pass takes each one and asks three questions: Does the issue actually exist at the cited line? Is it in the code that changed, or a pre-existing thing outside the diff? Is the stated impact real, or already mitigated elsewhere — a guard upstream, a value validated before this point, a config defined in another module? The key design choice: bias the verifier toward refuting. A wrongly-confirmed finding causes a needless (sometimes harmful) fix; a wrongly-dropped one is cheap to recover. So when the evidence isn't clear, drop it or escalate to a human — don't fix on a hunch. This one step kills the majority of hallucinated findings, because hallucinations rarely survive contact with "show me the exact line, and prove the impact can occur." Gate 2: prove the fix maps to the finding (anti-regression + provenance) Catching
AI 资讯
How to Set Up Claude Code for a Project with Skills, Agents, Hooks, and a Secure GitHub Repository
How to Set Up Claude Code for a Project with Skills, Agents, Hooks, and a Secure GitHub Repository AI coding tools work best when they understand the project around the code. A fresh Claude Code session can answer questions and edit files, but it does not automatically know your architecture decisions, coding standards, security expectations, testing rules, pull request format, or operational constraints. That context needs to live somewhere predictable. This guide walks through a full Claude Code project setup using a reusable repository owned by desertfox33 : Reference repository: https://github.com/desertfox33/claude-code-project-template The goal is not just to create folders. The goal is to make Claude Code behave consistently across real project work: reviewing code, writing tests, preparing pull requests, checking security concerns, and following project-specific rules. Before using this setup in a production environment, verify current Claude Code behavior against the latest official documentation. Tooling, configuration names, and feature behavior can change. What We Are Building The repository uses this structure: claude-code-project-template/ ├── CLAUDE.md ├── CLAUDE.local.md.example ├── AGENTS.md ├── .mcp.example.json ├── .gitignore ├── SECURITY.md ├── CONTRIBUTING.md ├── .github/ │ ├── CODEOWNERS │ ├── dependabot.yml │ └── pull_request_template.md ├── .claude/ │ ├── settings.json │ ├── settings.local.json.example │ ├── rules/ │ │ ├── code-style.md │ │ ├── api-conventions.md │ │ ├── testing-standard.md │ │ └── pr.md │ ├── commands/ │ │ ├── review.md │ │ ├── deploy.md │ │ ├── scaffold.md │ │ ├── test.md │ │ └── pr.md │ ├── skills/ │ │ ├── code-review/ │ │ │ ├── SKILL.md │ │ │ └── review-checklist.md │ │ ├── testing-patterns/ │ │ │ ├── SKILL.md │ │ │ └── test-strategy.md │ │ ├── pr-description/ │ │ │ ├── SKILL.md │ │ │ └── template.md │ │ └── security-review/ │ │ └── SKILL.md │ ├── agents/ │ │ ├── security-reviewer.md │ │ ├── test-writer.md │ │ └── researc
AI 资讯
I Got Tired of My Portfolio Looking Like a List of Links. So I Built an MCP Server for It.
The obvious fix for "my projects all look similar" is a better README — more screenshots, clearer descriptions, maybe a comparison table. I considered that for about five minutes and decided it was still just a nicer list of links. What actually made a portfolio project feel different was making it something you could talk to instead of read. That's what MCP (Model Context Protocol) is built for — it's the standard that lets AI clients like Claude Desktop call external tools directly, not just process text. So I built a server that exposes my 9 projects as queryable tools instead of static entries. What is MCP, and why does it matter here Almost every AI-developer portfolio I've seen is a list of links. Mine now includes something you can actually talk to . Open Claude Desktop, connect my server, and ask "what has Ayush built with FastAPI?" — it doesn't guess from a cached README, it calls a real tool and answers from structured, live data. What I built A Python MCP server ( FastMCP , stdio transport) exposing five tools: list_projects — short summary of all 9 projects get_project_details(project_name) — full stack, GitHub link, demo URL for one project, fuzzy-matched by name search_projects_by_stack(technology) — "show me everything using Groq" or "LangGraph" or "React" get_flagship_project — the single best project to look at first get_resume_summary — background, target role, core stack The data itself lives in plain Python dictionaries right now — no database needed for something this size. Each tool is a thin function around that data, decorated with @mcp.tool() . @mcp.tool () def search_projects_by_stack ( technology : str ) -> list [ dict ]: """ Find all projects that use a given technology or tool. """ query = technology . lower (). strip () matches = [ { " name " : p [ " name " ], " stack " : p [ " stack " ], " github " : p [ " github " ]} for p in PROJECTS if any ( query in tech . lower () for tech in p [ " stack " ]) ] return matches or [{ " message " : f
AI 资讯
What 74 ADRs in 70 days actually buy a solo dev (no hire, no clients, just the file)
The question you don't dare ask out loud It's 10:40 PM on a Tuesday, I just closed an ADR — the seventy-fourth in this setup, written conscientiously, dated, cross-referenced with its migration, its contract test, and the commit that triggered it. And the question rises, the way it always rises at that hour when you've been coding alone for ten hours: who did I just write this for . No tech lead to convince, no PR review that'll catch it, no hypothetical acquirer to reassure, no architecture committee to brief tomorrow. Just the file, just me, just the doubt. It's the question of a solo dev at 70 days of serious practice. It has an honest answer, and that answer is neither "it'll pay when you sell" nor "it'll pay when you hire". Those two ROIs belong to other trajectories. The ROI of the solo dev who documents is an ROI he buys himself — deferred, intangible at moments, but materially countable if you force yourself to measure it in the first person. Here's mine, over 74 ADRs and 18 doctrine rules accumulated in 70 days, with no external observer to validate the grid. The false economy of "I'll remember" First trap, the one that cost me three weeks before I learned the lesson. The solo dev believes he doesn't need to write down what he decided because he decided it himself — his memory is worth an ADR. False at 14 days, systematically false at six weeks. Not because general memory fails, but because technical memory has a deceptive shape: you remember perfectly that you decided , you no longer remember why you decided that way. Three weeks after the May 5 session where I wrote ADR-0051 (FK ON DELETE SET NULL + CHECK NOT NULL incompatible, DELETE failing silently), I reopen the migration to add a column. I reread the diff, I don't understand why a certain CHECK constraint is phrased like this — the alternative I mentally dismiss today seems simpler, and I'm two clicks from refactoring. I go check the ADR. The answer is there, dated, sourced, in three lines. The simpl
AI 资讯
60 days with Claude Code on a production ERP: the honest balance (no hype, raw numbers)
The evening Étienne asked to see the numbers Tuesday evening, end of the day, the open space had cleared except for Étienne. Étienne holds sixty percent of the house and spends his working week at a fund that acquires software publishers, and he looks at ERPs all year the way others read balance sheets. He sat on the edge of my desk, a metal water bottle in hand, and said what he always says when he senses someone is telling themselves a story. "What's that based on?" I was about to answer with a narrative. Sixty days of solo production on Rembrandt with Claude Code, learning the doctrine, the in-flight retractions, the incidents that hardened the rules. The declarative form was ready. But Étienne doesn't ask for a narrative, he asks for the material inventory. So I opened a terminal and let wc -l speak. This article is what I should have given him without waiting for him to ask — the dry, numbered balance, what worked, what didn't, what I would do differently. Not a success story, not a cautionary tale . Just the audit nobody runs on DEV.to because we're all too busy publishing the parts that shine. What's at stake behind Étienne's question is less the performance of a device than the possibility of measuring it honestly. Sixty days of practice with an AI assistant on a production project is a rare object at this stage. Most publications circulating on the subject are either brief demos from a hackathon or marketing announcements from vendors. The field return at sixty days, delivered with its numbers and retractions, barely exists. That's the gap I intend to close here, without more pedagogy than is strictly needed. The dry material inventory Sixty calendar days between the first session and today. Fifty-eight active days out of sixty , meaning two days without a commit and explaining why the rest of my life barely held. Over that window, the repo accumulated nine hundred and eighty-four commits bearing my name — an average of sixteen commits per working day, on d
AI 资讯
One Anthropic Researcher's Prompt Changed How I Use AI Forever. Here's the Exact Template.
Most prompts ask AI to explain things. The best ones ask it to show you something instead. That distinction sounds cosmetic. It isn't. It changes what the model generates, how you process it, and — more importantly — whether it actually sticks. I came across this idea while watching an interview with Amanda Askell — a philosopher and researcher at Anthropic whose work sits at the intersection of AI alignment and what you might loosely call Claude's inner life. She's a primary author of the document that defines Claude's values and character — the framework that governs how the model reasons when the rules run out. Almost as an aside near the end of the interview, she mentioned a prompting technique she uses to understand complex concepts. It stopped me cold. Not because it was elaborate. Because it was disarmingly simple, and it worked in a way I hadn't thought to ask for. The Exact Prompt Template Here it is, cleaned up and ready to use: I want to understand [concept]. Please explain it by writing a fable — an indirect, narrative version of the concept. The story should embody the concept completely without naming it directly. Ideally, the reader should only start to realize what the concept actually is near the end of the story. After the fable, add a short explanation that names the concept clearly and connects it back to the key moments in the story. That's it. No elaborate scaffolding. No chain-of-thought trigger. No persona assignment. Just a deliberate decision about the order in which understanding should arrive. Why This Works (and Why Direct Explanation Often Doesn't) When you ask AI to explain a concept directly, you get a definition. Definitions are accurate and forgettable. The model produces the statistical center of everything written about that concept — clear, complete, and utterly without friction. Friction, it turns out, is how things get encoded. When a concept arrives wrapped in a story, your brain does something different. It tracks characters,