<?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>Forem: Hiroyuki Nakahata</title>
    <description>The latest articles on Forem by Hiroyuki Nakahata (@iroha1203).</description>
    <link>https://forem.com/iroha1203</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3921684%2F387c0a8d-8e0c-41a8-b158-5a3349179896.png</url>
      <title>Forem: Hiroyuki Nakahata</title>
      <link>https://forem.com/iroha1203</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/iroha1203"/>
    <language>en</language>
    <item>
      <title>Gotanda Style: Do AI Agents Really Need Meetings?</title>
      <dc:creator>Hiroyuki Nakahata</dc:creator>
      <pubDate>Mon, 11 May 2026 14:28:47 +0000</pubDate>
      <link>https://forem.com/iroha1203/gotanda-style-do-ai-agents-really-need-meetings-7ii</link>
      <guid>https://forem.com/iroha1203/gotanda-style-do-ai-agents-really-need-meetings-7ii</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Once you start running multiple AI coding agents, coordination eventually becomes its own bottleneck.&lt;/p&gt;

&lt;p&gt;For long-running maintenance workflows, the cost of conversations, context, and tokens starts to add up.&lt;/p&gt;

&lt;p&gt;We call the pattern &lt;strong&gt;Gotanda Style&lt;/strong&gt;: agents do not talk to each other directly. Instead, they leave small structured signals in a shared environment. Other agents read those signals later.&lt;/p&gt;

&lt;p&gt;This is a lighter introduction to a workflow we use on a roughly 200,000-line Python repository: Sentry alerts become shared signals, recurring patterns become GitHub issues, and coding agents turn the right ones into small, reviewable PRs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Are we making AI agents attend too many meetings?
&lt;/h2&gt;

&lt;p&gt;If you are building with AI coding agents, you will probably hit the coordination problem sooner or later.&lt;/p&gt;

&lt;p&gt;When people design a multi-agent system, the first idea is often: "let the agents talk to each other."&lt;/p&gt;

&lt;p&gt;A Planner discusses the plan. A Researcher investigates. A Coder implements. A Reviewer comments. A Supervisor keeps the whole thing on track.&lt;/p&gt;

&lt;p&gt;That feels natural. It also works pretty well for small tasks.&lt;/p&gt;

&lt;p&gt;But when you try to run a large system for a long time, a different problem appears.&lt;/p&gt;

&lt;p&gt;More agents create more conversations. More conversations create more context. More context creates more token usage.&lt;/p&gt;

&lt;p&gt;Eventually, the agents can spend too much of their budget reading each other's messages instead of solving the actual problem.&lt;/p&gt;

&lt;p&gt;It starts to look a little like a human organization where work slows down because every decision turns into a meeting.&lt;/p&gt;

&lt;p&gt;So we started with a simple question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI agents don't need meetings.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Or more precisely: not every kind of coordination needs to be a conversation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Leave structured traces instead of chatting
&lt;/h2&gt;

&lt;p&gt;In the pattern we are trying, agents do not talk to each other directly.&lt;/p&gt;

&lt;p&gt;Instead, each agent writes down what it observed as a small signal in a shared environment.&lt;/p&gt;

&lt;p&gt;Another agent can read that signal later.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agents do not talk to each other.
They leave traces in a shared environment.
Other agents read those traces later.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This kind of coordination is called &lt;strong&gt;stigmergy&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The word sounds academic, but the idea is simple: coordinate through the environment.&lt;/p&gt;

&lt;p&gt;We call the shared signals "pheromones" internally. The name is a little weird, but the implementation is just a structured record:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(scope, location, worker, strength, half_life, metadata)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;For example, if a production error happens in a file, a Sentry worker might leave a signal like this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scope"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"file"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"location"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"app/services/invoices.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"worker"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sentry-worker"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"strength"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"half_life_days"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"metadata"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"runtime_error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"environment"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"production"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This is not a long chat log.&lt;/p&gt;

&lt;p&gt;It is small, structured, and easy to aggregate later.&lt;/p&gt;
&lt;h2&gt;
  
  
  The actual maintenance flow
&lt;/h2&gt;

&lt;p&gt;In a simplified form, the workflow looks like this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sentry worker   ----+
Datadog worker  ----+--&amp;gt;  Pheromone field  --&amp;gt;  Refactor worker  --&amp;gt;  GitHub Issue  --&amp;gt;  Code worker  --&amp;gt;  Pull Request
Quality worker  ----+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Each worker looks at the codebase or production system from a different angle.&lt;/p&gt;

&lt;p&gt;The Sentry worker watches production errors. The Datadog worker watches performance regressions. The Quality worker looks for test gaps and weakening module boundaries.&lt;/p&gt;

&lt;p&gt;But they do not immediately create a pile of issues.&lt;/p&gt;

&lt;p&gt;First, they leave signals in the shared environment.&lt;/p&gt;

&lt;p&gt;If several workers point to the same location, that location becomes a hotspot.&lt;/p&gt;

&lt;p&gt;If a weak signal happens only once, it fades over time.&lt;/p&gt;

&lt;p&gt;If something was previously reviewed and marked "not worth fixing right now," the system can leave a negative signal for that candidate too.&lt;/p&gt;

&lt;p&gt;The Refactor worker reads those signals and decides what should become an issue, what should go to a human, and what is safe enough for automated implementation.&lt;/p&gt;

&lt;p&gt;Only issues at the right size and clarity are passed to the Code worker and turned into pull requests.&lt;/p&gt;

&lt;p&gt;The nice part is that coordination cost moves from conversation to state updates.&lt;/p&gt;

&lt;p&gt;When we add a new worker, we mainly define what kind of signal it writes.&lt;/p&gt;

&lt;p&gt;A Security worker can write security signals. A Performance worker can write performance signals.&lt;/p&gt;

&lt;p&gt;The Integrator can read all of them as part of the same shared environment.&lt;/p&gt;

&lt;p&gt;That means production errors, slow endpoints, test gaps, and design drift do not all need to become all-hands agent meetings.&lt;/p&gt;
&lt;h2&gt;
  
  
  The small trick: zero does not always mean nothing
&lt;/h2&gt;

&lt;p&gt;If you only add signals together, you can accidentally hide useful information.&lt;/p&gt;

&lt;p&gt;Imagine one file has these two signals:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sentry-worker: +2.0
refactor-worker: -2.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The simple sum is zero.&lt;/p&gt;

&lt;p&gt;But that is not the same as a file with no signals at all.&lt;/p&gt;

&lt;p&gt;It means something more interesting: "production is complaining about this area, but we also have a previous decision saying not to chase it right now."&lt;/p&gt;

&lt;p&gt;That is a different situation from silence.&lt;/p&gt;

&lt;p&gt;So the system should not only ask, "what is the final score?"&lt;/p&gt;

&lt;p&gt;It should also ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How much positive signal is here?&lt;/li&gt;
&lt;li&gt;How much negative signal is here?&lt;/li&gt;
&lt;li&gt;Are different workers disagreeing?&lt;/li&gt;
&lt;li&gt;Is this a quiet area, or a contested one?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That small distinction changes the behavior of the whole maintenance loop.&lt;/p&gt;

&lt;p&gt;A quiet area can be ignored for now.&lt;/p&gt;

&lt;p&gt;A strongly positive area might become an implementation issue.&lt;/p&gt;

&lt;p&gt;A strongly negative area might stay suppressed.&lt;/p&gt;

&lt;p&gt;But a contested area probably needs a human to look at the tradeoff.&lt;/p&gt;

&lt;p&gt;That is the kind of detail that makes this feel less like "agents throwing tasks into a queue" and more like a maintenance system with memory.&lt;/p&gt;
&lt;h2&gt;
  
  
  The faster AI writes code, the more maintenance matters
&lt;/h2&gt;

&lt;p&gt;AI coding agents are making it faster to write code.&lt;/p&gt;

&lt;p&gt;But if code is written twice as fast, the maintenance load grows too.&lt;/p&gt;

&lt;p&gt;More code reaches production. More changes need monitoring, debugging, testing, and refactoring.&lt;/p&gt;

&lt;p&gt;It is like doubling the speed of a car. Speed is great, but only if the tires, brakes, suspension, and safety systems can keep up.&lt;/p&gt;

&lt;p&gt;So in AI-driven development, "write code faster" is not enough.&lt;/p&gt;

&lt;p&gt;This is not just a thought experiment for us.&lt;/p&gt;

&lt;p&gt;We are using this pattern to maintain a Python repository with roughly 200,000 lines of code.&lt;/p&gt;

&lt;p&gt;The loop from Sentry alert to pheromone deposit to GitHub issue to improvement pull request is already running.&lt;/p&gt;

&lt;p&gt;That does not mean we try to automate everything.&lt;/p&gt;

&lt;p&gt;Humans still step in when a fix needs architectural judgment, the cause is unclear, the blast radius is large, or an automated pull request needs review.&lt;/p&gt;

&lt;p&gt;As we give AI agents more work, I do not think the human role disappears. It moves toward higher-level judgment and boundary design.&lt;/p&gt;
&lt;h2&gt;
  
  
  As a practice of attractor engineering
&lt;/h2&gt;

&lt;p&gt;Zoom out a bit, and the whole codebase becomes part of the prompt for AI.&lt;/p&gt;

&lt;p&gt;If the codebase has good structure, AI is more likely to follow that structure.&lt;/p&gt;

&lt;p&gt;If the codebase has bad structure, AI is also more likely to treat that as the natural pattern.&lt;/p&gt;

&lt;p&gt;That is why we care about preventing AI-generated changes from pushing the codebase toward worse future changes.&lt;/p&gt;

&lt;p&gt;In that sense, this pattern is also a practice of attractor engineering.&lt;/p&gt;

&lt;p&gt;I wrote more about that idea here: &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/iroha1203/attractor-engineering-seeing-software-development-as-field-dynamics-16g5" class="crayons-story__hidden-navigation-link"&gt;Attractor Engineering: Seeing Software Development as Field Dynamics&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="/iroha1203" 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%2F3921684%2F387c0a8d-8e0c-41a8-b158-5a3349179896.png" alt="iroha1203 profile" class="crayons-avatar__image" width="96" height="96"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/iroha1203" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Hiroyuki Nakahata
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Hiroyuki Nakahata
                
              
              &lt;div id="story-author-preview-content-3639748" 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="/iroha1203" 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%2F3921684%2F387c0a8d-8e0c-41a8-b158-5a3349179896.png" class="crayons-avatar__image" alt="" width="96" height="96"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Hiroyuki Nakahata&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/iroha1203/attractor-engineering-seeing-software-development-as-field-dynamics-16g5" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;May 9&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/iroha1203/attractor-engineering-seeing-software-development-as-field-dynamics-16g5" id="article-link-3639748"&gt;
          Attractor Engineering: Seeing Software Development as Field Dynamics
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/softwareengineering"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;softwareengineering&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/architecture"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;architecture&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/computerscience"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;computerscience&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/iroha1203/attractor-engineering-seeing-software-development-as-field-dynamics-16g5" 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/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="24" height="24"&gt;
                  &lt;/span&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;5&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/iroha1203/attractor-engineering-seeing-software-development-as-field-dynamics-16g5#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add 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;
            24 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;p&gt;Before the codebase drifts toward a bad attractor, we observe it, leave signals, and correct the trajectory through issues and pull requests.&lt;/p&gt;

&lt;p&gt;This is not just about making AI coding agents go faster.&lt;/p&gt;

&lt;p&gt;It is about keeping the codebase itself in a better shape for the next AI-generated change.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this pattern fits, and where it does not
&lt;/h2&gt;

&lt;p&gt;This pattern is not always better than conversational multi-agent design.&lt;/p&gt;

&lt;p&gt;Direct agent conversation can be the right tool when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The task is small&lt;/li&gt;
&lt;li&gt;There are only a few agents&lt;/li&gt;
&lt;li&gt;The context is short-lived&lt;/li&gt;
&lt;li&gt;The goal is exploration or brainstorming&lt;/li&gt;
&lt;li&gt;It is faster to reach agreement in the moment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Leaving traces in a shared environment tends to work better when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The workflow runs for a long time&lt;/li&gt;
&lt;li&gt;Signals arrive asynchronously&lt;/li&gt;
&lt;li&gt;Multiple tools observe the same codebase&lt;/li&gt;
&lt;li&gt;You want weak signals to accumulate over time&lt;/li&gt;
&lt;li&gt;You want to add agents without increasing communication traffic too much&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So this is not a universal architecture.&lt;/p&gt;

&lt;p&gt;It is a coordination pattern for long-running maintenance work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap-up
&lt;/h2&gt;

&lt;p&gt;In AI multi-agent systems, conversation feels like the natural coordination model.&lt;/p&gt;

&lt;p&gt;But in long-running maintenance workflows, conversation itself can become the cost.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does AI agent coordination really need to be a conversation?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As one experiment around that question, we call this pattern &lt;strong&gt;Gotanda Style&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I wrote a deeper version on Hashnode covering the design background, pheromone handling, and the production workflow from Sentry alerts to issues and pull requests: &lt;br&gt;
&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://iroha1203.hashnode.dev/ai-agents-don-t-need-meetings-gotanda-style-for-stigmergic-software-maintenance" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;iroha1203.hashnode.dev&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;How are you coordinating AI agents today? Are they talking to each other, or are they coordinating through shared memory, queues, databases, event logs, or some other environment?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>devops</category>
      <category>architecture</category>
    </item>
    <item>
      <title>When Lean Proved My Durability Definition Too Easily</title>
      <dc:creator>Hiroyuki Nakahata</dc:creator>
      <pubDate>Sun, 10 May 2026 12:34:42 +0000</pubDate>
      <link>https://forem.com/iroha1203/when-lean-proved-my-durability-definition-too-easily-20nc</link>
      <guid>https://forem.com/iroha1203/when-lean-proved-my-durability-definition-too-easily-20nc</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I tried to formalize a small ACID-like model in Lean 4.&lt;/p&gt;

&lt;p&gt;Consistency became invariant preservation.&lt;br&gt;
Isolation became a deliberately strong commutation law.&lt;br&gt;
Durability exposed that my model had no persistence boundary.&lt;/p&gt;

&lt;p&gt;The result was not a proof that databases are correct.&lt;br&gt;
It was a reminder that every design claim depends on what the model can actually see.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The suspicious part was not that Lean failed to prove durability.&lt;/p&gt;

&lt;p&gt;The suspicious part was that Lean proved it with almost no assumptions.&lt;/p&gt;

&lt;p&gt;ACID is familiar enough that it is easy to stop thinking about it.&lt;/p&gt;

&lt;p&gt;Atomicity. Consistency. Isolation. Durability.&lt;/p&gt;

&lt;p&gt;In ordinary database terms, the rough meanings are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Atomicity
  A transaction is all-or-nothing. It commits as a unit or has no effect.

Consistency
  A transaction takes the database from one valid state to another valid state.

Isolation
  Concurrent transactions behave as if they were controlled by some serial order.

Durability
  Once a transaction commits, its effect survives failures and recovery.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most engineers learn these words through examples: bank transfers, constraints, concurrent transactions, crashes, logs, commits, and recovery.&lt;/p&gt;

&lt;p&gt;But I wanted to ask a slightly different question:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What kind of structure is ACID preserving?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So I tried to write a small ACID-like model in Lean 4.&lt;/p&gt;

&lt;p&gt;The result was not a proof that real databases are correct.&lt;/p&gt;

&lt;p&gt;That is the part worth sharing.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Minimal Model
&lt;/h2&gt;

&lt;p&gt;Start with the smallest model that still has something architectural in it.&lt;/p&gt;

&lt;p&gt;There is a state space &lt;code&gt;S&lt;/code&gt;. There are transactions. Each transaction acts on the state. There is also an invariant, a predicate that says which states are valid.&lt;/p&gt;

&lt;p&gt;This is not a formalization of real database ACID.&lt;/p&gt;

&lt;p&gt;It is a deliberately lossy projection: keep the state-transformer shape, and drop many operational details.&lt;/p&gt;

&lt;p&gt;In simplified Lean-shaped notation, the model looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="n"&gt;abbrev&lt;/span&gt; &lt;span class="n"&gt;Endo&lt;/span&gt; (&lt;span class="n"&gt;S&lt;/span&gt; : &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;) := &lt;span class="n"&gt;S&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;S&lt;/span&gt;

&lt;span class="n"&gt;structure&lt;/span&gt; &lt;span class="n"&gt;Model&lt;/span&gt; (&lt;span class="n"&gt;S&lt;/span&gt; : &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;) &lt;span class="n"&gt;where&lt;/span&gt;
  &lt;span class="n"&gt;Txn&lt;/span&gt;   : &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;
  &lt;span class="n"&gt;apply&lt;/span&gt; : &lt;span class="n"&gt;Txn&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Endo&lt;/span&gt; &lt;span class="n"&gt;S&lt;/span&gt;
  &lt;span class="n"&gt;inv&lt;/span&gt;   : &lt;span class="n"&gt;S&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Prop&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is intentionally abstract.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;S&lt;/code&gt; might be a relational database state. It might be an event-sourced aggregate. It might be a key-value store, an in-memory domain model, or a deliberately simplified toy system.&lt;/p&gt;

&lt;p&gt;The point is not to model every detail of a database. The point is to ask what can already be said if we only know this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;transaction = operation on state
invariant   = property we want valid states to preserve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This small model already gives a useful reading of some ACID-shaped claims.&lt;/p&gt;

&lt;h2&gt;
  
  
  Histories Are Composition
&lt;/h2&gt;

&lt;p&gt;Transactions rarely appear alone. They appear in histories.&lt;/p&gt;

&lt;p&gt;A history is a list of transactions. Replaying a history means composing the corresponding state transformations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replay&lt;/span&gt; (&lt;span class="n"&gt;M&lt;/span&gt; : &lt;span class="n"&gt;Model&lt;/span&gt; &lt;span class="n"&gt;S&lt;/span&gt;) : &lt;span class="n"&gt;List&lt;/span&gt; &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Txn&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Endo&lt;/span&gt; &lt;span class="n"&gt;S&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; []      &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; :: &lt;span class="n"&gt;hs&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replay&lt;/span&gt; &lt;span class="n"&gt;hs&lt;/span&gt; (&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;apply&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The empty history is the identity function. A non-empty history applies the first transaction, then replays the rest.&lt;/p&gt;

&lt;p&gt;The important lemma is that replaying appended histories corresponds to composing their replays:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="k"&gt;theorem&lt;/span&gt; &lt;span class="n"&gt;replay_append&lt;/span&gt;
    (&lt;span class="n"&gt;h1&lt;/span&gt; &lt;span class="n"&gt;h2&lt;/span&gt; : &lt;span class="n"&gt;List&lt;/span&gt; &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Txn&lt;/span&gt;) :
    &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replay&lt;/span&gt; (&lt;span class="n"&gt;h1&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="n"&gt;h2&lt;/span&gt;) &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replay&lt;/span&gt; &lt;span class="n"&gt;h2&lt;/span&gt; (&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replay&lt;/span&gt; &lt;span class="n"&gt;h1&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In plain English:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;append histories
  corresponds to
compose state transformations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is already algebraic. The list of transactions has a monoid structure under append. State endomorphisms have a monoid structure under composition. Replay connects the two.&lt;/p&gt;

&lt;p&gt;In less mathematical terms, replay is the bridge between a log and the effect that log has on the system.&lt;/p&gt;

&lt;p&gt;This is the first useful reframing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a transaction log is not just a list;
it is a way to build larger state transformations from smaller ones.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Consistency as Invariant Preservation
&lt;/h2&gt;

&lt;p&gt;For this model, the part of ACID consistency we keep is invariant preservation: a transaction should take a valid state to another valid state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;PreservesInvariant&lt;/span&gt; (&lt;span class="n"&gt;M&lt;/span&gt; : &lt;span class="n"&gt;Model&lt;/span&gt; &lt;span class="n"&gt;S&lt;/span&gt;) : &lt;span class="kt"&gt;Prop&lt;/span&gt; :=
  &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; : &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Txn&lt;/span&gt;, &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; : &lt;span class="n"&gt;S&lt;/span&gt;,
    &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inv&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inv&lt;/span&gt; (&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;apply&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is invariant preservation. The set of valid states is closed under every transaction.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;valid state
  -- transaction --&amp;gt;
valid state
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once written this way, a small theorem becomes immediate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="k"&gt;theorem&lt;/span&gt; &lt;span class="n"&gt;preservesInvariant_comp&lt;/span&gt;
    (&lt;span class="n"&gt;hC&lt;/span&gt; : &lt;span class="n"&gt;PreservesInvariant&lt;/span&gt; &lt;span class="n"&gt;M&lt;/span&gt;)
    (&lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt; : &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Txn&lt;/span&gt;)
    (&lt;span class="n"&gt;s&lt;/span&gt; : &lt;span class="n"&gt;S&lt;/span&gt;)
    (&lt;span class="n"&gt;hs&lt;/span&gt; : &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inv&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;) :
    &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inv&lt;/span&gt; (&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;apply&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt; (&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;apply&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;t1&lt;/code&gt; preserves the invariant and &lt;code&gt;t2&lt;/code&gt; preserves the invariant, then their composition preserves the invariant.&lt;/p&gt;

&lt;p&gt;The same idea extends from two transactions to any history:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="k"&gt;theorem&lt;/span&gt; &lt;span class="n"&gt;preservesInvariant_replay&lt;/span&gt;
    (&lt;span class="n"&gt;hC&lt;/span&gt; : &lt;span class="n"&gt;PreservesInvariant&lt;/span&gt; &lt;span class="n"&gt;M&lt;/span&gt;) :
    &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; : &lt;span class="n"&gt;List&lt;/span&gt; &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Txn&lt;/span&gt;, &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; : &lt;span class="n"&gt;S&lt;/span&gt;,
      &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inv&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inv&lt;/span&gt; (&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replay&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the cleanest part of the story. In this projection, consistency becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;the invariant survives every selected operation.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That sentence is also the bridge to software architecture, but we will come back to that at the end.&lt;/p&gt;

&lt;h2&gt;
  
  
  An Algebraic Shadow of Atomicity
&lt;/h2&gt;

&lt;p&gt;Atomicity is trickier.&lt;/p&gt;

&lt;p&gt;In this model, I cannot express all-or-nothing execution.&lt;/p&gt;

&lt;p&gt;There is no partial execution, no abort, no crash, and no visibility boundary.&lt;/p&gt;

&lt;p&gt;The closest algebraic property I can write is closure under sequencing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;ClosedUnderSequence&lt;/span&gt; (&lt;span class="n"&gt;M&lt;/span&gt; : &lt;span class="n"&gt;Model&lt;/span&gt; &lt;span class="n"&gt;S&lt;/span&gt;) : &lt;span class="kt"&gt;Prop&lt;/span&gt; :=
  &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt; : &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Txn&lt;/span&gt;,
    &lt;span class="n"&gt;exists&lt;/span&gt; &lt;span class="n"&gt;t3&lt;/span&gt; : &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Txn&lt;/span&gt;,
      &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;apply&lt;/span&gt; &lt;span class="n"&gt;t3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;apply&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt; (&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;apply&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This says that if two selected operations are executed in sequence, their combined effect can be represented as one selected operation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;transaction followed by transaction
  can be treated as
one transaction
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is not database atomicity. It is only an atomicity-shaped shadow.&lt;/p&gt;

&lt;p&gt;So this definition needs a boundary:&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 algebraic atomicity as closure of selected operations.
It is not a full crash/failure semantics for transactions.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This boundary prevents a small theorem from being advertised as a larger theorem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Isolation as Commutation, Also With a Warning
&lt;/h2&gt;

&lt;p&gt;Isolation is also subtle.&lt;/p&gt;

&lt;p&gt;A common intuition is that concurrent transactions should behave as if they had run one at a time. In database terms, serializability asks whether a concurrent execution is equivalent to some serial order.&lt;/p&gt;

&lt;p&gt;Commutation asks for something stronger: the two serial orders are indistinguishable at the level of final state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;CommutesOnValidStates&lt;/span&gt; (&lt;span class="n"&gt;M&lt;/span&gt; : &lt;span class="n"&gt;Model&lt;/span&gt; &lt;span class="n"&gt;S&lt;/span&gt;) : &lt;span class="kt"&gt;Prop&lt;/span&gt; :=
  &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt; : &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Txn&lt;/span&gt;, &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; : &lt;span class="n"&gt;S&lt;/span&gt;,
    &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inv&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;apply&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt; (&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;apply&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;)
        &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;apply&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; (&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;apply&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This says that on valid states, swapping the order of two selected operations does not change the result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;t1 then t2
  =
t2 then t1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is mathematically clean, but it is stronger than serializability. It removes order from the observable final state rather than merely finding some serial order.&lt;/p&gt;

&lt;p&gt;So this definition also needs a boundary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This definition captures a strong commutation-style isolation property.
It is not a taxonomy of real-world isolation levels.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The formal model is valuable because it makes the approximation visible. Without it, it is easy to slide from "this resembles isolation" to "this is isolation."&lt;/p&gt;

&lt;p&gt;Lean does not let that slide happen quietly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Durability Exposed a Missing Boundary
&lt;/h2&gt;

&lt;p&gt;Durability was the most interesting part.&lt;/p&gt;

&lt;p&gt;My first attempt was to define durability as monotonicity of history. If one history is a prefix of another, then the longer history should replay as the shorter history followed by some suffix.&lt;/p&gt;

&lt;p&gt;In pseudocode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;WrongDurabilityAttempt&lt;/span&gt; (&lt;span class="n"&gt;M&lt;/span&gt; : &lt;span class="n"&gt;Model&lt;/span&gt; &lt;span class="n"&gt;S&lt;/span&gt;) : &lt;span class="kt"&gt;Prop&lt;/span&gt; :=
  &lt;span class="n"&gt;forall&lt;/span&gt; &lt;span class="n"&gt;h1&lt;/span&gt; &lt;span class="n"&gt;h2&lt;/span&gt; : &lt;span class="n"&gt;List&lt;/span&gt; &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Txn&lt;/span&gt;,
    &lt;span class="n"&gt;Prefix&lt;/span&gt; &lt;span class="n"&gt;h1&lt;/span&gt; &lt;span class="n"&gt;h2&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;exists&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; : &lt;span class="n"&gt;List&lt;/span&gt; &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Txn&lt;/span&gt;,
        &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replay&lt;/span&gt; &lt;span class="n"&gt;h2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replay&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; (&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replay&lt;/span&gt; &lt;span class="n"&gt;h1&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This sounds plausible.&lt;/p&gt;

&lt;p&gt;If &lt;code&gt;h1&lt;/code&gt; is already committed and &lt;code&gt;h2&lt;/code&gt; extends it, then &lt;code&gt;h2&lt;/code&gt; should contain &lt;code&gt;h1&lt;/code&gt; as a stable prefix. The past should not be rewritten.&lt;/p&gt;

&lt;p&gt;But then something happened:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;the theorem was provable with no real assumptions.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That was the moment the model started to teach me something.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because if &lt;code&gt;h1&lt;/code&gt; is a prefix of &lt;code&gt;h2&lt;/code&gt;, then by definition there is some suffix &lt;code&gt;k&lt;/code&gt; such that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;h2 = h1 ++ k
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And &lt;code&gt;replay_append&lt;/code&gt; already gives:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;replay (h1 ++ k) = replay k . replay h1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the attempted durability theorem follows almost for free.&lt;/p&gt;

&lt;p&gt;At first, that feels like success: the theorem was proved, the code type-checked, and the definition seemed to behave.&lt;/p&gt;

&lt;p&gt;But that was the warning.&lt;/p&gt;

&lt;p&gt;This was the bug: I had not defined durability.&lt;/p&gt;

&lt;p&gt;I had defined a replay decomposition property of append-only histories.&lt;/p&gt;

&lt;p&gt;If a property that should depend on storage, crashes, and recovery can be proved from list concatenation alone, then the property is not talking about storage, crashes, or recovery.&lt;/p&gt;

&lt;p&gt;Durability is not just "the log has a prefix." It is a recovery guarantee under an explicit failure model.&lt;/p&gt;

&lt;p&gt;Committed effects should survive the crashes and recoveries the system promises to handle.&lt;/p&gt;

&lt;p&gt;A pure state-transition model does not contain storage.&lt;/p&gt;

&lt;p&gt;It does not contain crashes.&lt;/p&gt;

&lt;p&gt;It does not contain a recovery function.&lt;/p&gt;

&lt;p&gt;So it cannot express the full property.&lt;/p&gt;

&lt;p&gt;To talk about durability seriously, the model needs another layer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;volatile state
persistent state
write
crash
recover
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only after adding that layer can we ask for a non-trivial law 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;recover after write preserves the committed effect
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This was the most valuable lesson from the exercise.&lt;/p&gt;

&lt;p&gt;Lean did not merely help prove a theorem. It helped detect that a proposed definition was too weak to express the intended claim.&lt;/p&gt;

&lt;p&gt;In other words:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Lean did not reject the definition.
It accepted it so easily that the definition became suspicious.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What Lean Actually Gave Me
&lt;/h2&gt;

&lt;p&gt;The result was not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ACID has been proved correct.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That would be far too strong.&lt;/p&gt;

&lt;p&gt;What Lean gave me was a way to notice when a claim had silently moved outside its model.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Within a pure state-transition model:

Consistency-shaped claims can be read as invariant preservation.
The atomicity-shaped fragment becomes closure under sequencing.
The isolation-shaped fragment becomes commutation on valid states.
Durability cannot be expressed without persistence, recovery, and a fault model.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For software engineering, this discipline matters more than the notation.&lt;/p&gt;

&lt;p&gt;Many architecture discussions fail because claims move between levels without being noticed.&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;"We use Event Sourcing"
  quietly becomes
"we can always replay and recover correctly."

"We use Clean Architecture"
  quietly becomes
"dependencies cannot violate our boundary."

"We have tests"
  quietly becomes
"the behavior is preserved."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each of those moves may be valid under additional assumptions. But the assumptions need to be stated.&lt;/p&gt;

&lt;h2&gt;
  
  
  From ACID to Architecture
&lt;/h2&gt;

&lt;p&gt;The ACID example suggests a more general way to read software design.&lt;/p&gt;

&lt;p&gt;A design rule is not just a slogan.&lt;/p&gt;

&lt;p&gt;It is a claim that some operation should preserve some invariant.&lt;/p&gt;

&lt;p&gt;In ACID, the operations were transactions. One invariant was database consistency.&lt;/p&gt;

&lt;p&gt;In software architecture, the same pattern appears in a less obvious form.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ApplicationService -&amp;gt; SqlPaymentRepository
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Suppose the intended architecture says that application code should depend on a payment port, not on the SQL implementation directly.&lt;/p&gt;

&lt;p&gt;Then the issue is not simply that the design "looks bad."&lt;/p&gt;

&lt;p&gt;There is an invariant:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;application logic depends on declared abstractions,
not on infrastructure details directly
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is an operation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a feature addition or refactoring introduced a new dependency edge
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And there is a witness:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;the concrete edge ApplicationService -&amp;gt; SqlPaymentRepository
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is the same shape as the ACID model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;operation acts on a structure
invariant is expected to survive
failure should have a concrete witness
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the "state" is not a database state. It is a dependency graph.&lt;/p&gt;

&lt;p&gt;The operation is not a transaction. It is a code change that adds or removes edges.&lt;/p&gt;

&lt;p&gt;The invariant is not a database constraint. It is an architectural rule about allowed dependencies.&lt;/p&gt;

&lt;p&gt;The witness is not a bad row. It is a forbidden edge.&lt;/p&gt;

&lt;p&gt;I use the name Algebraic Architecture Theory (AAT) for this broader lens, but the name matters less than the discipline: state the operation, the invariant, the witness, and the boundary.&lt;/p&gt;

&lt;p&gt;The important word is not "algebra" for its own sake. The important word is &lt;strong&gt;invariant&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When we say a design is good, we should be able to ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Which invariant is being preserved?
By which operation?
Under which observation boundary?
If it fails, what is the witness?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same question can be asked for dependency direction, abstraction boundaries, substitutability, replay laws, compensation laws, and failure locality.&lt;/p&gt;

&lt;p&gt;When an invariant fails, we should not merely say "the design is bad." We should identify the concrete witness: a forbidden dependency edge, a cycle, an abstraction leak, an observation mismatch, or a failed compensation case.&lt;/p&gt;

&lt;p&gt;Different invariants can fail in different ways, and each failure should have a witness.&lt;/p&gt;

&lt;p&gt;The lesson from ACID carries over:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;do not ask whether the architecture is "good" in general;
ask which invariants are preserved, which witnesses remain,
and which axes were not measured.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;ACID was not the destination.&lt;/p&gt;

&lt;p&gt;It was a small, familiar example showing that software design can be read as invariant preservation under operations, with explicit witnesses when preservation fails.&lt;/p&gt;

&lt;p&gt;Lean did not turn a simplified model into a real database.&lt;/p&gt;

&lt;p&gt;It did something more useful.&lt;/p&gt;

&lt;p&gt;It showed that a definition can be wrong not because Lean rejects it, but because Lean accepts it for the wrong reason.&lt;/p&gt;

&lt;p&gt;In that sense, formalization is not only a tool for proving.&lt;/p&gt;

&lt;p&gt;It is a tool for discovering what your words were secretly assuming.&lt;/p&gt;

&lt;p&gt;That is the habit I want to bring from formal methods into everyday architecture work.&lt;/p&gt;

&lt;p&gt;Not every design discussion needs a proof assistant.&lt;/p&gt;

&lt;p&gt;But every serious design claim benefits from the same discipline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name the operation;
name the invariant;
name the witness;
name the boundary.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The working Lean repository for this line of thought is here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/iroha1203/AlgebraicArchitectureTheoryV2" rel="noopener noreferrer"&gt;https://github.com/iroha1203/AlgebraicArchitectureTheoryV2&lt;/a&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>database</category>
      <category>lean</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>AI does not only generate code faster. It changes the distribution of future changes. This post introduces Attractor Engineering: designing where software changes tend to converge.</title>
      <dc:creator>Hiroyuki Nakahata</dc:creator>
      <pubDate>Sat, 09 May 2026 11:33:16 +0000</pubDate>
      <link>https://forem.com/iroha1203/ai-does-not-only-generate-code-faster-it-changes-the-distribution-of-future-changes-this-post-2e22</link>
      <guid>https://forem.com/iroha1203/ai-does-not-only-generate-code-faster-it-changes-the-distribution-of-future-changes-this-post-2e22</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/iroha1203/attractor-engineering-seeing-software-development-as-field-dynamics-16g5" class="crayons-story__hidden-navigation-link"&gt;Attractor Engineering: Seeing Software Development as Field Dynamics&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="/iroha1203" 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%2F3921684%2F387c0a8d-8e0c-41a8-b158-5a3349179896.png" alt="iroha1203 profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/iroha1203" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Hiroyuki Nakahata
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Hiroyuki Nakahata
                
              
              &lt;div id="story-author-preview-content-3639748" 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="/iroha1203" 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%2F3921684%2F387c0a8d-8e0c-41a8-b158-5a3349179896.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Hiroyuki Nakahata&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/iroha1203/attractor-engineering-seeing-software-development-as-field-dynamics-16g5" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;May 9&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/iroha1203/attractor-engineering-seeing-software-development-as-field-dynamics-16g5" id="article-link-3639748"&gt;
          Attractor Engineering: Seeing Software Development as Field Dynamics
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/softwareengineering"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;softwareengineering&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/architecture"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;architecture&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/computerscience"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;computerscience&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/iroha1203/attractor-engineering-seeing-software-development-as-field-dynamics-16g5" 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/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;10&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/iroha1203/attractor-engineering-seeing-software-development-as-field-dynamics-16g5#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add 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;
            24 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;


</description>
      <category>ai</category>
      <category>architecture</category>
      <category>softwaredevelopment</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Attractor Engineering: Seeing Software Development as Field Dynamics</title>
      <dc:creator>Hiroyuki Nakahata</dc:creator>
      <pubDate>Sat, 09 May 2026 11:25:16 +0000</pubDate>
      <link>https://forem.com/iroha1203/attractor-engineering-seeing-software-development-as-field-dynamics-16g5</link>
      <guid>https://forem.com/iroha1203/attractor-engineering-seeing-software-development-as-field-dynamics-16g5</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A codebase can be read as a field that attracts future changes, and a pull request can be read as a force applied to that field.&lt;/li&gt;
&lt;li&gt;A good field makes good changes easier to make. A bad field repeatedly makes bad shortcuts look natural. In an era where AI can produce PRs quickly, this attraction becomes stronger.&lt;/li&gt;
&lt;li&gt;I call the practice of designing where future changes are pulled &lt;strong&gt;Attractor Engineering&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;CI/CD, tests, reviews, and harnesses can be read as dissipative systems: they remove unwanted force and shape the trajectory.&lt;/li&gt;
&lt;li&gt;ArchSig, or Architecture Signature, is a tool for observing that trajectory along multiple axes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;The first half of this article is written for practitioners: it explains the intuition in terms of codebases, PRs, review, CI, and AI-assisted development. The second half is more mathematical: it connects the same intuition to AAT, Architecture Signature, Lean formalization, and finite counterexamples.&lt;/p&gt;

&lt;h2&gt;
  
  
  The First Discovery
&lt;/h2&gt;

&lt;p&gt;The starting point was a simple thought experiment.&lt;/p&gt;

&lt;p&gt;What if we look at software architecture not only as a set of directories, design rules, or conventions, but as an &lt;strong&gt;algebraic structure&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;From that point of view, everyday changes such as feature additions, refactorings, splits, migrations, repairs, protections, deletions, and integrations become operations acting on the structure we call architecture.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;current codebase
  + feature addition
  + refactoring
  + review fix
  + migration
  + repair
  -&amp;gt; next codebase
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we take one more step, we can ask: if these operations are not applied once, but repeated dozens or hundreds of times, can the whole development process be read as a kind of dynamics?&lt;/p&gt;

&lt;p&gt;Each individual PR is small.&lt;/p&gt;

&lt;p&gt;But after enough PRs, the codebase gradually moves in some direction.&lt;/p&gt;

&lt;p&gt;When a good structure already exists, the next change tends to fit into a good place.&lt;/p&gt;

&lt;p&gt;When a bad structure exists, a locally natural change tends to take the same bad shortcut again.&lt;/p&gt;

&lt;p&gt;Can we treat "where changes tend to go" as something we design?&lt;/p&gt;

&lt;p&gt;I decided to call this way of thinking &lt;strong&gt;Attractor Engineering&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Codebase Is a Field, and a PR Is a Force
&lt;/h2&gt;

&lt;p&gt;The central interpretation is this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;codebase = a field that attracts changes
PR       = a force applied to that field
ArchSig  = an observer for the movement
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A codebase is not a neutral space that passively receives future changes.&lt;/p&gt;

&lt;p&gt;Existing names, types, responsibility boundaries, tests, directory structure, previous implementation examples, and review culture all shape which next change feels natural.&lt;/p&gt;

&lt;p&gt;A PR is a force applied to that field. Each one may be small, but repeated PRs create a trajectory of change.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;current codebase
  -&amp;gt; a PR is applied
  -&amp;gt; an architectural change is observed
  -&amp;gt; a trajectory of change emerges
  -&amp;gt; this becomes the next codebase
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important point is that a PR changes the codebase, and the changed codebase then changes what the next PR is likely to look like.&lt;/p&gt;

&lt;h2&gt;
  
  
  People and Systems Create the Field
&lt;/h2&gt;

&lt;p&gt;This field is not created only by engineers.&lt;/p&gt;

&lt;p&gt;Product managers, product owners, engineers, reviewers, AI agents, CI, tests, design documents, coding standards, and existing examples all participate in it.&lt;/p&gt;

&lt;p&gt;Everyone and everything involved in development affects which changes become likely next.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Participant / mechanism&lt;/th&gt;
&lt;th&gt;Effect on the field&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Product manager&lt;/td&gt;
&lt;td&gt;Decides which values and demands are repeatedly injected into the system.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Product owner&lt;/td&gt;
&lt;td&gt;Shapes PRs through requirement granularity, priorities, and acceptance criteria.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Engineer / architect&lt;/td&gt;
&lt;td&gt;Creates paths for change through boundaries, abstractions, standard patterns, and reference implementations.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reviewer&lt;/td&gt;
&lt;td&gt;Pushes back bad force and redirects it toward better directions.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CI / tests / types&lt;/td&gt;
&lt;td&gt;Rejects, weakens, and narrows inappropriate force.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI agent&lt;/td&gt;
&lt;td&gt;Reads the existing field and quickly proposes changes.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The way requirements are sliced, prioritized, scheduled, and accepted changes how later PRs are produced. Even people who do not write code apply indirect force to the field of the codebase.&lt;/p&gt;

&lt;p&gt;This becomes especially important in AI-assisted development. Vague requirements can quickly become vague PRs. If boundaries and non-goals are clear, an AI system is more likely to produce useful changes within those boundaries.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Changes in AI-Assisted Development
&lt;/h2&gt;

&lt;p&gt;The essence of AI-assisted development is not simply that code can be written faster.&lt;/p&gt;

&lt;p&gt;The more important change is that &lt;strong&gt;the distribution of selected change operations&lt;/strong&gt; changes.&lt;/p&gt;

&lt;p&gt;An AI system reads existing code, neighboring files, names, types, tests, previous implementation examples, READMEs, and design documents, and then generates the next proposed change.&lt;/p&gt;

&lt;p&gt;In other words, the whole codebase becomes input context for the AI.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;the codebase becomes input context for AI
  -&amp;gt; AI proposes a change
  -&amp;gt; the proposal becomes a PR
  -&amp;gt; review / CI / merge process handles it
  -&amp;gt; the codebase is updated
  -&amp;gt; the next input context changes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a good reference implementation is nearby, the AI is likely to imitate it.&lt;/p&gt;

&lt;p&gt;If a bad shortcut already exists, the AI is also likely to treat it as a natural option.&lt;/p&gt;

&lt;p&gt;In this sense, AI rapidly reproduces the local style already present in the field. That is why, in the AI era, what matters is not only the capability of an individual AI agent. The design of the field in which the AI participates matters just as much.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is an Attractor?
&lt;/h2&gt;

&lt;p&gt;When a codebase contains a huge &lt;code&gt;common&lt;/code&gt; module, an overly convenient helper, or an ambiguous service, changes tend to be pulled there.&lt;/p&gt;

&lt;p&gt;Conversely, when good responsibility boundaries and clear implementation examples exist, the next change tends to follow them.&lt;/p&gt;

&lt;p&gt;This destination toward which changes are pulled is what I call an attractor. When something moves repeatedly, it often tends to approach certain places or states.&lt;/p&gt;

&lt;p&gt;The surrounding region from which things are likely to fall into that attractor is what I call a basin.&lt;/p&gt;

&lt;p&gt;Technical debt can be read as a bad basin.&lt;/p&gt;

&lt;p&gt;Once a codebase falls into it, locally natural changes keep adding to the same place, and the cost of refactoring out of it grows higher and higher.&lt;/p&gt;

&lt;p&gt;The important point is that attractors can be good or bad.&lt;/p&gt;

&lt;p&gt;A good attractor pulls in good changes.&lt;/p&gt;

&lt;p&gt;A bad attractor makes bad shortcuts get selected again and again.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Attractor Engineering?
&lt;/h2&gt;

&lt;p&gt;Attractor Engineering is the idea that we should deliberately design these attractors.&lt;/p&gt;

&lt;p&gt;Its target is not just the codebase.&lt;/p&gt;

&lt;p&gt;It includes the whole development organization: product managers, product owners, engineers, reviewers, AI agents, CI/CD, tests, design documents, and coding standards.&lt;/p&gt;

&lt;p&gt;The goal is not only to block bad changes from the outside. The goal is to create a field where good changes are naturally easier to select.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Part of Attractor Engineering&lt;/th&gt;
&lt;th&gt;What it shapes&lt;/th&gt;
&lt;th&gt;Examples&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Create the field&lt;/td&gt;
&lt;td&gt;Which changes feel natural to propose.&lt;/td&gt;
&lt;td&gt;Requirements, priorities, design boundaries, types, APIs, examples, templates.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dissipate bad force&lt;/td&gt;
&lt;td&gt;Which proposed changes are rejected, weakened, or redirected.&lt;/td&gt;
&lt;td&gt;Harnesses, CI, tests, reviews, PR granularity.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Observe the trajectory&lt;/td&gt;
&lt;td&gt;How architectural movement becomes visible over time.&lt;/td&gt;
&lt;td&gt;ArchSig, architecture features, drift reports.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Attractor Engineering is an integrated design theory for the era of AI-assisted development. It treats the entire development organization as part of the system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Harness Engineering as a Dissipative System
&lt;/h2&gt;

&lt;p&gt;We cannot simply take changes produced by AI and put them directly into the codebase.&lt;/p&gt;

&lt;p&gt;Harnesses, CI, tests, type checking, static analysis, and review divide proposed changes into "accept", "fix and check again", and "do not merge".&lt;/p&gt;

&lt;p&gt;In Attractor Engineering, this behavior can be read as dissipation.&lt;/p&gt;

&lt;p&gt;Dissipation is the mechanism that removes unwanted components of the force entering the field.&lt;/p&gt;

&lt;p&gt;If dissipation is too weak, the fast change force produced by AI enters the codebase directly. If it is too strong, nothing moves. A good harness weakens the force that increases debt while preserving the force that moves the product forward.&lt;/p&gt;

&lt;p&gt;In this view, CI/CD is not merely a checklist. It is more like brakes, rails, signals, and safety equipment that convert fast PR generation into safe productivity.&lt;/p&gt;

&lt;p&gt;What matters in AI-assisted development is not only making the engine stronger.&lt;/p&gt;

&lt;p&gt;It is also preparing the field and the dissipative system that can receive a stronger engine.&lt;/p&gt;

&lt;h2&gt;
  
  
  What ArchSig Observes
&lt;/h2&gt;

&lt;p&gt;To design the field, we need to observe what is happening.&lt;/p&gt;

&lt;p&gt;That is the role of ArchSig.&lt;/p&gt;

&lt;p&gt;ArchSig is short for Architecture Signature.&lt;/p&gt;

&lt;p&gt;In my &lt;a href="https://github.com/iroha1203/AlgebraicArchitectureTheoryV2" rel="noopener noreferrer"&gt;repository&lt;/a&gt;, I use it to mean an observation framework for reading changes in a codebase or PR along multiple axes. Dependencies, boundaries, abstractions, runtime exposure, semantic drift, and test observability are not collapsed into a single score. They are treated as multiple features.&lt;/p&gt;

&lt;p&gt;ArchSig is an observer for seeing which direction a PR moves the architecture.&lt;/p&gt;

&lt;p&gt;For example, we may observe axes like these:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Axis&lt;/th&gt;
&lt;th&gt;What we want to observe&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Static dependencies&lt;/td&gt;
&lt;td&gt;Dependency direction and violations of forbidden dependencies.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Boundary rules&lt;/td&gt;
&lt;td&gt;Connections that cross boundaries or bypass rules.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Abstraction leakage&lt;/td&gt;
&lt;td&gt;Concrete dependencies that jump over abstractions.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Semantic drift&lt;/td&gt;
&lt;td&gt;Whether responsibilities or meanings have shifted away from what was intended.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test observability&lt;/td&gt;
&lt;td&gt;Whether the change can be observed through tests.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Per-PR change&lt;/td&gt;
&lt;td&gt;How each axis moves in a single PR.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The important point is that we do not compress good and bad into one score.&lt;/p&gt;

&lt;p&gt;What we want to know is which axes got worse, which axes improved, and what kind of force each change applies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PR
  -&amp;gt; observe change with ArchSig
  -&amp;gt; observe the trajectory of change
  -&amp;gt; see whether it is moving toward a good or bad region
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ArchSig becomes an observer for the AI PR era.&lt;/p&gt;

&lt;p&gt;Are AI-generated changes moving toward good attractors?&lt;/p&gt;

&lt;p&gt;Are they falling into a pool of technical debt?&lt;/p&gt;

&lt;p&gt;Is the harness dissipating enough bad force?&lt;/p&gt;

&lt;p&gt;ArchSig gives us shared language for discussing those questions.&lt;/p&gt;

&lt;h2&gt;
  
  
  PRs Become More Important, Not Less
&lt;/h2&gt;

&lt;p&gt;When AI reduces the cost of generating code, it may look as if PRs become less important.&lt;/p&gt;

&lt;p&gt;From a dynamical systems viewpoint, the opposite is true.&lt;/p&gt;

&lt;p&gt;A PR is not just a work unit.&lt;/p&gt;

&lt;p&gt;A PR has the following roles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It cuts continuous change into observable units.&lt;/li&gt;
&lt;li&gt;It lets us separate the directions in which a change acts.&lt;/li&gt;
&lt;li&gt;It embeds the dissipative process of review, CI, and approval.&lt;/li&gt;
&lt;li&gt;It creates a boundary for rollback and reversibility.&lt;/li&gt;
&lt;li&gt;It creates a unit for decision-making and discussion.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What AI lowers is mainly the cost of producing a PR.&lt;/p&gt;

&lt;p&gt;But the value of PRs as units of observation, decomposition, dissipation, reversibility, and decision-making increases. In the AI era, PRs do not become unnecessary. They become more important as units for observing and controlling architectural movement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Future Development Organizations
&lt;/h2&gt;

&lt;p&gt;In future development organizations, the central problem will not be only how fast we can write code. It will be how to design a field that can safely receive that speed.&lt;/p&gt;

&lt;p&gt;A fast train cannot run safely just because it has a powerful motor.&lt;/p&gt;

&lt;p&gt;It needs rails, brakes, signals, safety equipment, and operations control.&lt;/p&gt;

&lt;p&gt;Software development is similar. AI is a powerful motor, but by itself it can create semantic drift, responsibility drift, degradation of design properties we wanted to preserve, merge confusion, and flow toward technical debt.&lt;/p&gt;

&lt;p&gt;What we need is a field with properties like these:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Small and observable PRs.&lt;/li&gt;
&lt;li&gt;Fast feedback.&lt;/li&gt;
&lt;li&gt;Reliable CI.&lt;/li&gt;
&lt;li&gt;A useful type system.&lt;/li&gt;
&lt;li&gt;Architecture tests.&lt;/li&gt;
&lt;li&gt;Carefully selected reference implementations.&lt;/li&gt;
&lt;li&gt;Isolation of legacy code.&lt;/li&gt;
&lt;li&gt;Clear demands, requirements, and design boundaries.&lt;/li&gt;
&lt;li&gt;Human-designed boundaries for value and acceptance criteria.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The safest AI coding environment is not the one with the strongest external harness. It is the one where good changes are natural, easy to imitate, observable, and less likely to fall into bad shortcuts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary So Far
&lt;/h2&gt;

&lt;p&gt;The success or failure of AI-assisted development is not determined only by how fast AI can write code.&lt;/p&gt;

&lt;p&gt;The direction of the next PR changes depending on the field created by the codebase, requirements, design boundaries, reference implementations, review, CI/CD, and ArchSig.&lt;/p&gt;

&lt;p&gt;A good field attracts good changes. A bad field repeatedly makes bad changes look natural. That is why architecture design in the AI era becomes the design of where future changes are attracted.&lt;/p&gt;

&lt;p&gt;So far, this has been Attractor Engineering in practical engineering language. In the second half, I translate the same intuition into the language of AAT, Algebraic Architecture Theory, and dynamical systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  From Here, in Mathematical Language
&lt;/h2&gt;

&lt;p&gt;The rest of this article uses more mathematical formulation. If you only want the practical view first, it is fine to skip to the conclusion.&lt;/p&gt;

&lt;p&gt;Around AI development, there are many heuristics: "this prompt worked", "this workflow made us faster", and so on. These heuristics are valuable. But by themselves, they make it hard to separate why something worked, how far it generalizes, and under what conditions it breaks.&lt;/p&gt;

&lt;p&gt;So I decompose the flow: a change is selected, becomes a PR, passes review / CI, is merged, and then the updated codebase changes the distribution of future changes. By separating state, operation, observation, invariant, obstruction witness, and proof obligation, we can turn heuristics into something easier to test.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Short Introduction to AAT
&lt;/h2&gt;

&lt;p&gt;The background theory for this discussion is AAT, or Algebraic Architecture Theory. Here I introduce only the minimal vocabulary needed for the rest of the article.&lt;/p&gt;

&lt;p&gt;The Lean snippets below are excerpts from implemented APIs, adjusted for readability. Namespaces, imports, and some proof bodies are omitted.&lt;/p&gt;

&lt;p&gt;AAT treats software development not merely as a sequence of code changes, but as a theory of architectural extension, decomposition, repair, and composition.&lt;/p&gt;

&lt;p&gt;Its central proposition does not appear in Lean as one large equation. It appears as packages that combine operations and proof obligations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="n"&gt;structure&lt;/span&gt; &lt;span class="n"&gt;OperationProofObligation&lt;/span&gt; (&lt;span class="n"&gt;State&lt;/span&gt; : &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;) (&lt;span class="n"&gt;Witness&lt;/span&gt; : &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;) &lt;span class="n"&gt;where&lt;/span&gt;
  &lt;span class="n"&gt;kind&lt;/span&gt; : &lt;span class="n"&gt;ArchitectureOperationKind&lt;/span&gt;
  &lt;span class="n"&gt;obligation&lt;/span&gt; : &lt;span class="n"&gt;ProofObligation&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;Witness&lt;/span&gt;
  &lt;span class="n"&gt;precondition&lt;/span&gt; : &lt;span class="kt"&gt;Prop&lt;/span&gt;
  &lt;span class="n"&gt;nonConclusion&lt;/span&gt; : &lt;span class="kt"&gt;Prop&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Operations are first classified as an operation catalog on the Lean side.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="k"&gt;inductive&lt;/span&gt; &lt;span class="n"&gt;ArchitectureOperationKind&lt;/span&gt; &lt;span class="n"&gt;where&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;compose&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;refine&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;abstract&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;replace&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;split&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;merge&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;isolate&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;protect&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;migrate&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;reverse&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;contract&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;repair&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;synthesize&lt;/span&gt;
  &lt;span class="n"&gt;deriving&lt;/span&gt; &lt;span class="n"&gt;DecidableEq&lt;/span&gt;, &lt;span class="n"&gt;Repr&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important point is that names such as &lt;code&gt;split&lt;/code&gt; or &lt;code&gt;repair&lt;/code&gt; prove nothing by themselves. An operation kind is a classification for theorem packages. Claims about preservation, improvement, or repair must be stated separately as proof obligations.&lt;/p&gt;

&lt;p&gt;From this viewpoint, a design review is not only the question "is this design good or bad?"&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Is the existing structure embedded after extension?
- Can the new feature be split out from the existing structure?
- Do interactions pass through declared interfaces?
- Which invariants are preserved, and which invariants were broken?
- If a split is not possible, which obstruction witness blocks it?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The smallest object in AAT is &lt;code&gt;ArchitectureCore&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="n"&gt;structure&lt;/span&gt; &lt;span class="n"&gt;ArchitectureCore&lt;/span&gt; (&lt;span class="n"&gt;C&lt;/span&gt; : &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;) (&lt;span class="n"&gt;A&lt;/span&gt; : &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;)
    (&lt;span class="n"&gt;StaticObs&lt;/span&gt; : &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;) (&lt;span class="n"&gt;SemanticExpr&lt;/span&gt; : &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt;)
    (&lt;span class="n"&gt;SemanticObs&lt;/span&gt; : &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;) &lt;span class="n"&gt;where&lt;/span&gt;
  &lt;span class="n"&gt;flatness&lt;/span&gt; :
    &lt;span class="n"&gt;ArchitectureFlatnessModel&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="n"&gt;StaticObs&lt;/span&gt; &lt;span class="n"&gt;SemanticExpr&lt;/span&gt; &lt;span class="n"&gt;SemanticObs&lt;/span&gt;
  &lt;span class="n"&gt;staticUniverse&lt;/span&gt; : &lt;span class="n"&gt;ComponentUniverse&lt;/span&gt; &lt;span class="n"&gt;flatness&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;static&lt;/span&gt;
  &lt;span class="n"&gt;componentDecidableEq&lt;/span&gt; : &lt;span class="n"&gt;DecidableEq&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;
  &lt;span class="n"&gt;staticEdgeDecidable&lt;/span&gt; : &lt;span class="n"&gt;DecidableRel&lt;/span&gt; &lt;span class="n"&gt;flatness&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;static&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;edge&lt;/span&gt;
  &lt;span class="n"&gt;runtimeEdgeDecidable&lt;/span&gt; : &lt;span class="n"&gt;DecidableRel&lt;/span&gt; &lt;span class="n"&gt;flatness&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;edge&lt;/span&gt;
  &lt;span class="n"&gt;boundaryPolicyDecidable&lt;/span&gt; : &lt;span class="n"&gt;DecidableRel&lt;/span&gt; &lt;span class="n"&gt;flatness&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;boundaryAllowed&lt;/span&gt;
  &lt;span class="n"&gt;abstractionPolicyDecidable&lt;/span&gt; : &lt;span class="n"&gt;DecidableRel&lt;/span&gt; &lt;span class="n"&gt;flatness&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;abstractionAllowed&lt;/span&gt;
  &lt;span class="n"&gt;runtimeRole&lt;/span&gt; : &lt;span class="n"&gt;C&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;RuntimeDependencyRole&lt;/span&gt;
  &lt;span class="n"&gt;semanticRequiredDecidable&lt;/span&gt; :
    &lt;span class="o"&gt;∀&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; : &lt;span class="n"&gt;RequiredDiagram&lt;/span&gt; &lt;span class="n"&gt;SemanticExpr&lt;/span&gt;,
      &lt;span class="n"&gt;Decidable&lt;/span&gt; (&lt;span class="n"&gt;flatness&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;requiredSemantic&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here it is important that &lt;code&gt;ArchitectureCore&lt;/code&gt; is not the whole real-world codebase itself. It is a finite or bounded object extracted from code, specifications, reviews, and operational observations so that the theory can handle it.&lt;/p&gt;

&lt;p&gt;Feature addition is read as an operation that extends an existing architecture into a larger one while preserving the existing architecture.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ExistingCore X
  -&amp;gt; ExtendedArchitecture X'
  -&amp;gt; FeatureView F
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a good feature extension, the existing core is preserved inside the extension, the feature view can be extracted in an explainable way, and interactions from the feature to the core pass through declared interfaces. Conversely, hidden dependencies, boundary policy violations, abstraction leakage, runtime exposure, and semantic mismatch are treated not as impressions, but as &lt;code&gt;ObstructionWitness&lt;/code&gt; values.&lt;/p&gt;

&lt;p&gt;To count, remove, preserve, or explicitly decline to conclude about these obstructions, AAT makes &lt;code&gt;ProofObligation&lt;/code&gt; and &lt;code&gt;Certificate&lt;/code&gt; explicit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="n"&gt;structure&lt;/span&gt; &lt;span class="n"&gt;ProofObligation&lt;/span&gt; (&lt;span class="n"&gt;State&lt;/span&gt; : &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;) (&lt;span class="n"&gt;Witness&lt;/span&gt; : &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;) &lt;span class="n"&gt;where&lt;/span&gt;
  &lt;span class="n"&gt;formalUniverse&lt;/span&gt; : &lt;span class="kt"&gt;Prop&lt;/span&gt;
  &lt;span class="n"&gt;requiredLaws&lt;/span&gt; : &lt;span class="kt"&gt;Prop&lt;/span&gt;
  &lt;span class="n"&gt;invariantFamily&lt;/span&gt; : &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Prop&lt;/span&gt;
  &lt;span class="n"&gt;witnessUniverse&lt;/span&gt; : &lt;span class="n"&gt;Witness&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Prop&lt;/span&gt;
  &lt;span class="n"&gt;coverageAssumptions&lt;/span&gt; : &lt;span class="kt"&gt;Prop&lt;/span&gt;
  &lt;span class="n"&gt;exactnessAssumptions&lt;/span&gt; : &lt;span class="kt"&gt;Prop&lt;/span&gt;
  &lt;span class="n"&gt;operationPreconditions&lt;/span&gt; : &lt;span class="kt"&gt;Prop&lt;/span&gt;
  &lt;span class="n"&gt;conclusion&lt;/span&gt; : &lt;span class="kt"&gt;Prop&lt;/span&gt;
  &lt;span class="n"&gt;nonConclusions&lt;/span&gt; : &lt;span class="kt"&gt;Prop&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An obligation is not discharged merely because it exists. It is discharged only when the visible assumptions imply the conclusion.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;AssumptionsHold&lt;/span&gt; (&lt;span class="n"&gt;P&lt;/span&gt; : &lt;span class="n"&gt;ProofObligation&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;Witness&lt;/span&gt;) : &lt;span class="kt"&gt;Prop&lt;/span&gt; :=
  &lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;formalUniverse&lt;/span&gt; &lt;span class="o"&gt;∧&lt;/span&gt;
  &lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;requiredLaws&lt;/span&gt; &lt;span class="o"&gt;∧&lt;/span&gt;
  &lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;coverageAssumptions&lt;/span&gt; &lt;span class="o"&gt;∧&lt;/span&gt;
  &lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exactnessAssumptions&lt;/span&gt; &lt;span class="o"&gt;∧&lt;/span&gt;
  &lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;operationPreconditions&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;Discharged&lt;/span&gt; (&lt;span class="n"&gt;P&lt;/span&gt; : &lt;span class="n"&gt;ProofObligation&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;Witness&lt;/span&gt;) : &lt;span class="kt"&gt;Prop&lt;/span&gt; :=
  &lt;span class="n"&gt;AssumptionsHold&lt;/span&gt; &lt;span class="n"&gt;P&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conclusion&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same is true for certificates. For example, in repair synthesis, if we say "there is no solution", solver failure alone is not enough. Only when a valid certificate exists do we use soundness to conclude that no satisfying architecture exists.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="n"&gt;structure&lt;/span&gt; &lt;span class="n"&gt;NoSolutionCertificate&lt;/span&gt;
    &lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="n"&gt;State&lt;/span&gt; : &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Constraint&lt;/span&gt; : &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt; (&lt;span class="n"&gt;Certificate&lt;/span&gt; : &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;)
    (&lt;span class="n"&gt;C&lt;/span&gt; : &lt;span class="n"&gt;SynthesisConstraintSystem&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;Constraint&lt;/span&gt;)
    (&lt;span class="n"&gt;cert&lt;/span&gt; : &lt;span class="n"&gt;Certificate&lt;/span&gt;) &lt;span class="n"&gt;where&lt;/span&gt;
  &lt;span class="n"&gt;valid&lt;/span&gt; : &lt;span class="kt"&gt;Prop&lt;/span&gt;
  &lt;span class="n"&gt;sound&lt;/span&gt; : &lt;span class="n"&gt;valid&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;NoArchitectureSatisfies&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;
  &lt;span class="n"&gt;coverageAssumptions&lt;/span&gt; : &lt;span class="kt"&gt;Prop&lt;/span&gt;
  &lt;span class="n"&gt;exactnessAssumptions&lt;/span&gt; : &lt;span class="kt"&gt;Prop&lt;/span&gt;
  &lt;span class="n"&gt;nonConclusions&lt;/span&gt; : &lt;span class="kt"&gt;Prop&lt;/span&gt;

&lt;span class="k"&gt;theorem&lt;/span&gt; &lt;span class="n"&gt;sound_of_valid&lt;/span&gt;
    (&lt;span class="n"&gt;pkg&lt;/span&gt; : &lt;span class="n"&gt;NoSolutionCertificate&lt;/span&gt; &lt;span class="n"&gt;Certificate&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt; &lt;span class="n"&gt;cert&lt;/span&gt;)
    (&lt;span class="n"&gt;hValid&lt;/span&gt; : &lt;span class="n"&gt;ValidNoSolutionCertificate&lt;/span&gt; &lt;span class="n"&gt;pkg&lt;/span&gt;) :
    &lt;span class="n"&gt;NoArchitectureSatisfies&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;nonConclusions&lt;/code&gt; is not decoration. Even if a static split is proved, runtime flatness or semantic flatness does not automatically follow. Even if no obstruction is found in one observation universe, that does not imply there is no obstruction in every universe. Making this boundary explicit is necessary if we want to treat the theory as testable rather than as a collection of engineering anecdotes.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ArchitectureSignature&lt;/code&gt; is also not intended to collapse architecture quality into a single score. It is a multi-axis diagnosis for reading multiple invariant and obstruction families axis by axis.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="n"&gt;structure&lt;/span&gt; &lt;span class="n"&gt;ArchitectureSignatureV1&lt;/span&gt; &lt;span class="n"&gt;where&lt;/span&gt;
  &lt;span class="n"&gt;core&lt;/span&gt; : &lt;span class="n"&gt;ArchitectureSignatureV1Core&lt;/span&gt;
  &lt;span class="n"&gt;weightedSccRisk&lt;/span&gt; : &lt;span class="n"&gt;Option&lt;/span&gt; &lt;span class="n"&gt;Nat&lt;/span&gt;
  &lt;span class="n"&gt;projectionSoundnessViolation&lt;/span&gt; : &lt;span class="n"&gt;Option&lt;/span&gt; &lt;span class="n"&gt;Nat&lt;/span&gt;
  &lt;span class="n"&gt;lspViolationCount&lt;/span&gt; : &lt;span class="n"&gt;Option&lt;/span&gt; &lt;span class="n"&gt;Nat&lt;/span&gt;
  &lt;span class="n"&gt;nilpotencyIndex&lt;/span&gt; : &lt;span class="n"&gt;Option&lt;/span&gt; &lt;span class="n"&gt;Nat&lt;/span&gt;
  &lt;span class="n"&gt;runtimePropagation&lt;/span&gt; : &lt;span class="n"&gt;Option&lt;/span&gt; &lt;span class="n"&gt;Nat&lt;/span&gt;
  &lt;span class="n"&gt;relationComplexity&lt;/span&gt; : &lt;span class="n"&gt;Option&lt;/span&gt; &lt;span class="n"&gt;Nat&lt;/span&gt;
  &lt;span class="n"&gt;empiricalChangeCost&lt;/span&gt; : &lt;span class="n"&gt;Option&lt;/span&gt; &lt;span class="n"&gt;Nat&lt;/span&gt;
  &lt;span class="n"&gt;deriving&lt;/span&gt; &lt;span class="n"&gt;DecidableEq&lt;/span&gt;, &lt;span class="n"&gt;Repr&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some axes are &lt;code&gt;Option Nat&lt;/code&gt; because an unmeasured value must not be treated as zero. &lt;code&gt;none&lt;/code&gt; does not mean "no problem". It means "not measured in this universe / extractor / bridge".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="k"&gt;theorem&lt;/span&gt; &lt;span class="n"&gt;not_axisAvailableAndZero_of_axisValue_none&lt;/span&gt;
    &lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="n"&gt;sig&lt;/span&gt; : &lt;span class="n"&gt;ArchitectureSignatureV1&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="n"&gt;axis&lt;/span&gt; : &lt;span class="n"&gt;ArchitectureSignatureV1Axis&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;
    (&lt;span class="n"&gt;hNone&lt;/span&gt; : &lt;span class="n"&gt;axisValue&lt;/span&gt; &lt;span class="n"&gt;sig&lt;/span&gt; &lt;span class="n"&gt;axis&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;none&lt;/span&gt;) :
    &lt;span class="o"&gt;¬&lt;/span&gt; &lt;span class="n"&gt;axisAvailableAndZero&lt;/span&gt; &lt;span class="n"&gt;sig&lt;/span&gt; &lt;span class="n"&gt;axis&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From this perspective, a signature is not a convenient bag of metrics. It is a multi-axis invariant relative to a law universe. For selected required law axes, there are also bridge theorems connecting lawfulness and zero signature axes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="k"&gt;theorem&lt;/span&gt; &lt;span class="n"&gt;architectureLawful_iff_requiredSignatureAxesZero&lt;/span&gt;
    &lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt; : &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt; : &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Obs&lt;/span&gt; : &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;
    (&lt;span class="n"&gt;X&lt;/span&gt; : &lt;span class="n"&gt;ArchitectureLawModel&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="n"&gt;Obs&lt;/span&gt;)
    [&lt;span class="n"&gt;DecidableEq&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;] [&lt;span class="n"&gt;DecidableEq&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt;] [&lt;span class="n"&gt;DecidableEq&lt;/span&gt; &lt;span class="n"&gt;Obs&lt;/span&gt;]
    [&lt;span class="n"&gt;DecidableRel&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;G&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;edge&lt;/span&gt;] [&lt;span class="n"&gt;DecidableRel&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GA&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;edge&lt;/span&gt;]
    [&lt;span class="n"&gt;DecidableRel&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;boundaryAllowed&lt;/span&gt;]
    [&lt;span class="n"&gt;DecidableRel&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;abstractionAllowed&lt;/span&gt;] :
    &lt;span class="n"&gt;ArchitectureLawful&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="o"&gt;↔&lt;/span&gt;
      &lt;span class="n"&gt;RequiredSignatureAxesZero&lt;/span&gt; (&lt;span class="n"&gt;ArchitectureLawModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;signatureOf&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AAT does not treat every claim at the same level. It separates definitions, proved theorem packages, bounded bridge theorems, tooling-side evidence, and empirical hypotheses. It also records which universe, observation, coverage, and exactness assumptions each claim is relative to.&lt;/p&gt;

&lt;p&gt;The dynamics part below follows the same discipline. The important point is that AAT is not using mathematical vocabulary for atmosphere. It is trying to make the assumptions, conclusions, and non-conclusions part of the type-level structure.&lt;/p&gt;

&lt;p&gt;So far, AAT gives us vocabulary for a single architectural state and operations acting on it.&lt;/p&gt;

&lt;p&gt;But in AI-assisted development, the central issue is not only a single operation. Requirements, existing code, review, CI, and AI agents change which operation is likely to be selected next, and this selection is repeated many times.&lt;/p&gt;

&lt;p&gt;So we need to view AAT operations not only as one-time proof targets, but also as transformations repeatedly selected over time. This is where a chaos-game-like reading enters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Formalizing Attractor Dynamics
&lt;/h2&gt;

&lt;p&gt;From here, I use AAT vocabulary to rewrite "field", "force", "dissipation", and "observation" in a more mathematical form.&lt;/p&gt;

&lt;p&gt;This is not merely a metaphor that says "AI development is kind of like a chaos game". It is an attempt to place PR force, operation support, trajectory, and basin candidates on top of the AAT vocabulary of state, operation, invariant, obstruction, proof obligation, certificate, and signature.&lt;/p&gt;

&lt;p&gt;At this stage, I should be careful: this is not a finished theorem of real-world software development. It is a way to organize phenomena that practitioners can feel, in a structure that may eventually support measurement and verification.&lt;/p&gt;

&lt;p&gt;The minimal loop of the dynamics can be read as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;architecture field
  -&amp;gt; operation distribution
  -&amp;gt; accepted / rejected transitions
  -&amp;gt; signature trajectory
  -&amp;gt; updated architecture field
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The position is that architecture quality is not only a property of a snapshot. It is also a property of the future operation distribution and the signature trajectory.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. State, Operation, Observation
&lt;/h3&gt;

&lt;p&gt;Let the architectural state be &lt;code&gt;X_t&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Feature addition, repair, split, protection, migration, and refactoring are operations acting on that state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;X_{t+1} = op_t(X_t)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The operation &lt;code&gt;op_t&lt;/code&gt; is not selected uniformly at random.&lt;/p&gt;

&lt;p&gt;The current codebase, requirements, prompt, review policy, CI, design boundaries, and organizational judgment all change which operations are likely to be selected.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;op_t ~ P(operation | X_t, control_t)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This probability expression is notation for the practical reading. The formal core of AAT is not a probability distribution. It is finite or bounded operation support, bounded scripts, accepted transition predicates, and explicit preservation assumptions.&lt;/p&gt;

&lt;p&gt;In Lean, for example, operation support is represented not as a probability distribution, but as a finite list of candidate operations for each state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="n"&gt;structure&lt;/span&gt; &lt;span class="n"&gt;FiniteOperationKernel&lt;/span&gt;
    (&lt;span class="n"&gt;State&lt;/span&gt; : &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;) (&lt;span class="n"&gt;OperationId&lt;/span&gt; : &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;) &lt;span class="n"&gt;where&lt;/span&gt;
  &lt;span class="n"&gt;support&lt;/span&gt; : &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt; &lt;span class="n"&gt;OperationId&lt;/span&gt;
  &lt;span class="n"&gt;coverageAssumptions&lt;/span&gt; : &lt;span class="kt"&gt;Prop&lt;/span&gt;
  &lt;span class="n"&gt;weightSourceBoundary&lt;/span&gt; : &lt;span class="kt"&gt;Prop&lt;/span&gt;
  &lt;span class="n"&gt;normalizationBoundary&lt;/span&gt; : &lt;span class="kt"&gt;Prop&lt;/span&gt;
  &lt;span class="n"&gt;nonConclusions&lt;/span&gt; : &lt;span class="kt"&gt;Prop&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Weights, normalization, and completeness of AI-generated proposals are not mixed into the theorem here. Boundaries such as &lt;code&gt;weightSourceBoundary&lt;/code&gt; and &lt;code&gt;normalizationBoundary&lt;/code&gt; record what is outside the formal claim, and the probabilistic reading remains outside that core.&lt;/p&gt;

&lt;p&gt;Likewise, repeated operation sequences are first treated as bounded scripts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="n"&gt;structure&lt;/span&gt; &lt;span class="n"&gt;BoundedOperationScript&lt;/span&gt; (&lt;span class="n"&gt;OperationId&lt;/span&gt; : &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;) &lt;span class="n"&gt;where&lt;/span&gt;
  &lt;span class="n"&gt;operations&lt;/span&gt; : &lt;span class="n"&gt;List&lt;/span&gt; &lt;span class="n"&gt;OperationId&lt;/span&gt;
  &lt;span class="n"&gt;operationFamily&lt;/span&gt; : &lt;span class="n"&gt;OperationId&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Prop&lt;/span&gt;
  &lt;span class="n"&gt;operationsInFamily&lt;/span&gt; :
    &lt;span class="o"&gt;∀&lt;/span&gt; &lt;span class="n"&gt;op&lt;/span&gt;, &lt;span class="n"&gt;op&lt;/span&gt; &lt;span class="err"&gt;∈&lt;/span&gt; &lt;span class="n"&gt;operations&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;operationFamily&lt;/span&gt; &lt;span class="n"&gt;op&lt;/span&gt;
  &lt;span class="n"&gt;coverageAssumptions&lt;/span&gt; : &lt;span class="kt"&gt;Prop&lt;/span&gt;
  &lt;span class="n"&gt;nonConclusions&lt;/span&gt; : &lt;span class="kt"&gt;Prop&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This boundary helps avoid confusing probabilistic interpretation with preservation claims over finite support.&lt;/p&gt;

&lt;p&gt;Instead of observing the entire state directly, we map it into signature space through an observation function &lt;code&gt;Obs&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sigma_t = Obs(X_t)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This &lt;code&gt;sigma_t&lt;/code&gt; is the Architecture Signature.&lt;/p&gt;

&lt;p&gt;It contains multi-axis observations such as dependency direction, boundaries, abstraction, runtime exposure, and semantic mismatch.&lt;/p&gt;

&lt;p&gt;In Lean, even the observation itself is packaged. The package contains not only the observation function, but also coverage and non-conclusion boundaries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="n"&gt;structure&lt;/span&gt; &lt;span class="n"&gt;SignatureObservation&lt;/span&gt; (&lt;span class="n"&gt;State&lt;/span&gt; : &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;) (&lt;span class="n"&gt;Sig&lt;/span&gt; : &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;) &lt;span class="n"&gt;where&lt;/span&gt;
  &lt;span class="n"&gt;observe&lt;/span&gt; : &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Sig&lt;/span&gt;
  &lt;span class="n"&gt;coverageAssumptions&lt;/span&gt; : &lt;span class="kt"&gt;Prop&lt;/span&gt;
  &lt;span class="n"&gt;nonConclusions&lt;/span&gt; : &lt;span class="kt"&gt;Prop&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When architectural evolution is mapped into observation space, we get a signature trajectory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;SignatureTrajectory&lt;/span&gt; (&lt;span class="n"&gt;O&lt;/span&gt; : &lt;span class="n"&gt;SignatureObservation&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;Sig&lt;/span&gt;) :
    &lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt; : &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ArchitectureEvolution&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt; &lt;span class="n"&gt;Sig&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;, &lt;span class="n"&gt;_&lt;/span&gt;, &lt;span class="n"&gt;ArchitecturePath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; [&lt;span class="n"&gt;O&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;observe&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;]
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;, &lt;span class="n"&gt;_&lt;/span&gt;, &lt;span class="n"&gt;ArchitecturePath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cons&lt;/span&gt; &lt;span class="n"&gt;_step&lt;/span&gt; &lt;span class="n"&gt;rest&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;O&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;observe&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt; :: &lt;span class="n"&gt;SignatureTrajectory&lt;/span&gt; &lt;span class="n"&gt;O&lt;/span&gt; &lt;span class="n"&gt;rest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A change moves the signature.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Delta_t = sigma_{t+1} - sigma_t
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This &lt;code&gt;Delta_t&lt;/code&gt; can be read as the force applied by the PR or operation.&lt;/p&gt;

&lt;p&gt;However, not every axis admits simple subtraction. For numeric axes, we may read it as a signed delta. For other axes, we read it as a before / after comparison, the appearance of a witness, or a change in state classification.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. PR Force Model
&lt;/h3&gt;

&lt;p&gt;With this structure, a PR becomes more than a diff.&lt;/p&gt;

&lt;p&gt;A PR can be read as a force applied to the codebase in the selected Architecture Signature space.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PRForce(PR) = sigma(after(PR)) - sigma(before(PR))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The word force here does not mean physical force. It means an observed change in signature, relative to which axes are observed and which differences are defined.&lt;/p&gt;

&lt;p&gt;Delta sequences, like trajectories, are relative to finite paths in Lean.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;SignatureDeltaSequence&lt;/span&gt;
    (&lt;span class="n"&gt;O&lt;/span&gt; : &lt;span class="n"&gt;SignatureObservation&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;Sig&lt;/span&gt;) (&lt;span class="n"&gt;D&lt;/span&gt; : &lt;span class="n"&gt;SignatureDelta&lt;/span&gt; &lt;span class="n"&gt;Sig&lt;/span&gt; &lt;span class="n"&gt;Delta&lt;/span&gt;) :
    &lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt; : &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ArchitectureEvolution&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt; &lt;span class="n"&gt;Delta&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;, &lt;span class="n"&gt;_&lt;/span&gt;, &lt;span class="n"&gt;ArchitecturePath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; []
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;, &lt;span class="n"&gt;_&lt;/span&gt;, &lt;span class="n"&gt;ArchitecturePath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cons&lt;/span&gt; (&lt;span class="n"&gt;Y&lt;/span&gt; := &lt;span class="n"&gt;Y&lt;/span&gt;) &lt;span class="n"&gt;_step&lt;/span&gt; &lt;span class="n"&gt;rest&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;between&lt;/span&gt; (&lt;span class="n"&gt;O&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;observe&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;) (&lt;span class="n"&gt;O&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;observe&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt;) ::
        &lt;span class="n"&gt;SignatureDeltaSequence&lt;/span&gt; &lt;span class="n"&gt;O&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt; &lt;span class="n"&gt;rest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For selected additive deltas, the sum of step deltas agrees with the endpoint delta. This is proved as a theorem.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="k"&gt;theorem&lt;/span&gt; &lt;span class="n"&gt;netSignatureDelta_telescopes&lt;/span&gt; [&lt;span class="n"&gt;Zero&lt;/span&gt; &lt;span class="n"&gt;Delta&lt;/span&gt;] [&lt;span class="n"&gt;Add&lt;/span&gt; &lt;span class="n"&gt;Delta&lt;/span&gt;]
    (&lt;span class="n"&gt;O&lt;/span&gt; : &lt;span class="n"&gt;SignatureObservation&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;Sig&lt;/span&gt;) (&lt;span class="n"&gt;D&lt;/span&gt; : &lt;span class="n"&gt;SignatureDelta&lt;/span&gt; &lt;span class="n"&gt;Sig&lt;/span&gt; &lt;span class="n"&gt;Delta&lt;/span&gt;)
    (&lt;span class="n"&gt;law&lt;/span&gt; : &lt;span class="n"&gt;AdditiveSignatureDeltaLaw&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;) :
    &lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt; : &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; (&lt;span class="n"&gt;plan&lt;/span&gt; : &lt;span class="n"&gt;ArchitectureEvolution&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt;) &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;NetSignatureDelta&lt;/span&gt; (&lt;span class="n"&gt;SignatureDeltaSequence&lt;/span&gt; &lt;span class="n"&gt;O&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt; &lt;span class="n"&gt;plan&lt;/span&gt;) &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="n"&gt;EndpointSignatureDelta&lt;/span&gt; &lt;span class="n"&gt;O&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt; &lt;span class="n"&gt;plan&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But this theorem is finite path calculus under the assumption that the selected delta satisfies an additive law. It does not claim that unobserved axes, incident risk, review quality, or actual PR outcomes can all be added this way.&lt;/p&gt;

&lt;p&gt;The force has multiple components.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Force component&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Feature force&lt;/td&gt;
&lt;td&gt;The force that moves product functionality forward.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Repair force&lt;/td&gt;
&lt;td&gt;The force that repairs existing breakage.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Coupling force&lt;/td&gt;
&lt;td&gt;The force that increases or decreases coupling.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Boundary force&lt;/td&gt;
&lt;td&gt;The force that preserves or violates boundaries.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Type force&lt;/td&gt;
&lt;td&gt;The force that adds type information or creates type holes.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test force&lt;/td&gt;
&lt;td&gt;The force that increases or decreases observability through tests.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Debt force&lt;/td&gt;
&lt;td&gt;The force that pushes the system toward a bad basin.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Refactor force&lt;/td&gt;
&lt;td&gt;The force that helps it escape a bad basin.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A good PR has not only feature force, but also stabilizing force.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;v_PR = v_feature + v_stabilize
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A risky PR moves the feature forward locally while quietly adding small debt force.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;v_PR = v_feature + v_debt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In AI-generated PRs, the especially important case is one where tests pass and the specification is satisfied, but small &lt;code&gt;v_debt&lt;/code&gt;, &lt;code&gt;v_coupling&lt;/code&gt;, &lt;code&gt;v_type_hole&lt;/code&gt;, or &lt;code&gt;v_entropy&lt;/code&gt; accumulates repeatedly. It may be hard to see in a single PR. But as a trajectory, the system is moving toward a bad basin. I call this the Local Correctness Trap.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Three Classes of Force
&lt;/h3&gt;

&lt;p&gt;The earlier discussion about product managers, product owners, review, and CI/CD becomes clearer if we separate force by observability.&lt;/p&gt;

&lt;p&gt;Force can be divided into three classes.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Force class&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;th&gt;Main evidence&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ObservedForce&lt;/td&gt;
&lt;td&gt;Before / after signature delta of PRs that were actually merged.&lt;/td&gt;
&lt;td&gt;PRs, ArchSig reports, drift ledger.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LatentForce&lt;/td&gt;
&lt;td&gt;Invisible force by which requirements, design, prompts, and local code style shape which PRs are proposed.&lt;/td&gt;
&lt;td&gt;Requirements, prompts, proposal logs, case studies.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DissipatedForce&lt;/td&gt;
&lt;td&gt;Raw force that was rejected, corrected, or weakened by review / CI / types / policy.&lt;/td&gt;
&lt;td&gt;CI failures, requested changes in review, rejected proposals.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This classification makes AI-assisted development more concrete.&lt;/p&gt;

&lt;p&gt;If we look only at merged PRs, we see only ObservedForce.&lt;/p&gt;

&lt;p&gt;But in an era where AI can generate many proposals, the force that was not merged also matters. Force removed by review, rejected by CI, or reshaped before merge matters.&lt;/p&gt;

&lt;p&gt;To understand how well a dissipative system is working, we need DissipatedForce.&lt;/p&gt;

&lt;p&gt;To understand what kind of PR distribution is created by upstream requirements or prompts, we need LatentForce.&lt;/p&gt;

&lt;p&gt;In Lean, the separation between accepted and rejected changes appears as a damping / control schema.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="n"&gt;structure&lt;/span&gt; &lt;span class="n"&gt;DampingControlSchema&lt;/span&gt; (&lt;span class="n"&gt;State&lt;/span&gt; : &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;) (&lt;span class="n"&gt;Sig&lt;/span&gt; : &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;) &lt;span class="n"&gt;where&lt;/span&gt;
  &lt;span class="n"&gt;observation&lt;/span&gt; : &lt;span class="n"&gt;SignatureObservation&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;Sig&lt;/span&gt;
  &lt;span class="n"&gt;invariant&lt;/span&gt; : &lt;span class="n"&gt;SafeRegion&lt;/span&gt; &lt;span class="n"&gt;Sig&lt;/span&gt;
  &lt;span class="n"&gt;accepted&lt;/span&gt; :
    &lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt; : &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ArchitectureTransition&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Prop&lt;/span&gt;
  &lt;span class="n"&gt;rejected&lt;/span&gt; :
    &lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt; : &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ArchitectureTransition&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Prop&lt;/span&gt;
  &lt;span class="n"&gt;acceptedPreservesInvariant&lt;/span&gt; :
    &lt;span class="o"&gt;∀&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt; : &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt; (&lt;span class="n"&gt;t&lt;/span&gt; : &lt;span class="n"&gt;ArchitectureTransition&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt;),
      &lt;span class="n"&gt;accepted&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;StepPreservesSafeRegion&lt;/span&gt; &lt;span class="n"&gt;observation&lt;/span&gt; &lt;span class="n"&gt;invariant&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;
  &lt;span class="n"&gt;coverageAssumptions&lt;/span&gt; : &lt;span class="kt"&gt;Prop&lt;/span&gt;
  &lt;span class="n"&gt;nonConclusions&lt;/span&gt; : &lt;span class="kt"&gt;Prop&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What this proves is limited: transitions classified as &lt;code&gt;accepted&lt;/code&gt; preserve the explicitly stated &lt;code&gt;invariant&lt;/code&gt;. The existence of rejected changes does not prove that the whole future of the codebase is safe.&lt;/p&gt;

&lt;p&gt;On top of this schema, it is proved that accepted finite evolutions create trajectories inside the selected invariant.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="k"&gt;theorem&lt;/span&gt; &lt;span class="n"&gt;acceptedEvolution_preserves_selectedInvariant&lt;/span&gt;
    (&lt;span class="n"&gt;control&lt;/span&gt; : &lt;span class="n"&gt;DampingControlSchema&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;Sig&lt;/span&gt;) :
    &lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt; : &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; (&lt;span class="n"&gt;plan&lt;/span&gt; : &lt;span class="n"&gt;ArchitectureEvolution&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt;) &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;StateInSafeRegion&lt;/span&gt; &lt;span class="n"&gt;control&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;observation&lt;/span&gt; &lt;span class="n"&gt;control&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invariant&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;control&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AcceptedEvolution&lt;/span&gt; &lt;span class="n"&gt;plan&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="n"&gt;SignatureTrajectoryInSafeRegion&lt;/span&gt;
          &lt;span class="n"&gt;control&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invariant&lt;/span&gt; (&lt;span class="n"&gt;SignatureTrajectory&lt;/span&gt; &lt;span class="n"&gt;control&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;observation&lt;/span&gt; &lt;span class="n"&gt;plan&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. A Chaos-Game-Like Correspondence
&lt;/h3&gt;

&lt;p&gt;This is where the chaos-game-like reading appears.&lt;/p&gt;

&lt;p&gt;The similarity is that we have multiple transformations, one of them is selected at each step, and a state trajectory is produced.&lt;/p&gt;

&lt;p&gt;The difference is that, in software development, neither the set of transformations nor their likelihood is fixed. Requirements, review, CI, design boundaries, existing examples, and AI agent behavior all affect which operation is likely to be selected next.&lt;/p&gt;

&lt;p&gt;So the goal is not to claim that software development literally is the classical chaos game. The goal is to use AAT vocabulary to handle the structure where multiple operations are repeatedly selected and the resulting trajectory tends to move toward certain regions.&lt;/p&gt;

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

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Chaos-game side&lt;/th&gt;
&lt;th&gt;AAT / development side&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;State &lt;code&gt;X_t&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Architecture state / codebase field.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transformation &lt;code&gt;f_i&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Architecture operation / PR / patch.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transformation selection&lt;/td&gt;
&lt;td&gt;Operation selection by developer / AI / requirement / review.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trajectory&lt;/td&gt;
&lt;td&gt;Architecture Signature trajectory.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Attractor&lt;/td&gt;
&lt;td&gt;Signature region where the system tends to stay.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Basin&lt;/td&gt;
&lt;td&gt;Initial or surrounding states likely to fall into that attractor.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Control input&lt;/td&gt;
&lt;td&gt;Prompt, review policy, CI, type checker, architecture rule.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;As a formula:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;X_{t+1} = f_{i_t}(X_t)
i_t ~ P(. | X_t, control_t)
Y_t = sigma(X_t)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important point is not to assert probability or attractors as strong theorems too early.&lt;/p&gt;

&lt;p&gt;What we should handle in practice is first an attractor candidate or basin candidate relative to a finite observation window, bounded horizon, selected signature axes, and selected operation support.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;finite observed trajectory
  + selected signature region
  + bounded operation support
  -&amp;gt; attractor / basin candidate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not an escape into weak claims. It is a boundary that makes measurement and falsification possible.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Support Shaping
&lt;/h3&gt;

&lt;p&gt;The mathematical core of Attractor Engineering is support shaping.&lt;/p&gt;

&lt;p&gt;This is not just about "blocking bad PRs". It is about changing the set of operations that can naturally be selected next, and changing how likely they are to be selected.&lt;/p&gt;

&lt;p&gt;In short, Attractor Engineering is a theory of designing the geometry of the operation distribution.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;Supports&lt;/span&gt;
    (&lt;span class="n"&gt;kernel&lt;/span&gt; : &lt;span class="n"&gt;FiniteOperationKernel&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;OperationId&lt;/span&gt;)
    (&lt;span class="n"&gt;X&lt;/span&gt; : &lt;span class="n"&gt;State&lt;/span&gt;) (&lt;span class="n"&gt;op&lt;/span&gt; : &lt;span class="n"&gt;OperationId&lt;/span&gt;) : &lt;span class="kt"&gt;Prop&lt;/span&gt; :=
  &lt;span class="n"&gt;op&lt;/span&gt; &lt;span class="err"&gt;∈&lt;/span&gt; &lt;span class="n"&gt;kernel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;support&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the current architecture state &lt;code&gt;X&lt;/code&gt;, the set of operations that can naturally be selected is called operation support.&lt;/p&gt;

&lt;p&gt;Good design changes this support.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;SupportOperationsPreserveSafeRegion&lt;/span&gt;
    (&lt;span class="n"&gt;kernel&lt;/span&gt; : &lt;span class="n"&gt;FiniteOperationKernel&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;OperationId&lt;/span&gt;)
    (&lt;span class="n"&gt;sem&lt;/span&gt; : &lt;span class="n"&gt;OperationTransitionSemantics&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;OperationId&lt;/span&gt;)
    (&lt;span class="n"&gt;O&lt;/span&gt; : &lt;span class="n"&gt;SignatureObservation&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;Sig&lt;/span&gt;) (&lt;span class="n"&gt;R&lt;/span&gt; : &lt;span class="n"&gt;SafeRegion&lt;/span&gt; &lt;span class="n"&gt;Sig&lt;/span&gt;) : &lt;span class="kt"&gt;Prop&lt;/span&gt; :=
  &lt;span class="o"&gt;∀&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt; : &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt; (&lt;span class="n"&gt;op&lt;/span&gt; : &lt;span class="n"&gt;OperationId&lt;/span&gt;),
    &lt;span class="n"&gt;kernel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Supports&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="n"&gt;op&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;sem&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OperationPreservesSafeRegion&lt;/span&gt; &lt;span class="n"&gt;O&lt;/span&gt; &lt;span class="n"&gt;R&lt;/span&gt; &lt;span class="n"&gt;op&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The strong form of support shaping says: operations that remain in support preserve the selected safe region. In practical terms, we reduce bad operations, increase good operations, make correct paths easier to choose, and make dangerous shortcuts less convenient.&lt;/p&gt;

&lt;p&gt;This idea is packaged on the Attractor Engineering side as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="n"&gt;structure&lt;/span&gt; &lt;span class="n"&gt;AttractorEngineeringSupportPackage&lt;/span&gt;
    (&lt;span class="n"&gt;State&lt;/span&gt; : &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;) (&lt;span class="n"&gt;Sig&lt;/span&gt; : &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;) (&lt;span class="n"&gt;OperationId&lt;/span&gt; : &lt;span class="kt"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;) &lt;span class="n"&gt;where&lt;/span&gt;
  &lt;span class="n"&gt;observation&lt;/span&gt; : &lt;span class="n"&gt;SignatureObservation&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;Sig&lt;/span&gt;
  &lt;span class="n"&gt;kernel&lt;/span&gt; : &lt;span class="n"&gt;FiniteOperationKernel&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;OperationId&lt;/span&gt;
  &lt;span class="n"&gt;semantics&lt;/span&gt; : &lt;span class="n"&gt;OperationTransitionSemantics&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;OperationId&lt;/span&gt;
  &lt;span class="n"&gt;targetRegion&lt;/span&gt; : &lt;span class="n"&gt;SafeRegion&lt;/span&gt; &lt;span class="n"&gt;Sig&lt;/span&gt;
  &lt;span class="n"&gt;supportPreserves&lt;/span&gt; :
    &lt;span class="n"&gt;kernel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SupportOperationsPreserveSafeRegion&lt;/span&gt; &lt;span class="n"&gt;semantics&lt;/span&gt; &lt;span class="n"&gt;observation&lt;/span&gt; &lt;span class="n"&gt;targetRegion&lt;/span&gt;
  &lt;span class="n"&gt;coverageAssumptions&lt;/span&gt; : &lt;span class="kt"&gt;Prop&lt;/span&gt;
  &lt;span class="n"&gt;measurementBoundary&lt;/span&gt; : &lt;span class="kt"&gt;Prop&lt;/span&gt;
  &lt;span class="n"&gt;nonConclusions&lt;/span&gt; : &lt;span class="kt"&gt;Prop&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this package, if a bounded script uses only operations from finite support, and the starting point is in the target region, then the observed trajectory remains in the target region. This is stated as a theorem.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="k"&gt;theorem&lt;/span&gt; &lt;span class="n"&gt;supportPackage_preserves_targetTrajectory&lt;/span&gt;
    (&lt;span class="n"&gt;package&lt;/span&gt; : &lt;span class="n"&gt;AttractorEngineeringSupportPackage&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;Sig&lt;/span&gt; &lt;span class="n"&gt;OperationId&lt;/span&gt;)
    (&lt;span class="n"&gt;script&lt;/span&gt; : &lt;span class="n"&gt;BoundedOperationScript&lt;/span&gt; &lt;span class="n"&gt;OperationId&lt;/span&gt;)
    &lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt; : &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt; (&lt;span class="n"&gt;plan&lt;/span&gt; : &lt;span class="n"&gt;ArchitectureEvolution&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt;)
    (&lt;span class="n"&gt;hStart&lt;/span&gt; :
      &lt;span class="n"&gt;StateInSafeRegion&lt;/span&gt; &lt;span class="n"&gt;package&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;observation&lt;/span&gt; &lt;span class="n"&gt;package&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;targetRegion&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;)
    (&lt;span class="n"&gt;hRealizes&lt;/span&gt; : &lt;span class="n"&gt;script&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RealizesEvolution&lt;/span&gt; &lt;span class="n"&gt;package&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;semantics&lt;/span&gt; &lt;span class="n"&gt;plan&lt;/span&gt;)
    (&lt;span class="n"&gt;hSupport&lt;/span&gt; :
      &lt;span class="n"&gt;package&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;kernel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ScriptUsesSupport&lt;/span&gt; &lt;span class="n"&gt;script&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;operations&lt;/span&gt; &lt;span class="n"&gt;plan&lt;/span&gt;) :
    &lt;span class="n"&gt;SignatureTrajectoryInSafeRegion&lt;/span&gt; &lt;span class="n"&gt;package&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;targetRegion&lt;/span&gt;
      (&lt;span class="n"&gt;package&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TargetTrajectory&lt;/span&gt; &lt;span class="n"&gt;plan&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, good APIs, good examples, clear ownership, narrow modules, and domain states represented in types increase the local discoverability of good operations.&lt;/p&gt;

&lt;p&gt;Conversely, a huge common module, implicit global context, ambiguous services, and overly convenient helpers increase the local convenience of bad operations.&lt;/p&gt;

&lt;p&gt;From this viewpoint, refactoring is not only cleaning up the current structure. It is also a basin-reshaping operation that changes the future operation distribution.&lt;/p&gt;

&lt;p&gt;In the measurement layer, one tooling-side metric candidate to watch here is &lt;code&gt;SupportRiskMass&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SupportRiskMass(C) =
  sum over op in support(C) of weight(op) * risk(op, C)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here again, it is important not to reduce &lt;code&gt;risk&lt;/code&gt; to a simple 0 / 1.&lt;/p&gt;

&lt;p&gt;In AAT terms, we should distinguish at least:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;safe-preserving proved
safe-preserving measured
safe-preserving estimated
unsafe witness measured
unmeasured
unavailable
private
notComparable
outOfScope
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unmeasured must not be read as zero. This is a central principle in both ArchSig and AAT.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. The Same Signature Does Not Imply the Same Future
&lt;/h3&gt;

&lt;p&gt;An important point is that two states can have the same current Architecture Signature but different future operation distributions.&lt;/p&gt;

&lt;p&gt;For example, two modules might show the same number of dependency violations, the same test coverage, and the same complexity. But one may have a good canonical example nearby, while the other may contain many bad shortcuts.&lt;/p&gt;

&lt;p&gt;Even if the current observation values are the same, future PRs may be attracted in different directions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Obs(X) = Obs(Y)
  does not imply
OperationSupport(X) = OperationSupport(Y)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is why architecture quality should not be judged by snapshot metrics alone. The current value can be the same while the future force field is different. Attractor Engineering treats this future force field as a design object.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Accepted Preservation and Support Preservation Are Different
&lt;/h3&gt;

&lt;p&gt;There is another important separation.&lt;/p&gt;

&lt;p&gt;Suppose review and CI ensure that merged PRs preserve a safe region.&lt;/p&gt;

&lt;p&gt;Even then, unsafe operations may still remain inside operation support.&lt;/p&gt;

&lt;p&gt;This separation is not just a warning. It appears on the Lean side as a finite counterexample. Accepted-step invariant preservation can hold, and an accepted safe step can exist, while operations that do not preserve the safe region remain in support.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="k"&gt;theorem&lt;/span&gt; &lt;span class="n"&gt;acceptedPreservation_not_supportPreservation_counterexample&lt;/span&gt; :
    (&lt;span class="o"&gt;∃&lt;/span&gt; (&lt;span class="n"&gt;t&lt;/span&gt; : &lt;span class="n"&gt;ArchitectureTransition&lt;/span&gt; &lt;span class="n"&gt;ExampleState&lt;/span&gt; &lt;span class="n"&gt;safeState&lt;/span&gt; &lt;span class="n"&gt;safeState&lt;/span&gt;),
      &lt;span class="n"&gt;control&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AcceptedStep&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;∧&lt;/span&gt;
        &lt;span class="n"&gt;StepPreservesSafeRegion&lt;/span&gt; &lt;span class="n"&gt;control&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;observation&lt;/span&gt; &lt;span class="n"&gt;control&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invariant&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;) &lt;span class="o"&gt;∧&lt;/span&gt;
    (&lt;span class="o"&gt;∀&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt; : &lt;span class="n"&gt;ExampleState&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt; (&lt;span class="n"&gt;t&lt;/span&gt; : &lt;span class="n"&gt;ArchitectureTransition&lt;/span&gt; &lt;span class="n"&gt;ExampleState&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt;),
      &lt;span class="n"&gt;control&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AcceptedStep&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="n"&gt;StepPreservesSafeRegion&lt;/span&gt; &lt;span class="n"&gt;control&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;observation&lt;/span&gt; &lt;span class="n"&gt;control&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invariant&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;) &lt;span class="o"&gt;∧&lt;/span&gt;
    (&lt;span class="o"&gt;∃&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="n"&gt;op&lt;/span&gt;,
      &lt;span class="n"&gt;kernel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Supports&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="n"&gt;op&lt;/span&gt; &lt;span class="o"&gt;∧&lt;/span&gt;
        &lt;span class="o"&gt;¬&lt;/span&gt; &lt;span class="n"&gt;semantics&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OperationPreservesSafeRegion&lt;/span&gt; &lt;span class="n"&gt;control&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;observation&lt;/span&gt;
          &lt;span class="n"&gt;control&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invariant&lt;/span&gt; &lt;span class="n"&gt;op&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the difference between guardrails and attractor engineering.&lt;/p&gt;

&lt;p&gt;Strong guardrails may stop bad PRs.&lt;/p&gt;

&lt;p&gt;But a field where bad PRs are produced in large numbers every time is still not a good field.&lt;/p&gt;

&lt;p&gt;A good field is one where bad operations are less likely to appear in the first place, and good operations are natural, easy to imitate, observable, and low-friction.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. PRs Are Non-Commutative
&lt;/h3&gt;

&lt;p&gt;PRs are generally non-commutative.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PR_2 o PR_1 != PR_1 o PR_2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course, this only makes sense when both orders can be applied. Even then, the same two PRs can produce different final signatures depending on merge order.&lt;/p&gt;

&lt;p&gt;This matters in an era where AI agents can generate multiple PRs in parallel.&lt;/p&gt;

&lt;p&gt;Even when individual PRs are locally correct, their order can change boundaries, types, tests, and semantic alignment.&lt;/p&gt;

&lt;p&gt;I call this merge order sensitivity.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MergeOrderSensitivity(a, b, X) =
  distance(
    sigma(b(a(X))),
    sigma(a(b(X)))
  )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not merely a merge conflict issue. It is the non-commutativity of operation algebra branching the signature trajectory. We will need this viewpoint when evaluating teams of AI agents as well.&lt;/p&gt;

&lt;h3&gt;
  
  
  9. Observe the Shape of the Trajectory
&lt;/h3&gt;

&lt;p&gt;Architecture Signature should be read not only as a current value, but also as a trajectory.&lt;/p&gt;

&lt;p&gt;Even if the endpoint is safe, the path may have passed through a bad region.&lt;/p&gt;

&lt;p&gt;Even if net delta is zero, there may have been large churn inside the path.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;endpoint safe
  does not imply path safe

net force zero
  does not imply no excursion
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is also proved in Lean as a small finite counterexample. In a trajectory such as &lt;code&gt;0 -&amp;gt; 2 -&amp;gt; 0&lt;/code&gt;, both endpoints are the same safe state. The endpoint delta and net delta can both appear to be zero, while the path passed through an unsafe region.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lean"&gt;&lt;code&gt;&lt;span class="k"&gt;theorem&lt;/span&gt; &lt;span class="n"&gt;netSignatureDelta_eq_zero&lt;/span&gt; :
    &lt;span class="n"&gt;NetSignatureDelta&lt;/span&gt; (&lt;span class="n"&gt;SignatureDeltaSequence&lt;/span&gt; &lt;span class="n"&gt;observation&lt;/span&gt; &lt;span class="n"&gt;signedNatDelta&lt;/span&gt;
      &lt;span class="n"&gt;excursionPlan&lt;/span&gt;) &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="k"&gt;theorem&lt;/span&gt; &lt;span class="n"&gt;endpointSafe_and_zeroDelta_but_not_pathSafe&lt;/span&gt; :
    &lt;span class="n"&gt;EndpointSignatureDelta&lt;/span&gt; &lt;span class="n"&gt;observation&lt;/span&gt; &lt;span class="n"&gt;signedNatDelta&lt;/span&gt; &lt;span class="n"&gt;excursionPlan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;∧&lt;/span&gt;
      &lt;span class="n"&gt;StateInSafeRegion&lt;/span&gt; &lt;span class="n"&gt;observation&lt;/span&gt; &lt;span class="n"&gt;safeRegion&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;∧&lt;/span&gt;
      &lt;span class="n"&gt;StateInSafeRegion&lt;/span&gt; &lt;span class="n"&gt;observation&lt;/span&gt; &lt;span class="n"&gt;safeRegion&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;∧&lt;/span&gt;
      &lt;span class="o"&gt;¬&lt;/span&gt; &lt;span class="n"&gt;SignatureTrajectoryInSafeRegion&lt;/span&gt; &lt;span class="n"&gt;safeRegion&lt;/span&gt;
          (&lt;span class="n"&gt;SignatureTrajectory&lt;/span&gt; &lt;span class="n"&gt;observation&lt;/span&gt; &lt;span class="n"&gt;excursionPlan&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Trajectories have shapes.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Trajectory type&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Stable Orbit&lt;/td&gt;
&lt;td&gt;The system returns to a safe region after small changes.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Drift&lt;/td&gt;
&lt;td&gt;The system slowly shifts toward a bad region.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Spiral Debt&lt;/td&gt;
&lt;td&gt;It appears to return, but over the long run moves closer to a bad basin.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sudden Phase Shift&lt;/td&gt;
&lt;td&gt;A signature changes sharply after a particular PR.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Oscillation&lt;/td&gt;
&lt;td&gt;Feature additions and refactorings alternate between good and bad.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Basin Capture&lt;/td&gt;
&lt;td&gt;After some point, the system gets captured by a bad structure.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;What ArchSig really wants to observe is this trajectory.&lt;/p&gt;

&lt;p&gt;Not just the evaluation of one PR, but the resulting motion produced by a group of PRs.&lt;/p&gt;

&lt;h3&gt;
  
  
  10. Expanding Observation Can Suddenly Reveal Badness
&lt;/h3&gt;

&lt;p&gt;With coarse observation, a codebase may look safe.&lt;/p&gt;

&lt;p&gt;But if we add more observation axes, a hidden obstruction may suddenly appear as nonzero.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;coarse observation:
  safe

refined observation:
  hidden obstruction appears
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can call this an observability expansion shock.&lt;/p&gt;

&lt;p&gt;The important point is that this does not necessarily mean the architecture got worse. It may simply mean that an axis that used to be invisible has become visible.&lt;/p&gt;

&lt;p&gt;That is why ArchSig must distinguish &lt;code&gt;unmeasured&lt;/code&gt; from &lt;code&gt;zero&lt;/code&gt;. When something that was not measured becomes visible, we must separate "the architecture got worse" from "the observation became better".&lt;/p&gt;

&lt;h3&gt;
  
  
  About the Lean Formalization
&lt;/h3&gt;

&lt;p&gt;The structure above is not built only from metaphor. Some of the core vocabulary of AAT has been implemented as Lean definitions and theorems under &lt;code&gt;Formal/Arch&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The repository is &lt;a href="https://github.com/iroha1203/AlgebraicArchitectureTheoryV2" rel="noopener noreferrer"&gt;AlgebraicArchitectureTheoryV2&lt;/a&gt;. The proved API is summarized in the &lt;a href="https://github.com/iroha1203/AlgebraicArchitectureTheoryV2/blob/main/docs/aat/lean_theorem_index.md" rel="noopener noreferrer"&gt;Lean definition and theorem index&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The vocabulary used in the second half of this article mainly corresponds to &lt;code&gt;Formal/Arch/Evolution/SignatureDynamics.lean&lt;/code&gt; and &lt;code&gt;Formal/Arch/Evolution/AttractorEngineering.lean&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The role of Lean formalization is not to give this theory an aura of correctness. Its role is to record, with boundaries, what can be said under which universe, observation, coverage, and exactness assumptions.&lt;/p&gt;

&lt;p&gt;It is important that counterexamples live in the same place as proved theorems.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;proved:
  accepted evolution preserves selected invariant
  bounded sampled support-preserving script stays in target region
  selected additive delta telescopes over finite path

proved counterexamples:
  endpoint safe + zero delta does not imply path safe
  accepted preservation does not imply support preservation
  unmeasured axis is not available-zero evidence
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Conversely, the fact that something is proved in Lean does not mean that a real-world code extractor is complete, or that every runtime / semantic obstruction has already been observed. With this boundary, AAT can separate what is formally known, what depends on measurement, and what remains an empirical research question.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The discovery of Attractor Engineering changes how I see software architecture: from a static blueprint to a field that guides future changes.&lt;/p&gt;

&lt;p&gt;If software architecture is read as an algebraic structure, feature additions and refactorings become operations.&lt;/p&gt;

&lt;p&gt;When those operations are repeated, the architecture state draws a trajectory.&lt;/p&gt;

&lt;p&gt;We can then ask where that trajectory tends to go, and where it tends to stay. This is where attractors and basins enter the picture.&lt;/p&gt;

&lt;p&gt;Architecture design in the era of AI-assisted development can be described as creating a field where future changes gather in good places and can escape bad places.&lt;/p&gt;

&lt;p&gt;Harness engineering becomes the engineering of receiving AI's change force, dissipating unwanted components, and guiding the system toward good attractors.&lt;/p&gt;

&lt;p&gt;ArchSig is the tool for observing that trajectory.&lt;/p&gt;

&lt;p&gt;The essence of AI-assisted development is not only producing PRs faster.&lt;/p&gt;

&lt;p&gt;It is deciding where fast force should converge.&lt;/p&gt;

&lt;p&gt;A codebase is a field.&lt;/p&gt;

&lt;p&gt;A PR is a force.&lt;/p&gt;

&lt;p&gt;CI/CD is a dissipative system.&lt;/p&gt;

&lt;p&gt;Product managers, product owners, engineers, reviewers, and AI agents are participants in the field.&lt;/p&gt;

&lt;p&gt;ArchSig is an observer of the trajectory.&lt;/p&gt;

&lt;p&gt;With this framing, development in the AI era is no longer just automation. It becomes field design.&lt;/p&gt;

&lt;p&gt;As a design theory for that purpose, Attractor Engineering may be a useful direction for both practice and research.&lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>architecture</category>
      <category>ai</category>
      <category>computerscience</category>
    </item>
  </channel>
</rss>
