<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Lars Moelleken</title>
    <description>The latest articles on DEV Community by Lars Moelleken (@suckup_de).</description>
    <link>https://dev.to/suckup_de</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F30309%2F2945b2a8-f26d-4575-85eb-030996bcb91e.png</url>
      <title>DEV Community: Lars Moelleken</title>
      <link>https://dev.to/suckup_de</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/suckup_de"/>
    <language>en</language>
    <item>
      <title>Stop Prompting Like It's 2024</title>
      <dc:creator>Lars Moelleken</dc:creator>
      <pubDate>Sat, 08 Aug 2026 23:12:37 +0000</pubDate>
      <link>https://dev.to/suckup_de/stop-prompting-like-its-2024-19h4</link>
      <guid>https://dev.to/suckup_de/stop-prompting-like-its-2024-19h4</guid>
      <description>&lt;p&gt;Coding agents got much better.&lt;/p&gt;

&lt;p&gt;Our prompts often didn't or we use inefficient chat messages. &lt;/p&gt;

&lt;p&gt;In 2026, I don't try to find magical sentences that somehow make the model smarter.&lt;/p&gt;

&lt;p&gt;I try to make the task &lt;strong&gt;hard to misunderstand, hard to game, and easy to verify&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;After years of using LLMs on real codebases, these are the ten prompting patterns I keep coming back to.&lt;/p&gt;




&lt;h1&gt;
  
  
  1. Call It a "First Draft" and Attack It
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Instead of
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Is this implementation correct?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Try
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This is a first draft implementation.

Review it critically.

Assume there are mistakes.

Find concrete failures and prove them with tests.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How
&lt;/h2&gt;

&lt;p&gt;Change the task from &lt;strong&gt;confirmation&lt;/strong&gt; to &lt;strong&gt;falsification&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For important changes, I go one step further and review the implementation in a fresh context:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You are reviewing a first draft.

You get:

- the requirements
- relevant repository context
- the patch
- the tests

Assume the implementation may be wrong.

Find evidence.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not give the reviewer the previous agent's 40-message explanation of why every decision was supposedly brilliant.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why
&lt;/h2&gt;

&lt;p&gt;Framing changes the task.&lt;/p&gt;

&lt;p&gt;These are not equivalent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Is this correct?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Review this.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Assume this is wrong. Prove it.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first invites confirmation.&lt;/p&gt;

&lt;p&gt;The last explicitly asks for adversarial evidence.&lt;/p&gt;

&lt;p&gt;If the same agent wrote the code, its context also contains all the reasoning that justified the implementation. A fresh review removes part of that anchoring.&lt;/p&gt;

&lt;p&gt;Humans already struggle to review their own decisions objectively.&lt;/p&gt;

&lt;p&gt;Giving confirmation bias a GPU didn't magically solve it.&lt;/p&gt;




&lt;h1&gt;
  
  
  2. Use Sharp Language and Remove Hedge Words
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Instead of
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Could you maybe improve the tests where appropriate?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Try
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The current tests are insufficient.

Add tests until they can expose incorrect behavior.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or my less diplomatic version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Add tests until you find at least one real regression.

If your tests cannot distinguish broken behavior
from correct behavior, your tests are shit anyway.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How
&lt;/h2&gt;

&lt;p&gt;Use clear classifications:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INSUFFICIENT
INCORRECT
BROKEN
REJECTED
NOT DONE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And remove unnecessary hedge words:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;maybe
perhaps
try
consider
if possible
where appropriate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The profanity is not the important part.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;classification boundary&lt;/strong&gt; is.&lt;/p&gt;

&lt;p&gt;And there is a funny bit of 2026 evidence here.&lt;/p&gt;

&lt;p&gt;When Claude Code's source was accidentally exposed through a published source map in March 2026, people inspecting it found explicit frustration detection that classified phrases including profanity.&lt;/p&gt;

&lt;p&gt;So wording is not necessarily just some irrelevant wrapper around the "real" request.&lt;/p&gt;

&lt;p&gt;Modern agent harnesses can inspect language before we even get to what the model itself does with those tokens.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why
&lt;/h2&gt;

&lt;p&gt;Compare:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Maybe review this.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This is incorrect.

Discard this approach and find the failure.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They communicate different:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;expectations&lt;/li&gt;
&lt;li&gt;confidence levels&lt;/li&gt;
&lt;li&gt;quality thresholds&lt;/li&gt;
&lt;li&gt;acceptable continuations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Human communication contains lots of social cushioning because humans have feelings.&lt;/p&gt;

&lt;p&gt;The coding agent doesn't need emotional cushioning.&lt;/p&gt;

&lt;p&gt;It needs to know which side of the acceptance boundary its output currently occupies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ambiguity is an API bug.&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  3. Close the Cheap Escape Hatches
&lt;/h1&gt;

&lt;p&gt;This may be the most important pattern.&lt;/p&gt;

&lt;h3&gt;
  
  
  Instead of
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Improve test coverage.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Try
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Increase test coverage by at least 10 percentage points.

Do not add tests that merely execute code.

Use mutation testing to verify that the new tests
detect behavioral changes.

Investigate surviving mutants.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How
&lt;/h2&gt;

&lt;p&gt;Combine three things:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;measurable floor
+
anti-cheating constraint
+
independent verification
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same pattern works outside testing.&lt;/p&gt;

&lt;p&gt;Bad:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Improve performance.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Reduce median runtime by at least 20%.

Do not increase peak memory usage by more than 5%.

Run the benchmark at least five times.

Report the median before and after.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Reduce PHPStan errors in this module from 47 to 0.

Do not add ignores.

Do not add baseline entries.

Do not weaken types.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why
&lt;/h2&gt;

&lt;p&gt;Agents are extremely good at satisfying badly written requirements.&lt;/p&gt;

&lt;p&gt;Ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Improve coverage.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and technically this qualifies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;81.20% → 81.21%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mission accomplished.&lt;/p&gt;

&lt;p&gt;Human disappointed.&lt;/p&gt;

&lt;p&gt;Machine wondering why the human keeps moving the goalposts.&lt;/p&gt;

&lt;p&gt;Coverage alone has another cheap escape:&lt;/p&gt;

&lt;p&gt;A test can execute a line without meaningfully checking its behavior.&lt;/p&gt;

&lt;p&gt;That is why:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;coverage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;becomes more useful when combined with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mutation testing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Coverage asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Did this code execute?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Mutation testing asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Would your test notice if this code were wrong?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Much better.&lt;/p&gt;

&lt;p&gt;My general rule:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;If there is a stupid but technically valid way to satisfy your prompt, assume an agent will eventually find it.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Close the loophole before execution starts.&lt;/p&gt;




&lt;h1&gt;
  
  
  4. Make the Agent Prove the Bug Before Fixing It
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Instead of
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fix this bug.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Try
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Do not change production code yet.

First reproduce the suspected bug with a failing automated test.

Only after the failure is proven:

1. implement the smallest fix
2. rerun the regression test
3. run the complete validation suite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How
&lt;/h2&gt;

&lt;p&gt;Force this sequence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hypothesis
    ↓
Reproduction
    ↓
Evidence
    ↓
Implementation
    ↓
Verification
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Suspicious code
    ↓
Plausible theory
    ↓
Immediate rewrite
    ↓
Tests still green
    ↓
"Fixed!"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why
&lt;/h2&gt;

&lt;p&gt;Without reproduction, you may never know whether:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the reported bug actually existed&lt;/li&gt;
&lt;li&gt;the agent's explanation was correct&lt;/li&gt;
&lt;li&gt;the patch fixed that specific bug&lt;/li&gt;
&lt;li&gt;the new test protects against regression&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Coding agents can produce plausible fixes extremely quickly.&lt;/p&gt;

&lt;p&gt;That makes evidence &lt;strong&gt;more&lt;/strong&gt; important, not less.&lt;/p&gt;

&lt;p&gt;Implementation is becoming cheap.&lt;/p&gt;

&lt;p&gt;Knowing whether you are implementing the right thing isn't.&lt;/p&gt;




&lt;h1&gt;
  
  
  5. The Model Never Decides When It Is Done
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Instead of
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Make sure everything works.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Try
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DONE WHEN:

- the regression test fails before the fix
- the regression test passes afterward
- the complete test suite passes
- static analysis passes
- mutation score does not decrease
- the public API remains unchanged
- no unrelated files are modified
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And require evidence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Before finishing, report:

- commands executed
- test results
- static-analysis result
- mutation result
- remaining assumptions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How
&lt;/h2&gt;

&lt;p&gt;Move the stopping condition outside the model.&lt;/p&gt;

&lt;p&gt;The model saying:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Everything looks correct.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is not verification.&lt;/p&gt;

&lt;p&gt;The environment saying:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;428 tests passed
PHPStan: 0 errors
Infection MSI: 94%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is considerably more useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why
&lt;/h2&gt;

&lt;p&gt;The model should not simultaneously be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;author
+
reviewer
+
QA department
+
final authority
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is an absurd control system.&lt;/p&gt;

&lt;p&gt;For one of my PHP projects, the gates might be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Codeception
PHPStan
Infection
php-cs-fixer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For another project they may be completely different.&lt;/p&gt;

&lt;p&gt;The exact tools do not matter.&lt;/p&gt;

&lt;p&gt;The principle does:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The model proposes. Mechanical systems verify.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And &lt;code&gt;BLOCKED&lt;/code&gt; must be a valid result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;If a requirement cannot be satisfied under the current constraints:

STOP.

Provide:

- the blocking requirement
- evidence
- affected constraint
- smallest contract change that would unblock the task

Do not silently weaken the requirement.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sometimes the correct output from an agent is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I cannot prove this.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is far better than fabricated success.&lt;/p&gt;




&lt;h1&gt;
  
  
  6. Define Scope, Non-Goals, and Restart Rules
&lt;/h1&gt;

&lt;p&gt;Coding agents notice neighboring problems.&lt;/p&gt;

&lt;p&gt;Lots of them.&lt;/p&gt;

&lt;p&gt;That can turn:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fix validation bug.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;into:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I introduced ValidationFrameworkFactoryStrategyManager
and migrated 37 unrelated files.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A timeless software tradition, now automated.&lt;/p&gt;

&lt;h3&gt;
  
  
  Try
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GOAL

Fix the validation regression.

CONSTRAINTS

- keep the public API unchanged
- do not introduce dependencies
- do not modify unrelated modules

NON-GOALS

- no framework migration
- no API redesign
- no general validation cleanup
- no unrelated formatting changes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And if the agent violates the contract, don't politely negotiate with the patch.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This patch is incorrect.

Problems:

1. the public API changed
2. the regression is not reproduced
3. unrelated files were modified

Discard this implementation.

Restart with:

1. failing regression test first
2. minimal production change
3. public API unchanged
4. complete validation
5. report mechanical evidence
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How
&lt;/h2&gt;

&lt;p&gt;Define both:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;what to solve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;what deliberately not to solve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then make rejection explicit when the result crosses those boundaries.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why
&lt;/h2&gt;

&lt;p&gt;Scope is part of correctness.&lt;/p&gt;

&lt;p&gt;A technically elegant solution that solves three extra architectural problems may be a terrible patch.&lt;/p&gt;

&lt;p&gt;Explicit non-goals make YAGNI promptable.&lt;/p&gt;

&lt;p&gt;And an explicit restart is much clearer than spending six follow-up prompts trying to repair an approach that violated the basic contract from the beginning.&lt;/p&gt;

&lt;p&gt;Treat the output like a failed build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FAILED
WHY
EXPECTED
RETRY
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not like a colleague whose self-esteem depends on keeping 70% of the previous patch.&lt;/p&gt;




&lt;h1&gt;
  
  
  7. Give Agents Larger Planning Horizons, but Small Implementation Steps
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Instead of
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Plan the next step.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Try
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Plan the next three months.

Create falsifiable milestones.

For every milestone define:

- objective
- evidence
- dependencies
- risks
- explicit non-goals
- completion criteria
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Implement milestone 1 only.

Keep the diff small.

Do not begin milestone 2.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How
&lt;/h2&gt;

&lt;p&gt;Separate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;planning horizon
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;implementation size
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My preferred model is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Think in months.

Plan in milestones.

Implement in small diffs.

Verify continuously.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why
&lt;/h2&gt;

&lt;p&gt;Human project management evolved around human execution speed.&lt;/p&gt;

&lt;p&gt;A developer might work two days on "the next step."&lt;/p&gt;

&lt;p&gt;An agent may finish it before you've finished your coffee.&lt;/p&gt;

&lt;p&gt;If every tiny step requires another human prompt, the human becomes the scheduler.&lt;/p&gt;

&lt;p&gt;But giving the agent a large planning horizon does &lt;strong&gt;not&lt;/strong&gt; mean:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Autonomously rewrite this repository for three months.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It means the agent understands where today's small change is supposed to lead.&lt;/p&gt;

&lt;p&gt;Macro-plan.&lt;/p&gt;

&lt;p&gt;Micro-execute.&lt;/p&gt;




&lt;h1&gt;
  
  
  8. Treat Context as an Engineering Dependency
&lt;/h1&gt;

&lt;p&gt;A perfect prompt with wrong context produces a beautifully structured mistake.&lt;/p&gt;

&lt;h3&gt;
  
  
  Instead of only
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Refactor the parser.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;provide or derive:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PROJECT CONTEXT

- production runs PHP 8.3
- Parser.php contains canonical normalization behavior
- empty string and null have different domain semantics
- public APIs are consumed by external packages
- a previous refactor broke empty-string handling
- static analysis runs at maximum configured level
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But don't solve the problem by dumping the entire repository into the context window.&lt;/p&gt;

&lt;p&gt;Use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Identify the files, tests, documentation, decisions,
configuration and historical constraints relevant to this task.

Explain why each selected context source matters.

Ignore unrelated project history.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How
&lt;/h2&gt;

&lt;p&gt;Treat context selection as part of the task.&lt;/p&gt;

&lt;p&gt;The useful target is not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;maximum context
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;maximum relevant context
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why
&lt;/h2&gt;

&lt;p&gt;Real implementation decisions depend on project-specific facts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;supported runtime versions&lt;/li&gt;
&lt;li&gt;architecture&lt;/li&gt;
&lt;li&gt;deployment constraints&lt;/li&gt;
&lt;li&gt;existing tests&lt;/li&gt;
&lt;li&gt;backwards-compatibility promises&lt;/li&gt;
&lt;li&gt;dependency versions&lt;/li&gt;
&lt;li&gt;previous regressions&lt;/li&gt;
&lt;li&gt;CI behavior&lt;/li&gt;
&lt;li&gt;intentionally duplicated code&lt;/li&gt;
&lt;li&gt;failed previous approaches&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of that can reliably be reconstructed from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You are an expert senior developer.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Context is not decoration around the prompt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Context is a dependency of the task.&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  9. Use L2 Meta-Prompts as Prompt Compilers
&lt;/h1&gt;

&lt;p&gt;This is where I think prompting gets much more interesting.&lt;/p&gt;

&lt;p&gt;A normal prompt tells the agent what to do.&lt;/p&gt;

&lt;p&gt;An &lt;strong&gt;L2 meta-prompt creates the correct project-specific prompt first.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  L1
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fix the parser bug.

Add tests.

Run static analysis.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Still generic.&lt;/p&gt;

&lt;h3&gt;
  
  
  L2
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You are not implementing the task yet.

Your job is to create the project-specific operational prompt
that another coding agent should execute for this task:

TASK:
Fix the parser bug without changing existing public behavior.

Inspect the repository before creating the prompt.

Resolve project-specific facts from repository evidence.

At minimum determine:

- language and supported runtime versions
- package/dependency manager
- actual test framework(s)
- exact relevant test commands
- static-analysis tools and configured levels
- formatter/linter commands
- mutation-testing tools, if configured
- CI validation relevant to this change
- architecture and repository conventions
- public API / backwards-compatibility constraints
- relevant existing tests
- likely affected components
- AGENTS.md, CONTRIBUTING.md, ADRs or equivalent instructions
- historical regressions relevant to this task

Do not invent tools, commands or constraints.

Derive them from repository evidence such as:

- dependency manifests
- lock files
- CI configuration
- test configuration
- static-analysis configuration
- formatter configuration
- mutation-testing configuration
- existing scripts
- documentation
- existing tests

Then generate ONE ready-to-execute operational prompt.

Do NOT write generic instructions such as:

"run the tests"
"use the project's test framework"
"run static analysis"

when the repository allows the actual command to be resolved.

Write concrete instructions such as:

"Run `vendor/bin/codecept run unit`"

or:

"Run `composer phpstan`"

only when those exact commands are supported by repository evidence.

Structure the generated prompt as:

GOAL
PROJECT CONTEXT
RELEVANT COMPONENTS
CONSTRAINTS
NON-GOALS
IMPLEMENTATION APPROACH
VERIFICATION
DONE WHEN

If a required fact cannot be determined,
mark it UNKNOWN instead of guessing.

Do not implement the task.

Output only the final project-specific operational prompt.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How
&lt;/h2&gt;

&lt;p&gt;The L2 prompt acts like a compiler:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Task
+
Repository
        ↓
Discover project facts
        ↓
PHP version
test framework
exact commands
CI gates
static analysis
architecture
BC constraints
existing tests
        ↓
Compile
        ↓
Project-specific L1 operational prompt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the final generated prompt might contain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Tests use Codeception.

Add the regression to:
tests/unit/ParserTest.php

Run:
vendor/bin/codecept run unit

Static analysis:
vendor/bin/phpstan analyse -c phpstan.neon

Mutation testing:
vendor/bin/infection
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Run the project's tests and static analysis.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why
&lt;/h2&gt;

&lt;p&gt;The correct operational prompt for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a small open-source PHP library
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is not the same as the correct prompt for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a twenty-year-old internal IAM system
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;even when both happen to use PHP.&lt;/p&gt;

&lt;p&gt;The human should provide the &lt;strong&gt;intent&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The repository already contains much of the &lt;strong&gt;operational context&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The L2 prompt combines them.&lt;/p&gt;

&lt;p&gt;That scales much better than manually maintaining one universal monster prompt containing every rule accumulated since humans discovered Markdown.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Context is project-specific. Good operational prompts should be project-specific too.&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  10. Let Successful Sessions Teach Future Sessions
&lt;/h1&gt;

&lt;p&gt;Agent sessions are temporary.&lt;/p&gt;

&lt;p&gt;Project knowledge shouldn't be.&lt;/p&gt;

&lt;h3&gt;
  
  
  After a useful discovery
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;That worked.

Update AGENTS.md with the reusable constraint
that prevented the original failure.

Do not record task-specific implementation history.

Record only knowledge that should change how future agents
operate in this repository.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bad memory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;On Tuesday we changed Parser.php because test 17 failed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Useful memory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Empty strings and null represent different domain states.

Normalization code must preserve that distinction.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How
&lt;/h2&gt;

&lt;p&gt;Promote only durable findings from temporary working context into persistent project instructions.&lt;/p&gt;

&lt;p&gt;The loop becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Prompt
    ↓
Execute
    ↓
Verify
    ↓
Discover
    ↓
Learn
    ↓
Update project context
    ↓
Better next prompt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why
&lt;/h2&gt;

&lt;p&gt;Without learning, tomorrow's agent can repeat yesterday's mistake.&lt;/p&gt;

&lt;p&gt;But storing everything is just as bad.&lt;/p&gt;

&lt;p&gt;Eventually &lt;code&gt;AGENTS.md&lt;/code&gt; becomes a landfill of obsolete task history that poisons future context.&lt;/p&gt;

&lt;p&gt;So memory has to earn its place.&lt;/p&gt;

&lt;p&gt;Ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Would knowing this change how a competent agent should approach a future task?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If yes, preserve it.&lt;/p&gt;

&lt;p&gt;If not, let it disappear.&lt;/p&gt;

&lt;p&gt;Forgetting is part of good context management too.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Pattern Behind All Ten
&lt;/h1&gt;

&lt;p&gt;These techniques look different, but they keep collapsing into the same operational contract:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Operational Prompt
    =
    Goal
    + Context
    + Constraints
    + Verification
    + Done When
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Goal
&lt;/h2&gt;

&lt;p&gt;What observable result must exist?&lt;/p&gt;

&lt;h2&gt;
  
  
  Context
&lt;/h2&gt;

&lt;p&gt;Which project-specific facts affect the solution?&lt;/p&gt;

&lt;h2&gt;
  
  
  Constraints
&lt;/h2&gt;

&lt;p&gt;Which shortcuts and changes are forbidden?&lt;/p&gt;

&lt;h2&gt;
  
  
  Verification
&lt;/h2&gt;

&lt;p&gt;Which external tools determine whether the result is correct?&lt;/p&gt;

&lt;h2&gt;
  
  
  Done When
&lt;/h2&gt;

&lt;p&gt;What exact evidence allows execution to stop?&lt;/p&gt;

&lt;p&gt;That is how I increasingly prompt coding agents in 2026.&lt;/p&gt;

&lt;p&gt;Not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You are a world-class software engineer.

Think step by step.

Please provide your best possible solution.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Here is the goal.

Here is the relevant context.

Here are the boundaries.

Here is how reality will be measured.

Here is exactly when you are done.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, for important work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This is a first draft.

Assume it is wrong.

Break it.

Prove the failure.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And as projects get larger, I increasingly don't even want to manually write that operational prompt.&lt;/p&gt;

&lt;p&gt;I want an L2 meta-prompt to inspect the project and compile it for me.&lt;/p&gt;

&lt;p&gt;Because the future of prompting is not finding increasingly clever magic words.&lt;/p&gt;

&lt;p&gt;It is &lt;strong&gt;requirements engineering for machines that execute ridiculously fast&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Sharp language matters.&lt;/p&gt;

&lt;p&gt;Context matters more.&lt;/p&gt;

&lt;p&gt;Evidence beats confidence.&lt;/p&gt;

&lt;p&gt;And the machine does not get to decide that the machine is correct.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>You Bought the Machine. Now Build the Software Factory.</title>
      <dc:creator>Lars Moelleken</dc:creator>
      <pubDate>Sun, 02 Aug 2026 12:03:19 +0000</pubDate>
      <link>https://dev.to/suckup_de/you-bought-the-machine-now-build-the-software-factory-1nhp</link>
      <guid>https://dev.to/suckup_de/you-bought-the-machine-now-build-the-software-factory-1nhp</guid>
      <description>&lt;p&gt;// follow-up post from ...&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/suckup_de/ai-makes-bad-developers-faster-too-2o10" class="crayons-story__hidden-navigation-link"&gt;AI Makes Bad Developers Faster Too&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/suckup_de" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F30309%2F2945b2a8-f26d-4575-85eb-030996bcb91e.png" alt="suckup_de profile" class="crayons-avatar__image" width="800" height="800"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/suckup_de" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Lars Moelleken
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Lars Moelleken
                
              
              &lt;div id="story-author-preview-content-4292665" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/suckup_de" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F30309%2F2945b2a8-f26d-4575-85eb-030996bcb91e.png" class="crayons-avatar__image" alt="" width="800" height="800"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Lars Moelleken&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/suckup_de/ai-makes-bad-developers-faster-too-2o10" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Aug 2&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/suckup_de/ai-makes-bad-developers-faster-too-2o10" id="article-link-4292665"&gt;
          AI Makes Bad Developers Faster Too
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/programming"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;programming&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/productivity"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;productivity&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/softwaredevelopment"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;softwaredevelopment&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
            &lt;a href="https://dev.to/suckup_de/ai-makes-bad-developers-faster-too-2o10#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            5 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;





&lt;p&gt;A factory owner buys a machine that works 30x faster than his employees.&lt;/p&gt;

&lt;p&gt;He drops it into the middle of the workshop and switches it on.&lt;/p&gt;

&lt;p&gt;Within an hour, it produces hundreds of parts.&lt;/p&gt;

&lt;p&gt;Some are correct.&lt;/p&gt;

&lt;p&gt;Some are nearly correct.&lt;/p&gt;

&lt;p&gt;Some only look correct until somebody puts weight on them.&lt;/p&gt;

&lt;p&gt;Nobody can reliably tell the difference.&lt;/p&gt;

&lt;p&gt;The drawings are outdated. The measuring equipment is broken. Important specifications exist only inside the head of one senior employee. Quality control is one exhausted person saying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Looks fine to me.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Production has increased.&lt;/p&gt;

&lt;p&gt;Useful production has not.&lt;/p&gt;

&lt;p&gt;That is software development with coding agents.&lt;/p&gt;

&lt;p&gt;We bought the machine.&lt;/p&gt;

&lt;p&gt;Now we need to build the factory.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Machine Is Not the Factory
&lt;/h2&gt;

&lt;p&gt;Coding agents can already:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;inspect repositories&lt;/li&gt;
&lt;li&gt;implement features&lt;/li&gt;
&lt;li&gt;write tests&lt;/li&gt;
&lt;li&gt;execute commands&lt;/li&gt;
&lt;li&gt;analyze failures&lt;/li&gt;
&lt;li&gt;refactor code&lt;/li&gt;
&lt;li&gt;review diffs&lt;/li&gt;
&lt;li&gt;open pull requests&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is real production power.&lt;/p&gt;

&lt;p&gt;It is not engineering maturity.&lt;/p&gt;

&lt;p&gt;A factory also needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;specifications&lt;/li&gt;
&lt;li&gt;tolerances&lt;/li&gt;
&lt;li&gt;controlled environments&lt;/li&gt;
&lt;li&gt;measuring equipment&lt;/li&gt;
&lt;li&gt;inspections&lt;/li&gt;
&lt;li&gt;stop conditions&lt;/li&gt;
&lt;li&gt;traceability&lt;/li&gt;
&lt;li&gt;accountability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without those things, an agent is just a very fast developer with incomplete context and no responsibility for the production incident.&lt;/p&gt;

&lt;p&gt;We already had developers like that.&lt;/p&gt;

&lt;p&gt;Now they scale horizontally.&lt;/p&gt;




&lt;h2&gt;
  
  
  Stop Writing Wishes. Write Work Orders.
&lt;/h2&gt;

&lt;p&gt;This is not a useful agent task:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Improve customer validation.

Add tests where appropriate.

Do not break anything.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;“Do not break anything” is not a requirement.&lt;/p&gt;

&lt;p&gt;It is a prayer.&lt;/p&gt;

&lt;p&gt;A useful task defines the part:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Reject an empty customer identifier before database access.

Required behavior:
- Reject an empty string.
- Reject whitespace-only input.
- Throw InvalidArgumentException.
- Include "customerId" in the exception message.

Constraints:
- Preserve public interfaces.
- Do not add dependencies.
- Do not modify unrelated files.
- Do not suppress static-analysis errors.

Verification:
- Add a regression test that fails before the fix.
- Run PHPUnit.
- Run PHPStan.
- Run PHP-CS-Fixer in dry-run mode.
- Report commands, exit codes, and results.

No change is a valid result if the defect cannot be reproduced.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is not clever prompting.&lt;/p&gt;

&lt;p&gt;It is a work order.&lt;/p&gt;

&lt;p&gt;The agent does not need encouragement.&lt;/p&gt;

&lt;p&gt;It needs dimensions.&lt;/p&gt;




&lt;h2&gt;
  
  
  Get the Blueprints Out of People’s Heads
&lt;/h2&gt;

&lt;p&gt;Critical software knowledge still lives in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;old tickets&lt;/li&gt;
&lt;li&gt;Slack messages&lt;/li&gt;
&lt;li&gt;abandoned wiki pages&lt;/li&gt;
&lt;li&gt;pull-request comments&lt;/li&gt;
&lt;li&gt;production incidents nobody documented&lt;/li&gt;
&lt;li&gt;comments saying &lt;code&gt;DO NOT TOUCH&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;“ask Thomas”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A senior developer may understand the invisible rules around a codebase.&lt;/p&gt;

&lt;p&gt;The agent sees files.&lt;/p&gt;

&lt;p&gt;It does not see tribal knowledge.&lt;/p&gt;

&lt;p&gt;Store durable knowledge (ADRs, Skills, Docs, ...) in predictable places:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AGENTS.md
README.md
docs/architecture.md
docs/domain-rules.md
docs/decisions/
docs/runbooks/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But documentation is not enough.&lt;/p&gt;

&lt;p&gt;Make important rules executable.&lt;/p&gt;

&lt;p&gt;Do not merely write:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Controllers must not execute SQL.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Add an architecture test.&lt;/p&gt;

&lt;p&gt;Do not merely write:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Money uses integer cents.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Encode it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="k"&gt;declare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strict_types&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Money&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/**
     * @param int&amp;lt;0, max&amp;gt; $cents
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$cents&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$cents&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;InvalidArgumentException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="s1"&gt;'Money cannot contain negative cents.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The best documentation is a system that rejects invalid construction.&lt;/p&gt;




&lt;h2&gt;
  
  
  Define Tolerances
&lt;/h2&gt;

&lt;p&gt;Factories do not ask machines to produce “high-quality parts.”&lt;/p&gt;

&lt;p&gt;They define tolerances.&lt;/p&gt;

&lt;p&gt;Software needs the same thing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Public APIs must not change.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Domain code must not depend on HTTP infrastructure.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Only repository classes may execute SQL.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;No new production dependencies.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PHPStan errors must not be suppressed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Every skipped verification command must be reported.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A vague instruction forces the model to invent its own definition of quality.&lt;/p&gt;

&lt;p&gt;Then everybody acts surprised when it chooses convenience.&lt;/p&gt;

&lt;p&gt;Do not ask whether the model was smart.&lt;/p&gt;

&lt;p&gt;Ask whether the result stayed inside the tolerances.&lt;/p&gt;




&lt;h2&gt;
  
  
  Do Not Let the Machine Inspect Itself
&lt;/h2&gt;

&lt;p&gt;An agent saying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;All tests pass.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;is not evidence.&lt;/p&gt;

&lt;p&gt;It is text generated by the same system that generated the code.&lt;/p&gt;

&lt;p&gt;Require:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;exact command&lt;/li&gt;
&lt;li&gt;exact exit code&lt;/li&gt;
&lt;li&gt;relevant output&lt;/li&gt;
&lt;li&gt;tested scope&lt;/li&gt;
&lt;li&gt;skipped checks&lt;/li&gt;
&lt;li&gt;reason for every skipped check&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a PHP project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer &lt;span class="nb"&gt;test
&lt;/span&gt;vendor/bin/phpstan analyse &lt;span class="nt"&gt;--no-progress&lt;/span&gt;
vendor/bin/php-cs-fixer fix &lt;span class="nt"&gt;--dry-run&lt;/span&gt; &lt;span class="nt"&gt;--diff&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where configured:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vendor/bin/infection &lt;span class="nt"&gt;--min-msi&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result must be explicit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PASSED
FAILED
SKIPPED
NOT AVAILABLE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Looks good.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Should work.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I could not run the tests, but the change is straightforward.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A factory with broken gauges can produce consistently broken products.&lt;/p&gt;

&lt;p&gt;Consistency is not correctness.&lt;/p&gt;




&lt;h2&gt;
  
  
  Add a Stop Button
&lt;/h2&gt;

&lt;p&gt;Agents assume that every task must produce a patch.&lt;/p&gt;

&lt;p&gt;That creates ceremonial changes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pointless refactors&lt;/li&gt;
&lt;li&gt;speculative abstractions&lt;/li&gt;
&lt;li&gt;unnecessary validation&lt;/li&gt;
&lt;li&gt;comments explaining syntax&lt;/li&gt;
&lt;li&gt;tests that simply repeat the implementation&lt;/li&gt;
&lt;li&gt;unrelated cleanup nobody requested&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sometimes the correct result is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;No change required.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The bug may already be fixed.&lt;/p&gt;

&lt;p&gt;The report may be wrong.&lt;/p&gt;

&lt;p&gt;Another service may own the failure.&lt;/p&gt;

&lt;p&gt;The required external system may be unavailable.&lt;/p&gt;

&lt;p&gt;The requested change may make the architecture worse.&lt;/p&gt;

&lt;p&gt;Require reproduction first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Reproduce the reported behavior before modifying production code.

If it cannot be reproduced:
1. Report the scenarios tested.
2. Report the commands executed.
3. Report the observed behavior.
4. Identify unavailable dependencies.
5. Do not create a diff merely to appear productive.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Evidence is progress.&lt;/p&gt;

&lt;p&gt;A diff is not.&lt;/p&gt;




&lt;h2&gt;
  
  
  Review Risk, Not Every Screw
&lt;/h2&gt;

&lt;p&gt;Reading every generated line with equal intensity is not a quality strategy.&lt;/p&gt;

&lt;p&gt;It is an attention-distribution bug.&lt;/p&gt;

&lt;p&gt;Spend human attention on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;authentication&lt;/li&gt;
&lt;li&gt;authorization&lt;/li&gt;
&lt;li&gt;money&lt;/li&gt;
&lt;li&gt;migrations&lt;/li&gt;
&lt;li&gt;transactions&lt;/li&gt;
&lt;li&gt;concurrency&lt;/li&gt;
&lt;li&gt;input boundaries&lt;/li&gt;
&lt;li&gt;external integrations&lt;/li&gt;
&lt;li&gt;deleted tests&lt;/li&gt;
&lt;li&gt;weakened assertions&lt;/li&gt;
&lt;li&gt;dependency changes&lt;/li&gt;
&lt;li&gt;rollback behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Spend less attention on deterministic work protected by automation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;formatting&lt;/li&gt;
&lt;li&gt;generated DTOs&lt;/li&gt;
&lt;li&gt;repetitive mappings&lt;/li&gt;
&lt;li&gt;mechanical renames&lt;/li&gt;
&lt;li&gt;schema-generated clients&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A decorative screw and a structural bolt do not deserve the same inspection.&lt;/p&gt;

&lt;p&gt;That is not laziness.&lt;/p&gt;

&lt;p&gt;That is engineering.&lt;/p&gt;

&lt;p&gt;But there is no free shortcut:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Reading less code requires testing more behavior.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Reading less and testing less is not industrialization.&lt;/p&gt;

&lt;p&gt;It is negligence with better branding.&lt;/p&gt;




&lt;h2&gt;
  
  
  Stop Measuring Tokens
&lt;/h2&gt;

&lt;p&gt;Lines generated do not matter.&lt;/p&gt;

&lt;p&gt;Tokens consumed do not matter.&lt;/p&gt;

&lt;p&gt;The percentage of AI-written code does not matter.&lt;/p&gt;

&lt;p&gt;Measure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;successful repository tasks&lt;/li&gt;
&lt;li&gt;human corrections&lt;/li&gt;
&lt;li&gt;reverted changes&lt;/li&gt;
&lt;li&gt;ignored constraints&lt;/li&gt;
&lt;li&gt;regression rate&lt;/li&gt;
&lt;li&gt;review time&lt;/li&gt;
&lt;li&gt;verification cost&lt;/li&gt;
&lt;li&gt;production incidents&lt;/li&gt;
&lt;li&gt;reproducibility&lt;/li&gt;
&lt;li&gt;recovery time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One thousand generated lines may be useful.&lt;/p&gt;

&lt;p&gt;They may also be industrially produced waste.&lt;/p&gt;

&lt;p&gt;Your repository is the benchmark that matters.&lt;/p&gt;

&lt;p&gt;Not the vendor’s multiplier.&lt;/p&gt;




&lt;h2&gt;
  
  
  Someone Still Owns the Result
&lt;/h2&gt;

&lt;p&gt;When generated code breaks production, responsibility cannot be assigned to the model.&lt;/p&gt;

&lt;p&gt;The model does not:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;own the repository&lt;/li&gt;
&lt;li&gt;answer customers&lt;/li&gt;
&lt;li&gt;restore corrupted data&lt;/li&gt;
&lt;li&gt;carry legal liability&lt;/li&gt;
&lt;li&gt;receive the incident call at three in the morning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A real workflow defines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;who approved the task&lt;/li&gt;
&lt;li&gt;who defined acceptance criteria&lt;/li&gt;
&lt;li&gt;which checks were mandatory&lt;/li&gt;
&lt;li&gt;which checks ran&lt;/li&gt;
&lt;li&gt;who accepted skipped verification&lt;/li&gt;
&lt;li&gt;who reviewed high-risk changes&lt;/li&gt;
&lt;li&gt;who approved deployment&lt;/li&gt;
&lt;li&gt;how rollback works&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not new AI bureaucracy.&lt;/p&gt;

&lt;p&gt;This is engineering accountability that should already have existed.&lt;/p&gt;

&lt;p&gt;The machine simply exposes its absence.&lt;/p&gt;




&lt;h2&gt;
  
  
  Start With One Production Line
&lt;/h2&gt;

&lt;p&gt;Do not build a giant internal AI platform first.&lt;/p&gt;

&lt;p&gt;That is how companies spend a year automating work they never understood.&lt;/p&gt;

&lt;p&gt;Choose one repeatable task:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dependency updates&lt;/li&gt;
&lt;li&gt;regression tests&lt;/li&gt;
&lt;li&gt;DTO generation&lt;/li&gt;
&lt;li&gt;static-analysis fixes&lt;/li&gt;
&lt;li&gt;mechanical migrations&lt;/li&gt;
&lt;li&gt;deterministic renames&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then define:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;the input&lt;/li&gt;
&lt;li&gt;the required change&lt;/li&gt;
&lt;li&gt;the constraints&lt;/li&gt;
&lt;li&gt;the environment&lt;/li&gt;
&lt;li&gt;the verification&lt;/li&gt;
&lt;li&gt;the risk level&lt;/li&gt;
&lt;li&gt;the evidence&lt;/li&gt;
&lt;li&gt;the stop conditions&lt;/li&gt;
&lt;li&gt;the approval&lt;/li&gt;
&lt;li&gt;the learning after failure&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That is already a software factory.&lt;/p&gt;

&lt;p&gt;Small, but real.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Developer Becomes the Factory Builder
&lt;/h2&gt;

&lt;p&gt;The developer is not disappearing.&lt;/p&gt;

&lt;p&gt;The work is moving.&lt;/p&gt;

&lt;p&gt;Less value comes from manually typing predictable code.&lt;/p&gt;

&lt;p&gt;More value comes from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;defining correctness&lt;/li&gt;
&lt;li&gt;encoding constraints&lt;/li&gt;
&lt;li&gt;designing architecture&lt;/li&gt;
&lt;li&gt;building verification&lt;/li&gt;
&lt;li&gt;identifying risk&lt;/li&gt;
&lt;li&gt;measuring outcomes&lt;/li&gt;
&lt;li&gt;investigating failures&lt;/li&gt;
&lt;li&gt;deciding when the machine is wrong&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A master carpenter should not spend every day producing identical shelf pins.&lt;/p&gt;

&lt;p&gt;But somebody still needs to understand material, structure, load, and failure.&lt;/p&gt;

&lt;p&gt;Otherwise the factory produces furniture efficiently until somebody sits on it.&lt;/p&gt;

&lt;p&gt;The same applies to software.&lt;/p&gt;

&lt;p&gt;The agent is not the factory.&lt;/p&gt;

&lt;p&gt;The model is not the production system.&lt;/p&gt;

&lt;p&gt;Generated code is not automatically the product.&lt;/p&gt;

&lt;p&gt;The factory is the system of constraints, evidence, inspection, and responsibility around the machine.&lt;/p&gt;

&lt;p&gt;You bought the machine.&lt;/p&gt;

&lt;p&gt;Stop admiring how fast it moves.&lt;/p&gt;

&lt;p&gt;Build something that can reject its garbage.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>AI Makes Bad Developers Faster Too</title>
      <dc:creator>Lars Moelleken</dc:creator>
      <pubDate>Sun, 02 Aug 2026 11:27:04 +0000</pubDate>
      <link>https://dev.to/suckup_de/ai-makes-bad-developers-faster-too-2o10</link>
      <guid>https://dev.to/suckup_de/ai-makes-bad-developers-faster-too-2o10</guid>
      <description>&lt;h2&gt;
  
  
  The Circular Saw, the Apprentice, and the Software Factory
&lt;/h2&gt;

&lt;p&gt;A circular saw does not turn a bad carpenter into a good one. It merely allows him to destroy wood faster.&lt;/p&gt;

&lt;p&gt;A skilled carpenter still uses the circular saw. Refusing modern tools would not make him more professional, only slower. The difference is that he understands the material. He knows how wood behaves, where tension builds, how grain direction affects a cut, and when a clean-looking result is structurally wrong.&lt;/p&gt;

&lt;p&gt;The machine provides speed and force. The carpenter provides judgment.&lt;/p&gt;

&lt;p&gt;The same is true for LLMs in software development.&lt;/p&gt;

&lt;p&gt;An experienced developer can use an LLM to explore a codebase, generate implementations, write tests, investigate failures, and compare possible designs much faster than before. But the tool does not provide the developer’s understanding of the system. It does not automatically know which assumptions are valid, which abstractions belong together, or which apparently elegant solution will create maintenance problems six months later.&lt;/p&gt;

&lt;p&gt;An LLM amplifies the process around it.&lt;/p&gt;

&lt;p&gt;In a disciplined engineering process, it accelerates useful work. In a weak process, it accelerates confusion, duplication, security problems, and confidently formatted nonsense.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the Apprentice Still Needs the Hand Saw
&lt;/h2&gt;

&lt;p&gt;This does not mean beginners should avoid LLMs completely. It means they must not outsource the part of learning that creates judgment.&lt;/p&gt;

&lt;p&gt;A carpenter’s apprentice may work with a hand saw, a plane, and a chisel before relying entirely on powered machinery. Not because manual tools are morally superior or because suffering builds character, although humanity remains strangely attached to that idea. The apprentice uses them because direct contact with the material teaches lessons that the machine can hide.&lt;/p&gt;

&lt;p&gt;The same principle applies to programming.&lt;/p&gt;

&lt;p&gt;A developer must learn to follow control flow, model data, understand HTTP, inspect SQL, debug failures, reason about state, and recognize the consequences of architectural decisions. Those skills create the mental models required to evaluate generated code.&lt;/p&gt;

&lt;p&gt;Without them, the developer may be able to produce software but cannot reliably judge it.&lt;/p&gt;

&lt;p&gt;The output may compile. The tests may pass. The code may even look clean. Yet the developer does not know whether the implementation fits the surrounding system, whether important cases are missing, or whether the design is carrying assumptions that were never verified.&lt;/p&gt;

&lt;p&gt;The problem is therefore not that the apprentice used a machine. The problem is that the machine allowed the apprentice to skip learning what a correct cut actually is.&lt;/p&gt;

&lt;h2&gt;
  
  
  From Better Tools to Better Production
&lt;/h2&gt;

&lt;p&gt;Once the craft is understood, the next question is larger than individual skill.&lt;/p&gt;

&lt;p&gt;A good carpenter with a circular saw can build faster, but industrial production does not emerge merely because every carpenter receives a more powerful tool.&lt;/p&gt;

&lt;p&gt;Industrial production requires standards, repeatable processes, defined components, quality controls, inspections, and clear responsibility for the final product.&lt;/p&gt;

&lt;p&gt;This is where the IKEA analogy becomes useful.&lt;/p&gt;

&lt;p&gt;IKEA does not scale because every employee is the world’s greatest cabinetmaker. It scales because products are designed around standardized materials, documented parts, repeatable manufacturing, controlled tolerances, predictable logistics, and assembly processes that work across millions of units.&lt;/p&gt;

&lt;p&gt;The quality does not depend solely on one person’s memory or intuition. Knowledge has been moved into the production system.&lt;/p&gt;

&lt;p&gt;Software development has not fully reached that point.&lt;/p&gt;

&lt;p&gt;We have reusable packages, automated tests, static analysis, CI pipelines, containers, coding standards, observability, and increasingly capable coding agents. But many software systems still depend on undocumented assumptions, local knowledge, inconsistent architecture, incomplete tests, and developers who happen to remember why something was built ten years ago.&lt;/p&gt;

&lt;p&gt;That is not industrial production. It is craft production with increasingly powerful machinery.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Steam Engine Arrived Before the Factory
&lt;/h2&gt;

&lt;p&gt;This is why calling LLMs the industrial revolution of software is premature.&lt;/p&gt;

&lt;p&gt;They are closer to the steam engine arriving before we have finished building the factory.&lt;/p&gt;

&lt;p&gt;The machine is powerful. It can multiply output dramatically. But the surrounding structures are immature. We do not yet have universally reliable standards for generated code, consistent inspection methods, stable responsibility models, or production systems designed around autonomous implementation.&lt;/p&gt;

&lt;p&gt;So we place the steam engine inside the existing wooden workshop.&lt;/p&gt;

&lt;p&gt;Sometimes it powers a productive operation. Sometimes it shakes the building apart.&lt;/p&gt;

&lt;p&gt;The limiting factor is no longer only how quickly code can be written. The limiting factor becomes whether requirements are clear, context is available, assumptions are verified, results are tested, and decisions remain understandable after the agent has finished.&lt;/p&gt;

&lt;p&gt;LLMs expose this distinction brutally.&lt;/p&gt;

&lt;p&gt;When implementation becomes cheaper, every weakness around implementation becomes more visible. Poor specifications produce more incorrect code. Weak architecture produces more inconsistent code. Missing tests allow more regressions. Undocumented decisions become harder to reconstruct because the volume of change increases.&lt;/p&gt;

&lt;p&gt;The faster the machine, the more important the production system becomes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generated Code Is Not Yet IKEA
&lt;/h2&gt;

&lt;p&gt;There is another side to the IKEA analogy.&lt;/p&gt;

&lt;p&gt;An IKEA cabinet can be perfectly adequate. It may be inexpensive, consistent, easy to replace, and durable enough for its purpose. It does not become inferior merely because it was not handcrafted.&lt;/p&gt;

&lt;p&gt;Generated code should be judged the same way.&lt;/p&gt;

&lt;p&gt;Code does not gain value because a human typed every character. Nor does it lose value because an LLM produced most of it. What matters is whether it solves the right problem, fits the system, remains maintainable, handles failure safely, and can be verified.&lt;/p&gt;

&lt;p&gt;But IKEA furniture arrives with defined parts, known materials, tested connectors, numbered steps, and a repeatable assembly process.&lt;/p&gt;

&lt;p&gt;Generated software usually does not.&lt;/p&gt;

&lt;p&gt;The output may look standardized, but the assumptions behind it are often specific to the current prompt, context window, repository state, and model behavior. Two apparently similar generations may differ in subtle but important ways. The developer cannot simply assume that generated code is an interchangeable industrial component.&lt;/p&gt;

&lt;p&gt;We have the appearance of mass production without all the guarantees of mass production.&lt;/p&gt;

&lt;p&gt;That is why the human role shifts rather than disappears.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Developer Becomes Responsible for the System
&lt;/h2&gt;

&lt;p&gt;When code generation becomes cheap, manually producing every line becomes less important. Understanding the system becomes more important.&lt;/p&gt;

&lt;p&gt;The developer’s responsibility moves toward:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;defining the actual problem,&lt;/li&gt;
&lt;li&gt;providing relevant context,&lt;/li&gt;
&lt;li&gt;choosing architectural boundaries,&lt;/li&gt;
&lt;li&gt;identifying dangerous assumptions,&lt;/li&gt;
&lt;li&gt;verifying behavior,&lt;/li&gt;
&lt;li&gt;evaluating trade-offs,&lt;/li&gt;
&lt;li&gt;and preserving the reasoning behind decisions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not a retreat from engineering. It is engineering at a higher level.&lt;/p&gt;

&lt;p&gt;The carpenter using a circular saw is not less skilled because the blade moves automatically. Skill appears in how the cut is planned, how the material is secured, how errors are prevented, and how the result is inspected.&lt;/p&gt;

&lt;p&gt;Likewise, a developer does not prove competence by typing code slowly without assistance. Competence appears in the ability to direct the tool, detect when it is wrong, and integrate its output into a reliable system.&lt;/p&gt;

&lt;p&gt;The goal is not to protect manual coding as a ritual.&lt;/p&gt;

&lt;p&gt;The goal is to ensure that increased production does not outrun understanding.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Actual Path Toward the Software Factory
&lt;/h2&gt;

&lt;p&gt;The future of software development is therefore not simply more code generated by larger models.&lt;/p&gt;

&lt;p&gt;It is the gradual construction of a production system around those models.&lt;/p&gt;

&lt;p&gt;That system needs explicit requirements, constrained context, architecture rules, static analysis, automated tests, security checks, traceable decisions, reproducible agent workflows, and clear human approval points.&lt;/p&gt;

&lt;p&gt;Only then does the analogy begin to move from circular saw to IKEA.&lt;/p&gt;

&lt;p&gt;The individual developer still needs craftsmanship, because someone must understand the material and recognize failure. The apprentice still needs fundamentals, because judgment cannot be delegated before it exists. The organization needs production standards, because faster tools alone do not create reliable outcomes.&lt;/p&gt;

&lt;p&gt;LLMs are neither magical replacements for developers nor merely fancy autocomplete.&lt;/p&gt;

&lt;p&gt;They are powerful machinery.&lt;/p&gt;

&lt;p&gt;A skilled craftsperson can use that machinery to produce better work faster. A weak process can use it to manufacture defects at scale. And an immature industry can mistake increased output for industrialization.&lt;/p&gt;

&lt;p&gt;We have the circular saw.&lt;/p&gt;

&lt;p&gt;We may even have the steam engine.&lt;/p&gt;

&lt;p&gt;But we are still building the factory.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Distill Coding Agent Learnings</title>
      <dc:creator>Lars Moelleken</dc:creator>
      <pubDate>Thu, 16 Jul 2026 09:32:14 +0000</pubDate>
      <link>https://dev.to/suckup_de/distill-coding-agent-learnings-31og</link>
      <guid>https://dev.to/suckup_de/distill-coding-agent-learnings-31og</guid>
      <description>&lt;p&gt;Repo: &lt;a href="https://github.com/voku/agent-loop" rel="noopener noreferrer"&gt;https://github.com/voku/agent-loop&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Website: &lt;a href="https://voku.github.io/agent_loop_demo/" rel="noopener noreferrer"&gt;https://voku.github.io/agent_loop_demo/&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Your Coding Agent Can Write Code. Keep the Work Reliable.
&lt;/h1&gt;

&lt;p&gt;Coding agents are already surprisingly good at changing code.&lt;/p&gt;

&lt;p&gt;The harder problem is everything around the change.&lt;/p&gt;

&lt;p&gt;What exactly was requested?&lt;/p&gt;

&lt;p&gt;What is the agent allowed to touch?&lt;/p&gt;

&lt;p&gt;Which repository facts matter?&lt;/p&gt;

&lt;p&gt;Which validation actually ran?&lt;/p&gt;

&lt;p&gt;Does that validation still belong to the current implementation?&lt;/p&gt;

&lt;p&gt;What should happen next?&lt;/p&gt;

&lt;p&gt;And when something useful was learned, should it influence the next task, become durable guidance, or eventually disappear into a test, static-analysis rule, or CI check?&lt;/p&gt;

&lt;p&gt;The obvious response has often been:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Give the agent more memory.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So repositories slowly acquire things like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MEMORY.md
project-rules.md
agent-notes.md
lessons-learned.md
MEMORY_FINAL.md
actually-final-memory.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Soon the coding agent receives old decisions, temporary workarounds, copied transcripts, stale debugging notes, abandoned architecture ideas, and rules nobody remembers approving.&lt;/p&gt;

&lt;p&gt;It has more context.&lt;/p&gt;

&lt;p&gt;It does not necessarily have better context.&lt;/p&gt;

&lt;p&gt;At some point, memory becomes landfill.&lt;/p&gt;

&lt;p&gt;That was the problem I wanted to solve with &lt;a href="https://github.com/voku/agent-loop" rel="noopener noreferrer"&gt;voku/agent-loop&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Not by building another coding agent.&lt;/p&gt;

&lt;p&gt;By building a &lt;strong&gt;governed workflow around the coding agent you already use&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  The everyday loop should stay small
&lt;/h1&gt;

&lt;p&gt;The internals of Agent Loop are deliberately more sophisticated than its ordinary host contract.&lt;/p&gt;

&lt;p&gt;For normal governed work, the coding agent starts here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vendor/bin/agent-loop enter PROJECT-123 &lt;span class="nt"&gt;--format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result exposes the important state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mutation_ready
next_action_kind
next_action
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The host follows that result.&lt;/p&gt;

&lt;p&gt;It performs the current work.&lt;/p&gt;

&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vendor/bin/agent-loop finish PROJECT-123 &lt;span class="nt"&gt;--format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And again follows the returned next action until the workflow converges.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;developer intent
      ↓
agent-loop enter &amp;lt;task&amp;gt;
      ↓
canonical next_action
      ↓
coding agent works
      ↓
agent-loop finish &amp;lt;task&amp;gt;
      ↓
validation · review · learning
      ↓
repeat or complete
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is the important part.&lt;/p&gt;

&lt;p&gt;The coding agent does &lt;strong&gt;not&lt;/strong&gt; need to carry a giant workflow phase machine in its prompt.&lt;/p&gt;

&lt;p&gt;It should not have to memorize:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PLAN
MAP
SESSION
RECALL
IMPLEMENT
VALIDATE
REVIEW
LEARN
VERIFY
CLOSE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those capabilities exist.&lt;/p&gt;

&lt;p&gt;But they are implementation details behind the lifecycle.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;agent-loop&lt;/code&gt; owns the current workflow state and tells the host what happens next.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why this matters
&lt;/h1&gt;

&lt;p&gt;Without a governed workflow, coding-agent sessions tend to fail in remarkably repeatable ways.&lt;/p&gt;

&lt;p&gt;A new chat means reconstructing the task.&lt;/p&gt;

&lt;p&gt;The agent guesses whether it should investigate, implement, ask for approval, validate, or review.&lt;/p&gt;

&lt;p&gt;Large repositories become giant prompts.&lt;/p&gt;

&lt;p&gt;A passing test quietly becomes “done”.&lt;/p&gt;

&lt;p&gt;Useful experience disappears after the task.&lt;/p&gt;

&lt;p&gt;And project instructions keep growing because deleting prompt text feels more dangerous than adding one more paragraph.&lt;/p&gt;

&lt;p&gt;Agent Loop tries to invert those defaults.&lt;/p&gt;

&lt;p&gt;The task survives the chat.&lt;/p&gt;

&lt;p&gt;Context is selected instead of dumped.&lt;/p&gt;

&lt;p&gt;Evidence is tied to the state it actually verified.&lt;/p&gt;

&lt;p&gt;The next action is explicit.&lt;/p&gt;

&lt;p&gt;And useful learning has somewhere to go other than another permanent Markdown file.&lt;/p&gt;




&lt;h1&gt;
  
  
  Humans approve intent, not shell commands
&lt;/h1&gt;

&lt;p&gt;A governed workflow should not turn developers into operators of an orchestration CLI.&lt;/p&gt;

&lt;p&gt;The developer should still be able to talk naturally to the coding agent.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fix PROJECT-123.

Invalid order state transitions must be rejected.
Keep the public API unchanged.
Stay inside the order-state validation and its focused tests.
Run PHPStan and the focused test suite.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The coding agent investigates the repository and prepares a candidate Contract:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Goal:
Reject invalid order state transitions.

Scope:
Order-state validation and focused tests.

Non-goals:
Do not redesign the order aggregate.
Do not change the public API.

Validation:
composer phpstan
composer test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the lifecycle reaches a real human-authority boundary, the agent presents that exact decision.&lt;/p&gt;

&lt;p&gt;The developer can answer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Approved.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;No. Keep the repository layer untouched.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Approved, but do not change the public API.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The coding host records that explicit decision through Agent Loop.&lt;/p&gt;

&lt;p&gt;Approval belongs to one concrete Contract revision.&lt;/p&gt;

&lt;p&gt;It is not permanent permission attached to a task ID whose meaning can silently change later.&lt;/p&gt;

&lt;p&gt;If product intent or approved scope materially changes, the Contract changes too.&lt;/p&gt;

&lt;p&gt;That is where human authority is required again.&lt;/p&gt;

&lt;p&gt;But ordinary implementation, deterministic validation, review acknowledgement, Learning disposition, Recall outcome logging, local commits, and close-out inside the approved Contract do not need ceremonial confirmation every thirty seconds.&lt;/p&gt;

&lt;p&gt;Human authority should stay explicit without becoming human babysitting.&lt;/p&gt;




&lt;h1&gt;
  
  
  The workflow tells the agent what kind of action comes next
&lt;/h1&gt;

&lt;p&gt;A returned next action is not just a line of text.&lt;/p&gt;

&lt;p&gt;It has a kind.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;command
command_template
decision_required
host_work
none
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;command&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;means the workflow already knows the exact deterministic operation.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;command_template&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;means the coding agent must fill task-specific values from the request and current repository evidence.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;host_work&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;means actual engineering work is required.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;decision_required&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;means a real human-authority boundary has been reached.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;none&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;means there is no further lifecycle action.&lt;/p&gt;

&lt;p&gt;This removes a surprising amount of prompt choreography.&lt;/p&gt;

&lt;p&gt;The host does not need to guess:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is this something I can do myself?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;or:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Should I ask the developer now?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;or:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Which internal phase comes next?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The lifecycle result already answers that.&lt;/p&gt;

&lt;p&gt;Internally, Agent Loop projects the current owner-backed facts and evaluates them through executable policy.&lt;/p&gt;

&lt;p&gt;That produces the current:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;state
mutation_ready
next_action_kind
next_action
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The coding agent follows that result instead of maintaining another slightly different copy of the workflow in prose.&lt;/p&gt;




&lt;h1&gt;
  
  
  The CLI is the executable contract, not the user experience
&lt;/h1&gt;

&lt;p&gt;Agent Loop exposes a substantial CLI.&lt;/p&gt;

&lt;p&gt;You can discover it directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vendor/bin/agent-loop &lt;span class="nb"&gt;help
&lt;/span&gt;vendor/bin/agent-loop commands
vendor/bin/agent-loop commands &lt;span class="nt"&gt;--format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;json
vendor/bin/agent-loop commands &lt;span class="nt"&gt;--format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;toon
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The top-level command catalog is typed and also drives human-readable help.&lt;/p&gt;

&lt;p&gt;That is intentional.&lt;/p&gt;

&lt;p&gt;Humans and coding agents should discover the same installed capabilities from the same owner instead of maintaining separate README tables, UI registries, and prompt copies that inevitably drift apart.&lt;/p&gt;

&lt;p&gt;But despite the larger command surface, the normal host contract stays small:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;enter
  ↓
follow next_action
  ↓
work
  ↓
finish
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Specialist commands exist when the current task needs them.&lt;/p&gt;

&lt;p&gt;They are capabilities.&lt;/p&gt;

&lt;p&gt;They are not mandatory phases.&lt;/p&gt;




&lt;h1&gt;
  
  
  Skills help perform work. They do not invent workflow state.
&lt;/h1&gt;

&lt;p&gt;Earlier versions of this project leaned more heavily on phase-specific workflow instructions.&lt;/p&gt;

&lt;p&gt;That architecture made duplication too easy.&lt;/p&gt;

&lt;p&gt;A task-start skill knew one sequence.&lt;/p&gt;

&lt;p&gt;A review skill knew another.&lt;/p&gt;

&lt;p&gt;A README explained it again.&lt;/p&gt;

&lt;p&gt;Eventually there are three correct descriptions of the same workflow, which is software engineering’s traditional method for preparing three future bugs.&lt;/p&gt;

&lt;p&gt;The current boundary is stricter.&lt;/p&gt;

&lt;p&gt;The lifecycle result remains authoritative.&lt;/p&gt;

&lt;p&gt;Skills help the agent perform the &lt;strong&gt;current kind of engineering work&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Agent Loop can project focused assets for activities such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;agent-loop-discipline
agent-loop-workflow
agent-loop-investigate
agent-loop-surgical-edit
agent-loop-code-review
agent-loop-simplify-review
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An investigation role is read-only.&lt;/p&gt;

&lt;p&gt;A surgical-edit role is for an already-understood bounded change and must escalate instead of quietly widening scope.&lt;/p&gt;

&lt;p&gt;A review role inspects the real diff rather than trusting a generated summary.&lt;/p&gt;

&lt;p&gt;Broader engineering guidance lives separately in &lt;a href="https://github.com/voku/agent-skills" rel="noopener noreferrer"&gt;voku/agent-skills&lt;/a&gt;, with reusable skills for areas such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;engineering-codelight
coding-simplicity
php-best-practices
code-review-*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The ownership boundary is intentional:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;agent-loop
    workflow authority

agent-skills
    reusable engineering judgment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;agent-skills&lt;/code&gt; catalog is optional and separately installed.&lt;/p&gt;

&lt;p&gt;Agent Loop does not silently download another engineering rulebook merely because somebody thought seventeen more prompt files looked comforting.&lt;/p&gt;




&lt;h1&gt;
  
  
  Give the agent less context, but better context
&lt;/h1&gt;

&lt;p&gt;A coding agent does not need the whole repository in its prompt.&lt;/p&gt;

&lt;p&gt;It needs enough evidence to make the next engineering decision correctly.&lt;/p&gt;

&lt;p&gt;Agent Loop separates repository structure from project guidance because they answer different questions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Repository structure with agent-map
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/voku/agent-map" rel="noopener noreferrer"&gt;agent-map&lt;/a&gt; provides deterministic PHP repository intelligence.&lt;/p&gt;

&lt;p&gt;It can answer questions such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Where is this method defined?
Who calls it?
What does it call?
Which symbols are related?
What is the bounded edit context?
What may be affected by changing it?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It can operate structurally and optionally enrich the map through PHPStan when semantic evidence is available.&lt;/p&gt;

&lt;p&gt;The important output is not a gigantic graph to admire during architecture meetings.&lt;/p&gt;

&lt;p&gt;It is a bounded, source-backed edit context.&lt;/p&gt;

&lt;p&gt;And Map output remains derived navigation evidence.&lt;/p&gt;

&lt;p&gt;It does not replace the source code.&lt;/p&gt;

&lt;p&gt;If the Map says a method has no callers but the current capability cannot observe call edges, that is a capability limit.&lt;/p&gt;

&lt;p&gt;It is not proof that the method has no callers.&lt;/p&gt;

&lt;p&gt;That difference matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Task-specific context with agent-recall-compiler
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/voku/agent-recall-compiler" rel="noopener noreferrer"&gt;agent-recall-compiler&lt;/a&gt; answers a different question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Which bounded project knowledge is relevant to this task?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Inputs can include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;approved task intent
repository facts
project guidance
constraints
previous outcomes
LearningNote precedent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result is replayable task context plus, when applicable, L2 construction material for a concrete project-specific L1 contract.&lt;/p&gt;

&lt;p&gt;That L1 typically needs to answer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Goal
Context
Constraints
Verification
Done When
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The point is selection.&lt;/p&gt;

&lt;p&gt;Not permanent context inflation.&lt;/p&gt;

&lt;p&gt;The goal is not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Compress the whole repository and six months of transcripts into the model.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The goal is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Give the agent enough current, verified information to make the next decision correctly.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  Deterministic preparation should be automatic
&lt;/h1&gt;

&lt;p&gt;Once a Contract has been approved, &lt;code&gt;enter&lt;/code&gt; can prepare the governed execution state.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;approved Contract
      ↓
reconcile required Map state
      ↓
prepare or resume Session
      ↓
prepare governed Run
      ↓
replace stale Recall output
      ↓
compile current Recall
      ↓
return bounded context
      ↓
authorize implementation when ready
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The host should not have to memorize that ordering.&lt;/p&gt;

&lt;p&gt;If repository discovery can be repaired deterministically, the workflow can repair it.&lt;/p&gt;

&lt;p&gt;If an optional capability is unavailable, that does not automatically become a human decision.&lt;/p&gt;

&lt;p&gt;This distinction is useful:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deterministic preparation is choreography, not governance.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If software can safely do it itself, forcing the developer or coding agent to remember another ritual adds ceremony without adding authority.&lt;/p&gt;




&lt;h1&gt;
  
  
  Working memory should stay temporary
&lt;/h1&gt;

&lt;p&gt;During a task, the coding agent may need mutable state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;assumptions
decisions
checkpoints
validation observations
open questions
resume state
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That belongs in &lt;a href="https://github.com/voku/agent-session" rel="noopener noreferrer"&gt;agent-session&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A Session is working memory.&lt;/p&gt;

&lt;p&gt;It is not permanent project knowledge.&lt;/p&gt;

&lt;p&gt;This sounds obvious, but memory systems tend to blur this distinction surprisingly quickly.&lt;/p&gt;

&lt;p&gt;A debugging observation may be useful for twenty minutes and misleading two commits later.&lt;/p&gt;

&lt;p&gt;Temporary state should remain closable and pruneable.&lt;/p&gt;

&lt;p&gt;The durable workflow should preserve only the state and evidence that actually need to survive.&lt;/p&gt;




&lt;h1&gt;
  
  
  Validation belongs to an exact implementation
&lt;/h1&gt;

&lt;p&gt;An agent saying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tests passed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;is useful.&lt;/p&gt;

&lt;p&gt;But only if we know which implementation those tests validated.&lt;/p&gt;

&lt;p&gt;Validation evidence is bound to the task and exact workflow state, including:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Contract revision
command
exit code
implementation snapshot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Suppose this passed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then the agent changes three files.&lt;/p&gt;

&lt;p&gt;The old result is history.&lt;/p&gt;

&lt;p&gt;It is not evidence that the new implementation still passes.&lt;/p&gt;

&lt;p&gt;The same applies when the approved Contract revision changes.&lt;/p&gt;

&lt;p&gt;The system can therefore distinguish:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;current validation
superseded by implementation
superseded by Contract revision
missing validation
failed validation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;instead of carrying one immortal green checkmark around the repository.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;code&gt;finish&lt;/code&gt; does not mean “please declare victory”
&lt;/h1&gt;

&lt;p&gt;After implementation, the coding agent calls:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vendor/bin/agent-loop finish PROJECT-123 &lt;span class="nt"&gt;--format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;finish&lt;/code&gt; does not simply flip a task to done.&lt;/p&gt;

&lt;p&gt;It reconciles the current implementation with the current obligations.&lt;/p&gt;

&lt;p&gt;Depending on state, it may:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;run validation
prepare review evidence
request more host work
surface a human decision
record Learning disposition
log Recall outcomes
close the Session
complete the Run
surface remaining owner work such as Kanban reconciliation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That last distinction is important.&lt;/p&gt;

&lt;p&gt;If the governed Run is complete but the linked Kanban card is still active, Agent Loop does not quietly claim everything is finished.&lt;/p&gt;

&lt;p&gt;It surfaces the remaining Kanban-owned work.&lt;/p&gt;

&lt;p&gt;Evidence stays evidence.&lt;/p&gt;

&lt;p&gt;Owner state stays owner state.&lt;/p&gt;

&lt;p&gt;The gate ordering itself lives in executable policy rather than another copied checklist.&lt;/p&gt;

&lt;p&gt;If validation fails, the canonical next action may be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;next_action_kind = host_work

change the implementation so the declared validation passes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running the same failed validation forever would not make progress.&lt;/p&gt;

&lt;p&gt;Which gives us another useful invariant:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A canonical next action should converge.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If executing the recommended deterministic action always returns the exact same blocker and exact same recommendation, that is a workflow defect.&lt;/p&gt;

&lt;p&gt;The coding agent should not invent a private workaround.&lt;/p&gt;




&lt;h1&gt;
  
  
  Evidence is not authority
&lt;/h1&gt;

&lt;p&gt;This principle appears repeatedly because violating it is an excellent way to build an impressive automation system that is subtly wrong.&lt;/p&gt;

&lt;p&gt;A test result is evidence.&lt;/p&gt;

&lt;p&gt;It does not approve a scope change.&lt;/p&gt;

&lt;p&gt;A review report is evidence.&lt;/p&gt;

&lt;p&gt;Its existence does not automatically acknowledge the review.&lt;/p&gt;

&lt;p&gt;A generated prompt proves something was rendered.&lt;/p&gt;

&lt;p&gt;It does not prove the receiving model used it.&lt;/p&gt;

&lt;p&gt;A Map is derived repository structure.&lt;/p&gt;

&lt;p&gt;It is not source truth.&lt;/p&gt;

&lt;p&gt;A LearningNote is evidence-backed precedent.&lt;/p&gt;

&lt;p&gt;It is not active project policy.&lt;/p&gt;

&lt;p&gt;And a model sounding extremely confident is mostly evidence that models have become very good at adjectives.&lt;/p&gt;

&lt;p&gt;Authority and evidence answer different questions.&lt;/p&gt;

&lt;p&gt;The workflow keeps them separate.&lt;/p&gt;




&lt;h1&gt;
  
  
  Selected guidance is not necessarily useful guidance
&lt;/h1&gt;

&lt;p&gt;Suppose Recall selects a piece of guidance.&lt;/p&gt;

&lt;p&gt;That proves:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;the system selected it
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It does not prove:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;the agent consulted it
the agent needed it
the agent applied it
the result improved because of it
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Outcome tracking therefore keeps selection and usefulness separate.&lt;/p&gt;

&lt;p&gt;A selected item may eventually be judged:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;helpful
irrelevant
harmful
not used
unknown
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This becomes essential once you start asking whether all that carefully curated prompt material is actually worth its token cost.&lt;/p&gt;

&lt;p&gt;Otherwise, you are mostly measuring how often your software successfully copied text into another file.&lt;/p&gt;

&lt;p&gt;Computers were already very good at that before LLMs arrived.&lt;/p&gt;




&lt;h1&gt;
  
  
  Learning should begin with evidence, not policy
&lt;/h1&gt;

&lt;p&gt;This is the part of Agent Loop I find most interesting.&lt;/p&gt;

&lt;p&gt;The naive model is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The agent learned something useful. Save it as a rule.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That promotes evidence far too aggressively.&lt;/p&gt;

&lt;p&gt;The current architecture is closer to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;real task
   ↓
Finding
   ↓
LearningNote
   ↓
future Recall
   ↓
later real task
   ↓
observable result
   ↓
new Finding
   ↓
recurrence
   ↓
Dream
   ↓
Proposal
   ↓
human review
   ↓
Memory / Skill / Constraint
   ↓
deterministic enforcement
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are really two loops here.&lt;/p&gt;

&lt;p&gt;A fast precedent loop.&lt;/p&gt;

&lt;p&gt;And a slower promotion loop.&lt;/p&gt;




&lt;h1&gt;
  
  
  The fast loop: Finding → LearningNote → future task
&lt;/h1&gt;

&lt;p&gt;A &lt;strong&gt;Finding&lt;/strong&gt; records evidence from real work.&lt;/p&gt;

&lt;p&gt;It can preserve things such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;task identity
observation
validated conclusion
scope
evidence
pattern_key
validation case
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A useful solved case may be classified:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ADD_LEARNING_NOTE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That can become a &lt;strong&gt;LearningNote&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The important boundary is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A LearningNote is durable precedent, not active guidance.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It can preserve:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;what happened
what failed
why the resolution worked
when to apply it
when not to apply it
how to verify it
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A later task may receive that precedent through Recall.&lt;/p&gt;

&lt;p&gt;But the note does not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;approve mutation
widen task scope
satisfy validation
create a Skill
create a Constraint
become project policy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We have seen something like this before. Here is the evidence-backed solved case.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is much safer than promoting every successful patch into permanent instruction text.&lt;/p&gt;




&lt;h1&gt;
  
  
  The slow loop: recurrence earns promotion
&lt;/h1&gt;

&lt;p&gt;One solved case rarely deserves policy.&lt;/p&gt;

&lt;p&gt;Before promoting a lesson, we want stronger evidence.&lt;/p&gt;

&lt;p&gt;Did the pattern recur?&lt;/p&gt;

&lt;p&gt;Did it recur across independent tasks?&lt;/p&gt;

&lt;p&gt;Was the precedent actually useful?&lt;/p&gt;

&lt;p&gt;Was it irrelevant?&lt;/p&gt;

&lt;p&gt;Was it harmful?&lt;/p&gt;

&lt;p&gt;Is there already an owner for this behavior?&lt;/p&gt;

&lt;p&gt;Has later evidence contradicted it?&lt;/p&gt;

&lt;p&gt;Could software enforce the invariant instead?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/voku/agent-learning" rel="noopener noreferrer"&gt;agent-learning&lt;/a&gt; provides a deterministic maintenance pass called &lt;code&gt;dream&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When using it through Agent Loop, the workflow owner resolves the configured Learning root for you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vendor/bin/agent-loop learn dream &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--report&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;.agent-loop/dream/latest.json &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dream can evaluate accumulated evidence for things such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;promotion
staleness
replacement
conflicts
outcome coverage
duplicate candidate decisions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It can prepare reviewable candidates.&lt;/p&gt;

&lt;p&gt;It does &lt;strong&gt;not&lt;/strong&gt; approve them.&lt;/p&gt;

&lt;p&gt;It does not silently rewrite project guidance while everybody sleeps.&lt;/p&gt;

&lt;p&gt;A scheduler, if you use one, may decide when to wake this maintenance cycle.&lt;/p&gt;

&lt;p&gt;Learning decides whether the evidence warrants a candidate.&lt;/p&gt;

&lt;p&gt;A human remains the authority for durable promotion.&lt;/p&gt;

&lt;p&gt;Wake frequently.&lt;/p&gt;

&lt;p&gt;Promote rarely.&lt;/p&gt;




&lt;h1&gt;
  
  
  Most tasks should probably learn nothing permanent
&lt;/h1&gt;

&lt;p&gt;This is a feature.&lt;/p&gt;

&lt;p&gt;A perfectly good task-level outcome is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NO_DURABLE_LEARNING
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sometimes the correct conclusion after fixing a bug is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The bug is fixed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No new Memory entry.&lt;/p&gt;

&lt;p&gt;No new Skill.&lt;/p&gt;

&lt;p&gt;No small constitution drafted because one null check was missing on a Wednesday.&lt;/p&gt;

&lt;p&gt;Durable Learning should have a higher bar than task completion.&lt;/p&gt;




&lt;h1&gt;
  
  
  The best memory is sometimes a PHPStan rule
&lt;/h1&gt;

&lt;p&gt;Suppose repeated evidence eventually establishes a stable invariant:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Every X must satisfy Y.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If that property can be detected mechanically, the ideal destination may not be another prompt instruction.&lt;/p&gt;

&lt;p&gt;It may be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PHPStan rule
PHP-CS-Fixer rule
PHPCS sniff
architecture test
unit test
integration test
CI check
typed API
runtime invariant
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;repeated evidence
      ↓
reviewed Constraint
      ↓
deterministic enforcement
      ↓
obsolete prompt guidance can disappear
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is where “memory” becomes much more interesting.&lt;/p&gt;

&lt;p&gt;The system can &lt;strong&gt;distill experience into structure&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Once CI proves the invariant automatically, spending prompt tokens reminding the agent about it on every task is waste.&lt;/p&gt;

&lt;p&gt;The lesson has become infrastructure.&lt;/p&gt;

&lt;p&gt;The agent can forget it.&lt;/p&gt;




&lt;h1&gt;
  
  
  One semantic owner per kind of truth
&lt;/h1&gt;

&lt;p&gt;The project is split across focused packages because different kinds of state should have clear owners.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concern&lt;/th&gt;
&lt;th&gt;Owner&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Contract / Run authority and lifecycle&lt;/td&gt;
&lt;td&gt;&lt;code&gt;agent-loop&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Git-native work items&lt;/td&gt;
&lt;td&gt;&lt;code&gt;agent-kanban&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Temporary working memory and validation evidence&lt;/td&gt;
&lt;td&gt;&lt;code&gt;agent-session&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Repository structure and code navigation&lt;/td&gt;
&lt;td&gt;&lt;code&gt;agent-map&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bounded task context and prompt construction&lt;/td&gt;
&lt;td&gt;&lt;code&gt;agent-recall-compiler&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Findings, precedent and durable Learning&lt;/td&gt;
&lt;td&gt;&lt;code&gt;agent-learning&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Portable engineering and review guidance&lt;/td&gt;
&lt;td&gt;&lt;code&gt;agent-skills&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;There are optional surfaces too.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;agent-ui&lt;/code&gt; provides a local human control plane.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;agent-loop-runner&lt;/code&gt; provides an optional execution plane for isolated coding-host runs.&lt;/p&gt;

&lt;p&gt;Internally, &lt;code&gt;agent-graph&lt;/code&gt; provides shared deterministic SQLite graph mechanics for Map and Learning.&lt;/p&gt;

&lt;p&gt;It deliberately owns none of their domain semantics.&lt;/p&gt;

&lt;p&gt;That distinction matters.&lt;/p&gt;

&lt;p&gt;The UI should not independently decide what action is legal.&lt;/p&gt;

&lt;p&gt;The Runner should not decide that process exit &lt;code&gt;0&lt;/code&gt; means the governed Run is valid.&lt;/p&gt;

&lt;p&gt;A graph database should not become the semantic owner because it contains derived relations.&lt;/p&gt;

&lt;p&gt;The boring rule is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;One semantic owner per decision.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It becomes increasingly useful once multiple autonomous tools start touching the same repository.&lt;/p&gt;




&lt;h1&gt;
  
  
  This is still pre-1.0
&lt;/h1&gt;

&lt;p&gt;One claim deserves particular honesty.&lt;/p&gt;

&lt;p&gt;The individual mechanics of the Learning loop exist today:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Finding capture
LearningNotes
bounded Recall selection
L2 / L1 construction
outcome tracking
Dream
reviewed Proposals
Constraints
deterministic enforcement
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But I am still dogfooding the harder end-to-end claim:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Does precedent from one real task measurably improve a later independent task, and can repeated evidence eventually become a hard rule that catches a different manifestation of the same mistake?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The project has already proven substantial parts of that path.&lt;/p&gt;

&lt;p&gt;What I do &lt;strong&gt;not&lt;/strong&gt; want to do is declare success merely because a LearningNote appeared inside generated context.&lt;/p&gt;

&lt;p&gt;Prompt inclusion is not behavioral evidence.&lt;/p&gt;

&lt;p&gt;If the same engineering decision would have happened without the precedent, the honest result is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NO_DEMONSTRATED_VALUE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WITHHELD
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That experiment is still active.&lt;/p&gt;

&lt;p&gt;I would rather leave the claim open than build a learning system whose main learned behavior is how to congratulate itself.&lt;/p&gt;




&lt;h1&gt;
  
  
  Try it on one real task
&lt;/h1&gt;

&lt;p&gt;Agent Loop is open source, MIT licensed, local-first, and requires PHP 8.3+.&lt;/p&gt;

&lt;p&gt;Install it in an existing Composer repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require &lt;span class="nt"&gt;--dev&lt;/span&gt; voku/agent-loop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create the repository-local workflow scaffold:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vendor/bin/agent-loop init scaffold &lt;span class="nt"&gt;--demo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install the local coding-agent assets.&lt;/p&gt;

&lt;p&gt;For Codex:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vendor/bin/agent-loop init install-assets &lt;span class="nt"&gt;--agent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;codex
vendor/bin/agent-loop init doctor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then &lt;strong&gt;start a fresh Codex session or restart Codex before using the newly installed skills&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That boundary is worth stating explicitly.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;install-assets&lt;/code&gt; proves that the repository-side files were projected correctly.&lt;/p&gt;

&lt;p&gt;It does not prove that an already-running coding host retroactively loaded them.&lt;/p&gt;

&lt;p&gt;You can inspect the host-side repository integration with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vendor/bin/agent-loop init host-status &lt;span class="nt"&gt;--format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Other supported hosts can be selected instead of &lt;code&gt;codex&lt;/code&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  Start the governed task
&lt;/h1&gt;

&lt;p&gt;For the demo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vendor/bin/agent-loop enter DEMO-1 &lt;span class="nt"&gt;--format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mutation_ready
next_action_kind
next_action
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then do what the current lifecycle asks.&lt;/p&gt;

&lt;p&gt;For an unplanned task, that may first be a model-owned Contract template.&lt;/p&gt;

&lt;p&gt;The coding agent fills it using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;the developer's request
current repository evidence
the smallest honest scope
repository-supported validation commands
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the result reaches:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;decision_required
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the host presents the exact human decision.&lt;/p&gt;

&lt;p&gt;After approval, call &lt;code&gt;enter&lt;/code&gt; again.&lt;/p&gt;

&lt;p&gt;Once mutation is authorized, the coding agent implements normally.&lt;/p&gt;

&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vendor/bin/agent-loop finish DEMO-1 &lt;span class="nt"&gt;--format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow the result.&lt;/p&gt;

&lt;p&gt;Repeat until complete.&lt;/p&gt;

&lt;p&gt;That is the ordinary workflow.&lt;/p&gt;

&lt;p&gt;Everything else exists to make those decisions reliable.&lt;/p&gt;




&lt;h1&gt;
  
  
  The actual interface is still conversation
&lt;/h1&gt;

&lt;p&gt;In day-to-day use, I do not want to manually translate every lifecycle transition into CLI syntax.&lt;/p&gt;

&lt;p&gt;I want to tell the coding agent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Take PROJECT-123.

Reject invalid order state transitions.
Do not change the public API.
Run PHPStan and the focused tests.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The coding agent should inspect the repository, operate the workflow, show me the exact Contract when my authority is required, implement within that boundary, collect evidence, and report the result.&lt;/p&gt;

&lt;p&gt;If scope must change, I want that surfaced.&lt;/p&gt;

&lt;p&gt;If validation fails, I want the actual failure.&lt;/p&gt;

&lt;p&gt;If a Finding is reusable, I want it recorded.&lt;/p&gt;

&lt;p&gt;If the task teaches nothing durable, I want the system to say so.&lt;/p&gt;

&lt;p&gt;And if repeated evidence eventually produces a rule that PHPStan can enforce, I would rather delete the prompt instruction than celebrate that &lt;code&gt;MEMORY.md&lt;/code&gt; grew again.&lt;/p&gt;




&lt;h1&gt;
  
  
  What changed in my mental model
&lt;/h1&gt;

&lt;p&gt;When I started working on this problem, I thought mostly in terms of memory:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How can the coding agent remember useful things?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That question is too broad.&lt;/p&gt;

&lt;p&gt;A better sequence is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What happened?
    ↓
Is there evidence?
    ↓
Is it useful precedent?
    ↓
Does it recur?
    ↓
Should a human approve it as guidance?
    ↓
Can software enforce it instead?
    ↓
Can we delete the prose again?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That produces a very different system.&lt;/p&gt;

&lt;p&gt;Temporary state stays temporary.&lt;/p&gt;

&lt;p&gt;Historical precedent stays weaker than current authority.&lt;/p&gt;

&lt;p&gt;Validation remains bound to the implementation it actually tested.&lt;/p&gt;

&lt;p&gt;Workflow policy lives in executable owners instead of duplicated prompts.&lt;/p&gt;

&lt;p&gt;Human decisions stay explicit.&lt;/p&gt;

&lt;p&gt;And durable learning has somewhere to go other than an ever-growing pile of Markdown.&lt;/p&gt;




&lt;h1&gt;
  
  
  The actual lesson
&lt;/h1&gt;

&lt;p&gt;Coding agents do not need to remember everything.&lt;/p&gt;

&lt;p&gt;They need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;durable task intent;&lt;/li&gt;
&lt;li&gt;explicit authority boundaries;&lt;/li&gt;
&lt;li&gt;bounded repository context;&lt;/li&gt;
&lt;li&gt;temporary working memory;&lt;/li&gt;
&lt;li&gt;validation tied to the current implementation;&lt;/li&gt;
&lt;li&gt;one canonical next action;&lt;/li&gt;
&lt;li&gt;evidence-backed precedent;&lt;/li&gt;
&lt;li&gt;recurrence before promotion;&lt;/li&gt;
&lt;li&gt;human-reviewed durable guidance;&lt;/li&gt;
&lt;li&gt;deterministic enforcement when possible;&lt;/li&gt;
&lt;li&gt;intentional forgetting.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More memory can hide bad context management.&lt;/p&gt;

&lt;p&gt;A governed loop exposes it.&lt;/p&gt;

&lt;p&gt;The purpose of Agent Loop is not to make developers manually operate a more elaborate state machine.&lt;/p&gt;

&lt;p&gt;It is to give coding agents a reliable process they can operate themselves while humans retain authority over the decisions that matter.&lt;/p&gt;

&lt;p&gt;The agent can still investigate, edit, test, review, and learn.&lt;/p&gt;

&lt;p&gt;But:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I remember
I think
looks good
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;stop being workflow states.&lt;/p&gt;

&lt;p&gt;And once a lesson becomes stable enough that PHPStan, a test, a typed API, or CI can enforce it, the ideal outcome is not that the coding agent remembers it forever.&lt;/p&gt;

&lt;p&gt;The ideal outcome is that it no longer has to.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/voku/agent-loop" rel="noopener noreferrer"&gt;https://github.com/voku/agent-loop&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Demo: &lt;a href="https://voku.github.io/agent_loop_demo/" rel="noopener noreferrer"&gt;https://voku.github.io/agent_loop_demo/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>php</category>
      <category>agents</category>
    </item>
    <item>
      <title>Multi-Line Formatting by Default</title>
      <dc:creator>Lars Moelleken</dc:creator>
      <pubDate>Wed, 27 May 2026 01:04:14 +0000</pubDate>
      <link>https://dev.to/suckup_de/multi-line-formatting-by-default-chi</link>
      <guid>https://dev.to/suckup_de/multi-line-formatting-by-default-chi</guid>
      <description>&lt;p&gt;I have reviewed so much code that I usually prefer multi-line formatting by default.&lt;/p&gt;

&lt;p&gt;Not because it looks prettier.&lt;/p&gt;

&lt;p&gt;Because code review happens line by line. And also tools like static analysis or SQL errors are reported line by line.&lt;/p&gt;

&lt;p&gt;PS: in most IDEs you can directly jump into the code by typing or clicking FILE:LINE e.g. in the quick-seach (typing) or in the command line (clicking)&lt;/p&gt;

&lt;p&gt;A one-line change should ideally mean:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;one thing changed&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That sounds obvious, which means we apparently need examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with compact code
&lt;/h2&gt;

&lt;p&gt;Compact code often hides the actual change.&lt;/p&gt;

&lt;p&gt;A reviewer does not review “the code” in some magical abstract universe.&lt;/p&gt;

&lt;p&gt;A reviewer reviews a diff.&lt;/p&gt;

&lt;p&gt;And diffs are line-based.&lt;/p&gt;

&lt;p&gt;So when multiple independent decisions live on the same line, every change becomes harder to verify.&lt;/p&gt;

&lt;p&gt;That is how small changes sneak through review.&lt;/p&gt;

&lt;p&gt;Not because reviewers are lazy.&lt;/p&gt;

&lt;p&gt;Well, sometimes because reviewers are lazy.&lt;/p&gt;

&lt;p&gt;But often because the formatting makes the review harder than necessary.&lt;/p&gt;

&lt;h2&gt;
  
  
  JavaScript
&lt;/h2&gt;

&lt;p&gt;Bad:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;selectedUserId&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;active&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;deleted&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;selectedUserId&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;active&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;deleted&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now a reviewer can see whether someone changed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;selectedUserId&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;active&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;deleted&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One logical condition per line.&lt;/p&gt;

&lt;p&gt;Primitive stuff. Somehow still rare.&lt;/p&gt;

&lt;h2&gt;
  
  
  SQL
&lt;/h2&gt;

&lt;p&gt;Bad:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;deleted_at&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;created_at&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;deleted_at&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now changing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;email&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;private_email&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is one line.&lt;/p&gt;

&lt;p&gt;Adding a filter is one line.&lt;/p&gt;

&lt;p&gt;Removing a selected column is one line.&lt;/p&gt;

&lt;p&gt;The diff no longer looks like someone threw SQL into a blender and called it “compact”.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conditions
&lt;/h2&gt;

&lt;p&gt;Bad:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;isDeleted&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hasPermission&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'admin'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;isDeleted&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hasPermission&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'admin'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now each condition can be reviewed independently.&lt;/p&gt;

&lt;p&gt;This matters when someone changes this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hasPermission&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'admin'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hasPermission&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'user'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is not a formatting change.&lt;/p&gt;

&lt;p&gt;That is the kind of thing that becomes a production incident wearing a fake mustache.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTML
&lt;/h2&gt;

&lt;p&gt;Bad:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"form-control is-invalid"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"{{ email }}"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt; &lt;span class="na"&gt;autocomplete=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;
    &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
    &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
    &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
    &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"form-control is-invalid"&lt;/span&gt;
    &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"{{ email }}"&lt;/span&gt;
    &lt;span class="na"&gt;required&lt;/span&gt;
    &lt;span class="na"&gt;autocomplete=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now changing &lt;code&gt;required&lt;/code&gt;, &lt;code&gt;autocomplete&lt;/code&gt;, &lt;code&gt;class&lt;/code&gt;, or &lt;code&gt;value&lt;/code&gt; is visible.&lt;/p&gt;

&lt;p&gt;This also avoids huge horizontal lines, because apparently screens are wide but attention spans are not.&lt;/p&gt;

&lt;h2&gt;
  
  
  Function parameters
&lt;/h2&gt;

&lt;p&gt;Bad:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$userRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;findActiveUserByEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'admin'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'editor'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$userRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;findActiveUserByEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;includeDisabled&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;includeDeleted&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;roles&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'admin'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'editor'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not only easier to review.&lt;/p&gt;

&lt;p&gt;It also prevents the classic mystery-boolean nonsense:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lovely.&lt;/p&gt;

&lt;p&gt;Very expressive.&lt;/p&gt;

&lt;p&gt;Archaeologists will enjoy it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Arrays
&lt;/h2&gt;

&lt;p&gt;Bad:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'enabled'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'timeout'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'retries'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'log_errors'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;'enabled'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'timeout'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'retries'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'log_errors'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now changing one value changes one line.&lt;/p&gt;

&lt;p&gt;Adding one entry adds one line.&lt;/p&gt;

&lt;p&gt;Removing one entry removes one line.&lt;/p&gt;

&lt;p&gt;No fake diff noise.&lt;/p&gt;

&lt;p&gt;No guessing.&lt;/p&gt;

&lt;p&gt;No “wait, what changed here?”&lt;/p&gt;

&lt;h2&gt;
  
  
  Config blocks
&lt;/h2&gt;

&lt;p&gt;Bad:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'cache'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'ttl'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'debug'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'strict'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;'cache'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'ttl'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'debug'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'strict'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configuration changes are exactly where review clarity matters.&lt;/p&gt;

&lt;p&gt;One flag can change behavior across the whole system.&lt;/p&gt;

&lt;p&gt;So maybe, just maybe, hiding it inside a long horizontal sausage is not peak engineering.&lt;/p&gt;

&lt;h2&gt;
  
  
  Method chains
&lt;/h2&gt;

&lt;p&gt;Bad:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$queryBuilder&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'users'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'active = 1'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;orderBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'created_at'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'DESC'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$queryBuilder&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'users'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'active = 1'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;orderBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'created_at'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'DESC'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now each query operation has its own line.&lt;/p&gt;

&lt;p&gt;A reviewer can spot whether the change touched:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'active = 1'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That matters.&lt;/p&gt;

&lt;p&gt;Especially when someone quietly turns &lt;code&gt;50&lt;/code&gt; into &lt;code&gt;5000&lt;/code&gt; and suddenly the database starts filing a workplace complaint.&lt;/p&gt;

&lt;h2&gt;
  
  
  The actual rule
&lt;/h2&gt;

&lt;p&gt;Prefer multi-line formatting when a line contains multiple independent pieces of meaning.&lt;/p&gt;

&lt;p&gt;Especially for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;js expressions
sql queries
conditions
html attributes
function parameters
arrays
config blocks
method chains
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This does not mean every line must be split.&lt;/p&gt;

&lt;p&gt;This:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$isActive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;does not need ceremony.&lt;/p&gt;

&lt;p&gt;We are formatting for reviewability, not starting a whitespace religion.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compact code is not automatically readable
&lt;/h2&gt;

&lt;p&gt;Compact code can be readable when it contains one idea.&lt;/p&gt;

&lt;p&gt;Compact code becomes a problem when it compresses multiple decisions into one line.&lt;/p&gt;

&lt;p&gt;Reviewers need to answer simple questions fast:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What changed?&lt;/li&gt;
&lt;li&gt;Is the change safe?&lt;/li&gt;
&lt;li&gt;Is the changed line doing one thing?&lt;/li&gt;
&lt;li&gt;Did the author hide behavior inside formatting noise?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Multi-line formatting helps with that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It reduces noise.&lt;/li&gt;
&lt;li&gt;It makes intent visible.&lt;/li&gt;
&lt;li&gt;It makes review sharper.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;Readable diffs beat clever formatting.&lt;/p&gt;

&lt;p&gt;Every time.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>codereview</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Use Blunt Prompts and Get Shit Done</title>
      <dc:creator>Lars Moelleken</dc:creator>
      <pubDate>Tue, 26 May 2026 22:40:20 +0000</pubDate>
      <link>https://dev.to/suckup_de/use-blunt-prompts-and-get-shit-done-4mdd</link>
      <guid>https://dev.to/suckup_de/use-blunt-prompts-and-get-shit-done-4mdd</guid>
      <description>&lt;p&gt;Do not ask a coding agent for “more tests.”&lt;/p&gt;

&lt;p&gt;That is how you get coverage theater.&lt;/p&gt;

&lt;p&gt;Ask for pressure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Increase test coverage by at least 20%.

If you can’t find at least one real regression, your tests are shit anyway.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That prompt works because it has two parts.&lt;/p&gt;

&lt;p&gt;First, it gives the agent a measurable floor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Increase test coverage by at least 20%.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not “add some tests.”&lt;/p&gt;

&lt;p&gt;Not “improve coverage.”&lt;/p&gt;

&lt;p&gt;At least 20%.&lt;/p&gt;

&lt;p&gt;The number matters because it removes the cheap escape hatch.&lt;/p&gt;

&lt;p&gt;Second, it blocks fake success:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;If you can’t find at least one real regression...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That changes the job.&lt;/p&gt;

&lt;p&gt;The agent is no longer writing tests to satisfy a report.&lt;/p&gt;

&lt;p&gt;It is hunting for proof that the code can break.&lt;/p&gt;

&lt;p&gt;That is the point.&lt;/p&gt;

&lt;p&gt;Coverage alone only says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This line was executed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Regression hunting asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Did this test prove anything useful?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A weak test can execute code and still protect nothing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;assertNotNull&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is not confidence.&lt;/p&gt;

&lt;p&gt;That is noise.&lt;/p&gt;

&lt;p&gt;A useful test catches broken behavior, exposes a missing edge case, kills a mutant, or forces you to clarify what the code is supposed to do.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;So push the agent harder.&lt;/li&gt;
&lt;li&gt;Do not stop at green.&lt;/li&gt;
&lt;li&gt;Green is the starting line.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The real question is:&lt;/p&gt;

&lt;p&gt;What did the new tests actually discover?&lt;/p&gt;

&lt;p&gt;If the answer is “nothing,” keep going.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>testing</category>
      <category>programming</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>The Singleton Labyrinth</title>
      <dc:creator>Lars Moelleken</dc:creator>
      <pubDate>Tue, 26 May 2026 20:08:52 +0000</pubDate>
      <link>https://dev.to/suckup_de/the-singleton-labyrinth-19je</link>
      <guid>https://dev.to/suckup_de/the-singleton-labyrinth-19je</guid>
      <description>&lt;p&gt;Play the game first: &lt;a href="https://voku.github.io/DevLabyrinth/" rel="noopener noreferrer"&gt;voku.github.io/DevLabyrinth/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It teaches the problem faster than another architecture sermon ever could.&lt;/p&gt;

&lt;p&gt;You enter a labyrinth.&lt;/p&gt;

&lt;p&gt;Walls. Corridors. Turns. Dead ends.&lt;/p&gt;

&lt;p&gt;Annoying, yes.&lt;/p&gt;

&lt;p&gt;But fair.&lt;/p&gt;

&lt;p&gt;You can explain where you are.&lt;br&gt;&lt;br&gt;
You can explain how you got there.&lt;br&gt;&lt;br&gt;
You can walk back.&lt;br&gt;&lt;br&gt;
You can draw a map.&lt;/p&gt;

&lt;p&gt;That is maintainable software.&lt;/p&gt;

&lt;p&gt;Not perfect software.&lt;/p&gt;

&lt;p&gt;Not "clean" software.&lt;/p&gt;

&lt;p&gt;Maintainable software.&lt;/p&gt;

&lt;p&gt;The boring miracle where the structure you see is the structure you actually use.&lt;/p&gt;
&lt;h2&gt;
  
  
  Then Someone Adds a Hole
&lt;/h2&gt;

&lt;p&gt;At some point, someone adds a hole in the floor.&lt;/p&gt;

&lt;p&gt;You step into it and land somewhere else.&lt;/p&gt;

&lt;p&gt;Nice.&lt;/p&gt;

&lt;p&gt;Five corridors avoided.&lt;br&gt;&lt;br&gt;
Three turns skipped.&lt;br&gt;&lt;br&gt;
No ceremony.&lt;br&gt;&lt;br&gt;
Fast.&lt;/p&gt;

&lt;p&gt;Someone says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"This is much easier."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They are right.&lt;/p&gt;

&lt;p&gt;For now.&lt;/p&gt;

&lt;p&gt;And that is how most bad architecture starts.&lt;/p&gt;

&lt;p&gt;Not with evil.&lt;/p&gt;

&lt;p&gt;With convenience.&lt;/p&gt;
&lt;h2&gt;
  
  
  One Shortcut Is Not the Problem
&lt;/h2&gt;

&lt;p&gt;One shortcut can be fine.&lt;/p&gt;

&lt;p&gt;One hole can be documented.&lt;/p&gt;

&lt;p&gt;One emergency tunnel can be marked on the map.&lt;/p&gt;

&lt;p&gt;The problem starts when every frustrated developer adds their own shortcut.&lt;/p&gt;

&lt;p&gt;A hole near the entrance.&lt;br&gt;&lt;br&gt;
A tunnel near the middle.&lt;br&gt;&lt;br&gt;
A ladder near the exit.&lt;br&gt;&lt;br&gt;
A trapdoor from room C to room Q because "we needed it for that one release."&lt;/p&gt;

&lt;p&gt;The labyrinth still works.&lt;/p&gt;

&lt;p&gt;Technically.&lt;/p&gt;

&lt;p&gt;But nobody navigates anymore.&lt;/p&gt;

&lt;p&gt;They remember tricks.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Use the green hole, then skip the ladder, then don't touch the tunnel unless staging was reset."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is not architecture.&lt;/p&gt;

&lt;p&gt;That is folklore with deployment access.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Map Starts Lying
&lt;/h2&gt;

&lt;p&gt;The walls are still there.&lt;/p&gt;

&lt;p&gt;The corridors still exist.&lt;/p&gt;

&lt;p&gt;The official path still looks normal.&lt;/p&gt;

&lt;p&gt;But the real movement happens underground.&lt;/p&gt;

&lt;p&gt;The map says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Walk from A to B."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The system says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Actually, we jump from A to Q through a hidden tunnel depending on what happened earlier."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Congratulations.&lt;/p&gt;

&lt;p&gt;Your code has two architectures now.&lt;/p&gt;

&lt;p&gt;The visible one.&lt;/p&gt;

&lt;p&gt;And the real one.&lt;/p&gt;

&lt;p&gt;Guess which one breaks production.&lt;/p&gt;
&lt;h2&gt;
  
  
  This Is Where Bugs Become Archaeology
&lt;/h2&gt;

&lt;p&gt;A user lands in the wrong room.&lt;/p&gt;

&lt;p&gt;The corridor says impossible.&lt;/p&gt;

&lt;p&gt;The wall says impossible.&lt;/p&gt;

&lt;p&gt;The map says impossible.&lt;/p&gt;

&lt;p&gt;But it happened.&lt;/p&gt;

&lt;p&gt;So now you are not debugging the visible path anymore.&lt;/p&gt;

&lt;p&gt;You are inspecting holes.&lt;/p&gt;

&lt;p&gt;Where does this shortcut lead?&lt;br&gt;&lt;br&gt;
Who changed it?&lt;br&gt;&lt;br&gt;
Was it initialized?&lt;br&gt;&lt;br&gt;
Did a previous request mutate it?&lt;br&gt;&lt;br&gt;
Did a test forget to reset it?&lt;br&gt;&lt;br&gt;
Did someone patch it in 2019 and leave the company?&lt;/p&gt;

&lt;p&gt;Beautiful.&lt;/p&gt;

&lt;p&gt;We invented archaeology with syntax.&lt;/p&gt;
&lt;h2&gt;
  
  
  Now Call the Holes Singletons
&lt;/h2&gt;

&lt;p&gt;A Singleton often starts exactly like that first hole.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Database&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks useful.&lt;/p&gt;

&lt;p&gt;No constructor.&lt;br&gt;&lt;br&gt;
No dependency wiring.&lt;br&gt;&lt;br&gt;
No container setup.&lt;br&gt;&lt;br&gt;
No passing objects around like an adult.&lt;/p&gt;

&lt;p&gt;Just grab the thing from anywhere.&lt;/p&gt;

&lt;p&gt;That is the hole in the floor.&lt;/p&gt;

&lt;p&gt;One call is harmless.&lt;/p&gt;

&lt;p&gt;Ten calls are convenient.&lt;/p&gt;

&lt;p&gt;A hundred calls are architecture.&lt;/p&gt;

&lt;p&gt;Bad architecture.&lt;/p&gt;

&lt;p&gt;But architecture.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Code Lies to Your Face
&lt;/h2&gt;

&lt;p&gt;Look at this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="k"&gt;declare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strict_types&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserReportService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/**
     * @return list&amp;lt;array{id: int, email: string}&amp;gt;
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;activeUsers&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Database&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;fetchAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s1"&gt;'SELECT id, email FROM users WHERE active = 1'&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cute.&lt;/p&gt;

&lt;p&gt;Looks dependency-free.&lt;/p&gt;

&lt;p&gt;It is not.&lt;/p&gt;

&lt;p&gt;It depends on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a database connection&lt;/li&gt;
&lt;li&gt;a concrete database wrapper&lt;/li&gt;
&lt;li&gt;global configuration&lt;/li&gt;
&lt;li&gt;initialization order&lt;/li&gt;
&lt;li&gt;hidden mutable state&lt;/li&gt;
&lt;li&gt;whatever the previous code did to &lt;code&gt;Database::instance()&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The constructor says nothing.&lt;/p&gt;

&lt;p&gt;The method signature says nothing.&lt;/p&gt;

&lt;p&gt;The class smiles at you like it is simple.&lt;/p&gt;

&lt;p&gt;It is not simple.&lt;/p&gt;

&lt;p&gt;It is hiding the body under the floorboards.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem Is Not "One Instance"
&lt;/h2&gt;

&lt;p&gt;This is where most Singleton articles become useless.&lt;/p&gt;

&lt;p&gt;They scream:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Singletons are evil!"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Great. Very brave. Very 2009.&lt;/p&gt;

&lt;p&gt;The problem is not automatically that only one instance exists.&lt;/p&gt;

&lt;p&gt;One instance can be fine.&lt;/p&gt;

&lt;p&gt;The real problem is &lt;strong&gt;global reachability&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Any code can grab it.&lt;/p&gt;

&lt;p&gt;Any code can mutate it.&lt;/p&gt;

&lt;p&gt;Any code can depend on it without telling you.&lt;/p&gt;

&lt;p&gt;That destroys locality.&lt;/p&gt;

&lt;p&gt;And locality is the entire game.&lt;/p&gt;

&lt;p&gt;You want to understand this class?&lt;/p&gt;

&lt;p&gt;Too bad.&lt;/p&gt;

&lt;p&gt;You now need to understand the class, the Singleton, the boot order, the test setup, the previous request, and some ancient static method named &lt;code&gt;initLegacyMode()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Enjoy your afternoon.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tell the Truth Instead
&lt;/h2&gt;

&lt;p&gt;This code tells the truth:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="k"&gt;declare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strict_types&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;UserRepository&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/**
     * @return list&amp;lt;array{id: int, email: string}&amp;gt;
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;findActiveUsers&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserReportService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;UserRepository&lt;/span&gt; &lt;span class="nv"&gt;$userRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * @return list&amp;lt;array{id: int, email: string}&amp;gt;
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;activeUsers&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;userRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;findActiveUsers&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we know what the class needs.&lt;/p&gt;

&lt;p&gt;No magic.&lt;/p&gt;

&lt;p&gt;No tunnel.&lt;/p&gt;

&lt;p&gt;No "trust me bro" dependency.&lt;/p&gt;

&lt;p&gt;Tests can pass a fake repository.&lt;/p&gt;

&lt;p&gt;Production can pass the real one.&lt;/p&gt;

&lt;p&gt;The path is visible again.&lt;/p&gt;

&lt;p&gt;That is the point.&lt;/p&gt;

&lt;p&gt;Not purity.&lt;/p&gt;

&lt;p&gt;Visibility.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Singleton Smell Test
&lt;/h2&gt;

&lt;p&gt;A Singleton becomes dangerous when it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;can be called from anywhere&lt;/li&gt;
&lt;li&gt;hides a dependency&lt;/li&gt;
&lt;li&gt;stores mutable state&lt;/li&gt;
&lt;li&gt;changes after initialization&lt;/li&gt;
&lt;li&gt;depends on the current request&lt;/li&gt;
&lt;li&gt;depends on the current user&lt;/li&gt;
&lt;li&gt;depends on the current tenant&lt;/li&gt;
&lt;li&gt;needs reset methods in tests&lt;/li&gt;
&lt;li&gt;makes behavior depend on call order&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last one is the killer.&lt;/p&gt;

&lt;p&gt;Because now your code is no longer just code.&lt;/p&gt;

&lt;p&gt;It is a ritual.&lt;/p&gt;

&lt;p&gt;Call this first.&lt;br&gt;&lt;br&gt;
Then this.&lt;br&gt;&lt;br&gt;
Never that.&lt;br&gt;&lt;br&gt;
Unless CLI.&lt;br&gt;&lt;br&gt;
Unless tests.&lt;br&gt;&lt;br&gt;
Unless worker mode.&lt;br&gt;&lt;br&gt;
Unless Tuesday.&lt;/p&gt;

&lt;p&gt;This is not engineering.&lt;/p&gt;

&lt;p&gt;This is software necromancy.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Worst Singletons
&lt;/h2&gt;

&lt;p&gt;Some Singletons are merely annoying.&lt;/p&gt;

&lt;p&gt;A global formatter? Bad smell.&lt;/p&gt;

&lt;p&gt;A global database? Worse.&lt;/p&gt;

&lt;p&gt;A global current user?&lt;/p&gt;

&lt;p&gt;Now we are cooking garbage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;CurrentUser&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;TenantContext&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;tenantId&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;RequestContext&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is how request-specific state leaks into business logic.&lt;/p&gt;

&lt;p&gt;Now your domain code secretly knows about HTTP.&lt;/p&gt;

&lt;p&gt;Your CLI command needs a fake user.&lt;/p&gt;

&lt;p&gt;Your queue worker leaks tenant state.&lt;/p&gt;

&lt;p&gt;Your tests need global cleanup.&lt;/p&gt;

&lt;p&gt;Your production bugs depend on what happened before.&lt;/p&gt;

&lt;p&gt;Amazing.&lt;/p&gt;

&lt;p&gt;You saved one constructor argument and bought yourself a haunted house.&lt;/p&gt;

&lt;h2&gt;
  
  
  But Shared Instances Are Not Evil
&lt;/h2&gt;

&lt;p&gt;Do not be childish about this.&lt;/p&gt;

&lt;p&gt;A shared instance can be fine.&lt;/p&gt;

&lt;p&gt;This is fine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="k"&gt;declare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strict_types&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppConfig&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/**
     * @param non-empty-string $environment
     * @param non-empty-string $databaseDsn
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$environment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$databaseDsn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One config object per application boot?&lt;/p&gt;

&lt;p&gt;Fine.&lt;/p&gt;

&lt;p&gt;It is immutable.&lt;br&gt;&lt;br&gt;
It is lifecycle-owned.&lt;br&gt;&lt;br&gt;
It does not depend on the current user.&lt;br&gt;&lt;br&gt;
It does not remember the last request.&lt;br&gt;&lt;br&gt;
It does not mutate because someone opened another browser tab.&lt;/p&gt;

&lt;p&gt;That is not a trapdoor.&lt;/p&gt;

&lt;p&gt;That is a signpost.&lt;/p&gt;
&lt;h2&gt;
  
  
  Containers Are Not the Same Thing
&lt;/h2&gt;

&lt;p&gt;A dependency injection container may reuse one service instance.&lt;/p&gt;

&lt;p&gt;That does not make it the same mess.&lt;/p&gt;

&lt;p&gt;This is fine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="k"&gt;declare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strict_types&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Mailer&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;Transport&lt;/span&gt; &lt;span class="nv"&gt;$transport&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The container may share &lt;code&gt;Mailer&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Who cares?&lt;/p&gt;

&lt;p&gt;The class does not provide global access to itself.&lt;/p&gt;

&lt;p&gt;The dependency is still visible.&lt;/p&gt;

&lt;p&gt;Compare that with this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Mailer&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first version says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"This object needs a mailer."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The second says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"There is a hole in the floor. Jump."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Rule
&lt;/h2&gt;

&lt;p&gt;Before adding global access, ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Would this still be correct if two users, two tenants, two jobs, or two tests touched it at the same time?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If not, stop.&lt;/p&gt;

&lt;p&gt;Then ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Does passing this dependency explicitly actually make the code worse?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Usually, no.&lt;/p&gt;

&lt;p&gt;It just makes the truth visible.&lt;/p&gt;

&lt;p&gt;And developers hate visible complexity because it ruins the fantasy that the system is simple.&lt;/p&gt;

&lt;p&gt;Bad news:&lt;/p&gt;

&lt;p&gt;The complexity was already there.&lt;/p&gt;

&lt;p&gt;You just hid it under &lt;code&gt;::instance()&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Legacy Code: Do Not Start a War
&lt;/h2&gt;

&lt;p&gt;If your codebase already has Singletons, do not run through the office yelling about global state.&lt;/p&gt;

&lt;p&gt;Nobody cares.&lt;/p&gt;

&lt;p&gt;Also, you will lose.&lt;/p&gt;

&lt;p&gt;Start smaller.&lt;/p&gt;

&lt;p&gt;Stop adding new holes.&lt;/p&gt;

&lt;p&gt;Move old Singleton access toward the edges.&lt;/p&gt;

&lt;p&gt;Keep infrastructure dirty if needed.&lt;/p&gt;

&lt;p&gt;Keep new domain code clean.&lt;/p&gt;

&lt;p&gt;This:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="k"&gt;declare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strict_types&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;InvoiceService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;InvoiceRepository&lt;/span&gt; &lt;span class="nv"&gt;$invoiceRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;Clock&lt;/span&gt; &lt;span class="nv"&gt;$clock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="k"&gt;declare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strict_types&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;InvoiceService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;createInvoice&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Clock&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nv"&gt;$database&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Database&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first has corridors.&lt;/p&gt;

&lt;p&gt;The second has trapdoors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Refactor Like a Mechanic, Not a Prophet
&lt;/h2&gt;

&lt;p&gt;Do not rewrite everything.&lt;/p&gt;

&lt;p&gt;Do not "fix the architecture" in one heroic pull request.&lt;/p&gt;

&lt;p&gt;That is how teams create new disasters with better naming.&lt;/p&gt;

&lt;p&gt;Wrap the old mess.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="k"&gt;declare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strict_types&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Clock&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;DateTimeImmutable&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LegacyClockAdapter&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Clock&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;DateTimeImmutable&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;LegacyClock&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now new code depends on &lt;code&gt;Clock&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Old code can keep limping along.&lt;/p&gt;

&lt;p&gt;You built a corridor around the trapdoor.&lt;/p&gt;

&lt;p&gt;That is progress.&lt;/p&gt;

&lt;p&gt;Not glamorous.&lt;/p&gt;

&lt;p&gt;Useful.&lt;/p&gt;

&lt;p&gt;The best kind.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Lesson
&lt;/h2&gt;

&lt;p&gt;A Singleton is not bad because it creates one object.&lt;/p&gt;

&lt;p&gt;A Singleton is bad because it often creates hidden paths.&lt;/p&gt;

&lt;p&gt;One controlled shortcut can help.&lt;/p&gt;

&lt;p&gt;A labyrinth full of shortcuts becomes impossible to reason about.&lt;/p&gt;

&lt;p&gt;The code still runs.&lt;/p&gt;

&lt;p&gt;But nobody can explain why.&lt;/p&gt;

&lt;p&gt;And when nobody can explain why, every change becomes risky.&lt;/p&gt;

&lt;p&gt;That is the cost.&lt;/p&gt;

&lt;p&gt;Not the pattern.&lt;/p&gt;

&lt;p&gt;Not the theory.&lt;/p&gt;

&lt;p&gt;The lost map.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Singletons are not automatically evil.&lt;/p&gt;

&lt;p&gt;Hidden global access is the real problem.&lt;/p&gt;

&lt;p&gt;A shared immutable object can be fine.&lt;/p&gt;

&lt;p&gt;A globally reachable mutable dependency is usually a trap.&lt;/p&gt;

&lt;p&gt;The question is not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Is this a Singleton?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Does this keep the map honest?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If not, fill the hole.&lt;/p&gt;

&lt;p&gt;No new trapdoors.&lt;/p&gt;

&lt;p&gt;Visible dependencies.&lt;/p&gt;

&lt;p&gt;Boring code.&lt;/p&gt;

&lt;p&gt;Maintainable software.&lt;/p&gt;

&lt;p&gt;That is the exit.&lt;/p&gt;

</description>
      <category>php</category>
      <category>architecture</category>
      <category>refactoring</category>
      <category>singleton</category>
    </item>
    <item>
      <title>Stop Writing Architecture Rules in Confluence</title>
      <dc:creator>Lars Moelleken</dc:creator>
      <pubDate>Fri, 15 May 2026 03:33:56 +0000</pubDate>
      <link>https://dev.to/suckup_de/stop-writing-architecture-rules-in-confluence-4bn2</link>
      <guid>https://dev.to/suckup_de/stop-writing-architecture-rules-in-confluence-4bn2</guid>
      <description>&lt;p&gt;Implementation of the idea of the blog post: &lt;br&gt;
&lt;a href="https://github.com/voku/itp-context/" rel="noopener noreferrer"&gt;https://github.com/voku/itp-context/&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Use PHP attributes when the rule belongs to the code
&lt;/h3&gt;

&lt;p&gt;Every serious codebase has rules.&lt;/p&gt;

&lt;p&gt;Not formatting rules. Those are easy. Let PHP-CS-Fixer, PHP_CodeSniffer, Rector, PHPStan, and your IDE handle that part.&lt;/p&gt;

&lt;p&gt;I mean the rules that decide whether the system survives:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;external APIs stay behind adapters&lt;/li&gt;
&lt;li&gt;domain code does not know HTTP clients&lt;/li&gt;
&lt;li&gt;persistence goes through repositories&lt;/li&gt;
&lt;li&gt;legacy compatibility stays isolated&lt;/li&gt;
&lt;li&gt;security validation happens before data crosses a boundary&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These rules exist.&lt;/p&gt;

&lt;p&gt;The problem is where they live.&lt;/p&gt;

&lt;p&gt;Usually, they live in someone’s head, an old ticket, a forgotten ADR, or a Confluence page that looks official and is already wrong.&lt;/p&gt;

&lt;p&gt;That is documentation theater.&lt;/p&gt;

&lt;p&gt;Everyone pretends the architecture is documented. Then someone changes the wrong class, bypasses the wrong boundary, and the team suddenly remembers:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“We agreed not to do it like that.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Great.&lt;/p&gt;

&lt;p&gt;Where?&lt;/p&gt;

&lt;p&gt;Page 37 of the knowledge base.&lt;/p&gt;

&lt;p&gt;Very useful. Very dead.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;voku/itp-context&lt;/code&gt; solves a narrow problem: attach architecture rules to code with PHP attributes and resolve the rule definition directly from typed enums.&lt;/p&gt;

&lt;p&gt;Not magic.&lt;/p&gt;

&lt;p&gt;Just better placement.&lt;/p&gt;


&lt;h3&gt;
  
  
  Detached rules rot
&lt;/h3&gt;

&lt;p&gt;Documentation that lives away from the code has one fatal flaw:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It does not fail.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It does not fail builds.&lt;/li&gt;
&lt;li&gt;It does not appear in diffs.&lt;/li&gt;
&lt;li&gt;It does not stop a refactor.&lt;/li&gt;
&lt;li&gt;It does not warn a coding agent before it crosses a boundary.&lt;/li&gt;
&lt;li&gt;It waits somewhere else, slowly becoming archaeology.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is fine for old pottery.&lt;/p&gt;

&lt;p&gt;It is not fine when you need to know whether &lt;code&gt;PaymentGateway&lt;/code&gt; is allowed to leak HTTP exceptions into your domain layer.&lt;/p&gt;

&lt;p&gt;Architecture rules need two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Proximity&lt;/strong&gt; — the rule must be near the risky code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Identity&lt;/strong&gt; — the rule must have a stable name tools can resolve.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A PHP attribute pointing to an enum case gives you both.&lt;/p&gt;

&lt;p&gt;The model is simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;code symbol
    -&amp;gt; enum case
        -&amp;gt; getDefinition()
            -&amp;gt; statement / owner / rationale / refs / proof
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The enum case is the rule identity.&lt;/p&gt;

&lt;p&gt;The enum method is the rule definition.&lt;/p&gt;

&lt;p&gt;That is the whole trick.&lt;/p&gt;




&lt;h3&gt;
  
  
  One boundary, one rule
&lt;/h3&gt;

&lt;p&gt;Do not mix topics in examples.&lt;/p&gt;

&lt;p&gt;If the rule is about an external API boundary, keep the example about that boundary.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="k"&gt;declare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strict_types&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;Acme\Context&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Acme\Tests\Architecture\ExternalApiBoundaryTest&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;ItpContext\Contract\RuleIdentifier&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;ItpContext\Enum\Tier&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;ItpContext\Model\RuleDef&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;ArchitectureRules&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;RuleIdentifier&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;ExternalApiBoundary&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getDefinition&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;RuleDef&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nc"&gt;ExternalApiBoundary&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RuleDef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;statement&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Keep external API communication behind adapter boundaries.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;tier&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Tier&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nc"&gt;Required&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Team-Backend'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;rationale&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Domain and application code must not depend on HTTP clients, transport errors, or provider-specific response formats.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;verifiedBy&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                    &lt;span class="nc"&gt;ExternalApiBoundaryTest&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;],&lt;/span&gt;
                &lt;span class="n"&gt;refs&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                    &lt;span class="s1"&gt;'docs/adr/external-api-boundaries.md'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is enough.&lt;/p&gt;

&lt;p&gt;The rule has a typed identity:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;ArchitectureRules&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nc"&gt;ExternalApiBoundary&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The rule has a definition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nc"&gt;ExternalApiBoundary&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RuleDef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The rule has ownership, rationale, references, and proof.&lt;/p&gt;

&lt;p&gt;No stringly-typed sadness.&lt;/p&gt;

&lt;p&gt;No floating wiki paragraph.&lt;/p&gt;

&lt;p&gt;No “ask Frank, he knows why this exists.”&lt;/p&gt;

&lt;p&gt;The rule is project data.&lt;/p&gt;




&lt;h3&gt;
  
  
  The code marks the boundary
&lt;/h3&gt;

&lt;p&gt;The annotation belongs on the central symbol.&lt;/p&gt;

&lt;p&gt;Not every implementation.&lt;/p&gt;

&lt;p&gt;Not every method.&lt;/p&gt;

&lt;p&gt;The boundary.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="k"&gt;declare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strict_types&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;Acme\Payment&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Acme\Context\ArchitectureRules&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;ItpContext\Attribute\Rule&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="na"&gt;#[Rule(ArchitectureRules::ExternalApiBoundary)]&lt;/span&gt;
&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;PaymentGateway&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;authorize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;PaymentRequest&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;PaymentResult&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is the right place.&lt;/p&gt;

&lt;p&gt;A developer changing payment integration code should find this.&lt;/p&gt;

&lt;p&gt;A coding agent changing payment integration code should find this.&lt;/p&gt;

&lt;p&gt;A reviewer should see it and know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;provider-specific responses stay outside&lt;/li&gt;
&lt;li&gt;HTTP exceptions do not leak into domain code&lt;/li&gt;
&lt;li&gt;retries and logging belong near the adapter&lt;/li&gt;
&lt;li&gt;error translation happens at the boundary&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One rule.&lt;/p&gt;

&lt;p&gt;One boundary.&lt;/p&gt;

&lt;p&gt;One clear example.&lt;/p&gt;

&lt;p&gt;No UI.&lt;/p&gt;

&lt;p&gt;No translation.&lt;/p&gt;

&lt;p&gt;No unrelated method-level noise.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why enums are the right home
&lt;/h2&gt;

&lt;p&gt;Strings are a trap.&lt;/p&gt;

&lt;p&gt;They always are.&lt;/p&gt;

&lt;p&gt;This is fragile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="na"&gt;#[Rule('external-api-boundary')]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because sooner or later, someone writes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="na"&gt;#[Rule('ExternalApiBoundary')]&lt;/span&gt;
&lt;span class="na"&gt;#[Rule('external_api_boundary')]&lt;/span&gt;
&lt;span class="na"&gt;#[Rule('ExternlApiBoundary')]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congratulations.&lt;/p&gt;

&lt;p&gt;You now have fake metadata.&lt;/p&gt;

&lt;p&gt;Architecture rule identifiers should be symbols:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="na"&gt;#[Rule(ArchitectureRules::ExternalApiBoundary)]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the IDE can autocomplete.&lt;/p&gt;

&lt;p&gt;Static analysis can see it.&lt;/p&gt;

&lt;p&gt;Refactoring tools can rename it.&lt;/p&gt;

&lt;p&gt;Typos become errors.&lt;/p&gt;

&lt;p&gt;That matters because an architecture rule is not text.&lt;/p&gt;

&lt;p&gt;It is code-level context.&lt;/p&gt;

&lt;p&gt;So model it like code.&lt;/p&gt;




&lt;h3&gt;
  
  
  The definition belongs to the enum
&lt;/h3&gt;

&lt;p&gt;The enum should not only name the rule.&lt;/p&gt;

&lt;p&gt;It should explain it.&lt;/p&gt;

&lt;p&gt;That is what &lt;code&gt;getDefinition()&lt;/code&gt; is for.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getDefinition&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;RuleDef&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nc"&gt;ExternalApiBoundary&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RuleDef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;statement&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Keep external API communication behind adapter boundaries.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;tier&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Tier&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nc"&gt;Required&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Team-Backend'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;rationale&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Domain and application code must not depend on HTTP clients, transport errors, or provider-specific response formats.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;verifiedBy&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="nc"&gt;ExternalApiBoundaryTest&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="n"&gt;refs&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="s1"&gt;'docs/adr/external-api-boundaries.md'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That keeps the architecture identity and its meaning together.&lt;/p&gt;

&lt;p&gt;Good.&lt;/p&gt;

&lt;p&gt;Fewer moving parts.&lt;/p&gt;

&lt;p&gt;Fewer places for rules to rot.&lt;/p&gt;

&lt;p&gt;Fewer chances to pretend the documentation is still true.&lt;/p&gt;

&lt;p&gt;The rule definition should answer five boring questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is the rule?&lt;/li&gt;
&lt;li&gt;How important is it?&lt;/li&gt;
&lt;li&gt;Who owns it?&lt;/li&gt;
&lt;li&gt;Why does it exist?&lt;/li&gt;
&lt;li&gt;What proves or explains it?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Boring questions prevent expensive confusion.&lt;/p&gt;




&lt;h3&gt;
  
  
  Validation makes it real
&lt;/h3&gt;

&lt;p&gt;Metadata without validation is decoration.&lt;/p&gt;

&lt;p&gt;Decoration is where architecture goes to die wearing a nice badge.&lt;/p&gt;

&lt;p&gt;Run validation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vendor/bin/itp-context-validate &lt;span class="s1"&gt;'Acme\Context\ArchitectureRules'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important question is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Does every enum case expose a usable &lt;code&gt;RuleDef&lt;/code&gt;?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Put that into CI.&lt;/p&gt;

&lt;p&gt;Do not trust humans to keep metadata clean manually.&lt;/p&gt;

&lt;p&gt;Humans forget.&lt;/p&gt;

&lt;p&gt;CI does not care about your feelings.&lt;/p&gt;

&lt;p&gt;Good.&lt;/p&gt;




&lt;h2&gt;
  
  
  Export makes it usable
&lt;/h2&gt;

&lt;p&gt;Once the rule is attached to code, it can be exported.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vendor/bin/itp-context-export var/itp-context src &lt;span class="nt"&gt;--exclude&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;vendor &lt;span class="nt"&gt;--exclude&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;tests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A compact exported context document can look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Acme\Payment\PaymentGateway&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PaymentGateway&lt;/span&gt;
&lt;span class="na"&gt;source_path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;src/Payment/PaymentGateway.php&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;interface&lt;/span&gt;
&lt;span class="na"&gt;rule_ids&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Acme\Context\ArchitectureRules::ExternalApiBoundary&lt;/span&gt;
&lt;span class="na"&gt;owners&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Team-Backend&lt;/span&gt;
&lt;span class="na"&gt;refs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docs/adr/external-api-boundaries.md&lt;/span&gt;
&lt;span class="na"&gt;verified_by&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Acme\Tests\Architecture\ExternalApiBoundaryTest&lt;/span&gt;
&lt;span class="na"&gt;annotated_methods&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;
&lt;span class="na"&gt;rule_count&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is useful context.&lt;/p&gt;

&lt;p&gt;Small.&lt;/p&gt;

&lt;p&gt;Searchable.&lt;/p&gt;

&lt;p&gt;Owned by the repository.&lt;/p&gt;

&lt;p&gt;Not buried in a wiki swamp.&lt;/p&gt;

&lt;p&gt;Instead of writing this into an agent instruction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Please follow our architecture.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Write this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Before changing payment integration code, inspect the exported itp-context entry for Acme\Payment\PaymentGateway. Respect the ExternalApiBoundary rule and check its referenced proof artifacts.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is better because it points to repository-owned data.&lt;/p&gt;

&lt;p&gt;The prompt is not the architecture.&lt;/p&gt;

&lt;p&gt;The repository is.&lt;/p&gt;

&lt;p&gt;The prompt only tells the agent where to look.&lt;/p&gt;




&lt;h3&gt;
  
  
  Querying beats asking Frank
&lt;/h3&gt;

&lt;p&gt;Once context is exported, it can be queried.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vendor/bin/itp-context-query var/itp-context &lt;span class="nt"&gt;--rule-id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Acme\Context\ArchitectureRules::ExternalApiBoundary'&lt;/span&gt;

vendor/bin/itp-context-query var/itp-context &lt;span class="nt"&gt;--owner&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Team-Backend'&lt;/span&gt;

vendor/bin/itp-context-query var/itp-context &lt;span class="nt"&gt;--text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'external api'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This matters.&lt;/p&gt;

&lt;p&gt;Architecture knowledge should not require asking the one person who remembers why the adapter exists.&lt;/p&gt;

&lt;p&gt;That person may be in a meeting.&lt;/p&gt;

&lt;p&gt;Or on vacation.&lt;/p&gt;

&lt;p&gt;Or gone.&lt;/p&gt;

&lt;p&gt;Or worse: still here, but tired of explaining the same boundary for the eighth time this month.&lt;/p&gt;

&lt;p&gt;Make the repository answer.&lt;/p&gt;




&lt;h3&gt;
  
  
  Where annotations belong
&lt;/h3&gt;

&lt;p&gt;Annotate central discovery points.&lt;/p&gt;

&lt;p&gt;Not the whole tree.&lt;/p&gt;

&lt;p&gt;Good places:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;boundary interfaces&lt;/li&gt;
&lt;li&gt;adapter base classes&lt;/li&gt;
&lt;li&gt;application service roots&lt;/li&gt;
&lt;li&gt;persistence contracts&lt;/li&gt;
&lt;li&gt;legacy compatibility seams&lt;/li&gt;
&lt;li&gt;security input boundaries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bad places:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;every concrete class&lt;/li&gt;
&lt;li&gt;every method&lt;/li&gt;
&lt;li&gt;every helper&lt;/li&gt;
&lt;li&gt;every place where somebody felt nervous&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If every class is annotated, nothing is important.&lt;/p&gt;

&lt;p&gt;That is not architecture.&lt;/p&gt;

&lt;p&gt;That is Confluence with PHP syntax.&lt;/p&gt;




&lt;h3&gt;
  
  
  The generator should create useful scaffolding
&lt;/h3&gt;

&lt;p&gt;The generator should help you start a rule without turning the project into paperwork.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vendor/bin/itp-context-generate Architecture ExternalApiBoundary src/Context Acme&lt;span class="se"&gt;\\&lt;/span&gt;Context
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That creates or extends the rule enum:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/Context/ArchitectureRules.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The generated placeholder should force the right questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is the statement?&lt;/li&gt;
&lt;li&gt;Who owns it?&lt;/li&gt;
&lt;li&gt;Why does it exist?&lt;/li&gt;
&lt;li&gt;What verifies it?&lt;/li&gt;
&lt;li&gt;Where can I read more?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is useful scaffolding.&lt;/p&gt;

&lt;p&gt;Not ceremony.&lt;/p&gt;




&lt;h3&gt;
  
  
  What this is not
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;This is not a replacement for ADRs.&lt;/li&gt;
&lt;li&gt;It is not a replacement for tests.&lt;/li&gt;
&lt;li&gt;It is not a replacement for PHPStan.&lt;/li&gt;
&lt;li&gt;It is not a replacement for code review.&lt;/li&gt;
&lt;li&gt;It is not an AI framework.&lt;/li&gt;
&lt;li&gt;It is not going to fix bad architecture by sprinkling attributes on top like holy water.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It does one useful thing:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It connects architecture rules to the code symbols where those rules matter.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That is enough.&lt;/p&gt;

&lt;p&gt;Small tools are allowed to be useful without pretending to solve the universe.&lt;/p&gt;




&lt;h3&gt;
  
  
  Best practices
&lt;/h3&gt;

&lt;p&gt;Use &lt;code&gt;itp-context&lt;/code&gt; like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;define broad rules&lt;/li&gt;
&lt;li&gt;use enum cases as rule identifiers&lt;/li&gt;
&lt;li&gt;put &lt;code&gt;RuleDef&lt;/code&gt; metadata into &lt;code&gt;getDefinition()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;keep attributes small&lt;/li&gt;
&lt;li&gt;annotate central symbols only&lt;/li&gt;
&lt;li&gt;add owners and rationale&lt;/li&gt;
&lt;li&gt;link ADRs, tests, docs, and proof artifacts&lt;/li&gt;
&lt;li&gt;validate enum definitions in CI&lt;/li&gt;
&lt;li&gt;export compact context&lt;/li&gt;
&lt;li&gt;query exported context when changing boundaries&lt;/li&gt;
&lt;li&gt;delete rules that do not change decisions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The last point matters.&lt;/p&gt;

&lt;p&gt;A small rule enum people trust beats a huge rule enum everyone ignores.&lt;/p&gt;

&lt;p&gt;Every time.&lt;/p&gt;




&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;The problem is not Confluence.&lt;/p&gt;

&lt;p&gt;The problem is architecture knowledge living somewhere else.&lt;/p&gt;

&lt;p&gt;If a rule affects code, connect it to code.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;voku/itp-context&lt;/code&gt; gives you a pragmatic way to do that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PHP attributes attach rules to code symbols&lt;/li&gt;
&lt;li&gt;enum cases give rules stable identities&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;getDefinition()&lt;/code&gt; keeps the rule definition beside the identity&lt;/li&gt;
&lt;li&gt;validation checks whether enum cases expose usable definitions&lt;/li&gt;
&lt;li&gt;exports make context usable for humans and coding agents&lt;/li&gt;
&lt;li&gt;queries make architecture searchable instead of tribal&lt;/li&gt;
&lt;li&gt;the generator creates rule enums with useful placeholders&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not about making PHP “AI-native.”&lt;/p&gt;

&lt;p&gt;Good.&lt;/p&gt;

&lt;p&gt;That phrase already smells like a conference booth.&lt;/p&gt;

&lt;p&gt;The better goal is simpler:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Make architecture rules explicit enough that humans and tools can find them before they break them.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because the real enemy was never the LLM.&lt;/p&gt;

&lt;p&gt;The real enemy was architecture knowledge living somewhere else.&lt;/p&gt;

&lt;p&gt;Usually in Confluence.&lt;/p&gt;

&lt;p&gt;Beautiful, confident, and wrong.&lt;/p&gt;

&lt;p&gt;Happy coding. 😊 &lt;/p&gt;

</description>
      <category>php</category>
      <category>architecture</category>
      <category>llm</category>
      <category>agents</category>
    </item>
    <item>
      <title>Coding With Kids: From Paper Sketch to Playable Game</title>
      <dc:creator>Lars Moelleken</dc:creator>
      <pubDate>Mon, 16 Feb 2026 06:18:39 +0000</pubDate>
      <link>https://dev.to/suckup_de/coding-with-kids-from-paper-sketch-to-playable-game-49cm</link>
      <guid>https://dev.to/suckup_de/coding-with-kids-from-paper-sketch-to-playable-game-49cm</guid>
      <description>&lt;p&gt;The Process (Exactly as It Happened)&lt;/p&gt;

&lt;p&gt;We didn’t start with code.&lt;/p&gt;

&lt;p&gt;We started with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A4 paper&lt;/li&gt;
&lt;li&gt;Pens&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;“What do you like right now?”&lt;/p&gt;

&lt;p&gt;That week the answers were obvious:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Minecraft&lt;/li&gt;
&lt;li&gt;Harry Potter&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So we wrote a big headline at the top of the page and added 3–4 tiny mini-games.&lt;/p&gt;

&lt;p&gt;Bad drawings.&lt;br&gt;
Crooked arrows.&lt;br&gt;
TNT blocks.&lt;br&gt;
Potion labs.&lt;/p&gt;

&lt;p&gt;Perfect.&lt;/p&gt;




&lt;p&gt;Step 1: Let Them Design&lt;/p&gt;

&lt;p&gt;They decide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What happens in a round&lt;/li&gt;
&lt;li&gt;How you win&lt;/li&gt;
&lt;li&gt;What’s unfair&lt;/li&gt;
&lt;li&gt;What’s cool&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You just ask questions.&lt;/p&gt;

&lt;p&gt;No over-engineering. No “architecture discussion.”&lt;/p&gt;




&lt;p&gt;Step 2: Turn It Into Rules&lt;/p&gt;

&lt;p&gt;We took a photo and used Google AI Studio&lt;br&gt;
👉 &lt;a href="https://aistudio.google.com/" rel="noopener noreferrer"&gt;https://aistudio.google.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Base prompt:&lt;/p&gt;

&lt;p&gt;"Create a game based on our drawing for two players aged 8–10 years." &lt;/p&gt;

&lt;p&gt;Optional:&lt;br&gt;
"Please provide clear rules, round sequence, scoring and victory conditions." &lt;/p&gt;

&lt;p&gt;Now the messy sketch becomes a structured game.&lt;/p&gt;

&lt;p&gt;Not because AI is magical.&lt;/p&gt;

&lt;p&gt;Because it forces clarity.&lt;/p&gt;




&lt;p&gt;Step 3: Make It Playable on Tablet&lt;/p&gt;

&lt;p&gt;Then we refined it with the kids:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bigger buttons&lt;/li&gt;
&lt;li&gt;Clear rounds&lt;/li&gt;
&lt;li&gt;One screen per action&lt;/li&gt;
&lt;li&gt;Simple scoring&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They tested it.&lt;br&gt;
They complained.&lt;br&gt;
We adjusted.&lt;/p&gt;

&lt;p&gt;That’s product iteration. At age 8.&lt;/p&gt;




&lt;p&gt;Two Real Results&lt;/p&gt;

&lt;p&gt;No theory. Actual repos:&lt;/p&gt;

&lt;p&gt;🟩 Minecraft version:&lt;br&gt;
&lt;a href="https://github.com/voku/Minecraft_Game/" rel="noopener noreferrer"&gt;https://github.com/voku/Minecraft_Game/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🧙 Hogwarts version:&lt;br&gt;
&lt;a href="https://github.com/voku/Hogwarts_Game" rel="noopener noreferrer"&gt;https://github.com/voku/Hogwarts_Game&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;They started as messy A4 sketches.&lt;/p&gt;




&lt;p&gt;Why This Works&lt;/p&gt;

&lt;p&gt;Kids don’t struggle with imagination.&lt;/p&gt;

&lt;p&gt;They struggle with structure.&lt;/p&gt;

&lt;p&gt;AI helps with structure.&lt;br&gt;
Paper protects imagination.&lt;/p&gt;

&lt;p&gt;That combination is powerful.&lt;/p&gt;




&lt;p&gt;The Only Rule That Matters&lt;/p&gt;

&lt;p&gt;Let the kids:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Draw first&lt;/li&gt;
&lt;li&gt;Decide first&lt;/li&gt;
&lt;li&gt;Argue about fairness&lt;/li&gt;
&lt;li&gt;Change rules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You’re not building a game.&lt;/p&gt;

&lt;p&gt;You’re building thinking.&lt;/p&gt;

&lt;p&gt;And honestly?&lt;/p&gt;

&lt;p&gt;Watching them debug their own rules is better than most sprint reviews.&lt;/p&gt;

</description>
      <category>kids</category>
      <category>creativity</category>
      <category>ai</category>
      <category>coding</category>
    </item>
    <item>
      <title>PHP Top Salaries, 100% Remote – Surviving the AI Compression Era</title>
      <dc:creator>Lars Moelleken</dc:creator>
      <pubDate>Sun, 15 Feb 2026 23:45:04 +0000</pubDate>
      <link>https://dev.to/suckup_de/php-top-salaries-100-remote-surviving-the-ai-compression-era-5df0</link>
      <guid>https://dev.to/suckup_de/php-top-salaries-100-remote-surviving-the-ai-compression-era-5df0</guid>
      <description>&lt;p&gt;#blogPostAsWebApp: &lt;a href="https://voku.github.io/LinkedOut/" rel="noopener noreferrer"&gt;https://voku.github.io/LinkedOut/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction: The Carpenter and the Nail Gun
&lt;/h2&gt;

&lt;p&gt;Imagine two carpenters.&lt;/p&gt;

&lt;p&gt;One measures, plans, understands load distribution, humidity, long-term material behavior.&lt;br&gt;
The other is very, very fast with a nail gun.&lt;/p&gt;

&lt;p&gt;Now someone invents a nail gun that shoots 10x faster and never gets tired.&lt;/p&gt;

&lt;p&gt;Who is in danger?&lt;/p&gt;

&lt;p&gt;Not the carpenter.&lt;br&gt;
The nail gun operator.&lt;/p&gt;

&lt;p&gt;That’s exactly where large language models have landed in our industry.&lt;/p&gt;

&lt;p&gt;And yes — this absolutely affects PHP, remote jobs, and top salaries.&lt;/p&gt;

&lt;p&gt;Let’s remove the mysticism and talk about structure, economics, and responsibility.&lt;/p&gt;


&lt;h2&gt;
  
  
  Background: We’ve Seen This Movie Before
&lt;/h2&gt;

&lt;p&gt;The panic isn’t loud. It’s subtle.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“AI Engineer”&lt;/li&gt;
&lt;li&gt;“LLM Architect”&lt;/li&gt;
&lt;li&gt;“AI-First Developer”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yesterday: TYPO3 integrator.&lt;br&gt;
Today: AI systems builder.&lt;/p&gt;

&lt;p&gt;But we’ve seen this dynamic before:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When frameworks replaced manual routing.&lt;/li&gt;
&lt;li&gt;When ORMs replaced handwritten SQL.&lt;/li&gt;
&lt;li&gt;When CI/CD replaced FTP deployments.&lt;/li&gt;
&lt;li&gt;When static analysis replaced “it works on my machine.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every time, the market compressed mechanical work and rewarded structural thinking.&lt;/p&gt;

&lt;p&gt;If you’ve worked long enough in legacy systems, you know this already: tools don’t save you — structure does.&lt;/p&gt;

&lt;p&gt;AI is just another compression tool.&lt;/p&gt;

&lt;p&gt;But this one is extremely good at pattern instantiation.&lt;/p&gt;


&lt;h2&gt;
  
  
  1. Remove the Mysticism: What LLMs Actually Are
&lt;/h2&gt;

&lt;p&gt;LLMs are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Probabilistic language models&lt;/li&gt;
&lt;li&gt;Pattern reproduction engines&lt;/li&gt;
&lt;li&gt;Context compressors&lt;/li&gt;
&lt;li&gt;Next-token predictors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They are not:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Architects&lt;/li&gt;
&lt;li&gt;System designers&lt;/li&gt;
&lt;li&gt;Domain experts&lt;/li&gt;
&lt;li&gt;Responsible entities&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They don’t understand your business invariants.&lt;br&gt;
They don’t reason about financial risk.&lt;br&gt;
They don’t carry production liability.&lt;/p&gt;

&lt;p&gt;They produce plausibility.&lt;/p&gt;

&lt;p&gt;And plausibility is often good enough — for boilerplate.&lt;/p&gt;


&lt;h2&gt;
  
  
  2. The Uncomfortable Truth: They Are Good Enough
&lt;/h2&gt;

&lt;p&gt;LLMs are extremely good at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CRUD scaffolding&lt;/li&gt;
&lt;li&gt;DTO generation&lt;/li&gt;
&lt;li&gt;Test templates&lt;/li&gt;
&lt;li&gt;API wrappers&lt;/li&gt;
&lt;li&gt;Refactoring noise&lt;/li&gt;
&lt;li&gt;Documentation synthesis&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And let’s be brutally honest:&lt;/p&gt;

&lt;p&gt;A large percentage of web development is pattern repetition.&lt;/p&gt;

&lt;p&gt;Not distributed consensus.&lt;br&gt;
Not formal modeling.&lt;br&gt;
Not deep domain design.&lt;/p&gt;

&lt;p&gt;Pattern instantiation.&lt;/p&gt;

&lt;p&gt;If your value was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Assembling plugins&lt;/li&gt;
&lt;li&gt;Copy-adapting controllers&lt;/li&gt;
&lt;li&gt;Wiring framework defaults&lt;/li&gt;
&lt;li&gt;Repeating known structures&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then yes — LLMs are competitive with you.&lt;/p&gt;

&lt;p&gt;This is not an insult.&lt;br&gt;
It’s economics.&lt;/p&gt;

&lt;p&gt;Compression removes redundancy.&lt;br&gt;
And redundancy is where mediocre value hides.&lt;/p&gt;


&lt;h2&gt;
  
  
  3. The Real Divide: Medium Developer vs. Professional With AI
&lt;/h2&gt;

&lt;p&gt;This is not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;AI vs. No AI&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Medium Developer vs. Professional With AI&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  The Medium Developer
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Uses LLM like Google.&lt;/li&gt;
&lt;li&gt;Requests full solutions.&lt;/li&gt;
&lt;li&gt;Iterates blindly.&lt;/li&gt;
&lt;li&gt;Accepts verbose output.&lt;/li&gt;
&lt;li&gt;Ships quickly.&lt;/li&gt;
&lt;li&gt;Accumulates entropy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They generate more code.&lt;/p&gt;

&lt;p&gt;And if you’ve read &lt;em&gt;How to write readable code?&lt;/em&gt;  you already know: more code ≠ better code.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Professional
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Defines constraints first.&lt;/li&gt;
&lt;li&gt;Encodes invariants via types.&lt;/li&gt;
&lt;li&gt;Uses static analysis aggressively.&lt;/li&gt;
&lt;li&gt;Injects domain logic manually.&lt;/li&gt;
&lt;li&gt;Validates output.&lt;/li&gt;
&lt;li&gt;Deletes 70% of generated noise.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They multiply thinking instead of outsourcing it.&lt;/p&gt;

&lt;p&gt;They use principles like those defined in the &lt;em&gt;Codelight Manifesto&lt;/em&gt; :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clarity&lt;/li&gt;
&lt;li&gt;Optimization (after correctness)&lt;/li&gt;
&lt;li&gt;Error handling&lt;/li&gt;
&lt;li&gt;Generics&lt;/li&gt;
&lt;li&gt;Human-centric design&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The professional treats AI like a deterministic macro engine.&lt;/p&gt;

&lt;p&gt;Not like a brain.&lt;/p&gt;


&lt;h2&gt;
  
  
  4. The Token Dilemma: We’re Paying for Lines of Code Again
&lt;/h2&gt;

&lt;p&gt;Remember the 90s mistake?&lt;/p&gt;

&lt;p&gt;Paying developers by lines of code.&lt;/p&gt;

&lt;p&gt;Now look at token billing models.&lt;/p&gt;

&lt;p&gt;We are literally paying for output length.&lt;/p&gt;

&lt;p&gt;What does the model optimize for?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More explanation&lt;/li&gt;
&lt;li&gt;More scaffolding&lt;/li&gt;
&lt;li&gt;More verbosity&lt;/li&gt;
&lt;li&gt;More plausible filler&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s the ultimate junior developer incentive structure.&lt;/p&gt;

&lt;p&gt;As someone said recently:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;My productivity as a senior developer no longer comes from writing faster.&lt;br&gt;
It comes from deleting faster.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This aligns perfectly with white space discipline from &lt;em&gt;Do Not Fear The White Space in your Code&lt;/em&gt; :&lt;/p&gt;

&lt;p&gt;Clarity is subtraction.&lt;/p&gt;

&lt;p&gt;AI generates quantity.&lt;br&gt;
Experts generate quality by omission.&lt;/p&gt;


&lt;h2&gt;
  
  
  5. Where Top PHP Salaries Actually Live
&lt;/h2&gt;

&lt;p&gt;Let’s answer the core question.&lt;/p&gt;

&lt;p&gt;Can you still earn top PHP salaries, 100% remote, without AI?&lt;/p&gt;

&lt;p&gt;Yes.&lt;/p&gt;

&lt;p&gt;But only if your value is above the compression layer.&lt;/p&gt;

&lt;p&gt;That layer includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Architectural trade-offs&lt;/li&gt;
&lt;li&gt;Long-term maintainability&lt;/li&gt;
&lt;li&gt;Static analysis integration&lt;/li&gt;
&lt;li&gt;Refactoring strategy&lt;/li&gt;
&lt;li&gt;Security guarantees&lt;/li&gt;
&lt;li&gt;Performance bottleneck diagnosis&lt;/li&gt;
&lt;li&gt;Domain modeling&lt;/li&gt;
&lt;li&gt;Responsibility under production pressure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is exactly the mindset described in &lt;em&gt;What have I learned so far in my job?&lt;/em&gt; :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No panic.&lt;/li&gt;
&lt;li&gt;Read official documentation.&lt;/li&gt;
&lt;li&gt;Think before acting.&lt;/li&gt;
&lt;li&gt;Solve root causes.&lt;/li&gt;
&lt;li&gt;Learn continuously.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI does not remove the need for that.&lt;/p&gt;

&lt;p&gt;It increases the need.&lt;/p&gt;


&lt;h2&gt;
  
  
  6. Implementation: Professional AI Usage in Modern PHP
&lt;/h2&gt;

&lt;p&gt;Here’s the difference in practice.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 1 – Encode Constraints First
&lt;/h3&gt;

&lt;p&gt;Use modern PHP features (see PHP 8.x guide ):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;declare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strict_types&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Money&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="cd"&gt;/** @var numeric-string $amount */&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$currency&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;is_numeric&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$amount&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;InvalidArgumentException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Amount must be numeric.'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2 – Add Static Guarantees
&lt;/h3&gt;

&lt;p&gt;Leverage advanced PHPDoc generics and shapes (see coding standards ):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cd"&gt;/**
 * @param non-empty-list&amp;lt;Money&amp;gt; $items
 */&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;calculateTotal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$items&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;Money&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// AI can scaffold this.&lt;/span&gt;
    &lt;span class="c1"&gt;// You verify invariants.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3 – Let AI Scaffold, Not Decide
&lt;/h3&gt;

&lt;p&gt;Ask AI to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generate repetitive repository boilerplate&lt;/li&gt;
&lt;li&gt;Create test skeletons&lt;/li&gt;
&lt;li&gt;Draft migration scripts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Review types&lt;/li&gt;
&lt;li&gt;Validate edge cases&lt;/li&gt;
&lt;li&gt;Remove unnecessary abstractions&lt;/li&gt;
&lt;li&gt;Reduce surface area&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI becomes a deterministic macro tool.&lt;/p&gt;

&lt;p&gt;Not a system designer.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Common Pitfalls in the AI Era
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ❌ Blind Acceptance
&lt;/h3&gt;

&lt;p&gt;Shipping plausible but unverified code.&lt;/p&gt;

&lt;h3&gt;
  
  
  ❌ Over-Abstraction
&lt;/h3&gt;

&lt;p&gt;Generating factories for trivial objects because the model “likes patterns.”&lt;/p&gt;

&lt;h3&gt;
  
  
  ❌ Entropy Explosion
&lt;/h3&gt;

&lt;p&gt;More code → more maintenance → more hidden bugs.&lt;/p&gt;

&lt;h3&gt;
  
  
  ❌ Replacing Thinking
&lt;/h3&gt;

&lt;p&gt;Outsourcing domain decisions to a statistical engine.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Best Practices for Surviving the Compression
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Strengthen type systems.&lt;/li&gt;
&lt;li&gt;Use PHPStan aggressively.&lt;/li&gt;
&lt;li&gt;Automate refactoring.&lt;/li&gt;
&lt;li&gt;Enforce code style automatically.&lt;/li&gt;
&lt;li&gt;Reduce public surface area.&lt;/li&gt;
&lt;li&gt;Prefer deletion over addition.&lt;/li&gt;
&lt;li&gt;Move up the abstraction ladder.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Think like a systems engineer, not a syntax operator.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion: The Market Is Compressing — Not Dying
&lt;/h2&gt;

&lt;p&gt;LLMs are not architects.&lt;br&gt;
They are pattern engines.&lt;/p&gt;

&lt;p&gt;But in a world where much work is pattern instantiation, pattern engines are disruptive.&lt;/p&gt;

&lt;p&gt;You can absolutely earn top PHP salaries, 100% remote.&lt;/p&gt;

&lt;p&gt;But not if your value was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;typing code faster than others.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You must operate where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Patterns stop&lt;/li&gt;
&lt;li&gt;Trade-offs begin&lt;/li&gt;
&lt;li&gt;Responsibility matters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything below that layer is compressing.&lt;/p&gt;

&lt;p&gt;Compression does not care about feelings.&lt;/p&gt;

&lt;p&gt;It cares about economics.&lt;/p&gt;




&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;AI is a compression engine for repetitive code.&lt;/li&gt;
&lt;li&gt;Mechanical developers are at risk.&lt;/li&gt;
&lt;li&gt;Structural thinkers are amplified.&lt;/li&gt;
&lt;li&gt;Token-based billing incentivizes verbosity.&lt;/li&gt;
&lt;li&gt;Experts win by deleting, not generating.&lt;/li&gt;
&lt;li&gt;Modern PHP + strict typing + static analysis are your leverage.&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Call to Action
&lt;/h1&gt;

&lt;p&gt;Audit your own work.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are you adding value above the pattern layer?&lt;/li&gt;
&lt;li&gt;Or are you a very fast nail gun operator?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Implement code quality gates: static analysis, test coverage, ...&lt;br&gt;
Automate the boring parts.&lt;br&gt;
Move upward in abstraction.&lt;br&gt;
Let the LLM write code generators that write deterministic code.&lt;/p&gt;

</description>
      <category>php</category>
      <category>ai</category>
      <category>career</category>
    </item>
    <item>
      <title>The System Inspector: We need to Approve the Code</title>
      <dc:creator>Lars Moelleken</dc:creator>
      <pubDate>Tue, 03 Feb 2026 05:26:20 +0000</pubDate>
      <link>https://dev.to/suckup_de/the-system-inspector-we-need-to-approve-the-code-5agc</link>
      <guid>https://dev.to/suckup_de/the-system-inspector-we-need-to-approve-the-code-5agc</guid>
      <description>&lt;p&gt;This is a follow-up blog post: &lt;/p&gt;
&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/suckup_de/the-wild-west-of-coding-why-were-still-burning-digital-cities-4ph5" class="crayons-story__hidden-navigation-link"&gt;The Wild West of Coding: Why We’re Still Burning Digital Cities&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/suckup_de" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F30309%2F2945b2a8-f26d-4575-85eb-030996bcb91e.png" alt="suckup_de profile" class="crayons-avatar__image" width="800" height="800"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/suckup_de" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Lars Moelleken
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Lars Moelleken
                
              
              &lt;div id="story-author-preview-content-2237279" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/suckup_de" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F30309%2F2945b2a8-f26d-4575-85eb-030996bcb91e.png" class="crayons-avatar__image" alt="" width="800" height="800"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Lars Moelleken&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/suckup_de/the-wild-west-of-coding-why-were-still-burning-digital-cities-4ph5" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jan 31 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/suckup_de/the-wild-west-of-coding-why-were-still-burning-digital-cities-4ph5" id="article-link-2237279"&gt;
          The Wild West of Coding: Why We’re Still Burning Digital Cities
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/general"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;general&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
            &lt;a href="https://dev.to/suckup_de/the-wild-west-of-coding-why-were-still-burning-digital-cities-4ph5#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            4 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


&lt;p&gt;The year 2050 is closer than 2000. And yet, software development is entering a phase where writing code is no longer the bottleneck.&lt;/p&gt;

&lt;p&gt;For the first time, &lt;strong&gt;code generation is virtually free&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Large Language Models (LLMs) can generate thousands of lines of syntactically valid, locally plausible code in seconds. The bottleneck is no longer how fast we can implement features - it's how reliably we can absorb what has been produced.&lt;/p&gt;

&lt;p&gt;This shift is not theoretical. It's already showing up in real-world codebases.&lt;/p&gt;

&lt;h2&gt;
  
  
  OpenClaw: Code Without Memory
&lt;/h2&gt;

&lt;p&gt;Take the OpenClaw repository. At first glance, it looks like boring TypeScript. No red flags. The kind of code that would sail through a shallow pull request review.&lt;/p&gt;

&lt;p&gt;But zoom out, and the deeper you go, the more disturbing it becomes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Redundant checks live next to reckless type assertions.&lt;/li&gt;
&lt;li&gt;Standard APIs are quietly reinvented.&lt;/li&gt;
&lt;li&gt;Near-identical helpers exist side by side, none reused. One even comes with a completely unnecessary comment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/openclaw/openclaw/commit/d1ecb46076145deb188abcba8f0699709ea17198" rel="noopener noreferrer"&gt;https://github.com/openclaw/openclaw/commit/d1ecb46076145deb188abcba8f0699709ea17198&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fctvfgue4bcta4zimvrxz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fctvfgue4bcta4zimvrxz.png" alt=" " width="800" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this commit, the same escape-handling rule&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;isDoubleQuoteEscape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;appears three times, implemented independently in three different parsing loops. It works, but it is duplicated logic, not a shared rule.&lt;/p&gt;

&lt;p&gt;The newly introduced constant&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DOUBLE_QUOTE_ESCAPES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;"&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\r&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;makes the same problem visible at the naming level.&lt;br&gt;&lt;br&gt;
&lt;code&gt;DOUBLE_QUOTE_ESCAPES&lt;/code&gt; sounds like “things that happen in double quotes”. What the code actually enforces is much narrower: a whitelist of characters that are allowed &lt;em&gt;after a backslash&lt;/em&gt; while inside a double-quoted string.&lt;/p&gt;

&lt;p&gt;That distinction matters, because this is not a general shell grammar. It is a parser rule with intentionally restricted semantics. A name that encodes the mechanism is therefore clearer and harder to misread:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DOUBLE_QUOTE_BACKSLASH_FOLLOWERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;"&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\r&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not a one-off mistake. It is a pattern: rules are re-expressed locally instead of being named once and reused. The code still works. But it doesn’t remember what it already knows.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. From Coder to Inspector
&lt;/h2&gt;

&lt;p&gt;For decades, software was naturally throttled by human speed... typing, thinking, debugging. That friction caught many errors before they reached production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LLMs remove that friction.&lt;/strong&gt; They don't understand systems. They don't remember outages, postmortems, or audit logs. They see the end result of code and predict patterns based on surface-level plausibility.&lt;/p&gt;

&lt;p&gt;As a result:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Defensive logic gets "simplified" away.&lt;/li&gt;
&lt;li&gt;Ugly but necessary patches get erased.&lt;/li&gt;
&lt;li&gt;Implicit architectural contracts get violated.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And yet, CI passes. Tests are green. The code looks fine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But the foundation quietly erodes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is where the role of the Senior Engineer shifts. Their value is no longer in &lt;strong&gt;writing&lt;/strong&gt; code, it's in knowing &lt;strong&gt;when not to&lt;/strong&gt; and where to stop Claude from adding even more markdown files and not needed feature lists.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. The Dangerous Gap Between Commit and Reality
&lt;/h2&gt;

&lt;p&gt;Today's pipelines can take code from prompt to production in minutes. What's missing isn't automation, as in the last decade, it's human &lt;strong&gt;verification&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Did we actually mean to solve the problem this way?&lt;/li&gt;
&lt;li&gt;Did we just break a hidden assumption?&lt;/li&gt;
&lt;li&gt;Will the next dev understand what this does?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The most dangerous bugs aren't crashes. They're subtle degradations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Re-emergent race conditions&lt;/li&gt;
&lt;li&gt;Broken security invariants&lt;/li&gt;
&lt;li&gt;Unnecessary abstractions that raise cognitive load&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tests won't catch all of this. Reviews barely scratch the surface when volume explodes.&lt;/p&gt;

&lt;p&gt;And in this new regime, the cost of errors doesn't hit one dev, but it's paid by the organization in the long run.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Enter the System Inspector
&lt;/h2&gt;

&lt;p&gt;In the 19th century, societies learned that bridges shouldn't be approved by the people who built them. &lt;strong&gt;Structural collapses birthed the role of inspectors.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Software is hitting that same phase.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;System Inspector&lt;/strong&gt; is not a title. It's a &lt;strong&gt;responsibility&lt;/strong&gt;: Someone whose job is to &lt;strong&gt;approve&lt;/strong&gt; code, not write it. Not just another Code-Review between the next features. Not based on aesthetics, but on &lt;strong&gt;integrity&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Their responsibilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Define and protect non-negotiable system rules&lt;/li&gt;
&lt;li&gt;Preserve organizational and historical knowledge&lt;/li&gt;
&lt;li&gt;Manage cognitive load&lt;/li&gt;
&lt;li&gt;Reject syntactically correct but structurally harmful code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not about blocking progress. It's about preventing scale-induced disasters.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Regulation Is a Prerequisite for Scaling
&lt;/h2&gt;

&lt;p&gt;Guidelines don't scale. Style guides don't survive contact with LLMs. Comments get reworded, ignored, or helpfully "improved" into something else entirely.&lt;/p&gt;

&lt;p&gt;Advice is optional. Code generation is not.&lt;/p&gt;

&lt;p&gt;What actually works are &lt;strong&gt;machine-enforceable constraints&lt;/strong&gt;: e.g.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Linting, tests, static analysis, contract checks.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;AGENTS.md&lt;/code&gt; files that define &lt;strong&gt;rules&lt;/strong&gt;, not suggestions.&lt;/li&gt;
&lt;li&gt;Unchanging values that must apply regardless of how the code was created.&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This isn't bureaucracy. This is infrastructure.&lt;/p&gt;

&lt;p&gt;These constraints are the building codes of software systems that want to grow without collapsing. Every familiar argument against them sounds exactly like the arguments once made against fire codes or electrical standards. They were wrong then. They're wrong now.&lt;/p&gt;

&lt;p&gt;Scaling requires automation. Automation requires limits. And limits still require humans in the loop, just not humans doing the policing by hand.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Blind Spots: The Parts We Prefer to Ignore
&lt;/h2&gt;

&lt;p&gt;Even good systems carry risk. Here are some overlooked failure points:&lt;/p&gt;

&lt;h3&gt;
  
  
  🧱 Lack of Organizational Support
&lt;/h3&gt;

&lt;p&gt;System Inspectors need &lt;strong&gt;mandates and time&lt;/strong&gt;. Without this, their role collapses into unpaid heroism or burnout.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧠 Concentrated Psychological Load
&lt;/h3&gt;

&lt;p&gt;Decision bottlenecks are unsustainable. Approval authority needs to be distributed via frameworks, heuristics, or shared ownership... in the team.&lt;/p&gt;

&lt;h3&gt;
  
  
  🌍 One Size Doesn't Fit All
&lt;/h3&gt;

&lt;p&gt;Not every team need this. These principles apply broadly but must be &lt;strong&gt;contextually adapted&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. IKEA Was Never the Problem
&lt;/h2&gt;

&lt;p&gt;This isn't a moral panic about LLMs.&lt;/p&gt;

&lt;p&gt;Pandora’s box is open. Code generation is here: fast, cheap, and inescapable. Some teams will &lt;strong&gt;choose velocity over resilience&lt;/strong&gt;. That's a valid economic tradeoff.&lt;/p&gt;

&lt;p&gt;The problem begins when these systems are sold as something they are not.&lt;/p&gt;

&lt;p&gt;IKEA furniture is not marketed as handmade oak. Software should follow the same principle of honesty. If we build with particle board, we should say so, and we should not pretend that it can bear the same load.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. The Industrial Phase of Software
&lt;/h2&gt;

&lt;p&gt;Software is leaving its artisanal phase, not because we matured, but because &lt;strong&gt;scale made failure expensive&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Code will be abundant. &lt;strong&gt;Responsibility will be scarce.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We are no longer writing code line by line. We are approving &lt;strong&gt;systems&lt;/strong&gt; that outlast individuals and define entire orgs.&lt;/p&gt;

&lt;p&gt;That's why we need &lt;strong&gt;System Inspectors&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Not to halt innovation, but to ensure our digital cities don't collapse like their wooden ancestors.&lt;/p&gt;

&lt;p&gt;Let's build like we know what we're doing. :P&lt;/p&gt;

</description>
      <category>ai</category>
      <category>softwareengineering</category>
      <category>codereview</category>
    </item>
    <item>
      <title>How to Use LLMs for Coding Without Losing Your Mind: A Pragmatic Guide</title>
      <dc:creator>Lars Moelleken</dc:creator>
      <pubDate>Thu, 29 Jan 2026 03:13:41 +0000</pubDate>
      <link>https://dev.to/suckup_de/how-to-use-llms-for-coding-without-losing-your-mind-a-pragmatic-guide-1dap</link>
      <guid>https://dev.to/suckup_de/how-to-use-llms-for-coding-without-losing-your-mind-a-pragmatic-guide-1dap</guid>
      <description>&lt;p&gt;#blogPostAsWebApp: &lt;a href="https://voku.github.io/LLMCodingTrainMap/" rel="noopener noreferrer"&gt;https://voku.github.io/LLMCodingTrainMap/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  You Don't Work with LLMs — LLMs Work for You
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;If you treat an LLM like a teammate, you'll be disappointed.&lt;br&gt;&lt;br&gt;
If you treat it like a compiler, you'll ship valuable results.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Developers fail with LLMs for the same reason they fail at planning tasks like writing Jira tickets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;vague inputs
&lt;/li&gt;
&lt;li&gt;missing constraints
&lt;/li&gt;
&lt;li&gt;no stopping condition
&lt;/li&gt;
&lt;li&gt;no definition of done
&lt;/li&gt;
&lt;li&gt;blind trust
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This guide is not about &lt;strong&gt;what LLMs are&lt;/strong&gt;. (I alread did that here) &lt;/p&gt;
&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/suckup_de/crayons-and-the-wall-2ia7" class="crayons-story__hidden-navigation-link"&gt;Crayons and the Wall&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/suckup_de" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F30309%2F2945b2a8-f26d-4575-85eb-030996bcb91e.png" alt="suckup_de profile" class="crayons-avatar__image" width="800" height="800"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/suckup_de" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Lars Moelleken
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Lars Moelleken
                
              
              &lt;div id="story-author-preview-content-3196828" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/suckup_de" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F30309%2F2945b2a8-f26d-4575-85eb-030996bcb91e.png" class="crayons-avatar__image" alt="" width="800" height="800"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Lars Moelleken&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/suckup_de/crayons-and-the-wall-2ia7" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jan 25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/suckup_de/crayons-and-the-wall-2ia7" id="article-link-3196828"&gt;
          Crayons and the Wall
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/llm"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;llm&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/engineering"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;engineering&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/programming"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;programming&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/suckup_de/crayons-and-the-wall-2ia7" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;1&lt;span class="hidden s:inline"&gt;&amp;nbsp;reaction&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/suckup_de/crayons-and-the-wall-2ia7#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            5 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;
 &lt;br&gt;
It’s about &lt;strong&gt;how to use them every day&lt;/strong&gt; without losing time, correctness, control or your mind.

&lt;p&gt;Vibes are good. Prompting is not that helpful in 2026, so remove your collected prompts e.g. &lt;a href="https://gist.github.com/voku/4ad5a27836ae7c5100b746848e30d278" rel="noopener noreferrer"&gt;Me as PHP chat bot. 🤖&lt;/a&gt; and use your context window for real work.&lt;br&gt;&lt;br&gt;
But context, workflows and hard constraints are what actually work in production.&lt;/p&gt;

&lt;p&gt;Let's get hands-on.&lt;/p&gt;


&lt;h2&gt;
  
  
  Mental Model: LLM as a Probabilistic Compiler
&lt;/h2&gt;

&lt;p&gt;Before tools, prompts, or rituals, internalize this model:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Programming Concept&lt;/th&gt;
&lt;th&gt;LLM Equivalent&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Source Code&lt;/td&gt;
&lt;td&gt;Prompt + Context&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Include Paths&lt;/td&gt;
&lt;td&gt;Files, snippets, constraints&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Compiler&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;LLM&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Intermediate Representation&lt;/td&gt;
&lt;td&gt;Generated output&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Type Checker&lt;/td&gt;
&lt;td&gt;Static analysis, tests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Linker&lt;/td&gt;
&lt;td&gt;Manual edits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Runtime&lt;/td&gt;
&lt;td&gt;Production&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;If something breaks, &lt;strong&gt;the bug is in the input&lt;/strong&gt;, mostly not in the compiler. (even if we sometimes think it is)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;PS: Here are some 01/2026 facts about LLM usage: If a colleague argues that this doesn't work at all, remind them ...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Cursor Team used hundreds of concurrent AI agents to write over a million lines of code for a browser prototype in a week. Autonomous workflows are real. &lt;/li&gt;
&lt;/ul&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/wilsonzlin" rel="noopener noreferrer"&gt;
        wilsonzlin
      &lt;/a&gt; / &lt;a href="https://github.com/wilsonzlin/fastrender" rel="noopener noreferrer"&gt;
        fastrender
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Experimental new browser engine
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;FastRender&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A browser rendering engine in Rust. Parses HTML/CSS, computes styles, performs layout, and paints pixels. Includes a desktop browser shell and JavaScript execution via an embedded JS engine.&lt;/p&gt;
&lt;p&gt;Under heavy development. APIs are unstable and change frequently. Not recommended for production use.&lt;/p&gt;
&lt;p&gt;Developed as part of &lt;a href="https://cursor.com/blog/scaling-agents" rel="nofollow noopener noreferrer"&gt;research into collaborative parallel AI coding agents&lt;/a&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Repository structure&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;
&lt;pre class="notranslate"&gt;&lt;code&gt;src/
├── api.rs                 # Public API (FastRender, RenderOptions)
├── dom.rs                 # DOM tree, parsing, shadow DOM
├── dom2/                  # Live DOM for JS mutation
├── css/                   # CSS parsing, selectors, values
├── style/                 # Cascade, computed styles, media queries
│   ├── cascade.rs         # Cascade algorithm, layers, scope
│   ├── properties.rs      # Property definitions
│   └── values.rs          # Value types, calc(), colors
├── tree/                  # Box tree generation
│   ├── box_tree.rs        # Box nodes, formatting contexts
│   ├── box_generation.rs  # Styled → box mapping
│   └── table_fixup.rs     # Anonymous table wrapper insertion
├── layout/&lt;/code&gt;&lt;/pre&gt;…&lt;/div&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/wilsonzlin/fastrender" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
 

&lt;ul&gt;
&lt;li&gt;Uncle Bob (Robert C. Martin), the master of Clean Code, admitted that LLM Coding-Agents are working surprisingly well.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-2016523982560727349-359" src="https://platform.twitter.com/embed/Tweet.html?id=2016523982560727349"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-2016523982560727349-359');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=2016523982560727349&amp;amp;theme=dark"
  }



 &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Linus Torvalds himself used tools like Google Antigravity for hobby projects and accepted the results.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/torvalds" rel="noopener noreferrer"&gt;
        torvalds
      &lt;/a&gt; / &lt;a href="https://github.com/torvalds/GuitarPedal" rel="noopener noreferrer"&gt;
        GuitarPedal
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Linus learns analog circuits
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Resurrected random guitar pedal project&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;This is a resurrected version of my old guitar pedal project, except
this time with a screen and a few rotary encoders instead of the old
horrid analog potentiometers.&lt;/p&gt;
&lt;p&gt;There's a 'Hardware' directory with the kicad files.&lt;/p&gt;
&lt;p&gt;There's a 'Software' directory that contains the firmware to make it do
something.&lt;/p&gt;
&lt;p&gt;And there's a 'Documentation' directory, which is a very optimistic
thing for this project.&lt;/p&gt;
&lt;p&gt;Anyway, with the update to have a screen and proper rotary encores, the
thing can now have multiple effects and a sane-ish UI to them.  Except
I'm not exactly known for my mad UI designing skillz.  So...&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Firmware&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;I've only ever built the firmware on Linux, but it &lt;em&gt;should&lt;/em&gt; be perfectly
possible to build on MacOS or Windows too if you just figure out the
platform requirements. The project depends on the &lt;code&gt;pico-sdk&lt;/code&gt; and
&lt;code&gt;tinyusb&lt;/code&gt; libraries, and has submodules for both…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/torvalds/GuitarPedal" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;





&lt;h2&gt;
  
  
  1. Input Discipline (Before You Ask Anything)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Rule: Never Prompt Raw Thought
&lt;/h3&gt;

&lt;p&gt;LLMs amplify ambiguity.&lt;br&gt;&lt;br&gt;
If your input is fuzzy, the output will be confidently wrong. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy2qx8ebnwi1b6gpv3kda.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy2qx8ebnwi1b6gpv3kda.png" alt=" " width="799" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bad input:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Implement the refund logic.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Good input:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Context:
- PHP 8.2
- Existing service RefundService
- Amounts are integers (cents)
- Manual approval required above 500 EUR

Constraints:
- Do not change public interfaces
- No new dependencies
- Existing tests must pass

Task:
Draft the internal calculation logic only.

Related Files:
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Pro Tip for Long-Term Memory&lt;/strong&gt;: Don't try to hold everything in the active chat context. Have the LLM write summaries or decisions into markdown files in the repo. Use repository artifacts as the LLM's long-term memory.&lt;/p&gt;

&lt;p&gt;PS: Google Gemini has currently the highest context window, so switch to that model for those tasks if needed&lt;/p&gt;


&lt;h2&gt;
  
  
  2. The 90% Rule (Where LLMs Are Actually Good)
&lt;/h2&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-2013373307291340870-29" src="https://platform.twitter.com/embed/Tweet.html?id=2013373307291340870"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-2013373307291340870-29');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=2013373307291340870&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;LLMs are excellent at the &lt;strong&gt;first 80–90%&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;scaffolding&lt;/li&gt;
&lt;li&gt;DTOs&lt;/li&gt;
&lt;li&gt;adapters&lt;/li&gt;
&lt;li&gt;mappings&lt;/li&gt;
&lt;li&gt;test skeletons&lt;/li&gt;
&lt;li&gt;documentation that mirrors code&lt;/li&gt;
&lt;li&gt;mechanical refactoring&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They are &lt;strong&gt;bad&lt;/strong&gt; at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;domain invariants&lt;/li&gt;
&lt;li&gt;legal constraints&lt;/li&gt;
&lt;li&gt;historical edge cases&lt;/li&gt;
&lt;li&gt;“this legacy code is ugly for a reason”&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Rule
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Mostly you don't want to prompt the last 10%.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The moment you think “it’s almost right”, stop prompting.&lt;/p&gt;

&lt;p&gt;You either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fix it manually, or&lt;/li&gt;
&lt;li&gt;encode the missing rule as a test or type&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Anything else becomes prompt addiction.&lt;/p&gt;


&lt;h2&gt;
  
  
  3. Daily Workflows
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Step 1: Planning — Use LLMs for Triage, Not Code
&lt;/h3&gt;

&lt;p&gt;Start the feature or project by converting chaos into structure.&lt;/p&gt;

&lt;p&gt;Use LLMs to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;summarize long ticket threads&lt;/li&gt;
&lt;li&gt;extract precise acceptance criteria&lt;/li&gt;
&lt;li&gt;identify system invariants&lt;/li&gt;
&lt;li&gt;list unknowns and highlight risks&lt;/li&gt;
&lt;li&gt;debate technical trade-offs (ping-pong arguments)&lt;/li&gt;
&lt;li&gt;run a "blind spot analysis" against your plan (&lt;a href="https://voku.github.io/BlindSpotMetaPromptApp/" rel="noopener noreferrer"&gt;Meta-Prompt&lt;/a&gt; or via &lt;a href="https://chatgpt.com/g/g-6816771cf34c8191bf5a053958ce0c79-blind-spot-prompt-generator" rel="noopener noreferrer"&gt;Chatty&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No code yet. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hint&lt;/strong&gt;: And remember, before you use the latest shiny framework version, that the current models were trained with data from last year, so you should “at least” be from that time, maybe even older, so that more training data was available at that time.&lt;/p&gt;

&lt;p&gt;If you skip this, you’re outsourcing thinking, not typing.&lt;/p&gt;

&lt;p&gt;Note: If you are typing a lot, voice tools like &lt;a href="https://wisprflow.ai/" rel="noopener noreferrer"&gt;wisprflow.ai&lt;/a&gt; can reduce friction (and yes, that matters).&lt;/p&gt;


&lt;h3&gt;
  
  
  Step 2: Implementation
&lt;/h3&gt;
&lt;h4&gt;
  
  
  Lane A: The "Legacy Stack" Approach (e.g., older PHP, Java)
&lt;/h4&gt;

&lt;p&gt;If the LLM struggles with your 1996 template engine quirks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Generate a Mockup&lt;/strong&gt; (image) after you provided your "style guide" and examples PS: if you haven't a style guide yet, let the LLM help you also with that task - &lt;a href="https://gist.github.com/voku/8615cc2b095ec2d46a3e69faa2595dad" rel="noopener noreferrer"&gt;https://gist.github.com/voku/8615cc2b095ec2d46a3e69faa2595dad&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Generate a Click-Dummy&lt;/strong&gt; of the Mockup: Turn the mockup into a clickable prototype to verify flows against constraints.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Manual Integration&lt;/strong&gt;: Use the Click-Dummy to integeate the feature into the real code, mostly by hand&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tests&lt;/strong&gt;: Let the LLM add some tests in the end :) (I know we want to use TDD but anyway)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;h4&gt;
  
  
  Lane B: Frontend "Vibe-Coding" (The 2026 Way)
&lt;/h4&gt;

&lt;p&gt;For modern stacks where iteration is cheap:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Go to &lt;strong&gt;&lt;a href="https://aistudio.google.com/" rel="noopener noreferrer"&gt;AI Studio&lt;/a&gt;&lt;/strong&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use your &lt;strong&gt;planning&lt;/strong&gt; from before, and copy&amp;amp;past just the full document into the input. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;PS: for me ChatGPT is still best in planning such stuff without adding un-wanted stuff like Claude often does&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Now is Ping-Pong time, let's &lt;strong&gt;shape&lt;/strong&gt; the results by using the AI-Studio to providing direct feedback and ideas that pop-up while seeing the results. :)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Push&lt;/strong&gt; the 90% version to github (just one click in the UI)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Agentic Cleanup&lt;/strong&gt;: Now let's use another LLM (e.g. codex web or github agent) ... and you can give the agents more than one task, if the tasks are small, so that you do not need 10/100 free request but just 1/100 e.g.:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Remove GEMINI references
Update README.md to remove AI Studio ads and references
Update README.md with production-ready documentation
Add "Key Files Detector" helper prompt to README.md
Add a favicon
Create a contribution link (https://github.com/[YOUR_LINK_HERE]) in the webapp
Configure GitHub Pages deployment with Vite build
Add GitHub Actions workflow for automatic deployment
Build and verify the application works
Review and finalize changes and make sure the entry point from the webapp is in the html file
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Activate github pages (for free) and your Webapp is &lt;strong&gt;online&lt;/strong&gt; while you managed all this with your phone :)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;PS: here are my example Webapp stuff that I created mostly this way: &lt;/p&gt;


&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/suckup_de/posts-as-webapps-26lk" class="crayons-story__hidden-navigation-link"&gt;BlogPosts as WebApps&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/suckup_de" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F30309%2F2945b2a8-f26d-4575-85eb-030996bcb91e.png" alt="suckup_de profile" class="crayons-avatar__image" width="800" height="800"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/suckup_de" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Lars Moelleken
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Lars Moelleken
                
              
              &lt;div id="story-author-preview-content-3179432" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/suckup_de" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F30309%2F2945b2a8-f26d-4575-85eb-030996bcb91e.png" class="crayons-avatar__image" alt="" width="800" height="800"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Lars Moelleken&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/suckup_de/posts-as-webapps-26lk" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jan 17&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/suckup_de/posts-as-webapps-26lk" id="article-link-3179432"&gt;
          BlogPosts as WebApps
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/typescript"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;typescript&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/webdev"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;webdev&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/learning"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;learning&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
            &lt;a href="https://dev.to/suckup_de/posts-as-webapps-26lk#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            4 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  




&lt;h4&gt;
  
  
  Lane C: Agentic-Coding (Vibe-Coding with Control)
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Plan with Restrictions&lt;/strong&gt;: Ensure your planning phase is solid and you have clear constraints documented (e.g., in an AGENTS.md file in your repo root).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Define Tasks&lt;/strong&gt;: Add clear, bite-sized tasks into a docs/TODO.md file via the LLM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Run the Agent&lt;/strong&gt;: Use CLI tools (see "What's Next" below) to execute the list.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example: &lt;code&gt;codex --yolo "Implement the open tasks from docs/TODO.md"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This tools are also working with your subscription, and often has a free try and at the end of the post I wrote a quick one minute intro to install it, see &lt;code&gt;What’s Next: Agentic Coding (Try It)&lt;/code&gt;&lt;/p&gt;




&lt;p&gt;I created the next project via agents (without any IDE) and while working on it, I saw that the agents really has problems with e.g. Android Apps because the build time (feedback loop) was way to slow with my mini pc :/ so I asked the agent to convert it into a Webapp and it worked. :D &lt;/p&gt;

&lt;p&gt;My main pain point is that if you didn't do the coding work anymore you haven't this mental model of the project in mind and it's more and more complicated to plan new things and to keep it stable. &lt;/p&gt;

&lt;p&gt;(still not 100% done, we need to train the ML Engine now)&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/voku" rel="noopener noreferrer"&gt;
        voku
      &lt;/a&gt; / &lt;a href="https://github.com/voku/AmysEcho" rel="noopener noreferrer"&gt;
        AmysEcho
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      This repository contains the development work for my little girl — to help her be understood, to help her learn, and to help others understand her world.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Amy's Echo&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://github.com/voku/AmysEcho/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667" alt="Open Source – MIT"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;This repository contains the development work for my little girl — to help her be understood, to help her learn, and to help others understand her world.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Amy is four years old. She was born with &lt;strong&gt;22q11 Deletion Syndrome&lt;/strong&gt; and communicates using &lt;strong&gt;Deutsche Gebärdensprache (DGS)&lt;/strong&gt; — German Sign Language. Her gestures are expressive, her intent is clear — but most people around her don't understand what she's trying to say.&lt;/p&gt;
&lt;p&gt;This project turns those gestures into speech and symbols so she can be heard anywhere. Each child profile receives personalized gesture recognition trained from their own samples, making the system effective for 22q11 workflows in group settings like kindergartens.&lt;/p&gt;
&lt;p&gt;All app UI text and error messages are written in German to match Amy's language environment.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Current Focus&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;The project is being maintained in a &lt;strong&gt;supported-core&lt;/strong&gt; mode.&lt;/p&gt;
&lt;p&gt;Current first-class scope:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;caregiver auth and child profiles&lt;/li&gt;
&lt;li&gt;live gesture recognition&lt;/li&gt;
&lt;li&gt;low-confidence…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/voku/AmysEcho" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;





&lt;h3&gt;
  
  
  Lane D: The Daily Driver (IDE-Centric Coding with Guardrails)
&lt;/h3&gt;

&lt;p&gt;This lane is for daily engineering work inside the IDE (e.g. PhpStorm + GitHub Copilot). Maintenance, debugging, and refactoring where correctness matters more than speed.&lt;/p&gt;

&lt;p&gt;No agents. No pipelines. Just quick feedback loops.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Curate Context Explicitly&lt;/strong&gt;: Copilot does not understand your project:&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open&lt;/strong&gt; the interface or contract&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open&lt;/strong&gt; the concrete implementation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open&lt;/strong&gt; the relevant test&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open&lt;/strong&gt; involved DTOs or config files&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Rule&lt;/strong&gt;: If the file is not open tab, it doesn’t exist for the LLM.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Prefer Inline Edit Mode Over Chat&lt;/strong&gt;: Use Copilot where diffs are visible and reversible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Select&lt;/strong&gt; code in the editor&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trigger&lt;/strong&gt; inline edit (Ctrl + Shift + I)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prompt&lt;/strong&gt; with a precise, local instruction&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;: "Extract the loop logic into a private method &lt;code&gt;processItems&lt;/code&gt; with an explicit return type."&lt;/p&gt;

&lt;p&gt;Review the diff. Accept deliberately.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Stabilize Legacy Code via Reverse Documentation&lt;/strong&gt;: For unclear or fragile code, do not ask for a refactor immediately.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Select&lt;/strong&gt; the code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ask&lt;/strong&gt; Copilot to describe it, not change it.&lt;/li&gt;
&lt;li&gt;"Write a PHPDoc explaining exactly what this code does, including edge cases."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validate&lt;/strong&gt; the explanation first.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Refactor&lt;/strong&gt; only after the behavior is explicit.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Actively Prevent "Passenger Mode"&lt;/strong&gt;: The &lt;code&gt;Tab&lt;/code&gt; → &lt;code&gt;Accept&lt;/code&gt; → &lt;code&gt;Commit&lt;/code&gt; loop is a trap.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Read generated code &lt;strong&gt;before&lt;/strong&gt; accepting.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you can’t explain it, &lt;strong&gt;reject&lt;/strong&gt; it.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Copilot accelerates thinking. It should not replace it in this lane.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 3: Validation — Treat Output as Untrusted
&lt;/h3&gt;

&lt;p&gt;LLM output is &lt;strong&gt;never final code&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It must pass:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;strict type checking&lt;/li&gt;
&lt;li&gt;aggressive linters&lt;/li&gt;
&lt;li&gt;automated tests&lt;/li&gt;
&lt;li&gt;static analysis tools&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If it doesn’t:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fix the constraint
&lt;/li&gt;
&lt;li&gt;or add more context
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;A compiler that issues warnings is telling you something.&lt;br&gt;&lt;br&gt;
An LLM often believes it has done everything correctly and therefore also requires similar validation steps&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Adding more context sounds more easy that it sometimes: UI Bug Example&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Provide the exact error message from the CI pipeline.&lt;/li&gt;
&lt;li&gt;Use an MCP (Model Context Protocol) tool to let the LLM view the app in a headless browser.&lt;/li&gt;
&lt;li&gt;Provide a screenshot with browser DevTools open showing the DOM state.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Step 4: commit&amp;amp;push — Let the Repo Remember
&lt;/h3&gt;

&lt;p&gt;Humans forget why things exist.&lt;br&gt;&lt;br&gt;
LLMs don’t, if you ask at the right moment.&lt;/p&gt;

&lt;p&gt;Use them to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Summarize diffs into commit messages. Crucial: Manually add the "WHY" to the message; the LLM usually only sees the "WHAT".&lt;/li&gt;
&lt;li&gt;Draft Architectural Decision Records (ADRs). Hint: Add a note in generated docs that they are drafts and need human review.&lt;/li&gt;
&lt;li&gt;Explain "why this legacy code is ugly" and document it in a comment near the code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This kills tribal knowledge without requiring meetings.&lt;/p&gt;


&lt;h2&gt;
  
  
  4. Constraints Beat Prompts (Always)
&lt;/h2&gt;

&lt;p&gt;Stop writing clever prompts. (&lt;a href="https://voku.github.io/PromptMastery/" rel="noopener noreferrer"&gt;https://voku.github.io/PromptMastery/&lt;/a&gt;)&lt;br&gt;
Start writing &lt;strong&gt;constraint boxes&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Constraints:
- No new public methods allowed.
- Must preserve backward compatibility with API v2.
- Assume input is already validated (do not add redundant checks).
- Output must be deterministic (seed random number generators).
- Fail fast with a specific Exception class on invalid state.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Constraints shrink the solution space, making correct answers more likely. But sady they traind the current LLMs just the happy path. :P&lt;/p&gt;


&lt;h2&gt;
  
  
  5. Generators Over Code
&lt;/h2&gt;

&lt;p&gt;If you ask an LLM to write the same thing 5x, you already failed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bad&lt;/strong&gt;: "Generate 30 DTOs for these tables..."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Good&lt;/strong&gt;: "Write a Python script using Jinja2 templates that reads this database schema YAML and generates the 30 DTO files fitting our project structure."&lt;/p&gt;

&lt;p&gt;This turns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;probability → determinism
&lt;/li&gt;
&lt;li&gt;conversation → reusable tooling&lt;/li&gt;
&lt;li&gt;magic → a reproducible build step&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Other example: PHP&lt;br&gt;
In larger legacy systems, I recently had the LLM create various custom PHP-CS-Fixer rules so that we could easily migrate things in a deterministic way. That's the way.  &lt;/p&gt;
&lt;h2&gt;
  
  
  What’s Next: Agentic Coding (Try It)
&lt;/h2&gt;

&lt;p&gt;If you haven’t played with CLI-based code agents yet, you’re missing the point of all this.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Don’t overthink it.
&lt;/li&gt;
&lt;li&gt;Don’t integrate it into prod.
&lt;/li&gt;
&lt;li&gt;Try it locally and break things safely.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here are three options you can test quickly.&lt;/p&gt;


&lt;h3&gt;
  
  
  1. Google Gemini CLI
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/google-gemini" rel="noopener noreferrer"&gt;
        google-gemini
      &lt;/a&gt; / &lt;a href="https://github.com/google-gemini/gemini-cli" rel="noopener noreferrer"&gt;
        gemini-cli
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      An open-source AI agent that brings the power of Gemini directly into your terminal.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Gemini CLI&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://github.com/google-gemini/gemini-cli/actions/workflows/ci.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/google-gemini/gemini-cli/actions/workflows/ci.yml/badge.svg" alt="Gemini CLI CI"&gt;&lt;/a&gt;
&lt;a href="https://github.com/google-gemini/gemini-cli/actions/workflows/chained_e2e.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/google-gemini/gemini-cli/actions/workflows/chained_e2e.yml/badge.svg" alt="Gemini CLI E2E (Chained)"&gt;&lt;/a&gt;
&lt;a href="https://www.npmjs.com/package/@google/gemini-cli" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/34811703a711b6037aa43a44195c31c3844bdb76af3fb0221142c7a3f03d5929/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f40676f6f676c652f67656d696e692d636c69" alt="Version"&gt;&lt;/a&gt;
&lt;a href="https://github.com/google-gemini/gemini-cli/blob/main/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/8ad45b29989b35a46e9a9881bd5cbc03e8393ae620f6c70884d3e8e05afe92c0/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f676f6f676c652d67656d696e692f67656d696e692d636c69" alt="License"&gt;&lt;/a&gt;
&lt;a href="https://codewiki.google/github.com/google-gemini/gemini-cli?utm_source=badge&amp;amp;utm_medium=github&amp;amp;utm_campaign=github.com/google-gemini/gemini-cli" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/94541bcea8452983959d62ea7b483d19909ad00e9827d23ca65ade5aab87b795/68747470733a2f2f6173736574732e636f646577696b692e676f6f676c652f726561646d652d62616467652f7374617469632e737667" alt="View Code Wiki"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/docs/assets/gemini-screenshot.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fdocs%2Fassets%2Fgemini-screenshot.png" alt="Gemini CLI Screenshot"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Gemini CLI is an open-source AI agent that brings the power of Gemini directly
into your terminal. It provides lightweight access to Gemini, giving you the
most direct path from your prompt to our model.&lt;/p&gt;
&lt;p&gt;Learn all about Gemini CLI in our &lt;a href="https://geminicli.com/docs/" rel="nofollow noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🚀 Why Gemini CLI?&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;🎯 Free tier&lt;/strong&gt;: 60 requests/min and 1,000 requests/day with personal Google
account.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🧠 Powerful Gemini 3 models&lt;/strong&gt;: Access to improved reasoning and 1M token
context window.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🔧 Built-in tools&lt;/strong&gt;: Google Search grounding, file operations, shell
commands, web fetching.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🔌 Extensible&lt;/strong&gt;: MCP (Model Context Protocol) support for custom
integrations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;💻 Terminal-first&lt;/strong&gt;: Designed for developers who live in the command line.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🛡️ Open source&lt;/strong&gt;: Apache 2.0 licensed.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;📦 Installation&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;See
&lt;a href="https://www.geminicli.com/docs/get-started/installation" rel="nofollow noopener noreferrer"&gt;Gemini CLI installation, execution, and releases&lt;/a&gt;
for recommended system specifications and a detailed installation guide.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Quick Install&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h4 class="heading-element"&gt;Run instantly with npx&lt;/h4&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Using npx (no installation&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/google-gemini/gemini-cli" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Install&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @google/gemini-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Run (inside your local project)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gemini &lt;span class="nt"&gt;--yolo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. OpenAI Codex CLI
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/openai" rel="noopener noreferrer"&gt;
        openai
      &lt;/a&gt; / &lt;a href="https://github.com/openai/codex" rel="noopener noreferrer"&gt;
        codex
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Lightweight coding agent that runs in your terminal
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;p&gt;&lt;strong&gt;Codex CLI&lt;/strong&gt; is a coding agent from OpenAI that runs locally on your computer
&lt;/p&gt;
&lt;p&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/openai/codex/blob/main/.github/codex-cli-splash.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fopenai%2Fcodex%2Fraw%2Fmain%2F.github%2Fcodex-cli-splash.png" alt="Codex CLI splash" width="80%"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;br&gt;
If you want Codex in your code editor (VS Code, Cursor, Windsurf), &lt;a href="https://developers.openai.com/codex/ide" rel="nofollow noopener noreferrer"&gt;install in your IDE.&lt;/a&gt;
&lt;br&gt;If you want the desktop app experience, run &lt;code&gt;codex app&lt;/code&gt; or visit &lt;a href="https://chatgpt.com/codex?app-landing-page=true" rel="nofollow noopener noreferrer"&gt;the Codex App page&lt;/a&gt;
&lt;br&gt;If you are looking for the &lt;em&gt;cloud-based agent&lt;/em&gt; from OpenAI, &lt;strong&gt;Codex Web&lt;/strong&gt;, go to &lt;a href="https://chatgpt.com/codex" rel="nofollow noopener noreferrer"&gt;chatgpt.com/codex&lt;/a&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Quickstart&lt;/h2&gt;

&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Installing and running Codex CLI&lt;/h3&gt;

&lt;/div&gt;

&lt;p&gt;Run the following on Mac or Linux to install Codex CLI:&lt;/p&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;curl -fsSL https://chatgpt.com/codex/install.sh &lt;span class="pl-k"&gt;|&lt;/span&gt; sh&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Run the following on Windows to install Codex CLI:&lt;/p&gt;

&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;powershell -ExecutionPolicy ByPass -c "irm https://chatgpt.com/codex/install.ps1 | iex"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Codex CLI can also be installed via the following package managers:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Install using npm&lt;/span&gt;
npm install -g @openai/codex&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Install using Homebrew&lt;/span&gt;
brew install --cask codex&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Then simply run &lt;code&gt;codex&lt;/code&gt; to get started.&lt;/p&gt;

You can also go to the &lt;a href="https://github.com/openai/codex/releases/latest" rel="noopener noreferrer"&gt;latest GitHub Release&lt;/a&gt; and download the appropriate…&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/openai/codex" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;Codex CLI is explicitly designed to run locally and operate on the selected directory. (&lt;a href="https://developers.openai.com/codex/cli/?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;developers.openai.com&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i &lt;span class="nt"&gt;-g&lt;/span&gt; @openai/codex
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Run&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codex &lt;span class="nt"&gt;--yolo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;⚠️ Use this only in a &lt;strong&gt;local / restricted environment&lt;/strong&gt;. It can delete things. That’s not a joke.&lt;/p&gt;


&lt;h3&gt;
  
  
  3. opencode-ai (open source)
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/anomalyco" rel="noopener noreferrer"&gt;
        anomalyco
      &lt;/a&gt; / &lt;a href="https://github.com/anomalyco/opencode" rel="noopener noreferrer"&gt;
        opencode
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      The open source coding agent.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;p&gt;
  &lt;a href="https://opencode.ai" rel="nofollow noopener noreferrer"&gt;
    
      
      
      &lt;/a&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fanomalyco%2Fopencode%2FHEAD%2Fpackages%2Fconsole%2Fapp%2Fsrc%2Fasset%2Flogo-ornate-light.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fanomalyco%2Fopencode%2FHEAD%2Fpackages%2Fconsole%2Fapp%2Fsrc%2Fasset%2Flogo-ornate-light.svg" alt="OpenCode logo"&gt;&lt;/a&gt;
    
  
&lt;/p&gt;
&lt;p&gt;The open source AI coding agent.&lt;/p&gt;
&lt;p&gt;
  &lt;a href="https://opencode.ai/discord" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Discord" src="https://camo.githubusercontent.com/83daa53aa89771d7c1b411e9d8aab90692f07934a8c2aea6a6794687082e2f68/68747470733a2f2f696d672e736869656c64732e696f2f646973636f72642f313339313833323432363034383635313333343f7374796c653d666c61742d737175617265266c6162656c3d646973636f7264"&gt;&lt;/a&gt;
  &lt;a href="https://www.npmjs.com/package/opencode-ai" rel="nofollow noopener noreferrer"&gt;&lt;img alt="npm" src="https://camo.githubusercontent.com/4e57d77e1805497a6befb9cc1743a8069756f26377e832d09f1ba2ca49f9370c/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f6f70656e636f64652d61693f7374796c653d666c61742d737175617265"&gt;&lt;/a&gt;
  &lt;a href="https://github.com/anomalyco/opencode/actions/workflows/publish.yml" rel="noopener noreferrer"&gt;&lt;img alt="Build status" src="https://camo.githubusercontent.com/dfb623969ed19b150f1ccf242b1b4c4b4629515c1aa0603fb795ff3e407c1b2d/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f616e6f6d616c79636f2f6f70656e636f64652f7075626c6973682e796d6c3f7374796c653d666c61742d737175617265266272616e63683d646576"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;a href="https://github.com/anomalyco/opencode/README.md" rel="noopener noreferrer"&gt;English&lt;/a&gt; |
  &lt;a href="https://github.com/anomalyco/opencode/README.zh.md" rel="noopener noreferrer"&gt;简体中文&lt;/a&gt; |
  &lt;a href="https://github.com/anomalyco/opencode/README.zht.md" rel="noopener noreferrer"&gt;繁體中文&lt;/a&gt; |
  &lt;a href="https://github.com/anomalyco/opencode/README.ko.md" rel="noopener noreferrer"&gt;한국어&lt;/a&gt; |
  &lt;a href="https://github.com/anomalyco/opencode/README.de.md" rel="noopener noreferrer"&gt;Deutsch&lt;/a&gt; |
  &lt;a href="https://github.com/anomalyco/opencode/README.es.md" rel="noopener noreferrer"&gt;Español&lt;/a&gt; |
  &lt;a href="https://github.com/anomalyco/opencode/README.fr.md" rel="noopener noreferrer"&gt;Français&lt;/a&gt; |
  &lt;a href="https://github.com/anomalyco/opencode/README.it.md" rel="noopener noreferrer"&gt;Italiano&lt;/a&gt; |
  &lt;a href="https://github.com/anomalyco/opencode/README.da.md" rel="noopener noreferrer"&gt;Dansk&lt;/a&gt; |
  &lt;a href="https://github.com/anomalyco/opencode/README.ja.md" rel="noopener noreferrer"&gt;日本語&lt;/a&gt; |
  &lt;a href="https://github.com/anomalyco/opencode/README.pl.md" rel="noopener noreferrer"&gt;Polski&lt;/a&gt; |
  &lt;a href="https://github.com/anomalyco/opencode/README.ru.md" rel="noopener noreferrer"&gt;Русский&lt;/a&gt; |
  &lt;a href="https://github.com/anomalyco/opencode/README.bs.md" rel="noopener noreferrer"&gt;Bosanski&lt;/a&gt; |
  &lt;a href="https://github.com/anomalyco/opencode/README.ar.md" rel="noopener noreferrer"&gt;العربية&lt;/a&gt; |
  &lt;a href="https://github.com/anomalyco/opencode/README.no.md" rel="noopener noreferrer"&gt;Norsk&lt;/a&gt; |
  &lt;a href="https://github.com/anomalyco/opencode/README.br.md" rel="noopener noreferrer"&gt;Português (Brasil)&lt;/a&gt; |
  &lt;a href="https://github.com/anomalyco/opencode/README.th.md" rel="noopener noreferrer"&gt;ไทย&lt;/a&gt; |
  &lt;a href="https://github.com/anomalyco/opencode/README.tr.md" rel="noopener noreferrer"&gt;Türkçe&lt;/a&gt; |
  &lt;a href="https://github.com/anomalyco/opencode/README.uk.md" rel="noopener noreferrer"&gt;Українська&lt;/a&gt; |
  &lt;a href="https://github.com/anomalyco/opencode/README.bn.md" rel="noopener noreferrer"&gt;বাংলা&lt;/a&gt; |
  &lt;a href="https://github.com/anomalyco/opencode/README.gr.md" rel="noopener noreferrer"&gt;Ελληνικά&lt;/a&gt; |
  &lt;a href="https://github.com/anomalyco/opencode/README.vi.md" rel="noopener noreferrer"&gt;Tiếng Việt&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;&lt;a href="https://opencode.ai" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fanomalyco%2Fopencode%2FHEAD%2Fpackages%2Fweb%2Fsrc%2Fassets%2Flander%2Fscreenshot.png" alt="OpenCode Terminal UI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Installation&lt;/h3&gt;
&lt;/div&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; YOLO&lt;/span&gt;
curl -fsSL https://opencode.ai/install &lt;span class="pl-k"&gt;|&lt;/span&gt; bash
&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Package managers&lt;/span&gt;
npm i -g opencode-ai@latest        &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; or bun/pnpm/yarn&lt;/span&gt;
scoop install opencode             &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Windows&lt;/span&gt;
choco install opencode             &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Windows&lt;/span&gt;
brew install anomalyco/tap/opencode &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; macOS and Linux (recommended, always up to date)&lt;/span&gt;
brew install opencode              &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; macOS and Linux (official brew formula, updated less)&lt;/span&gt;
sudo pacman -S opencode            &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Arch Linux (Stable)&lt;/span&gt;
paru -S opencode-bin               &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Arch Linux (Latest from AUR)&lt;/span&gt;
mise use -g opencode               &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Any OS&lt;/span&gt;
nix run nixpkgs#opencode           &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; or github:anomalyco/opencode for latest dev branch&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-alert markdown-alert-tip"&gt;
&lt;p class="markdown-alert-title"&gt;Tip&lt;/p&gt;
&lt;p&gt;Remove versions older than 0.1.x before installing.&lt;/p&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Desktop App (BETA)&lt;/h3&gt;

&lt;/div&gt;

&lt;p&gt;OpenCode is…&lt;/p&gt;&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/anomalyco/opencode" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;&lt;strong&gt;Install&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i &lt;span class="nt"&gt;-g&lt;/span&gt; opencode-ai@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Important (learn this early)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;run agents &lt;strong&gt;locally or in Docker&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;combine them with:

&lt;ul&gt;
&lt;li&gt;static analysis&lt;/li&gt;
&lt;li&gt;code style checks&lt;/li&gt;
&lt;li&gt;tests&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;treat agents like a &lt;strong&gt;junior dev with root access&lt;/strong&gt;
&lt;/li&gt;

&lt;li&gt;add skills/instructions (AGENTS.md etc.) step by step

&lt;ul&gt;
&lt;li&gt;less is more
&lt;/li&gt;
&lt;li&gt;MCP and tool calls are cool, but it eats your context window
&lt;/li&gt;
&lt;li&gt;ideas: &lt;a href="https://voku.github.io/your_agent_config/" rel="noopener noreferrer"&gt;https://voku.github.io/your_agent_config/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Agentic development isn’t magic, but at some point we need a IDE again. :D  &lt;/p&gt;




&lt;h2&gt;
  
  
  Some !funny takes at the end
&lt;/h2&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-2015115128149041360-526" src="https://platform.twitter.com/embed/Tweet.html?id=2015115128149041360"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-2015115128149041360-526');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=2015115128149041360&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-2015180689335812480-644" src="https://platform.twitter.com/embed/Tweet.html?id=2015180689335812480"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-2015180689335812480-644');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=2015180689335812480&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-2016599645997216050-547" src="https://platform.twitter.com/embed/Tweet.html?id=2016599645997216050"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-2016599645997216050-547');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=2016599645997216050&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;Happy Coding!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
