<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Rafał Opiłowski</title><description>Personal portfolio and blog of Rafał Opiłowski</description><link>https://justsomebody.dev</link><language>en-us</language><item><title>How to Make an Agent Know It Screwed Up</title><link>https://justsomebody.dev/blog/how-to-make-an-agent-know-it-screw-up</link><guid isPermaLink="true">https://justsomebody.dev/blog/how-to-make-an-agent-know-it-screw-up</guid><description>DevOps for AI-augmented development: patterns for testability, maintainability, and resilience against AI agent flaws</description><pubDate>Mon, 06 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;AI agents write code fast. They also leak &lt;code class=&quot;px-1 py-0.5 rounded font-mono print:text-[7.5pt] print:leading-tight&quot;&gt;null&lt;/code&gt; through every layer, create 2,000-line router files, leave bugs in production, and generate dead code once the happy path compiles.&lt;/p&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;This isn’t malice; LLMs optimize for plausible output, not production durability. You won’t stop them from making mistakes, but you can build a system where the agent finds out it screwed up before a human has to tell it.&lt;/p&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;I’ve implemented features and maintained code quality through an AI agent on a production TypeScript monorepo (10+ packages, 3+ apps). These are the layers that made it work.&lt;/p&gt;
&lt;hr class=&quot;mb-4 print:mb-2&quot;&gt;
&lt;h3 id=&quot;layer-0-documentation&quot; class=&quot;text-2xl font-semibold my-8 mb-4 mt-8 font-sans print:text-[7.5pt] print:leading-tight print:my-0 print:mb-0.5 print:mt-0&quot;&gt;Layer 0: Documentation&lt;/h3&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;Write down what, how, and why; otherwise the agent guesses.&lt;/p&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;Agent context windows can’t hold the full codebase, so layered documentation delivers just-in-time context: project overview, package-specific rules, task specs. Write it once; the agent stops asking “what’s the structure?” on every task.&lt;/p&gt;
&lt;h2 id=&quot;layered-agent-instructions&quot; class=&quot;text-xl font-semibold my-6 mb-3 mt-6 font-sans print:text-[7.5pt] print:leading-tight print:my-0 print:mb-0.5 print:mt-0&quot;&gt;Layered Agent Instructions&lt;/h2&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;A root-level &lt;code class=&quot;px-1 py-0.5 rounded font-mono print:text-[7.5pt] print:leading-tight&quot;&gt;AGENTS.md&lt;/code&gt; covers project overview, tech stack, filesystem structure, build system, and scripts. Each app and package has its own file with domain conventions: the API package documents router patterns, the database package documents schema, the frontend package documents components.&lt;/p&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;&lt;picture&gt;&lt;source srcset=&quot;/images/blog/how-to-make-an-agent-tell-it-screw-up/documentation-agents.png&quot; type=&quot;image/avif&quot;&gt;&lt;source srcset=&quot;/images/blog/how-to-make-an-agent-tell-it-screw-up/documentation-agents.png&quot; type=&quot;image/webp&quot;&gt;&lt;img src=&quot;https://justsomebody.dev/images/blog/how-to-make-an-agent-tell-it-screw-up/documentation-agents.png&quot; alt=&quot;Documentation about AGENTS.md&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;800&quot; height=&quot;600&quot; class=&quot;rounded-lg&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;Files concatenate from root downward (OpenAI’s discovery pattern &lt;sup&gt;&lt;a href=&quot;#user-content-fn-7&quot; id=&quot;user-content-fnref-7&quot; data-footnote-ref=&quot;true&quot; aria-describedby=&quot;footnote-label&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;text-(--color-accent) visited:text-(--color-accent) hover:text-(--color-accent-hover) transition inline print:text-[7.5pt] focus:underline focus:outline-none print:leading-tight&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;), deeper files override shallower ones. An agent gets project context plus localized rules without reading every file.&lt;/p&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;&lt;picture&gt;&lt;source srcset=&quot;/images/blog/how-to-make-an-agent-tell-it-screw-up/documentation-meta.png&quot; type=&quot;image/avif&quot;&gt;&lt;source srcset=&quot;/images/blog/how-to-make-an-agent-tell-it-screw-up/documentation-meta.png&quot; type=&quot;image/webp&quot;&gt;&lt;img src=&quot;https://justsomebody.dev/images/blog/how-to-make-an-agent-tell-it-screw-up/documentation-meta.png&quot; alt=&quot;Documentation about making documentation&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;800&quot; height=&quot;600&quot; class=&quot;rounded-lg&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;hr class=&quot;mb-4 print:mb-2&quot;&gt;
&lt;h3 id=&quot;layer-1-test-driven-development&quot; class=&quot;text-2xl font-semibold my-8 mb-4 mt-8 font-sans print:text-[7.5pt] print:leading-tight print:my-0 print:mb-0.5 print:mt-0&quot;&gt;Layer 1: Test-Driven Development&lt;/h3&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;Tests first, then code. An agent can’t fake coverage when CI enforces thresholds.&lt;/p&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;&lt;picture&gt;&lt;source srcset=&quot;/images/blog/how-to-make-an-agent-tell-it-screw-up/test-driven-development-vitest.png&quot; type=&quot;image/avif&quot;&gt;&lt;source srcset=&quot;/images/blog/how-to-make-an-agent-tell-it-screw-up/test-driven-development-vitest.png&quot; type=&quot;image/webp&quot;&gt;&lt;img src=&quot;https://justsomebody.dev/images/blog/how-to-make-an-agent-tell-it-screw-up/test-driven-development-vitest.png&quot; alt=&quot;Vitest test suite running&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;800&quot; height=&quot;600&quot; class=&quot;rounded-lg&quot;&gt;&lt;/picture&gt;
&lt;picture&gt;&lt;source srcset=&quot;/images/blog/how-to-make-an-agent-tell-it-screw-up/test-driven-development-code-coverage.png&quot; type=&quot;image/avif&quot;&gt;&lt;source srcset=&quot;/images/blog/how-to-make-an-agent-tell-it-screw-up/test-driven-development-code-coverage.png&quot; type=&quot;image/webp&quot;&gt;&lt;img src=&quot;https://justsomebody.dev/images/blog/how-to-make-an-agent-tell-it-screw-up/test-driven-development-code-coverage.png&quot; alt=&quot;Code coverage report&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;800&quot; height=&quot;600&quot; class=&quot;rounded-lg&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;Agents make tests pass, but they don’t know which tests to write. The configurations below remove that choice: passing tests mean working code, not well-mocked code.&lt;/p&gt;
&lt;h2 id=&quot;base-test-configuration&quot; class=&quot;text-xl font-semibold my-6 mb-3 mt-6 font-sans print:text-[7.5pt] print:leading-tight print:my-0 print:mb-0.5 print:mt-0&quot;&gt;Base Test Configuration&lt;/h2&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;A shared config centralizes test settings: global utilities, dependency optimization, and coverage thresholds. In CI, the floor is 80% across branches, functions, lines, and statements.&lt;/p&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;Tests live next to the code they test (&lt;code class=&quot;px-1 py-0.5 rounded font-mono print:text-[7.5pt] print:leading-tight&quot;&gt;__tests__/&lt;/code&gt; directories co-located with source), so the agent finds them without guessing where test files are stored.&lt;/p&gt;
&lt;h2 id=&quot;in-memory-database-tests&quot; class=&quot;text-xl font-semibold my-6 mb-3 mt-6 font-sans print:text-[7.5pt] print:leading-tight print:my-0 print:mb-0.5 print:mt-0&quot;&gt;In-Memory Database Tests&lt;/h2&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;Integration tests use PGLite&lt;sup&gt;&lt;a href=&quot;#user-content-fn-1&quot; id=&quot;user-content-fnref-1&quot; data-footnote-ref=&quot;true&quot; aria-describedby=&quot;footnote-label&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;text-(--color-accent) visited:text-(--color-accent) hover:text-(--color-accent-hover) transition inline print:text-[7.5pt] focus:underline focus:outline-none print:leading-tight&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;, an in-memory WebAssembly Postgres that runs in-process. No Docker, no network setup. A setup helper creates a fresh database, applies the production schema, and returns a Drizzle ORM client identical to production.&lt;/p&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;Benefits over traditional mocking:&lt;/p&gt;
&lt;ul class=&quot;list-disc list-outside mb-4 mt-4 pl-6 font-extralight print:text-[7.5pt] print:leading-tight print:mb-0.5 print:mt-0 print:pl-4&quot;&gt;
&lt;li class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;Same schema as production, so no drift between test and real queries&lt;/li&gt;
&lt;li class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;Real PostgreSQL constraints, triggers, transactions, and locking all work as expected&lt;/li&gt;
&lt;li class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;No mocked query builders, so the agent can’t write a query that passes tests but fails in prod&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;network-layer-api-tests&quot; class=&quot;text-xl font-semibold my-6 mb-3 mt-6 font-sans print:text-[7.5pt] print:leading-tight print:my-0 print:mb-0.5 print:mt-0&quot;&gt;Network-Layer API Tests&lt;/h2&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;For client-side code, tests use Mock Service Worker (MSW&lt;sup&gt;&lt;a href=&quot;#user-content-fn-2&quot; id=&quot;user-content-fnref-2&quot; data-footnote-ref=&quot;true&quot; aria-describedby=&quot;footnote-label&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;text-(--color-accent) visited:text-(--color-accent) hover:text-(--color-accent-hover) transition inline print:text-[7.5pt] focus:underline focus:outline-none print:leading-tight&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;) to intercept HTTP requests at the network layer. The test server uses production router definitions. The agent tests against real request/response cycles, not mocked function returns.&lt;/p&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;This catches mistakes module-level mocks miss:&lt;/p&gt;
&lt;ul class=&quot;list-disc list-outside mb-4 mt-4 pl-6 font-extralight print:text-[7.5pt] print:leading-tight print:mb-0.5 print:mt-0 print:pl-4&quot;&gt;
&lt;li class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;Request serialization errors (wrong content-type, malformed body)&lt;/li&gt;
&lt;li class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;Response parsing failures (wrong shape, missing fields)&lt;/li&gt;
&lt;li class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;Error handling paths (HTTP 400, 401, 403, 500)&lt;/li&gt;
&lt;li class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;Caching and retry behavior&lt;/li&gt;
&lt;/ul&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;The full client stack (transport, serialization, error handling, caching) runs unmodified. Only the network hop is replaced.&lt;/p&gt;
&lt;hr class=&quot;mb-4 print:mb-2&quot;&gt;
&lt;h3 id=&quot;layer-2-spec-driven-development-4&quot; class=&quot;text-2xl font-semibold my-8 mb-4 mt-8 font-sans print:text-[7.5pt] print:leading-tight print:my-0 print:mb-0.5 print:mt-0&quot;&gt;Layer 2: Spec-Driven Development &lt;sup&gt;&lt;a href=&quot;#user-content-fn-3&quot; id=&quot;user-content-fnref-3&quot; data-footnote-ref=&quot;true&quot; aria-describedby=&quot;footnote-label&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;text-(--color-accent) visited:text-(--color-accent) hover:text-(--color-accent-hover) transition inline print:text-[7.5pt] focus:underline focus:outline-none print:leading-tight&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/h3&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;The best time to catch a mistake is before the agent writes any code.&lt;/p&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;Give an agent a vague prompt and it guesses scope, usually wrong. A spec forces thinking before typing:&lt;/p&gt;
&lt;ul class=&quot;list-disc list-outside mb-4 mt-4 pl-6 font-extralight print:text-[7.5pt] print:leading-tight print:mb-0.5 print:mt-0 print:pl-4&quot;&gt;
&lt;li class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;&lt;strong&gt;Scope boundaries&lt;/strong&gt; prevent feature creep. The agent reads “out of scope: bulk operations” and doesn’t spend cycles building pagination when all that’s needed is a text input.&lt;/li&gt;
&lt;li class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;&lt;strong&gt;User scenarios&lt;/strong&gt; encode edge cases the agent doesn’t know to ask about. What happens when the search returns zero results? What’s the error message for a network timeout?&lt;/li&gt;
&lt;li class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;&lt;strong&gt;Acceptance criteria&lt;/strong&gt; are the test the agent can verify against. No “looks done.” The spec says exactly what done means.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;the-workflow&quot; class=&quot;text-xl font-semibold my-6 mb-3 mt-6 font-sans print:text-[7.5pt] print:leading-tight print:my-0 print:mb-0.5 print:mt-0&quot;&gt;The Workflow&lt;/h2&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;The screenshots below span different projects within a similar tech stack. The workflow uses &lt;a href=&quot;https://neolab.finance/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;text-(--color-accent) visited:text-(--color-accent) hover:text-(--color-accent-hover) transition inline print:text-[7.5pt] focus:underline focus:outline-none print:leading-tight&quot;&gt;NeoLab&lt;/a&gt;’s &lt;a href=&quot;https://neolab.gitbook.io/cek&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;text-(--color-accent) visited:text-(--color-accent) hover:text-(--color-accent-hover) transition inline print:text-[7.5pt] focus:underline focus:outline-none print:leading-tight&quot;&gt;Context Engineering Kit&lt;/a&gt;.&lt;/p&gt;
&lt;ol class=&quot;list-decimal list-outside mb-4 print:mb-0.5 font-extralight print:text-[7.5pt] print:leading-tight&quot;&gt;
&lt;li class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;Human writes → Initial prompt (captured verbatim in draft/)
&lt;picture&gt;&lt;source srcset=&quot;/images/blog/how-to-make-an-agent-tell-it-screw-up/spec-driven-development-brainstorm.png&quot; type=&quot;image/avif&quot;&gt;&lt;source srcset=&quot;/images/blog/how-to-make-an-agent-tell-it-screw-up/spec-driven-development-brainstorm.png&quot; type=&quot;image/webp&quot;&gt;&lt;img src=&quot;https://justsomebody.dev/images/blog/how-to-make-an-agent-tell-it-screw-up/spec-driven-development-brainstorm.png&quot; alt=&quot;Brainstorming of the feature&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;800&quot; height=&quot;600&quot; class=&quot;rounded-lg&quot;&gt;&lt;/picture&gt;&lt;/li&gt;
&lt;li class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;Agent expands → Structured spec with scope, scenarios, ACs
&lt;picture&gt;&lt;source srcset=&quot;/images/blog/how-to-make-an-agent-tell-it-screw-up/spec-driven-development-plan.png&quot; type=&quot;image/avif&quot;&gt;&lt;source srcset=&quot;/images/blog/how-to-make-an-agent-tell-it-screw-up/spec-driven-development-plan.png&quot; type=&quot;image/webp&quot;&gt;&lt;img src=&quot;https://justsomebody.dev/images/blog/how-to-make-an-agent-tell-it-screw-up/spec-driven-development-plan.png&quot; alt=&quot;Planning of the feature&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;800&quot; height=&quot;600&quot; class=&quot;rounded-lg&quot;&gt;&lt;/picture&gt;&lt;/li&gt;
&lt;li class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;Human reviews → Validates direction, adjusts scope
&lt;picture&gt;&lt;source srcset=&quot;/images/blog/how-to-make-an-agent-tell-it-screw-up/spec-driven-development-review.png&quot; type=&quot;image/avif&quot;&gt;&lt;source srcset=&quot;/images/blog/how-to-make-an-agent-tell-it-screw-up/spec-driven-development-review.png&quot; type=&quot;image/webp&quot;&gt;&lt;img src=&quot;https://justsomebody.dev/images/blog/how-to-make-an-agent-tell-it-screw-up/spec-driven-development-review.png&quot; alt=&quot;Review of the spec&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;800&quot; height=&quot;600&quot; class=&quot;rounded-lg&quot;&gt;&lt;/picture&gt;&lt;/li&gt;
&lt;li class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;Agent implements → Follows spec, verifies against ACs
&lt;picture&gt;&lt;source srcset=&quot;/images/blog/how-to-make-an-agent-tell-it-screw-up/spec-driven-development-implement.png&quot; type=&quot;image/avif&quot;&gt;&lt;source srcset=&quot;/images/blog/how-to-make-an-agent-tell-it-screw-up/spec-driven-development-implement.png&quot; type=&quot;image/webp&quot;&gt;&lt;img src=&quot;https://justsomebody.dev/images/blog/how-to-make-an-agent-tell-it-screw-up/spec-driven-development-implement.png&quot; alt=&quot;Implementing of the feature&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;800&quot; height=&quot;600&quot; class=&quot;rounded-lg&quot;&gt;&lt;/picture&gt;&lt;/li&gt;
&lt;li class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;Spec graduates → Moved to done/ as documentation&lt;/li&gt;
&lt;/ol&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;The spec is the contract. It stops the agent from building the wrong thing.&lt;/p&gt;
&lt;hr class=&quot;mb-4 print:mb-2&quot;&gt;
&lt;h3 id=&quot;layer-3-architectural-isolation&quot; class=&quot;text-2xl font-semibold my-8 mb-4 mt-8 font-sans print:text-[7.5pt] print:leading-tight print:my-0 print:mb-0.5 print:mt-0&quot;&gt;Layer 3: Architectural Isolation&lt;/h3&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;Some bug classes shouldn’t be possible. Architecture, not code review, enforces that.&lt;/p&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;When business logic tangles with infrastructure, agents inject database calls into validators, API calls into pure functions, and framework imports into domain models. Physical separation prevents this because you can’t import what isn’t there.&lt;/p&gt;
&lt;h2 id=&quot;monorepo-structure&quot; class=&quot;text-xl font-semibold my-6 mb-3 mt-6 font-sans print:text-[7.5pt] print:leading-tight print:my-0 print:mb-0.5 print:mt-0&quot;&gt;Monorepo Structure&lt;/h2&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;Everything in one repo. The agent gathers cross-domain context in a single workspace instead of hopping repos and losing state.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#24292e;color:#24292e;--shiki-dark:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;├── apps/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   ├── backend/               # API server&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   ├── admin/                 # Web admin&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   └── frontend/              # Frontend app&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;└── packages/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    ├── api/                   # API router definitions&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    ├── auth/                  # Authentication primitives&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    ├── common/                # Pure business logic &amp;#x26; utilities&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    └── db/                    # Database schema, migrations, client&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;module-boundaries&quot; class=&quot;text-xl font-semibold my-6 mb-3 mt-6 font-sans print:text-[7.5pt] print:leading-tight print:my-0 print:mb-0.5 print:mt-0&quot;&gt;Module Boundaries&lt;/h2&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;A monorepo without enforcement is just a folder convention. Explicit module boundaries prevent packages from importing each other’s internals:&lt;/p&gt;
&lt;ul class=&quot;list-disc list-outside mb-4 mt-4 pl-6 font-extralight print:text-[7.5pt] print:leading-tight print:mb-0.5 print:mt-0 print:pl-4&quot;&gt;
&lt;li class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;&lt;code class=&quot;px-1 py-0.5 rounded font-mono print:text-[7.5pt] print:leading-tight&quot;&gt;packages/common&lt;/code&gt; can’t import from &lt;code class=&quot;px-1 py-0.5 rounded font-mono print:text-[7.5pt] print:leading-tight&quot;&gt;packages/db&lt;/code&gt;. Pure logic stays database-agnostic.&lt;/li&gt;
&lt;li class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;&lt;code class=&quot;px-1 py-0.5 rounded font-mono print:text-[7.5pt] print:leading-tight&quot;&gt;apps/frontend&lt;/code&gt; can’t import from &lt;code class=&quot;px-1 py-0.5 rounded font-mono print:text-[7.5pt] print:leading-tight&quot;&gt;apps/backend&lt;/code&gt;. They share typed packages, not each other’s code.&lt;/li&gt;
&lt;li class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;Each package exports a controlled surface area via its &lt;code class=&quot;px-1 py-0.5 rounded font-mono print:text-[7.5pt] print:leading-tight&quot;&gt;index.ts&lt;/code&gt;; everything else is private.&lt;/li&gt;
&lt;/ul&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;Lint rules enforce this (ESLint &lt;code class=&quot;px-1 py-0.5 rounded font-mono print:text-[7.5pt] print:leading-tight&quot;&gt;import/no-restricted-paths&lt;/code&gt;, Nx module boundary tags). The agent can’t wire a frontend import to a server-only module, and the build fails.&lt;/p&gt;
&lt;h2 id=&quot;pure-logic-separation&quot; class=&quot;text-xl font-semibold my-6 mb-3 mt-6 font-sans print:text-[7.5pt] print:leading-tight print:my-0 print:mb-0.5 print:mt-0&quot;&gt;Pure Logic Separation&lt;/h2&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;Business logic lives in &lt;code class=&quot;px-1 py-0.5 rounded font-mono print:text-[7.5pt] print:leading-tight&quot;&gt;common&lt;/code&gt; with zero infrastructure dependencies. No database, HTTP, or framework imports:&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#24292e;color:#24292e;--shiki-dark:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;packages/common/src/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;├── challenges/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   ├── validators.ts          # Pure validation, no mocks needed&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   ├── dateUtils.ts           # Date math, no timezone mocking&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   └── votingTimes.ts         # Computation, no DB to seed&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;├── rewards/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   ├── validators.ts          # Reward rule validation&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   └── calculateProgress.ts   # Progress math&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;├── users/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   └── banUtils.ts            # Status parsing&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;├── coins/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   └── statistics.ts          # Statistics&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;└── __tests__/                 # Co-located unit tests, instant feedback&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;Each function takes inputs, returns outputs, has no side effects. Testing is trivial with no mocks or seeding. The agent can’t accidentally call a database inside a pure function because there’s no client to import.&lt;/p&gt;
&lt;hr class=&quot;mb-4 print:mb-2&quot;&gt;
&lt;h3 id=&quot;layer-4-automated-enforcement&quot; class=&quot;text-2xl font-semibold my-8 mb-4 mt-8 font-sans print:text-[7.5pt] print:leading-tight print:my-0 print:mb-0.5 print:mt-0&quot;&gt;Layer 4: Automated Enforcement&lt;/h3&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;Every mistake should surface within minutes, and the earlier it surfaces, the cheaper it is to fix.&lt;/p&gt;
&lt;h2 id=&quot;local-gate-git-hooks&quot; class=&quot;text-xl font-semibold my-6 mb-3 mt-6 font-sans print:text-[7.5pt] print:leading-tight print:my-0 print:mb-0.5 print:mt-0&quot;&gt;Local Gate: Git Hooks&lt;/h2&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;The first defense runs on the developer’s machine, before anything reaches the remote.&lt;/p&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;&lt;strong&gt;Pre-commit:&lt;/strong&gt; Formatter auto-fixes staged files, linter runs on changed files, type checker validates the full project. If formatting or types fail, the commit stops.&lt;/p&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;&lt;strong&gt;Commit message:&lt;/strong&gt; An interactive prompt guides through Conventional Commits&lt;sup&gt;&lt;a href=&quot;#user-content-fn-4&quot; id=&quot;user-content-fnref-4&quot; data-footnote-ref=&quot;true&quot; aria-describedby=&quot;footnote-label&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;text-(--color-accent) visited:text-(--color-accent) hover:text-(--color-accent-hover) transition inline print:text-[7.5pt] focus:underline focus:outline-none print:leading-tight&quot;&gt;5&lt;/a&gt;&lt;/sup&gt; format. This isn’t cosmetic; downstream automation parses this string. A validation hook checks conformity and appends a DCO&lt;sup&gt;&lt;a href=&quot;#user-content-fn-5&quot; id=&quot;user-content-fnref-5&quot; data-footnote-ref=&quot;true&quot; aria-describedby=&quot;footnote-label&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;text-(--color-accent) visited:text-(--color-accent) hover:text-(--color-accent-hover) transition inline print:text-[7.5pt] focus:underline focus:outline-none print:leading-tight&quot;&gt;6&lt;/a&gt;&lt;/sup&gt; sign-off automatically.&lt;/p&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;&lt;strong&gt;Pre-push:&lt;/strong&gt; Test runner triggers before push, but only if test files changed (skipping docs-only pushes saves minutes). All branch commits re-validate against Conventional Commits, catching violations from squashed commits. Dead code detection flags every unused export and orphaned file the AI left behind.&lt;/p&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;Hooks install automatically via &lt;code class=&quot;px-1 py-0.5 rounded font-mono print:text-[7.5pt] print:leading-tight&quot;&gt;prepare&lt;/code&gt; with no setup and no excuses.&lt;/p&gt;
&lt;h2 id=&quot;ci-pipeline&quot; class=&quot;text-xl font-semibold my-6 mb-3 mt-6 font-sans print:text-[7.5pt] print:leading-tight print:my-0 print:mb-0.5 print:mt-0&quot;&gt;CI Pipeline&lt;/h2&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;When code passes local gates, CI takes over. Each workflow covers a distinct risk:&lt;/p&gt;
&lt;ul class=&quot;list-disc list-outside mb-4 mt-4 pl-6 font-extralight print:text-[7.5pt] print:leading-tight print:mb-0.5 print:mt-0 print:pl-4&quot;&gt;
&lt;li class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;&lt;strong&gt;Lint &amp;amp; Format:&lt;/strong&gt; Runs the same formatter and linter as local hooks, plus module boundary enforcement.&lt;/li&gt;
&lt;li class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;&lt;strong&gt;Type Check:&lt;/strong&gt; Full TypeScript type checking. On PRs, reviewdog&lt;sup&gt;&lt;a href=&quot;#user-content-fn-6&quot; id=&quot;user-content-fnref-6&quot; data-footnote-ref=&quot;true&quot; aria-describedby=&quot;footnote-label&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;text-(--color-accent) visited:text-(--color-accent) hover:text-(--color-accent-hover) transition inline print:text-[7.5pt] focus:underline focus:outline-none print:leading-tight&quot;&gt;7&lt;/a&gt;&lt;/sup&gt; annotates errors on the diff. The agent sees the exact line, not a wall of logs.&lt;/li&gt;
&lt;li class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;&lt;strong&gt;Test Suite:&lt;/strong&gt; Tests shard across parallel runners. On main branch pushes or critical path changes, the full suite runs. Coverage artifacts upload per-shard for merged reporting.&lt;/li&gt;
&lt;li class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;&lt;strong&gt;Coverage Gate:&lt;/strong&gt; A diff-coverage comment on every PR shows lines touched vs. covered, failing if the threshold drops.&lt;/li&gt;
&lt;li class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;&lt;strong&gt;PR Title Lint:&lt;/strong&gt; PR titles must follow Conventional Commits, the same standard as commits. No agent opens a PR titled ‘fix stuff’.&lt;/li&gt;
&lt;/ul&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;Only when all checks pass can the PR merge. This gate is a hard firewall against sloppy code.&lt;/p&gt;
&lt;hr class=&quot;mb-4 print:mb-2&quot;&gt;
&lt;h3 id=&quot;layer-5-the-human--agent-loop&quot; class=&quot;text-2xl font-semibold my-8 mb-4 mt-8 font-sans print:text-[7.5pt] print:leading-tight print:my-0 print:mb-0.5 print:mt-0&quot;&gt;Layer 5: The Human + Agent Loop&lt;/h3&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;None of these layers work without a human. Guardrails don’t replace review; they make review productive by catching boring mistakes so humans focus on architecture.&lt;/p&gt;
&lt;h2 id=&quot;when-guardrails-fail&quot; class=&quot;text-xl font-semibold my-6 mb-3 mt-6 font-sans print:text-[7.5pt] print:leading-tight print:my-0 print:mb-0.5 print:mt-0&quot;&gt;When Guardrails Fail&lt;/h2&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;The layers catch mechanical mistakes: wrong types, missing tests, dead code, broken boundaries. They don’t catch:&lt;/p&gt;
&lt;ul class=&quot;list-disc list-outside mb-4 mt-4 pl-6 font-extralight print:text-[7.5pt] print:leading-tight print:mb-0.5 print:mt-0 print:pl-4&quot;&gt;
&lt;li class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;&lt;strong&gt;Wrong feature&lt;/strong&gt;: Spec fits the prompt but doesn’t solve the user’s actual problem&lt;/li&gt;
&lt;li class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;&lt;strong&gt;Right feature, wrong UX&lt;/strong&gt;: Everything works, nobody can use it&lt;/li&gt;
&lt;li class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;&lt;strong&gt;Technical debt acceleration&lt;/strong&gt;: Code passes all checks but makes the next change harder&lt;/li&gt;
&lt;/ul&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;These require human judgment. Zero mistakes is the wrong target, so aim for zero surprises. Every error should be visible and cheap to fix before production.&lt;/p&gt;
&lt;hr class=&quot;mb-4 print:mb-2&quot;&gt;
&lt;hr class=&quot;mb-4 print:mb-2&quot;&gt;
&lt;section data-footnotes=&quot;true&quot; class=&quot;footnotes&quot;&gt;&lt;h3 class=&quot;sr-only&quot; id=&quot;footnote-label&quot; class=&quot;text-2xl font-semibold my-8 mb-4 mt-8 font-sans print:text-[7.5pt] print:leading-tight print:my-0 print:mb-0.5 print:mt-0&quot;&gt;Footnotes&lt;/h3&gt;
&lt;ol class=&quot;list-decimal list-outside mb-4 print:mb-0.5 font-extralight print:text-[7.5pt] print:leading-tight&quot;&gt;
&lt;li id=&quot;user-content-fn-7&quot; class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;&lt;a href=&quot;https://developers.openai.com/codex/guides/agents-md#layer-project-instructions&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;text-(--color-accent) visited:text-(--color-accent) hover:text-(--color-accent-hover) transition inline print:text-[7.5pt] focus:underline focus:outline-none print:leading-tight&quot;&gt;OpenAI guidelines to AGENTS.md&lt;/a&gt; &lt;a href=&quot;#user-content-fnref-7&quot; data-footnote-backref aria-label=&quot;Back to reference 1&quot; class=&quot;data-footnote-backref&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;text-(--color-accent) visited:text-(--color-accent) hover:text-(--color-accent-hover) transition inline print:text-[7.5pt] focus:underline focus:outline-none print:leading-tight&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-1&quot; class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;&lt;a href=&quot;https://pglite.dev/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;text-(--color-accent) visited:text-(--color-accent) hover:text-(--color-accent-hover) transition inline print:text-[7.5pt] focus:underline focus:outline-none print:leading-tight&quot;&gt;PGLite&lt;/a&gt; - In-process WebAssembly PostgreSQL &lt;a href=&quot;#user-content-fnref-1&quot; data-footnote-backref aria-label=&quot;Back to reference 2&quot; class=&quot;data-footnote-backref&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;text-(--color-accent) visited:text-(--color-accent) hover:text-(--color-accent-hover) transition inline print:text-[7.5pt] focus:underline focus:outline-none print:leading-tight&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-2&quot; class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;&lt;a href=&quot;https://mswjs.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;text-(--color-accent) visited:text-(--color-accent) hover:text-(--color-accent-hover) transition inline print:text-[7.5pt] focus:underline focus:outline-none print:leading-tight&quot;&gt;Mock Service Worker&lt;/a&gt; - API mocking at the network layer &lt;a href=&quot;#user-content-fnref-2&quot; data-footnote-backref aria-label=&quot;Back to reference 3&quot; class=&quot;data-footnote-backref&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;text-(--color-accent) visited:text-(--color-accent) hover:text-(--color-accent-hover) transition inline print:text-[7.5pt] focus:underline focus:outline-none print:leading-tight&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-3&quot; class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;&lt;a href=&quot;https://specdriven.ai/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;text-(--color-accent) visited:text-(--color-accent) hover:text-(--color-accent-hover) transition inline print:text-[7.5pt] focus:underline focus:outline-none print:leading-tight&quot;&gt;Spec-Driven Development&lt;/a&gt; - methodology that prioritizes the creation of precise, machine-readable specifications over immediate coding &lt;a href=&quot;#user-content-fnref-3&quot; data-footnote-backref aria-label=&quot;Back to reference 4&quot; class=&quot;data-footnote-backref&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;text-(--color-accent) visited:text-(--color-accent) hover:text-(--color-accent-hover) transition inline print:text-[7.5pt] focus:underline focus:outline-none print:leading-tight&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-4&quot; class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;&lt;a href=&quot;https://www.conventionalcommits.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;text-(--color-accent) visited:text-(--color-accent) hover:text-(--color-accent-hover) transition inline print:text-[7.5pt] focus:underline focus:outline-none print:leading-tight&quot;&gt;Conventional Commits&lt;/a&gt; - Structured commit message specification &lt;a href=&quot;#user-content-fnref-4&quot; data-footnote-backref aria-label=&quot;Back to reference 5&quot; class=&quot;data-footnote-backref&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;text-(--color-accent) visited:text-(--color-accent) hover:text-(--color-accent-hover) transition inline print:text-[7.5pt] focus:underline focus:outline-none print:leading-tight&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-5&quot; class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;&lt;a href=&quot;https://developercertificate.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;text-(--color-accent) visited:text-(--color-accent) hover:text-(--color-accent-hover) transition inline print:text-[7.5pt] focus:underline focus:outline-none print:leading-tight&quot;&gt;DCO&lt;/a&gt; - Developer Certificate of Origin &lt;a href=&quot;#user-content-fnref-5&quot; data-footnote-backref aria-label=&quot;Back to reference 6&quot; class=&quot;data-footnote-backref&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;text-(--color-accent) visited:text-(--color-accent) hover:text-(--color-accent-hover) transition inline print:text-[7.5pt] focus:underline focus:outline-none print:leading-tight&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-6&quot; class=&quot;ml-4 print:ml-2 list-outside mb-2 print:text-[7.5pt] print:leading-tight print:mb-0.5&quot;&gt;
&lt;p class=&quot;mb-4 print:mb-0.5 print:text-[7.5pt] font-extralight print:leading-tight leading-[1.6]&quot;&gt;&lt;a href=&quot;https://github.com/reviewdog/reviewdog&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;text-(--color-accent) visited:text-(--color-accent) hover:text-(--color-accent-hover) transition inline print:text-[7.5pt] focus:underline focus:outline-none print:leading-tight&quot;&gt;reviewdog&lt;/a&gt; - Automated code review tool &lt;a href=&quot;#user-content-fnref-6&quot; data-footnote-backref aria-label=&quot;Back to reference 7&quot; class=&quot;data-footnote-backref&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;text-(--color-accent) visited:text-(--color-accent) hover:text-(--color-accent-hover) transition inline print:text-[7.5pt] focus:underline focus:outline-none print:leading-tight&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded><category>ai</category><category>agents</category><category>testing</category><category>code-quality</category><category>devops</category><category>monorepo</category><author>me@justsomebody.dev (Rafał Opiłowski)</author></item></channel></rss>