{"slug": "context-engineering-the-discipline-that-keeps-ai-from-writing-slop", "title": "Context Engineering: The Discipline That Keeps AI From Writing Slop", "summary": "Context engineering, defined by Shopify CEO Tobi Lütke as 'the art of providing all the context for the task to be plausibly solvable by the LLM,' is the discipline that prevents AI slop, according to a new article by Alberto Arena, maintainer of the Laravel package Truss. Arena identifies four context failure modes—burst, poisoning, noise, and conflict—and argues that most agent failures are context failures, not model failures, citing findings from Anthropic, LangChain, and Manus. He illustrates the practice with Truss's 52-line CLAUDE.md file, which states the stack, commands, and invariants, and recommends keeping such files short enough to read in under a minute.", "body_md": "AI\n\n# Context Engineering: The Discipline That Keeps AI From Writing Slop\n\nAI slop isn't usually a bad model, it's bad context. Here's the discipline that prevents it, the failure modes behind it, and three checks you can actually run to enforce it.\n\n## On this page\n\n## how to use AI series\n\n- 1\n[AI Code Hallucinations: When Your AI Writes Confident Nonsense](/posts/ai-hallucination-in-coding-agents/) - 2\n[We Became Editors-in-Chief, and Nobody Trained Us](/posts/we-became-editors-in-chief/) - 3\n[Claude Code Auto Mode: What Still Needs a Human](/posts/claude-code-auto-mode-still-needs-a-human/) - 4 Context Engineering: The Discipline That Keeps AI From Writing Slop\n\n[View series →](/series/how-to-use-ai/)\n\n“The art of providing all the context for the task to be plausibly solvable by the LLM.”\n\nTobi Lütke, Shopify CEO, on\n\n[X], June 19, 2025\n\nThat’s the definition Tobi Lütke gave the term “context engineering” when he decided he liked it better than “prompt engineering.” I think it’s the right definition, and I think most people complaining about AI slop are one inference away from noticing why.\n\nA vibecoder who fires a prompt at an agent with no project context isn’t getting a worse model than the one I use. They’re getting the same model doing its honest best with nothing to ground it: no rules file, no memory of yesterday’s decisions, no pointer to the component that already solves this. So it invents something plausible. Inconsistent naming, a reinvented helper that already exists three files over, an architecture assumption that was wrong two refactors ago. That’s not the model being bad. That’s the model being under-informed, confidently.\n\nAnthropic, LangChain, and the team behind Manus have all converged on the same finding from production agents: most agent failures are context failures, not model failures. Bad context in, sloppy software out.\n\n## The four ways context goes wrong\n\nThe clearest breakdown of *how* context fails comes from Drew Breunig’s [How Long Contexts Fail](https://www.dbreunig.com/2025/06/22/how-contexts-fail-and-how-to-fix-them.html): poisoning, distraction, confusion, and clash. What follows is my own relabeling of those four, translated into what each one actually looks like in a codebase rather than restated in Breunig’s original terms:\n\n| Failure mode | What it looks like |\n|---|---|\nBurst | Everything gets dumped into context upfront, so the one relevant fact is buried under forty irrelevant ones and the agent weighs them about equally |\nPoisoning | One wrong or hallucinated detail early in a session (a method that doesn’t exist, a convention that was never real) gets treated as fact for the rest of it |\nNoise | The context is technically all relevant, just too much of it, so the signal-to-text ratio collapses and the agent can’t tell what actually matters right now |\nConflict | The system prompt says one thing, the project’s rules file says another, and the agent has to guess which one wins, silently, every time |\n\nNone of these are model problems. They’re all things a human decided, or failed to decide, about what the agent sees and when. Which means they’re fixable the same way any other engineering problem is fixable: on purpose, not by accident.\n\n## What it looks like when it’s done on purpose\n\nI’d rather show this than diagram it, so here’s the actual `CLAUDE.md`\n\nfrom [Truss](https://github.com/albertoarena/laravel-truss), a Laravel package I maintain. It’s [52 lines long](https://github.com/albertoarena/laravel-truss/blob/main/CLAUDE.md), it states the stack, the commands, and a short list of invariants that must never break, like “no data exposed, ever, only structure,” and then it stops:\n\n```\n## Pointers\n\n- Architecture and domain model: `docs/DESIGN.md`\n- Phased build plan: `docs/INSTRUCTIONS.md`\n- Decision log: `docs/DECISIONS.md`\n- Path-scoped rules (auto-load when matching files are touched): `.claude/rules/`\n\nThis file should stay short enough to read in under a minute. If you're\nabout to add detail, it probably belongs in `docs/` instead, with a\npointer added here.\n```\n\nEverything that isn’t needed on every single turn lives one hop away instead of sitting resident in context by default. That’s not a documentation choice, it’s a context budget: the file names its own constraint and holds itself to it. Those `.claude/rules/`\n\nfiles are real, not a placeholder: `introspection.md`\n\nscopes to `src/Introspection/**`\n\n, `frontend.md`\n\nto `resources/js`\n\n, `resources/css`\n\n, and `resources/views`\n\n, `release.md`\n\nto `CHANGELOG.md`\n\n, each one loading only when Claude actually touches a matching path, not resident by default the way `CLAUDE.md`\n\nitself is. I’ve written up the fuller mechanics of how that split works, RAM versus demand-paged rules versus skills versus disk, in [CLAUDE.md Is RAM, Skills Are Not Disk](/posts/claude-md-skills-are-not-disk/), if you want the reasoning behind the shape rather than just the result.\n\nThe point here isn’t “copy this file.” It’s that the file is small enough to *audit*. Compare that to the ordinary case: a three-hundred-line `CLAUDE.md`\n\nnobody’s re-read in months isn’t context engineering, it’s context archaeology, and the agent is the one doing the digging, badly, every session.\n\n## Three checks, not a checklist\n\nA checklist gets skimmed once and forgotten. What actually holds a team to this is something mechanical enough to enforce, so here are three checks, in ascending effort, none of which require trusting anyone’s discipline going forward.\n\n**A line budget.** Truss’s `CLAUDE.md`\n\nstates its own limit in prose, “short enough to read in under a minute”, but doesn’t enforce it, and reading time isn’t something CI can check directly. Line count is the closest cheap proxy, so here’s what that could look like as a CI step (120 is my own suggested threshold, not a number Truss enforces today):\n\n```\n- name: Keep CLAUDE.md readable in under a minute\n  run: |\n    LINES=$(wc -l < CLAUDE.md)\n    if [ \"$LINES\" -gt 120 ]; then\n      echo \"CLAUDE.md is $LINES lines, over the 120-line budget. Move detail to docs/.\"\n      exit 1\n    fi\n```\n\nCheap, mechanical, and it’s enforcing a rule the file already claims for itself.\n\n**A drift check.** This is the one I trust most, because it’s the same idea Truss already applies to database schemas. A committed export file, checked against the live schema, build fails if they’ve drifted apart:\n\n```\nphp artisan truss:export --output=schema.dbml --check\n```\n\nIt compares the freshly generated export against whatever’s already committed at that path and exits non-zero if they don’t match byte for byte, the same mechanism as `git diff --exit-code`\n\nfor a generated file, just schema-aware. Context files rot the exact same way, except what’s usually committed is nothing: no file that gets checked against the thing it describes. Does every path `CLAUDE.md`\n\npoints to still exist? Was `docs/DESIGN.md`\n\nlast touched *before* the architecture it describes changed? A pre-commit hook or CI step that resolves every referenced path and flags anything missing or stale catches the failure mode that actually bites: an agent working confidently off documentation that quietly stopped being true.\n\n**Golden-task regression checks.** A small, fixed set of representative prompts, “add a new artisan command,” “explain the authorization gate”, run periodically against whatever the current context bundle produces, with the expected shape of the answer written down somewhere. This one doesn’t fully automate. But even a manual pass before a release catches the case the other two checks can’t: a change to a rules file that’s individually reasonable but breaks something two files away, silently, because nobody asked the agent to actually do the task before shipping the instruction change.\n\nNone of these are exotic. They’re linting, drift detection, and regression testing, the same three things you’d already reach for if the artifact in question were code instead of prose. That’s the actual point: it is code, in every way that matters except syntax highlighting.\n\n## The discipline is the whole difference\n\nThe vibecoder fires prompts into a context vacuum and ships whatever comes back, because “prompting” is the only lever they know is there. The engineer treats context, the rules file, the memory, the docs it points to, as a first-class artifact: versioned, reviewed, budgeted, checked for drift, same as anything else that ships. Same model, same tool, wildly different output, and the difference was never the prompt.\n\nIf you’re looking at a vibe-coded app that feels inconsistent, half-finished, confidently wrong about how your own codebase works, don’t ask what model built it. Ask what it was allowed to see.\n\n[Open a discussion on GitHub](https://github.com/albertoarena/albertoarena.it/discussions)or\n\n[send me an email](mailto:hello@albertoarena.it).", "url": "https://wpnews.pro/news/context-engineering-the-discipline-that-keeps-ai-from-writing-slop", "canonical_source": "https://albertoarena.it/posts/context-engineering-not-slop/", "published_at": "2026-08-17 09:41:21.795794+00:00", "updated_at": "2026-08-17 09:41:23.781418+00:00", "lang": "en", "topics": ["artificial-intelligence", "large-language-models", "ai-agents", "ai-tools"], "entities": ["Tobi Lütke", "Shopify", "Anthropic", "LangChain", "Manus", "Drew Breunig", "Alberto Arena", "Truss"], "alternates": {"html": "https://wpnews.pro/news/context-engineering-the-discipline-that-keeps-ai-from-writing-slop", "markdown": "https://wpnews.pro/news/context-engineering-the-discipline-that-keeps-ai-from-writing-slop.md", "text": "https://wpnews.pro/news/context-engineering-the-discipline-that-keeps-ai-from-writing-slop.txt", "jsonld": "https://wpnews.pro/news/context-engineering-the-discipline-that-keeps-ai-from-writing-slop.jsonld"}}