[{"data":1,"prerenderedAt":45},["ShallowReactive",2],{"blog-post-cognitive-debt-is-cheap-until-the-code-takes-money":3},{"slug":4,"title":5,"description":6,"date":7,"updated":8,"tags":9,"pillar":15,"draft":16,"image":17,"imageAlt":18,"html":19,"markdown":20,"faq":21,"readingTimeText":43,"readingTimeMinutes":44},"cognitive-debt-is-cheap-until-the-code-takes-money","Cognitive debt is cheap until the code takes money","Cognitive debt costs you a slow refactor in most code and a wrong payment in billing code. How to scale AI review to what breaks when you are wrong.","2026-08-04T00:00:00.000Z",null,[10,11,12,13,14],"ai","code-review","code-quality","billing","maintainability","products-that-last",false,"/blog-covers/products-that-last.png","Products that last cover","\u003Cdiv class=\"post-tldr\">\u003Cdiv class=\"post-tldr-label\">TL;DR\u003C/div>\u003Cp>Cognitive debt does not charge the same interest everywhere in a codebase. Scale how hard you look at generated code to what breaks when you are wrong, because in billing code the bill arrives as a wrong payment rather than a slow refactor.\u003C/p>\u003C/div>\n\u003Cp>This post is mostly an argument with one part of somebody else’s work, so let me say up front whose. Addy Osmani has written the clearest account of how AI erodes understanding, across \u003Ca href=\"https://addyosmani.com/blog/cognitive-surrender/\">cognitive surrender\u003C/a>, \u003Ca href=\"https://addyosmani.com/blog/dont-outsource-learning/\">don’t outsource the learning\u003C/a> and \u003Ca href=\"https://addyosmani.com/blog/intent-debt/\">intent debt\u003C/a>. The distinction he takes from Steven Shaw and Gideon Nave’s Wharton paper is the one worth carrying: offloading is handing over the work and keeping the judgement, surrender is when you stop forming your own view at all, so there is nothing left to check the output against.\u003C/p>\n\u003Cp>I think the diagnosis is right. What I want to push on is the implied prescription, which is to think harder in general. In the part of the codebase I work in, general is the wrong unit.\u003C/p>\n\u003Ch2 id=\"two-kinds-of-debt%2C-two-different-interest-rates\" tabindex=\"-1\">Two kinds of debt, two different interest rates\u003C/h2>\n\u003Cp>Take an admin screen. You let an agent build it, you skim the diff, you ship. That is debt. The interest arrives months later as a change that takes a day instead of an hour, because you have to work out what the code does before you can touch it. Annoying, recoverable, and nobody outside the team hears about it.\u003C/p>\n\u003Cp>Now the same posture on a renewal handler. The interest is not charged in months and it is not charged in your time. It is charged the first time a webhook is redelivered, and it is charged to a customer.\u003C/p>\n\u003Cp>Three things make that gap wider than it looks.\u003C/p>\n\u003Cp>\u003Cstrong>Revenue failures are quiet by construction.\u003C/strong> A broken page throws something a human sees. A renewal that fails to extend an expiry throws nothing, because from the software’s point of view the operation succeeded. I went through the specific shapes in \u003Ca href=\"/blog/six-payments-edge-cases-that-bite-at-2am\">six payments edge cases that bite at 2am\u003C/a>; most of them share the property that the system reports success while getting it wrong. Osmani’s line is that surface correctness is not systemic correctness. In billing code the surface is worse than merely unhelpful, because it is built to look calm.\u003C/p>\n\u003Cp>\u003Cstrong>The cost lands on someone else first.\u003C/strong> Debt in ordinary code costs you a bad afternoon. Debt in billing code costs a customer, and then costs you the conversation about it.\u003C/p>\n\u003Cp>\u003Cstrong>Reconstruction is hardest exactly where it matters most.\u003C/strong> If you do not understand a UI component you can read it and work it out. If you do not understand why a refund path checks a flag before issuing a credit, reading tells you what it does and nothing about what it was defending against. That reason lived in an incident. If nobody wrote it down it is gone, and no amount of reading brings it back.\u003C/p>\n\u003Cp>That last one has a name and a literature. Margaret-Anne Storey’s \u003Ca href=\"https://arxiv.org/abs/2603.22106\">triple debt model\u003C/a> separates technical debt, which lives in the code, from cognitive debt, which she frames as a team-level erosion of \u003Cem>shared\u003C/em> understanding, from intent debt, which lives in artefacts nobody wrote: the goals, constraints and rationale behind why a system is the way it is. Osmani’s \u003Ca href=\"https://addyosmani.com/blog/intent-debt/\">essay on intent debt\u003C/a> is where it clicked for me, and his point is the one that bites here. An agent can restore comprehension by reading the code back to you. It cannot restore intent, because asked why a guard clause exists it will produce a confident answer whether or not it has any idea.\u003C/p>\n\u003Ch2 id=\"does-ai-assisted-coding-make-engineers-worse%3F\" tabindex=\"-1\">Does AI-assisted coding make engineers worse?\u003C/h2>\n\u003Cp>On unfamiliar material the evidence points that way, and I want to be careful about how far it goes.\u003C/p>\n\u003Cp>Anthropic ran a \u003Ca href=\"https://www.anthropic.com/research/AI-assistance-coding-skills\">randomised trial\u003C/a> where engineers learned an unfamiliar Python library, half with an assistant and half without. The assisted group scored around 50% on a comprehension quiz against roughly 67% for the group working by hand, with the widest gap on debugging questions. Anthropic describes that as close to two letter grades. The speed advantage was small enough not to be statistically significant, so on this task the assistance bought almost no time and cost most of the understanding.\u003C/p>\n\u003Cp>The part I keep returning to is smaller and much less certain. Inside the assisted group, the people who came out well were the ones who used the model to build comprehension: some asked only conceptual questions and never had code generated for them, others generated code and then asked for an explanation of what they had just been handed. The worst scores went to people who generated and moved on. The authors are explicit that this is a qualitative observation across a handful of participants and not a causal finding, and the groups involved are single digits. I would not build a policy on it.\u003C/p>\n\u003Cp>But it is the only evidence I have seen pointing at \u003Cem>how you asked\u003C/em> instead of \u003Cem>whether you used it\u003C/em>, and it matches something I notice in myself. That is not evidence. It is the reason I bothered to read the study.\u003C/p>\n\u003Ch2 id=\"where-the-posture-slips%2C-in-money-code\" tabindex=\"-1\">Where the posture slips, in money code\u003C/h2>\n\u003Cp>Osmani names four moments where surrender happens: reading the diff, debugging something you do not understand, making a design call, and learning something new. I have not found a fifth. What I can add is what three of them cost when the directory is \u003Ccode>app/Billing\u003C/code> instead of anywhere else.\u003C/p>\n\u003Cp>\u003Cstrong>Reading a diff and calling it a review.\u003C/strong> His version: the tests pass, the names look reasonable, you approve, and what you did was ratify instead of review. The billing-specific question that separates the two is narrow enough to ask every time. \u003Cem>What does this do if it runs twice?\u003C/em> With at-least-once delivery the second run is normal operation, not an error case, so a handler that is only correct once is a handler that is wrong and has not been caught yet.\u003C/p>\n\u003Cp>\u003Cstrong>Fixing something you cannot reproduce.\u003C/strong> His version: paste the trace, apply the fix, move on, and your mental model is now wrong somewhere you cannot point to. Here the cost compounds differently. A wrong model of a rendering path costs you one bug. A wrong model of a state transition costs you every bug that transition will ever produce, because the misunderstanding is still sitting there generating them.\u003C/p>\n\u003Cp>\u003Cstrong>Taking the framing along with the answer.\u003C/strong> His version: you ask queue or direct call, and accepting the answer means accepting the model’s version of the question. The money-code equivalent is whether to store an amount as an integer or trust a library to handle it. I have a position on that, \u003Ca href=\"/blog/store-money-as-integer-cents-never-a-float\">integer cents, never a float\u003C/a>, and the reason it is a position instead of a preference is that this is a class of decision you cannot recover from by editing later.\u003C/p>\n\u003Cp>None of that is a new taxonomy. It is his taxonomy with the interest rate recalculated.\u003C/p>\n\u003Ch2 id=\"the-same-failure%2C-seen-from-the-other-chair\" tabindex=\"-1\">The same failure, seen from the other chair\u003C/h2>\n\u003Cp>There is an inverted version that gets discussed less, and it applies to anyone paid to be the expert on someone else’s system.\u003C/p>\n\u003Cp>Antonio Pagano wrote about \u003Ca href=\"https://wawand.co/blog/posts/the-senior-engineers-trap/\">the senior engineer’s trap\u003C/a> for Wawandco: an architecture review where the facilitator kept finishing the other engineer’s sentences, adding boxes to the diagram, steering toward the answer he had already reached. The session found the real risks. The other engineer left compliant instead of sharper.\u003C/p>\n\u003Cp>Put that beside the surrender research and it runs on a similar mechanism with the roles swapped. In one, a model hands you a complete answer and you stop building your own. In the other, you are the one handing over the complete answer, and someone else stops building theirs. Pagano frames it through scaffolding theory instead of borrowed confidence, so the parallel is loose. The outcome is not.\u003C/p>\n\u003Cp>The team-level version has been studied. Alami, Zahedi and Krancher’s \u003Ca href=\"https://doi.org/10.1016/j.infsof.2023.107267\">\u003Cem>Antecedents of psychological safety in agile software development teams\u003C/em>\u003C/a> (Information and Software Technology, 2023) ran eighteen interviews and then surveyed 365 practitioners to find out what produces the conditions where people say the awkward thing. The answers were behavioural: openness, absence of blame, collective decision-making inside the team, and leadership taking ownership of the climate.\u003C/p>\n\u003Cp>The result I did not expect is a negative one. Team autonomy, slack time and technical practices providing a safety net were not found to promote psychological safety. That is a non-significant result on a survey rather than proof of no effect, so read it as an absence of evidence. But it is an uncomfortable absence, because the safety net is the thing most teams reach for first, and because Pagano’s own post cites a separate study finding that autonomy does increase psychological safety. The literature is not settled and I am not going to pretend otherwise from an adjacent field.\u003C/p>\n\u003Cp>One caveat on my use of it. That paper studies teams, and the thing I am describing is often one person deciding whether to admit to themselves that they have not formed a view. There is no interpersonal risk in that, so it is not psychological safety in the measured sense. I am borrowing the shape of a finding, not its authority.\u003C/p>\n\u003Cp>What I take from all three is narrower than any of them: the conditions under which somebody admits they do not understand something are made by behaviour, and tooling does not appear to be sufficient. Which is inconvenient, because tooling is what everyone would prefer the answer to be. Myself included, since a checklist is a thing I can ship and a climate is not.\u003C/p>\n\u003Ch2 id=\"how-to-review-ai-generated-billing-code\" tabindex=\"-1\">How to review AI-generated billing code\u003C/h2>\n\u003Cp>The habits below are Osmani’s, from the posts linked at the top. I am reproducing them because they work, not because I improved them. One is mine and I have marked it.\u003C/p>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Write down what you expect before you read the answer.\u003C/strong> Two lines: what you think is wrong, and roughly what the fix should look like. If the answer matches, you are calibrated. If it does not, you have a decision to make instead of a plausible paragraph to accept. This is the one I skip most often when tired, which is exactly when it matters.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Read the diff as though a competent stranger submitted it.\u003C/strong> Would you merge this on the strength of a green build? You would not. The standard does not change because the author is a model.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Record the why at the moment you decide it.\u003C/strong> A minute at the time, unrecoverable later. The guard clause with no reason attached is the most expensive artefact in a legacy codebase, because the next reader, human or agent, will delete it confidently and be right about the code and wrong about the system.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Build something small without assistance now and then.\u003C/strong> Not on principle, as a measurement. There is no other way to find out how much you have quietly stopped being able to do.\u003C/p>\n\u003C/li>\n\u003Cli>\n\u003Cp>\u003Cstrong>Ask what happens on the second delivery.\u003C/strong> This one is mine, and it is the only thing in this post that is. Apply it to every change that touches money. It is narrow enough to ask every time, and it covers a large share of what I have seen go wrong in this kind of code.\u003C/p>\n\u003C/li>\n\u003C/ol>\n\u003Cp>That is four borrowed and one added, which is roughly the ratio this whole post runs at. I would rather say so than let the framing imply otherwise.\u003C/p>\n\u003Ch2 id=\"where-this-does-not-apply\" tabindex=\"-1\">Where this does not apply\u003C/h2>\n\u003Cp>Most of what I write gets none of this.\u003C/p>\n\u003Cp>Scaffolding, one-off scripts, admin screens, test fixtures, a migration for a reporting table. Delegate all of it and do not feel virtuous about reviewing it line by line. The cost of not understanding a throwaway script is that you throw it away.\u003C/p>\n\u003Cp>There is a tension here with something else I believe. I have argued that \u003Ca href=\"/blog/boring-code-is-a-feature-you-ship-to-your-future-self\">boring, legible code\u003C/a> is worth defending everywhere, and that a competent stranger should be able to change any part of a system without archaeology. That still holds, and the two are reconcilable only if you separate them. Write everything legibly. Spend the expensive kind of attention, the slow adversarial what-if-this-runs-twice kind, unevenly.\u003C/p>\n\u003Cp>Understanding is finite. The mistake is not offloading. It is offloading at the same rate in the directory that issues refunds as in the directory that renders a settings page.\u003C/p>\n\u003Cdiv class=\"post-takeaway\">\u003Cdiv class=\"post-takeaway-label\">The takeaway\u003C/div>\u003Cp>The research on cognitive debt is getting better and the general advice attached to it is fine as far as it goes. What it skips is that the interest rate varies enormously by what the code does. Somewhere in your system is a path where not understanding something costs a customer money today instead of costing you an afternoon next quarter, and that path deserves a different standard. The standard is not to think harder. It is a small number of questions asked every single time.\u003C/p>\n\u003Cp>Somebody has to be able to reconstruct the money path from first principles. If that is nobody, the tools did not cause the problem, but they made it a great deal easier to arrive at.\u003C/p>\u003C/div>\u003Ch2 id=\"faq\" tabindex=\"-1\">FAQ\u003C/h2>\n\u003Cdiv class=\"post-faq\">\u003Cdiv class=\"faq-item\">\u003Cdiv class=\"faq-q\">What is the difference between cognitive offloading and cognitive surrender?\u003C/div>\u003Cdiv class=\"faq-a\">\u003Cp>Offloading is handing over the work while keeping the judgement, so you still form your own view and can override the output. Surrender is when you stop forming an independent view at all, so there is nothing left to check against. The distinction is from Steven Shaw and Gideon Nave’s Wharton paper on AI and reasoning, and Addy Osmani’s \u003Ca href=\"https://addyosmani.com/blog/cognitive-surrender/\">cognitive surrender\u003C/a> is the clearest explanation of it for engineers.\u003C/p>\u003C/div>\u003C/div>\u003Cdiv class=\"faq-item\">\u003Cdiv class=\"faq-q\">Does AI-assisted coding make engineers worse?\u003C/div>\u003Cdiv class=\"faq-a\">\u003Cp>On unfamiliar material the evidence points that way. Anthropic’s \u003Ca href=\"https://www.anthropic.com/research/AI-assistance-coding-skills\">randomised trial\u003C/a> reported that engineers learning a new Python library with an assistant scored around 50% on a comprehension quiz against roughly 67% for those working by hand, with the largest gap on debugging, and close to no speed advantage. Within the assisted group, the people who used the model to build comprehension scored well, whether they asked only conceptual questions or generated code and then asked for an explanation. The worst scores went to those who generated and moved on. That within-group comparison is observational and involves very few participants, so treat it as a direction and not a law.\u003C/p>\u003C/div>\u003C/div>\u003Cdiv class=\"faq-item\">\u003Cdiv class=\"faq-q\">Why does this matter more in billing code than elsewhere?\u003C/div>\u003Cdiv class=\"faq-a\">\u003Cp>Because revenue failures are quiet and immediate. A broken page raises an error somebody sees; a renewal that fails to extend an expiry reports success. The debt is charged as a wrong payment to a real customer instead of as a slower refactor two quarters out.\u003C/p>\u003C/div>\u003C/div>\u003Cdiv class=\"faq-item\">\u003Cdiv class=\"faq-q\">What is intent debt?\u003C/div>\u003Cdiv class=\"faq-a\">\u003Cp>The goals, constraints and rationale behind a system that were never written down outside somebody’s head. The term is Margaret-Anne Storey’s, from her \u003Ca href=\"https://arxiv.org/abs/2603.22106\">triple debt model\u003C/a>, which separates it from technical debt in the code and cognitive debt in a team’s shared understanding. It is the only one of the three an agent cannot repay: asked why a guard clause exists, a model will produce a confident answer whether or not it knows.\u003C/p>\u003C/div>\u003C/div>\u003Cdiv class=\"faq-item\">\u003Cdiv class=\"faq-q\">How should I review AI-generated billing code?\u003C/div>\u003Cdiv class=\"faq-a\">\u003Cp>Write down what you expect the change to look like before you read it. Read the diff as though a competent stranger submitted it and you had to defend merging it. Record the reason for anything defensive next to the code, so the next reader does not delete it. And ask what the change does if it runs twice, because with at-least-once delivery that is normal operation and not an edge case.\u003C/p>\u003C/div>\u003C/div>\u003Cdiv class=\"faq-item\">\u003Cdiv class=\"faq-q\">Can tooling fix this, with better tests or stricter review?\u003C/div>\u003Cdiv class=\"faq-a\">\u003Cp>Not on its own, as far as the evidence goes. Alami, Zahedi and Krancher’s \u003Ca href=\"https://doi.org/10.1016/j.infsof.2023.107267\">study of psychological safety in agile teams\u003C/a> found openness, absence of blame, collective decision-making and leadership ownership produced it, while team autonomy, slack time and technical practices providing a safety net did not reach significance. That is an absence of evidence and not proof of no effect, and other work disagrees about autonomy. Treat it as a caution against assuming a safety net is sufficient.\u003C/p>\u003C/div>\u003C/div>\u003Cdiv class=\"faq-item\">\u003Cdiv class=\"faq-q\">How do I know if I have crossed the line?\u003C/div>\u003Cdiv class=\"faq-a\">\u003Cp>Try to reconstruct a recent design decision without opening the code or the agent. If you can say why it was made and what it was defending against, you offloaded. If you can only say it seemed reasonable at the time, you did not.\u003C/p>\u003C/div>\u003C/div>\u003C/div>","\n## TL;DR\n\nCognitive debt does not charge the same interest everywhere in a codebase. Scale how hard you look at generated code to what breaks when you are wrong, because in billing code the bill arrives as a wrong payment rather than a slow refactor.\n\nThis post is mostly an argument with one part of somebody else's work, so let me say up front whose. Addy Osmani has written the clearest account of how AI erodes understanding, across [cognitive surrender](https://addyosmani.com/blog/cognitive-surrender/), [don't outsource the learning](https://addyosmani.com/blog/dont-outsource-learning/) and [intent debt](https://addyosmani.com/blog/intent-debt/). The distinction he takes from Steven Shaw and Gideon Nave's Wharton paper is the one worth carrying: offloading is handing over the work and keeping the judgement, surrender is when you stop forming your own view at all, so there is nothing left to check the output against.\n\nI think the diagnosis is right. What I want to push on is the implied prescription, which is to think harder in general. In the part of the codebase I work in, general is the wrong unit.\n\n## Two kinds of debt, two different interest rates\n\nTake an admin screen. You let an agent build it, you skim the diff, you ship. That is debt. The interest arrives months later as a change that takes a day instead of an hour, because you have to work out what the code does before you can touch it. Annoying, recoverable, and nobody outside the team hears about it.\n\nNow the same posture on a renewal handler. The interest is not charged in months and it is not charged in your time. It is charged the first time a webhook is redelivered, and it is charged to a customer.\n\nThree things make that gap wider than it looks.\n\n**Revenue failures are quiet by construction.** A broken page throws something a human sees. A renewal that fails to extend an expiry throws nothing, because from the software's point of view the operation succeeded. I went through the specific shapes in [six payments edge cases that bite at 2am](/blog/six-payments-edge-cases-that-bite-at-2am); most of them share the property that the system reports success while getting it wrong. Osmani's line is that surface correctness is not systemic correctness. In billing code the surface is worse than merely unhelpful, because it is built to look calm.\n\n**The cost lands on someone else first.** Debt in ordinary code costs you a bad afternoon. Debt in billing code costs a customer, and then costs you the conversation about it.\n\n**Reconstruction is hardest exactly where it matters most.** If you do not understand a UI component you can read it and work it out. If you do not understand why a refund path checks a flag before issuing a credit, reading tells you what it does and nothing about what it was defending against. That reason lived in an incident. If nobody wrote it down it is gone, and no amount of reading brings it back.\n\nThat last one has a name and a literature. Margaret-Anne Storey's [triple debt model](https://arxiv.org/abs/2603.22106) separates technical debt, which lives in the code, from cognitive debt, which she frames as a team-level erosion of *shared* understanding, from intent debt, which lives in artefacts nobody wrote: the goals, constraints and rationale behind why a system is the way it is. Osmani's [essay on intent debt](https://addyosmani.com/blog/intent-debt/) is where it clicked for me, and his point is the one that bites here. An agent can restore comprehension by reading the code back to you. It cannot restore intent, because asked why a guard clause exists it will produce a confident answer whether or not it has any idea.\n\n## Does AI-assisted coding make engineers worse?\n\nOn unfamiliar material the evidence points that way, and I want to be careful about how far it goes.\n\nAnthropic ran a [randomised trial](https://www.anthropic.com/research/AI-assistance-coding-skills) where engineers learned an unfamiliar Python library, half with an assistant and half without. The assisted group scored around 50% on a comprehension quiz against roughly 67% for the group working by hand, with the widest gap on debugging questions. Anthropic describes that as close to two letter grades. The speed advantage was small enough not to be statistically significant, so on this task the assistance bought almost no time and cost most of the understanding.\n\nThe part I keep returning to is smaller and much less certain. Inside the assisted group, the people who came out well were the ones who used the model to build comprehension: some asked only conceptual questions and never had code generated for them, others generated code and then asked for an explanation of what they had just been handed. The worst scores went to people who generated and moved on. The authors are explicit that this is a qualitative observation across a handful of participants and not a causal finding, and the groups involved are single digits. I would not build a policy on it.\n\nBut it is the only evidence I have seen pointing at *how you asked* instead of *whether you used it*, and it matches something I notice in myself. That is not evidence. It is the reason I bothered to read the study.\n\n## Where the posture slips, in money code\n\nOsmani names four moments where surrender happens: reading the diff, debugging something you do not understand, making a design call, and learning something new. I have not found a fifth. What I can add is what three of them cost when the directory is `app/Billing` instead of anywhere else.\n\n**Reading a diff and calling it a review.** His version: the tests pass, the names look reasonable, you approve, and what you did was ratify instead of review. The billing-specific question that separates the two is narrow enough to ask every time. *What does this do if it runs twice?* With at-least-once delivery the second run is normal operation, not an error case, so a handler that is only correct once is a handler that is wrong and has not been caught yet.\n\n**Fixing something you cannot reproduce.** His version: paste the trace, apply the fix, move on, and your mental model is now wrong somewhere you cannot point to. Here the cost compounds differently. A wrong model of a rendering path costs you one bug. A wrong model of a state transition costs you every bug that transition will ever produce, because the misunderstanding is still sitting there generating them.\n\n**Taking the framing along with the answer.** His version: you ask queue or direct call, and accepting the answer means accepting the model's version of the question. The money-code equivalent is whether to store an amount as an integer or trust a library to handle it. I have a position on that, [integer cents, never a float](/blog/store-money-as-integer-cents-never-a-float), and the reason it is a position instead of a preference is that this is a class of decision you cannot recover from by editing later.\n\nNone of that is a new taxonomy. It is his taxonomy with the interest rate recalculated.\n\n## The same failure, seen from the other chair\n\nThere is an inverted version that gets discussed less, and it applies to anyone paid to be the expert on someone else's system.\n\nAntonio Pagano wrote about [the senior engineer's trap](https://wawand.co/blog/posts/the-senior-engineers-trap/) for Wawandco: an architecture review where the facilitator kept finishing the other engineer's sentences, adding boxes to the diagram, steering toward the answer he had already reached. The session found the real risks. The other engineer left compliant instead of sharper.\n\nPut that beside the surrender research and it runs on a similar mechanism with the roles swapped. In one, a model hands you a complete answer and you stop building your own. In the other, you are the one handing over the complete answer, and someone else stops building theirs. Pagano frames it through scaffolding theory instead of borrowed confidence, so the parallel is loose. The outcome is not.\n\nThe team-level version has been studied. Alami, Zahedi and Krancher's [*Antecedents of psychological safety in agile software development teams*](https://doi.org/10.1016/j.infsof.2023.107267) (Information and Software Technology, 2023) ran eighteen interviews and then surveyed 365 practitioners to find out what produces the conditions where people say the awkward thing. The answers were behavioural: openness, absence of blame, collective decision-making inside the team, and leadership taking ownership of the climate.\n\nThe result I did not expect is a negative one. Team autonomy, slack time and technical practices providing a safety net were not found to promote psychological safety. That is a non-significant result on a survey rather than proof of no effect, so read it as an absence of evidence. But it is an uncomfortable absence, because the safety net is the thing most teams reach for first, and because Pagano's own post cites a separate study finding that autonomy does increase psychological safety. The literature is not settled and I am not going to pretend otherwise from an adjacent field.\n\nOne caveat on my use of it. That paper studies teams, and the thing I am describing is often one person deciding whether to admit to themselves that they have not formed a view. There is no interpersonal risk in that, so it is not psychological safety in the measured sense. I am borrowing the shape of a finding, not its authority.\n\nWhat I take from all three is narrower than any of them: the conditions under which somebody admits they do not understand something are made by behaviour, and tooling does not appear to be sufficient. Which is inconvenient, because tooling is what everyone would prefer the answer to be. Myself included, since a checklist is a thing I can ship and a climate is not.\n\n## How to review AI-generated billing code\n\nThe habits below are Osmani's, from the posts linked at the top. I am reproducing them because they work, not because I improved them. One is mine and I have marked it.\n\n1. **Write down what you expect before you read the answer.** Two lines: what you think is wrong, and roughly what the fix should look like. If the answer matches, you are calibrated. If it does not, you have a decision to make instead of a plausible paragraph to accept. This is the one I skip most often when tired, which is exactly when it matters.\n\n2. **Read the diff as though a competent stranger submitted it.** Would you merge this on the strength of a green build? You would not. The standard does not change because the author is a model.\n\n3. **Record the why at the moment you decide it.** A minute at the time, unrecoverable later. The guard clause with no reason attached is the most expensive artefact in a legacy codebase, because the next reader, human or agent, will delete it confidently and be right about the code and wrong about the system.\n\n4. **Build something small without assistance now and then.** Not on principle, as a measurement. There is no other way to find out how much you have quietly stopped being able to do.\n\n5. **Ask what happens on the second delivery.** This one is mine, and it is the only thing in this post that is. Apply it to every change that touches money. It is narrow enough to ask every time, and it covers a large share of what I have seen go wrong in this kind of code.\n\nThat is four borrowed and one added, which is roughly the ratio this whole post runs at. I would rather say so than let the framing imply otherwise.\n\n## Where this does not apply\n\nMost of what I write gets none of this.\n\nScaffolding, one-off scripts, admin screens, test fixtures, a migration for a reporting table. Delegate all of it and do not feel virtuous about reviewing it line by line. The cost of not understanding a throwaway script is that you throw it away.\n\nThere is a tension here with something else I believe. I have argued that [boring, legible code](/blog/boring-code-is-a-feature-you-ship-to-your-future-self) is worth defending everywhere, and that a competent stranger should be able to change any part of a system without archaeology. That still holds, and the two are reconcilable only if you separate them. Write everything legibly. Spend the expensive kind of attention, the slow adversarial what-if-this-runs-twice kind, unevenly.\n\nUnderstanding is finite. The mistake is not offloading. It is offloading at the same rate in the directory that issues refunds as in the directory that renders a settings page.\n\n## The takeaway\n\nThe research on cognitive debt is getting better and the general advice attached to it is fine as far as it goes. What it skips is that the interest rate varies enormously by what the code does. Somewhere in your system is a path where not understanding something costs a customer money today instead of costing you an afternoon next quarter, and that path deserves a different standard. The standard is not to think harder. It is a small number of questions asked every single time.\n\nSomebody has to be able to reconstruct the money path from first principles. If that is nobody, the tools did not cause the problem, but they made it a great deal easier to arrive at.\n\n## FAQ\n\n**What is the difference between cognitive offloading and cognitive surrender?**\nOffloading is handing over the work while keeping the judgement, so you still form your own view and can override the output. Surrender is when you stop forming an independent view at all, so there is nothing left to check against. The distinction is from Steven Shaw and Gideon Nave's Wharton paper on AI and reasoning, and Addy Osmani's [cognitive surrender](https://addyosmani.com/blog/cognitive-surrender/) is the clearest explanation of it for engineers.\n\n**Does AI-assisted coding make engineers worse?**\nOn unfamiliar material the evidence points that way. Anthropic's [randomised trial](https://www.anthropic.com/research/AI-assistance-coding-skills) reported that engineers learning a new Python library with an assistant scored around 50% on a comprehension quiz against roughly 67% for those working by hand, with the largest gap on debugging, and close to no speed advantage. Within the assisted group, the people who used the model to build comprehension scored well, whether they asked only conceptual questions or generated code and then asked for an explanation. The worst scores went to those who generated and moved on. That within-group comparison is observational and involves very few participants, so treat it as a direction and not a law.\n\n**Why does this matter more in billing code than elsewhere?**\nBecause revenue failures are quiet and immediate. A broken page raises an error somebody sees; a renewal that fails to extend an expiry reports success. The debt is charged as a wrong payment to a real customer instead of as a slower refactor two quarters out.\n\n**What is intent debt?**\nThe goals, constraints and rationale behind a system that were never written down outside somebody's head. The term is Margaret-Anne Storey's, from her [triple debt model](https://arxiv.org/abs/2603.22106), which separates it from technical debt in the code and cognitive debt in a team's shared understanding. It is the only one of the three an agent cannot repay: asked why a guard clause exists, a model will produce a confident answer whether or not it knows.\n\n**How should I review AI-generated billing code?**\nWrite down what you expect the change to look like before you read it. Read the diff as though a competent stranger submitted it and you had to defend merging it. Record the reason for anything defensive next to the code, so the next reader does not delete it. And ask what the change does if it runs twice, because with at-least-once delivery that is normal operation and not an edge case.\n\n**Can tooling fix this, with better tests or stricter review?**\nNot on its own, as far as the evidence goes. Alami, Zahedi and Krancher's [study of psychological safety in agile teams](https://doi.org/10.1016/j.infsof.2023.107267) found openness, absence of blame, collective decision-making and leadership ownership produced it, while team autonomy, slack time and technical practices providing a safety net did not reach significance. That is an absence of evidence and not proof of no effect, and other work disagrees about autonomy. Treat it as a caution against assuming a safety net is sufficient.\n\n**How do I know if I have crossed the line?**\nTry to reconstruct a recent design decision without opening the code or the agent. If you can say why it was made and what it was defending against, you offloaded. If you can only say it seemed reasonable at the time, you did not.\n",[22,25,28,31,34,37,40],{"q":23,"a":24},"What is the difference between cognitive offloading and cognitive surrender?","Offloading is handing over the work while keeping the judgement, so you still form your own view and can override the output. Surrender is when you stop forming an independent view at all, so there is nothing left to check against. The distinction is from Steven Shaw and Gideon Nave's Wharton paper on AI and reasoning, and Addy Osmani's cognitive surrender is the clearest explanation of it for engineers.",{"q":26,"a":27},"Does AI-assisted coding make engineers worse?","On unfamiliar material the evidence points that way. Anthropic's randomised trial reported that engineers learning a new Python library with an assistant scored around 50% on a comprehension quiz against roughly 67% for those working by hand, with the largest gap on debugging, and close to no speed advantage. Within the assisted group, the people who used the model to build comprehension scored well, whether they asked only conceptual questions or generated code and then asked for an explanation. The worst scores went to those who generated and moved on. That within-group comparison is observational and involves very few participants, so treat it as a direction and not a law.",{"q":29,"a":30},"Why does this matter more in billing code than elsewhere?","Because revenue failures are quiet and immediate. A broken page raises an error somebody sees; a renewal that fails to extend an expiry reports success. The debt is charged as a wrong payment to a real customer instead of as a slower refactor two quarters out.",{"q":32,"a":33},"What is intent debt?","The goals, constraints and rationale behind a system that were never written down outside somebody's head. The term is Margaret-Anne Storey's, from her triple debt model, which separates it from technical debt in the code and cognitive debt in a team's shared understanding. It is the only one of the three an agent cannot repay: asked why a guard clause exists, a model will produce a confident answer whether or not it knows.",{"q":35,"a":36},"How should I review AI-generated billing code?","Write down what you expect the change to look like before you read it. Read the diff as though a competent stranger submitted it and you had to defend merging it. Record the reason for anything defensive next to the code, so the next reader does not delete it. And ask what the change does if it runs twice, because with at-least-once delivery that is normal operation and not an edge case.",{"q":38,"a":39},"Can tooling fix this, with better tests or stricter review?","Not on its own, as far as the evidence goes. Alami, Zahedi and Krancher's study of psychological safety in agile teams found openness, absence of blame, collective decision-making and leadership ownership produced it, while team autonomy, slack time and technical practices providing a safety net did not reach significance. That is an absence of evidence and not proof of no effect, and other work disagrees about autonomy. Treat it as a caution against assuming a safety net is sufficient.",{"q":41,"a":42},"How do I know if I have crossed the line?","Try to reconstruct a recent design decision without opening the code or the agent. If you can say why it was made and what it was defending against, you offloaded. If you can only say it seemed reasonable at the time, you did not.","14 min read",14,1785920899637]