{"slug": "the-two-joints-where-agentic-engineering-breaks", "title": "The Two Joints: Where Agentic Engineering Breaks", "summary": "An engineer describes a system that integrates intent, verification, and correction into a single agentic engineering workflow, identifying two critical joints where the layers connect. The design separates an inner loop that fixes code from an outer loop that amends the spec, preventing agents from altering their own targets. The approach highlights the risk of common-cause failure when tests are generated solely from the spec.", "body_md": "Intent — the spec says what correct means.\n\nVerification — tests check whether you got it.\n\nCorrection — a loop closes the gap.\n\nThis post is what happened when I stopped running those as three separate practices and wired them into one system.\n\nThe layers were the easy part.\n\nThe hard part is where they join, and there are **exactly two joints**.\n\nRunning three methodologies \"concurrently\" looked like this:\n\nAll three were real.\n\nThe connection between them was **me, noticing things**.\n\nI noticed that a failing test meant a PRD assumption was wrong.\n\nI noticed that slices five through nine came from a version of the spec that no longer existed.\n\nI noticed that an agent had \"fixed\" a failing test by making the test weaker.\n\nThat's not a system.\n\nThat's three components and an operator, and **the operator is the part that doesn't scale**.\n\nEach layer had a trigger, an input and an output.\n\nNone of them had a defined interface to the layer next door, so the interface defaulted to my attention.\n\nSo the goal isn't:\n\n\"Adopt all three.\"\n\nIt's:\n\nGive the handoffs between layers a name, a trigger and an artifact, so they happen without me.\n\nThe system looks like this:\n\n```\n                         SPEC\n                    (what correct means)\n                           |\n                           v\n                 +---------+---------+\n                 |                   |\n                 v                   v\n            work slices        tests written\n                              and FROZEN first\n                 |                   |\n                 v                   |\n          agent implements           |\n                 |                   |\n                 +---------+---------+\n                           |\n                           v\n                      run the tests\n                           |\n                 +---------+---------+\n                 |                   |\n                 v                   v\n             code is wrong       spec looks wrong\n             INNER LOOP          OUTER LOOP\n             retry N times       STOP, no retries\n             agent fixes it      human decides\n                 |                   |\n                 v                   v\n             human gate,        amend the spec,\n             by blast radius    re-derive the rest\n```\n\nTwo loops.\n\nThe difference between them is the whole design:\n\n**The inner loop fixes the code.**\n\nRuns unsupervised, on a retry budget, allowed to act.\n\n**The outer loop fixes the spec.**\n\nRuns on escalation, no retry budget, allowed only to propose.\n\nChanging the spec means changing intent, and intent isn't something an agent gets to change by itself.\n\nA loop that can edit its own target will move the target instead of solving the problem.\n\nEvery time.\n\nThe rest of this post is those two joints.\n\nPart two ended on this claim, and it's harder than it sounds:\n\nA feedback loop with a bad sensor is worse than no loop, because it converges, confidently, at machine speed, on the wrong thing.\n\nThe obvious move is to generate your tests from your spec.\n\nThat's the spec-driven pitch, and it works.\n\nBut it buys you exactly one thing:\n\n**It catches the code disagreeing with the spec.**\n\nNow notice what it can't catch.\n\nIf the spec is wrong about the real world, a test generated from that spec is wrong in the same direction.\n\nIt passes.\n\nGreen checkmark.\n\nEveryone goes home.\n\nSafety engineering has a name for this: **common-cause failure**.\n\nTwo backups don't help if they share a design flaw, which is why aircraft use sensors built on different physical principles instead of just duplicating one.\n\nYour spec-generated test suite is one channel, and its design is the spec.\n\n| What went wrong | Example | Can a spec-generated test catch it? |\n|---|---|---|\nCode doesn't match the spec |\nPRD says retry 3 times, code retries once |\nYes. This is its job |\nSpec contradicts itself |\nRequires strict ordering on a queue that doesn't guarantee it | Yes, cheaply |\nSpec is silent |\nSays nothing about ordering, so the agent picks one |\nNo. No test exists for an unstated rule |\nSpec is wrong about the world |\n\"The provider's charge endpoint is idempotent.\" It isn't |\nNo. The test asserts the same falsehood |\nSpec is right, the requirement was bad |\nFlawless build of the wrong feature |\nNo, and no test ever will |\n\nRows three and four are where money gets lost.\n\nThe fix isn't a better prompt.\n\nIt's a **second kind of test**.\n\nI now split tests by what they're measured against, not by unit/integration/e2e.\n\nGenerated from the spec.\n\nMeasured against intent.\n\nProperty tests over the stated invariants, assertions on the out-of-scope list.\n\nCheap, generated, and I make a lot of them.\n\nThey ask:\n\nDoes the code do what we said?\n\nNot generated from the spec.\n\nMeasured against the world.\n\nProvider sandbox checks, fault injection, replays of real incidents, reconciliation against the provider's ledger.\n\nExpensive, mostly hand-written, they accumulate slowly.\n\nThey ask:\n\nDoes this survive contact?\n\nThe line that reorganized my thinking:\n\nOnly a test that didn't come from the spec can prove the spec wrong.\n\nAnything derived from the target can confirm the target.\n\nNothing derived from it can contradict it.\n\nWhich gives a hard rule:\n\nA failing spec test is never grounds for changing the spec. It means the code is wrong. Only a failing reality test is allowed to say the spec is wrong.\n\nThat sounds like bureaucracy until the first time an agent responds to a hard failing test by suggesting you amend the PRD.\n\nWhich it will, because that's the cheapest path to green.\n\nNot the same session.\n\nNot after there's an implementation to look at.\n\nSequencing buys independence almost free.\n\nThe agent writing the code may not edit its own tests.\n\nIf a slice genuinely needs a test changed, that's not a code change.\n\nIt's a claim about intent, and it escalates.\n\nThis one rule killed my worst failure mode.\n\nThe clarifying-questions pass from `/to-prd`\n\nwas aimed at my rough prompt.\n\nI now run it again on the finished spec, asking only:\n\nWhat does this not say that an implementer would have to guess?\n\nEach answer becomes a spec edit or a recorded \"don't care.\"\n\nBoth are durable.\n\nAn agent's undocumented assumptions are the most dangerous thing in the system, because they're the only part that isn't written down anywhere.\n\nA loop with a retry budget and no escape hatch doesn't stop when the spec is wrong.\n\nIt keeps going, because that's what loops do.\n\nAnd since it can't reach the spec, it reduces the error the only other way available:\n\n**by weakening the test.**\n\nRelax the assertion.\n\nWiden the tolerance.\n\nSkip the case with a plausible comment.\n\nSpecial-case the failing input.\n\nEach move is locally reasonable, and each one lies to you afterward.\n\nA loop that can weaken its own tests will always converge. That's not a feature, that's the bug.\n\nSo the outer loop isn't mainly a correction mechanism.\n\nIt's a **stop button**.\n\nAnd stopping is its most important capability.\n\nWhen a reality test fails in a way the inner loop can't fix, the loop halts that branch.\n\n**Zero retries.**\n\nBecause retrying a spec error just buys more attempts at the wrong problem.\n\nThen it files a spec challenge that blocks the parent PRD.\n\nFor example:\n\n```\nspec_challenge:\n  spec: PRD-412 @ a3f19c2\n\n  assumption: \"provider charge endpoint is idempotent on our key\"\n\n  contradicted_by:\n    test: reality/provider-sandbox-conformance\n    # must be a reality test\n\n    observed: \"duplicate charge on retry with identical key\"\n\n    reproduced: \"5 of 5 runs\"\n\n  blast_radius:\n    slices_blocked: [4, 5, 7]\n    slices_already_merged_on_this_assumption: [1, 2]\n\n  smallest_fix_proposed: |\n    key on provider_ref only; add 15m reconciliation sweep\n    against provider ledger.\n```\n\nFour fields do the work.\n\nBecause it decides who's even allowed to file this.\n\nBecause that's the expensive number and I want it before I decide anything.\n\nBecause \"smallest\" is load-bearing.\n\nAn unconstrained agent will propose rewriting the spec around its discovery.\n\nBecause \"failed once\" and \"failed five out of five\" are different conversations.\n\nThen a human decides.\n\nThere are exactly four answers, and naming them turned a judgment call into triage:\n\nAn amendment describes what changed, not the whole world again.\n\nThen it propagates, in three tiers with very different costs.\n\n**Regenerate.**\n\nFree.\n\nThis is the entire payoff of spec-driven work.\n\n**Halt, throw away, re-derive.**\n\nCosts tokens and nothing else.\n\nImplementations are disposable; that was the bet.\n\nThe one nobody warns you about.\n\nIt isn't automatically wrong, but it is now unverified and has to be re-checked against the amended spec.\n\nSo every derived artifact carries the spec revision it came from:\n\nFor example:\n\n```\nDerived-From: PRD-412@a3f19c2\n```\n\nUnglamorous, and it converts the worst question in the system from an archaeology dig into a search.\n\nWhich merged work came from a spec that has since changed?\n\nWithout stamps, the honest answer after three amendments is:\n\n\"Some of it, let me read the git log.\"\n\nWith them, you get a list.\n\nAnd lists can be worked.\n\nIf the same assumption gets amended twice in one feature, I stop.\n\nTwo amendments mean I'm not correcting my model of the system.\n\nI'm searching for one.\n\nThat's a spike, run deliberately in a throwaway branch, with nothing derived from it until it finishes.\n\nA target that moves every time a test complains isn't a target.\n\nIt's worth being honest about what this architecture doesn't solve.\n\nReality tests are expensive and don't generate well.\n\nThat's the honest asymmetry here.\n\nThe channel I need most for correctness is the one that can't be derived from the artifact I have, by definition.\n\nFault injection.\n\nReal sandboxes.\n\nRecorded incidents.\n\nIt accumulates at human speed.\n\nAnyone selling fully generated verification is selling you one channel and calling it two.\n\nWhich is the same bottleneck again.\n\nIf the loop escalates too readily, spec challenges pile up and get rubber-stamped exactly the way oversized diffs do.\n\nI've moved the constraint from reviewing code to deciding about intent.\n\nThat's a better place for it, far more leverage per decision, but part one's point holds and it's recursive:\n\nYou don't eliminate a bottleneck, you relocate it. Then you go find it again.\n\nSpec.\n\nSpec tests.\n\nReality tests.\n\nVersion stamps.\n\nPart two warned that a hybrid fails as a stale spec that agents still trust.\n\nVersion stamps make that detectable, not impossible.\n\nNo tooling for any of the provenance.\n\nCommit trailers and issue labels, which is to say conventions and discipline, which is to say it will decay.\n\nThis feels like something that should exist.\n\nIf it does, tell me.\n\nNo answer to part one's open question.\n\nIf the mechanical work is where judgment used to get manufactured, and that work is now agentic, where do the next senior engineers come from?\n\nDeciding spec challenges is excellent practice for exactly the skill that matters, and it's also the task I'd hand to the most experienced person in the room.\n\nWhich means it isn't a training ground.\n\nI'm suspicious of anyone who claims to have solved this.\n\n**Part one:** your job moved from building the system to designing the system that builds the system.\n\n**Part two:** sort the methodologies by where truth lives between runs, and you get three layers.\n\n**Part three:** the layers were the easy part, and a hybrid is defined by its joints, not its parts.\n\nIf one thing survives out of all of it:\n\nBoth joints are the same problem stated twice.\n\nIndependence has to be engineered in.\n\nIt is never the default.\n\nA test derived from the spec can't correct the spec, and a loop that can edit its target will move the target instead of doing the work.\n\nAnd part two's caveat applies here more than anywhere.\n\nA lot of this is model-specific error correction with a good name on it.\n\nThe rule about tests exists because today's models will happily weaken one to reach green.\n\nThe zero-retry rule exists because they'll happily rewrite a target to hit it.\n\nIf a future model reliably refuses both, some of this becomes scar tissue and should be cut.\n\n**Notice which of your rituals are load-bearing.**\n\nRetune when you change models.\n\nAnd if you've built the same shape and hit a different joint, tell me, because I'm fairly sure I've only found two of them.\n\n*Part three of a series on agentic engineering in production. Part one covered the three-skill workflow and where the bottleneck goes when code stops being the constraint. Part two mapped the methodology landscape by asking where truth lives between agent runs.*", "url": "https://wpnews.pro/news/the-two-joints-where-agentic-engineering-breaks", "canonical_source": "https://dev.to/mtsammy40/the-two-joints-where-agentic-engineering-breaks-52lm", "published_at": "2026-08-18 18:30:35+00:00", "updated_at": "2026-08-18 18:44:24.784960+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "ai-safety"], "entities": [], "alternates": {"html": "https://wpnews.pro/news/the-two-joints-where-agentic-engineering-breaks", "markdown": "https://wpnews.pro/news/the-two-joints-where-agentic-engineering-breaks.md", "text": "https://wpnews.pro/news/the-two-joints-where-agentic-engineering-breaks.txt", "jsonld": "https://wpnews.pro/news/the-two-joints-where-agentic-engineering-breaks.jsonld"}}