{"slug": "guardrails-protect-your-codebase-what-protects-your-judgment", "title": "Guardrails Protect Your Codebase. What Protects Your Judgment?", "summary": "Cal Newport's essay 'On AI Coding and Its Discontents' argues that AI coding tools trade speed for the deep thinking that builds engineering skill, and developers are seeking a middle path that preserves friction and judgment. The author, who co-runs a Python to Rust cohort, recommends scoping AI agents to narrow tasks, reviewing all generated code, and using stronger types and compile-time assertions to enforce correctness, as AI can learn constraints and apply them consistently.", "body_md": "# Guardrails Protect Your Codebase. What Protects Your Judgment?\n\n*Learning Rust? I co-run a 6-week Python to Rust cohort where you build a performant JSON parser with PyO3 bindings.*\n\nCal Newport's [On AI Coding and Its Discontents](https://calnewport.com/on-ai-coding-and-its-discontents/) lands on an uncomfortable point: the speed AI gives you is paid for with the thinking that made us good engineers in the first place.\n\nRead code instead of writing it and you get passive recognition where you used to have an active model of the code.\n\nThe vendors sell one answer to this: more AI. The nostalgic answer is the opposite: go back to writing everything by hand. I am searching for a midway.\n\n## No right answer, but at least a direction to pursue\n\nWhen I posted about this recently, I offered 3 options: write more code manually, double down on AI, or find some middle with more friction. I got some valuable comments from developers picking the middle. And that's where I've landed too.\n\nThe more I read and think about it, the more the middle stops looking like a compromise. It seems the way forward, but only if you specify what *friction* to keep.\n\nSkill atrophy isn't caused by using AI per se. It's caused by delegating the part that builds your internal model.\n\nI've argued that [the friction is where the learning lives](/blog/dont-delegate-the-friction/), and nothing about agents changes that. What changes is that it's now easier to bypass friction and it's on us to keep it in.\n\nIt helps to separate two problems here, because AI creates both and they aren't the same. One is skill atrophy: stop doing the thinking and your mental model fades. The other is correctness: AI writes plausible code that can be subtly wrong.\n\nLet's look at each in turn.\n\n## Do you 'own' the code?\n\nA sharp reply came from someone on Bluesky:\n\nagents draft, but re-derive the hard path before merge. If you can't explain a weird branch without re-reading the whole file, you rewrote too little.\n\nNot all code is created equal. The boundary conditions, error paths, and testing assumptions are where we as engineers pull our weight.\n\nFor every diff, can you explain the change? What are the edge cases and risks?\n\nIn practice I find that this gets easier when you scope the agent to narrow, well-defined tasks instead of blanket features. Small tasks keep you in the loop, stop the agent from drifting, and prevent giant code reviews nobody wants to read.\n\nI also like [how Corey Schafer summarized how he keeps the friction](https://youtu.be/tHh0UaL_V4w?si=lLP4cZxvcikLo1yA&t=1155):\n\n- Use detailed prompts, not one-liners: spec the tools, architecture, and reuse saved research prompts that force citing official docs.\n- Review everything: read and understand all generated code like a junior's PR you'd never merge blindly.\n- Interrogate unfamiliar code / concepts: make the AI explain things in plain English, pull docs, and justify the approach and trade-offs.\n- Push back: offer your own approach, ask if the AI's is better/worse/different, and fold what you learn into your own toolkit.\n\n## Push the rest into the system\n\nThose four habits are all manual. They keep your judgment in the loop, but they run on your attention, and attention is finite. You can't re-read every branch on every diff forever. So whatever those habits can't cover by hand, you push into the system and let it enforce the rest automatically.\n\nA commenter on Threads put it well:\n\nthe real fix is correctness by design, stronger types, compile-time assertions, more \"faff in the way.\" We never fully adopted that stuff because it takes patience humans run out of. AI doesn't. It learns your constraints once, then works inside them on every diff after.\n\nAnd on Fosstodon:\n\nI feel like all these systems have too many surprises, and making invalid states illegal is the best defensive alternative to not using them, which would be the first choice. Once you get guarantees, if you can type faster with gen ai than your fingers, maybe thats worth the squeeze depending on your morals.\n\nThat's why Rust is so appealing to me. Making invalid states unrepresentable and the agent has to comply with this. I discussed this [here](/blog/rust-compiler-ai-agent-guardrail/).\n\nPython gives you less strict guarantees, but we can approximate it. Your [type checker (ty, pyrefly, mypy)](/blog/modern-python-tooling-uv-ruff-ty/) catches the class of type errors the model would otherwise slip past you. Pydantic models validate at the boundary, so bad data fails loudly instead of drifting three functions deep. And well-thought out test cases can challenge plausible looking code. And for AI generated tests you can use mutation testing (an article on this soon here ...)\n\nSo balancing responsible AI use has two sides. Re-derive the decisions that matter, which keeps your judgment sharp. And encode stricter rules to keep your agent accountable to higher standards. One protects your mental model, the other protects the code base. Both protect peace of mind.\n\nAs said before: the tooling / way of working has changed, but [AI doesn't change what software engineering is](/blog/ai-doesnt-change-what-software-engineering-is/); we can automate some of the boring parts, but the majority of the work (including the code-producing part) is a lot of back-and-forth and applying experience and judgment.\n\n## Keep reading\n\n[How to Keep Your Developer Instincts When AI Writes the Code](/blog/dont-delegate-the-friction/)[AI Is an Accelerator, Not a Compass](/blog/ai-accelerator-needs-direction/)[From 1,069 to 156 LOC: Design Over Code](/blog/design-over-code/)\n\nNewport's worry is right: outsourced thinking atrophies. The escape isn't more or less AI. It's identifying, every time you build software, the small set of decisions you refuse to let the model make for you.\n\nCan you explain each change? Do you truly own it? Did you keep making the hard decisions yourself? And are strict guardrails in place to protect the codebase when AI writes more of the code?\n\nReach out to me if you want to chat about this. It feels a bit like the wild west right now, and nobody has final answers. I'm really keen to hear how you're navigating the fast pace of change our industry is going through.", "url": "https://wpnews.pro/news/guardrails-protect-your-codebase-what-protects-your-judgment", "canonical_source": "https://belderbos.dev/blog/ai-skill-atrophy-keep-the-friction/", "published_at": "2026-08-18 00:00:00+00:00", "updated_at": "2026-08-19 13:43:07.387318+00:00", "lang": "en", "topics": ["artificial-intelligence", "ai-tools", "ai-agents", "ai-ethics"], "entities": ["Cal Newport", "Corey Schafer", "Bluesky", "Threads", "Fosstodon"], "alternates": {"html": "https://wpnews.pro/news/guardrails-protect-your-codebase-what-protects-your-judgment", "markdown": "https://wpnews.pro/news/guardrails-protect-your-codebase-what-protects-your-judgment.md", "text": "https://wpnews.pro/news/guardrails-protect-your-codebase-what-protects-your-judgment.txt", "jsonld": "https://wpnews.pro/news/guardrails-protect-your-codebase-what-protects-your-judgment.jsonld"}}