<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Hiroyuki Nakahata</title>
    <description>The latest articles on DEV Community by Hiroyuki Nakahata (@iroha1203).</description>
    <link>https://dev.to/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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3921684%2F387c0a8d-8e0c-41a8-b158-5a3349179896.png</url>
      <title>DEV Community: Hiroyuki Nakahata</title>
      <link>https://dev.to/iroha1203</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/iroha1203"/>
    <language>en</language>
    <item>
      <title>Atom Is All You Need: Read a Codebase as an Atom Map, Not a Dependency Graph</title>
      <dc:creator>Hiroyuki Nakahata</dc:creator>
      <pubDate>Sun, 31 May 2026 16:55:51 +0000</pubDate>
      <link>https://dev.to/iroha1203/atom-is-all-you-need-read-a-codebase-as-an-atom-map-not-a-dependency-graph-e5d</link>
      <guid>https://dev.to/iroha1203/atom-is-all-you-need-read-a-codebase-as-an-atom-map-not-a-dependency-graph-e5d</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the AI era, architecture analysis cannot stop at reading code as files, functions, imports, and dependency graphs.&lt;/p&gt;

&lt;p&gt;We need to observe the smallest units that carry architectural meaning. I call those units &lt;code&gt;Atom&lt;/code&gt;s.&lt;/p&gt;

&lt;p&gt;By extracting Atoms from a codebase and reading the algebraic structure they generate, we can analyze architecture beyond ordinary dependency relationships.&lt;/p&gt;

&lt;p&gt;The workflow looks like this:&lt;/p&gt;


&lt;pre class="highlight plaintext"&gt;&lt;code&gt;codebase
  -&amp;gt; Atom observations
  -&amp;gt; ArchMap
  + LawPolicy
  -&amp;gt; ArchSig analysis packet
  -&amp;gt; architecture reading
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;This lets us see design pressure, semantic coupling, missing evidence, and review focus that ordinary linting, static analysis, and dependency graphs often miss.&lt;/p&gt;

&lt;p&gt;We built a new tool for this workflow: &lt;a href="https://github.com/iroha1203/AlgebraicArchitectureTheoryV2/tree/main/tools/archsig" rel="noopener noreferrer"&gt;ArchSig&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The repository is public and MIT licensed, so you can try it on your own codebases.&lt;/p&gt;

&lt;p&gt;The key idea is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Architecture analysis does not need a bigger natural-language summary.&lt;/p&gt;

&lt;p&gt;It needs the right unit of observation.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why We Need an Architecture Analyzer
&lt;/h2&gt;

&lt;p&gt;AI agents can write code fast.&lt;/p&gt;

&lt;p&gt;But writing code fast is not the same thing as evolving a system well.&lt;/p&gt;

&lt;p&gt;For an AI agent, the codebase is the largest prompt.&lt;/p&gt;

&lt;p&gt;If the existing codebase contains shortcuts, those shortcuts become examples.&lt;br&gt;
If boundaries are vague, new code naturally lands in vague places.&lt;br&gt;
If responsibilities are mixed, that mixing becomes part of the next implementation context.&lt;/p&gt;

&lt;p&gt;Traditional tools often look at the current shape of code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;import graphs&lt;/li&gt;
&lt;li&gt;dependency cycles&lt;/li&gt;
&lt;li&gt;layer violations&lt;/li&gt;
&lt;li&gt;lint rules&lt;/li&gt;
&lt;li&gt;complexity metrics&lt;/li&gt;
&lt;li&gt;test coverage&lt;/li&gt;
&lt;li&gt;security rules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of these matter.&lt;/p&gt;

&lt;p&gt;But in AI-era architecture review, we often want to ask deeper questions.&lt;/p&gt;

&lt;p&gt;Imagine a business backend where users select input data, run automated processing or generation, persist the result, receive events from external systems, run async jobs, call external providers, and save generated artifacts back into business state.&lt;/p&gt;

&lt;p&gt;The important questions are not only:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Are the dependencies pointing in the right direction?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We also want to know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Who is allowed to use which input for which operation?&lt;/li&gt;
&lt;li&gt;Through which validation path does generated output become persisted state?&lt;/li&gt;
&lt;li&gt;Where is an external provider failure recorded as durable state?&lt;/li&gt;
&lt;li&gt;Do two workflows that produce the same artifact actually have the same effect order?&lt;/li&gt;
&lt;li&gt;Do entrypoint-level permissions match the intended business scope?&lt;/li&gt;
&lt;li&gt;Are privileged operations separated from ordinary workflow authority?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are difficult to read from a dependency graph alone.&lt;/p&gt;

&lt;p&gt;We need to read code not only as a collection of files and functions, but as a set of observations that carry architectural meaning.&lt;/p&gt;

&lt;p&gt;That unit is the &lt;code&gt;Atom&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Atom: The Smallest Unit of Architectural Meaning
&lt;/h2&gt;

&lt;p&gt;An Atom is the smallest observation unit I want to use when reading architecture.&lt;/p&gt;

&lt;p&gt;It is not necessarily a function, class, module, or file.&lt;/p&gt;

&lt;p&gt;In practice, it is the thing you point at during review and say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is a boundary.&lt;/p&gt;

&lt;p&gt;This is state.&lt;/p&gt;

&lt;p&gt;This is an effect.&lt;/p&gt;

&lt;p&gt;This is a contract.&lt;/p&gt;

&lt;p&gt;This is where trust changes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Examples of Atom families include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;component atom&lt;/code&gt;: an architectural unit exists&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;relation atom&lt;/code&gt;: two units or atoms are related&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;capability atom&lt;/code&gt;: a unit provides a specific capability&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;state atom&lt;/code&gt;: something is persisted or held as state&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;effect atom&lt;/code&gt;: an external call or side effect occurs&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;authority atom&lt;/code&gt;: someone is allowed to do something&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;trust relation atom&lt;/code&gt;: some output or provider is trusted up to a boundary&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;contract atom&lt;/code&gt;: inputs, outputs, preconditions, or failure behavior are promised&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;semantic atom&lt;/code&gt;: something has architectural meaning beyond its code location&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important point is that an Atom is not small in the syntactic sense.&lt;/p&gt;

&lt;p&gt;It is small in the architectural sense.&lt;/p&gt;

&lt;p&gt;For example, the observation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Only an authorized actor may update this resource.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;may cross multiple files.&lt;/p&gt;

&lt;p&gt;The observation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Generated output must pass through a service-level contract before persistence.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;may cross a route, service, validation layer, job state, and repository.&lt;/p&gt;

&lt;p&gt;Still, each observation is one meaningful unit in architecture review.&lt;/p&gt;

&lt;p&gt;That is what an Atom records.&lt;/p&gt;
&lt;h2&gt;
  
  
  A Small Code Example
&lt;/h2&gt;

&lt;p&gt;Even a tiny function can contain multiple Atoms.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;publish_artifact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;artifact_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gateway&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;artifact&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load_for_actor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;artifact_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;gateway&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;artifact&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;artifact&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mark_published&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;artifact&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we only say "this is one function," we miss most of the architectural content.&lt;/p&gt;

&lt;p&gt;Read as Atoms, we can observe at least:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;component&lt;/code&gt;: &lt;code&gt;repository&lt;/code&gt; and &lt;code&gt;gateway&lt;/code&gt; are architectural units&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;relation&lt;/code&gt;: the handler flows into both the repository and the gateway&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;capability&lt;/code&gt;: the repository provides load/save, while the gateway provides publish&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;state&lt;/code&gt;: the artifact's published state is persisted&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;effect&lt;/code&gt;: &lt;code&gt;gateway.publish&lt;/code&gt; changes external state&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;authority&lt;/code&gt;: the actor must be allowed to publish this artifact&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;trust_relation&lt;/code&gt;: the gateway response and failure behavior must be trusted only through a boundary&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;contract&lt;/code&gt;: publish success, save failure, and retry behavior need explicit promises&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;semantic&lt;/code&gt;: published is not only a flag; it means externally visible&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These nine Atom schemas are the basic vocabulary for treating primitive architectural facts as generators of an architecture object.&lt;/p&gt;

&lt;h2&gt;
  
  
  ArchMap: Turning a Codebase into an Atom Map
&lt;/h2&gt;

&lt;p&gt;An &lt;code&gt;ArchMap&lt;/code&gt; is a map of these observations.&lt;/p&gt;

&lt;p&gt;It is not a full copy of the codebase.&lt;br&gt;
It is not an AST dump.&lt;br&gt;
It is not only a dependency graph.&lt;/p&gt;

&lt;p&gt;It is a source-grounded map of architectural observations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;source code
  observed as
Atom / Molecule / Semantic observations
  recorded as
ArchMap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If an Atom is one observation, a Molecule is a finite composition of Atoms that acts as one responsibility boundary.&lt;/p&gt;

&lt;p&gt;For example, an ArchMap of a backend might contain Molecules such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;authenticated request boundary&lt;/li&gt;
&lt;li&gt;credential lifecycle&lt;/li&gt;
&lt;li&gt;repository transaction boundary&lt;/li&gt;
&lt;li&gt;interactive processing workflow&lt;/li&gt;
&lt;li&gt;input-to-artifact pipeline&lt;/li&gt;
&lt;li&gt;external integration ingress&lt;/li&gt;
&lt;li&gt;job-managed generation surface&lt;/li&gt;
&lt;li&gt;input-backed artifact boundary&lt;/li&gt;
&lt;li&gt;edge policy and observability boundary&lt;/li&gt;
&lt;li&gt;privileged governance boundary&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important point is not that the codebase has folders such as &lt;code&gt;api&lt;/code&gt;, &lt;code&gt;services&lt;/code&gt;, &lt;code&gt;repositories&lt;/code&gt;, and &lt;code&gt;models&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The important point is that architectural meaning sits on top of those folders:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;authority&lt;/li&gt;
&lt;li&gt;generation&lt;/li&gt;
&lt;li&gt;external effect&lt;/li&gt;
&lt;li&gt;durable state&lt;/li&gt;
&lt;li&gt;artifact lifecycle&lt;/li&gt;
&lt;li&gt;semantic contract&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ArchMap records that meaning in a machine-readable form.&lt;/p&gt;

&lt;h2&gt;
  
  
  AAT: Reading Structure from an Atom Map
&lt;/h2&gt;

&lt;p&gt;Once we have an ArchMap, we can ask a different kind of question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Under which laws does this architecture object have pressure?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AAT, Algebraic Architecture Theory, reads software architecture as an algebraic structure generated from Atoms.&lt;/p&gt;

&lt;p&gt;It studies architecture through objects, operations, laws, invariants, obstructions, and signature axes.&lt;/p&gt;

&lt;p&gt;I will leave the detailed theory to &lt;a href="https://iroha1203.dev/aat/" rel="noopener noreferrer"&gt;Algebraic Architecture Theory&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For this article, the intuition is enough:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;law&lt;/code&gt;: a design property we want to preserve&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;witness&lt;/code&gt;: observed evidence related to that property&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;obstruction&lt;/code&gt;: a structure that blocks the law&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;signature axis&lt;/code&gt;: the direction in which pressure appears&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;operation&lt;/code&gt;: a design operation such as split, move, protect, or refactor&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;path / homotopy&lt;/code&gt;: whether two change paths preserve the same structure&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;curvature / holonomy&lt;/code&gt;: when something looks locally natural but becomes inconsistent around a loop&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In ordinary review, engineers often process these ideas in their heads:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This responsibility is mixed.&lt;/p&gt;

&lt;p&gt;This external call should not be inside the transaction.&lt;/p&gt;

&lt;p&gt;These two job statuses look the same, but the failure paths differ.&lt;/p&gt;

&lt;p&gt;This generated output must be validated before it becomes domain state.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AAT tries to move this review vocabulary toward something we can compute.&lt;/p&gt;

&lt;p&gt;The important step is to treat Atoms not as labels, but as primitive facts that generate architecture objects.&lt;/p&gt;

&lt;p&gt;Once Atoms carry relation, state, effect, contract, and semantic axes, we can see things a dependency graph cannot show:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a locally natural change that changes effect order through another path&lt;/li&gt;
&lt;li&gt;a split that moves complexity to another boundary&lt;/li&gt;
&lt;li&gt;two workflows that look statically similar but differ under a semantic contract&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are non-trivial architecture readings.&lt;/p&gt;

&lt;p&gt;They should not live only in a senior engineer's intuition.&lt;/p&gt;

&lt;p&gt;They should be tied to a selected law universe and a selected set of witnesses.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  ArchSig: Reading Structure from ArchMap + LawPolicy
&lt;/h2&gt;

&lt;p&gt;ArchSig takes an ArchMap and a LawPolicy, then produces an AAT-style analysis packet.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ArchMap
  + LawPolicy
  -&amp;gt; ArchSig
  -&amp;gt; analysis packet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;LawPolicy&lt;/code&gt; is the interpretation profile.&lt;/p&gt;

&lt;p&gt;It selects the law universe, witness rules, signature axes, measurement policy, and coverage requirements for the analysis.&lt;/p&gt;

&lt;p&gt;The same ArchMap can be read in different ways depending on what you care about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;authority boundaries&lt;/li&gt;
&lt;li&gt;state/effect consistency&lt;/li&gt;
&lt;li&gt;generated output mediation&lt;/li&gt;
&lt;li&gt;domain cohesion&lt;/li&gt;
&lt;li&gt;permission coverage&lt;/li&gt;
&lt;li&gt;repair preconditions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ArchSig does not collapse all of this into one "good / bad" score.&lt;/p&gt;

&lt;p&gt;It reports pressure and semantic coupling along different axes.&lt;/p&gt;

&lt;p&gt;The output can include readings such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;nonzero pressure by law axis&lt;/li&gt;
&lt;li&gt;workflow risk&lt;/li&gt;
&lt;li&gt;transfer bridge pressure&lt;/li&gt;
&lt;li&gt;state/effect reconciliation pressure&lt;/li&gt;
&lt;li&gt;operation squares&lt;/li&gt;
&lt;li&gt;axis-wise monodromy defects&lt;/li&gt;
&lt;li&gt;architectural holes&lt;/li&gt;
&lt;li&gt;boundary holonomy&lt;/li&gt;
&lt;li&gt;repair precondition blockers&lt;/li&gt;
&lt;li&gt;review focus&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not a code quality score.&lt;/p&gt;

&lt;p&gt;It is a measurement surface for reading where design pressure and semantic coupling appear.&lt;/p&gt;

&lt;h2&gt;
  
  
  Case Study: Analyzing a Backend Repository
&lt;/h2&gt;

&lt;p&gt;So far, the discussion has been conceptual.&lt;/p&gt;

&lt;p&gt;Now let us look at the shape of one backend repository through ArchSig.&lt;/p&gt;

&lt;p&gt;This repository has multiple users, authority boundaries, business data, external effects, async jobs, and generated outputs.&lt;/p&gt;

&lt;p&gt;Users select input data and run analysis, generation, extraction, or transformation workflows.&lt;br&gt;
External systems send events.&lt;br&gt;
Async jobs call providers.&lt;br&gt;
Results are persisted as business artifacts.&lt;/p&gt;

&lt;p&gt;From the ArchMap, ArchSig could read structures like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a backend split into API, service, repository, model, schema, and task layers&lt;/li&gt;
&lt;li&gt;authority boundaries across users, organizations, and resources&lt;/li&gt;
&lt;li&gt;a domain model where multiple artifacts derive from input data&lt;/li&gt;
&lt;li&gt;generated output mediated by service contracts and job state&lt;/li&gt;
&lt;li&gt;external provider effects paired with durable job state&lt;/li&gt;
&lt;li&gt;privileged operations separated from ordinary workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is already different from a dependency graph.&lt;/p&gt;

&lt;p&gt;ArchSig reads the repository as a business backend with authority boundaries, generated outputs, external effects, and durable state.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Design Pressure It Found
&lt;/h2&gt;

&lt;p&gt;The strongest pressure appeared at the intersection of authority and generation.&lt;/p&gt;

&lt;p&gt;The system is not merely saying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An authenticated actor can run generation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The real architectural question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Who can use which resource as input, and which generated output can become which domain state?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is a central boundary.&lt;/p&gt;

&lt;p&gt;Reviewing only authorization is not enough.&lt;br&gt;
Reviewing only the generation job is not enough.&lt;br&gt;
The two boundaries are bridged.&lt;/p&gt;

&lt;p&gt;The next large pressure was state/effect reconciliation.&lt;/p&gt;

&lt;p&gt;The repository has external providers, async jobs, event handlers, retries, roundtrips, and compensation paths.&lt;/p&gt;

&lt;p&gt;In this kind of system, not everything can live inside one transaction.&lt;/p&gt;

&lt;p&gt;The architecture needs durable intermediate state, external effect recovery, explicit failure finalization, and retryable paths.&lt;/p&gt;

&lt;p&gt;ArchSig reads this through the relation between state atoms and effect atoms.&lt;/p&gt;

&lt;p&gt;The third pressure was generated output mediation.&lt;/p&gt;

&lt;p&gt;Generated output is useful, but it should not become domain state without mediation.&lt;/p&gt;

&lt;p&gt;You need input construction, structured output, filtering, validation, job failure handling, and persistence gates.&lt;/p&gt;

&lt;p&gt;In this repository, the mediation appeared across multiple workflows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;interactive workflows&lt;/li&gt;
&lt;li&gt;analysis execution&lt;/li&gt;
&lt;li&gt;content extraction&lt;/li&gt;
&lt;li&gt;generated artifact creation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the design question is not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Does the system use generation?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The real question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Through which contract does generated output pass before it becomes domain state?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is not just dependency analysis.&lt;/p&gt;

&lt;p&gt;It is a reading of where authority, state, effect, contract, and semantic meaning overlap.&lt;/p&gt;
&lt;h2&gt;
  
  
  Same Destination, Different Path
&lt;/h2&gt;

&lt;p&gt;One of the most interesting ArchSig readings is the monodromy defect.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Two paths may appear to arrive at the same place.&lt;/p&gt;

&lt;p&gt;But do they preserve the same structure?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the repository, several workflows looked similar from the outside.&lt;/p&gt;

&lt;p&gt;They produced artifacts or updated state.&lt;/p&gt;

&lt;p&gt;But the order of provider calls, repository commits, job state transitions, and status finalization could differ.&lt;/p&gt;

&lt;p&gt;A dependency graph may not show that.&lt;/p&gt;

&lt;p&gt;Even if the static dependencies point in the same direction, the workflow path can change failure behavior.&lt;/p&gt;

&lt;p&gt;Does the system create state before calling the provider?&lt;br&gt;
Does it call the provider first?&lt;br&gt;
Where is failure finalized?&lt;br&gt;
Does retry use the same idempotency key?&lt;/p&gt;

&lt;p&gt;ArchSig reads this kind of path difference as operation squares and axis-wise defects.&lt;/p&gt;

&lt;p&gt;This is practical in review.&lt;/p&gt;

&lt;p&gt;When someone says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This follows the existing pattern.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;ArchSig helps ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Does it really?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It may look like the same endpoint.&lt;br&gt;
It may create the same kind of artifact.&lt;/p&gt;

&lt;p&gt;But if the effect order differs, the operational behavior differs.&lt;/p&gt;

&lt;p&gt;That difference often becomes incident cost or future refactoring cost.&lt;/p&gt;
&lt;h2&gt;
  
  
  Architectural Holes: Loops That Do Not Close
&lt;/h2&gt;

&lt;p&gt;Another important result was the architectural hole.&lt;/p&gt;

&lt;p&gt;ArchSig found holes around paths such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API -&amp;gt; service -&amp;gt; repository&lt;/li&gt;
&lt;li&gt;async provider jobs&lt;/li&gt;
&lt;li&gt;generated output -&amp;gt; domain state promotion&lt;/li&gt;
&lt;li&gt;semantic contracts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This does not mean "there is a bug."&lt;/p&gt;

&lt;p&gt;It means the evidence is not enough to say the architectural loop is closed.&lt;/p&gt;

&lt;p&gt;For example, the path from generated output to domain state may involve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;input data&lt;/li&gt;
&lt;li&gt;context construction&lt;/li&gt;
&lt;li&gt;structured output&lt;/li&gt;
&lt;li&gt;validation&lt;/li&gt;
&lt;li&gt;job state&lt;/li&gt;
&lt;li&gt;repository persistence&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To say this loop is closed, source reading alone is not enough.&lt;/p&gt;

&lt;p&gt;You may need test evidence, runtime traces, provider logs, and entrypoint-by-entrypoint permission audits.&lt;/p&gt;

&lt;p&gt;ArchSig does not treat missing evidence as zero.&lt;/p&gt;

&lt;p&gt;It preserves it as a hole.&lt;/p&gt;

&lt;p&gt;That matters because one of the dangerous failure modes in architecture review is to read "unknown" as "fine."&lt;/p&gt;

&lt;p&gt;ArchSig keeps the gap visible.&lt;/p&gt;

&lt;p&gt;And the gap becomes a review proposal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gap:
  - permission evidence is incomplete
  - runtime trace is missing
  - provider failure path is not covered

review proposal:
  - human reviewer: check authority boundary and failure handling
  - LLM reviewer: compare the generated output path with the declared contract
  - test reviewer: add evidence for retry and finalization behavior
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In other words, ArchSig does not hide uncertainty.&lt;/p&gt;

&lt;p&gt;It turns uncertainty into review focus.&lt;/p&gt;

&lt;h2&gt;
  
  
  Spectral Analysis: Where Pressure Comes Back
&lt;/h2&gt;

&lt;p&gt;One of the most interesting parts of ArchSig is &lt;code&gt;ArchitectureSpectrumReport&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Ordinary review often ends with a list of issues.&lt;/p&gt;

&lt;p&gt;But in architecture, pressure does not always appear once and disappear.&lt;/p&gt;

&lt;p&gt;An authority mismatch can show up in generated output persistence.&lt;br&gt;
From there it can move into job state.&lt;br&gt;
Then it can come back through retry behavior or provider failure handling.&lt;/p&gt;

&lt;p&gt;Spectral analysis reads this recurrence.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curvature support
  -&amp;gt; transfer edge
  -&amp;gt; recurrent mode
  -&amp;gt; hotspot / witness cluster
  -&amp;gt; review focus
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, the point is not a single score.&lt;/p&gt;

&lt;p&gt;The interesting questions are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where does pressure concentrate?&lt;/li&gt;
&lt;li&gt;Which obstructions recur?&lt;/li&gt;
&lt;li&gt;Which witness clusters cross multiple law axes?&lt;/li&gt;
&lt;li&gt;Which coverage gaps block a zero reading?&lt;/li&gt;
&lt;li&gt;Which boundary should be reviewed before a repair candidate is trusted?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From a dependency graph, a workflow may look cleanly separated.&lt;/p&gt;

&lt;p&gt;But spectral analysis may show remaining transfer between effect order, semantic contract, job state, and authority boundary.&lt;/p&gt;

&lt;p&gt;That is not simply "there is a cycle."&lt;/p&gt;

&lt;p&gt;It is a more structural reading:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Locally separate pressures return to the same support inside the architecture object.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;ArchSig can surface that as a hotspot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Repair Candidates Are Not Automatic Fixes
&lt;/h2&gt;

&lt;p&gt;ArchSig can also produce repair candidates.&lt;/p&gt;

&lt;p&gt;In this repository, many candidates were stopped by precondition blockers.&lt;/p&gt;

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

&lt;p&gt;Seeing pressure does not mean the system should immediately be split or rewritten.&lt;/p&gt;

&lt;p&gt;If you cut one boundary, complexity may move somewhere else.&lt;br&gt;
Fixing authority may increase runtime effect pressure.&lt;br&gt;
Strengthening generated output mediation may change job state and retry paths.&lt;/p&gt;

&lt;p&gt;ArchSig does not treat repair as an automatic safe edit.&lt;/p&gt;

&lt;p&gt;It checks preconditions, witnesses, coverage, and transfer risk.&lt;/p&gt;

&lt;p&gt;This is close to how experienced engineers review architecture:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This looks risky.&lt;/p&gt;

&lt;p&gt;But before fixing it, we need this evidence.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That difference matters.&lt;/p&gt;
&lt;h2&gt;
  
  
  How This Differs from Existing Tools
&lt;/h2&gt;

&lt;p&gt;So what exactly is different?&lt;/p&gt;

&lt;p&gt;Existing tools are good at reading the current shape of code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does a dependency cycle exist?&lt;/li&gt;
&lt;li&gt;Is there a layer violation?&lt;/li&gt;
&lt;li&gt;Is test coverage missing?&lt;/li&gt;
&lt;li&gt;Is a security rule violated?&lt;/li&gt;
&lt;li&gt;Is complexity too high?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ArchSig is trying to read something else:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where are responsibility boundaries composed?&lt;/li&gt;
&lt;li&gt;On which law axis does pressure appear?&lt;/li&gt;
&lt;li&gt;Do two paths with the same destination preserve the same effect order?&lt;/li&gt;
&lt;li&gt;Where do generated output, external providers, authority, and durable state intersect?&lt;/li&gt;
&lt;li&gt;Would a repair candidate move complexity to another boundary?&lt;/li&gt;
&lt;li&gt;Which evidence is missing, and therefore should become review focus?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not a code quality metric.&lt;/p&gt;

&lt;p&gt;It is an instrument for reading architectural state.&lt;/p&gt;

&lt;p&gt;Another important point is that review can happen around the ArchMap artifact.&lt;/p&gt;

&lt;p&gt;The source-grounded observation still has to be produced from real code.&lt;/p&gt;

&lt;p&gt;But after that, sharing, reviewing, and comparing can happen around ArchMap and the analysis packet.&lt;/p&gt;

&lt;p&gt;That matters for teams and companies that cannot freely share full codebases.&lt;/p&gt;

&lt;p&gt;There is also an AI angle.&lt;/p&gt;

&lt;p&gt;If you simply ask an LLM to review a large codebase, the full context will not fit.&lt;/p&gt;

&lt;p&gt;Even if it does fit, it is hard to make the model consistently focus on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the right boundary&lt;/li&gt;
&lt;li&gt;the missing evidence&lt;/li&gt;
&lt;li&gt;the relevant law axis&lt;/li&gt;
&lt;li&gt;the path where effect order differs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ArchMap and ArchSig change the shape of the context.&lt;/p&gt;

&lt;p&gt;Instead of handing the model all code and asking for a huge summary, you hand it Atoms, Molecules, law axes, holes, and review focus.&lt;/p&gt;

&lt;p&gt;Then the model can reason around the architecture boundary that actually matters.&lt;/p&gt;
&lt;h2&gt;
  
  
  Atom Is All You Need
&lt;/h2&gt;

&lt;p&gt;Trying to understand a large codebase all at once breaks down quickly.&lt;/p&gt;

&lt;p&gt;There are too many files.&lt;br&gt;
Too many functions.&lt;br&gt;
Too many dependencies.&lt;br&gt;
Too many external providers.&lt;br&gt;
Too much code added by fast AI agents.&lt;/p&gt;

&lt;p&gt;So start with Atoms.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;component
relation
capability
state
effect
authority
trust_relation
contract
semantic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Observe them.&lt;br&gt;
Record them as an ArchMap.&lt;br&gt;
Choose a LawPolicy.&lt;br&gt;
Run ArchSig.&lt;/p&gt;

&lt;p&gt;This lets us read meaningful architecture boundaries without pretending we can understand the entire codebase at once.&lt;/p&gt;

&lt;p&gt;What AI-era architecture analysis needs is not a larger natural-language summary.&lt;/p&gt;

&lt;p&gt;It needs the right unit of observation.&lt;/p&gt;

&lt;p&gt;Atom is all you need.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Review Experience This Enables
&lt;/h2&gt;

&lt;p&gt;Future review could look like this.&lt;/p&gt;

&lt;p&gt;First, generate an ArchMap delta from a codebase or pull request.&lt;/p&gt;

&lt;p&gt;Then run ArchSig using the team's selected LawPolicy.&lt;/p&gt;

&lt;p&gt;The reviewer no longer has to read the entire diff as a flat pile of changes.&lt;/p&gt;

&lt;p&gt;They can focus on the boundaries that require design judgment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This change touches:
  - authority boundary
  - generated output mediation
  - state/effect reconciliation
  - async provider job path

Measured pressure:
  - nonzero on permission coverage axis
  - positive path continuation defect on effect axis
  - architectural hole on output promotion path

Review focus:
  - entrypoint-level permission evidence
  - job finalization behavior
  - provider failure handling
  - persistence gate before domain promotion
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AI agents can read the same packet.&lt;/p&gt;

&lt;p&gt;They can implement with more than a request like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Just add the feature.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They can receive architectural constraints:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Preserve this Atom.&lt;/p&gt;

&lt;p&gt;Do not cross this boundary.&lt;/p&gt;

&lt;p&gt;Do not increase pressure on this law axis.&lt;/p&gt;

&lt;p&gt;Do not treat these paths as equivalent; their effect order differs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That matters because AI agents are strongly shaped by context.&lt;/p&gt;

&lt;p&gt;If you give them only the codebase, you also give them every existing shortcut.&lt;/p&gt;

&lt;p&gt;If you give them the ArchMap and the ArchSig analysis packet, you also give them the architecture's structural pressure and semantic coupling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;ArchSig is not a tool for grading code.&lt;/p&gt;

&lt;p&gt;It is an architecture analyzer for reading a codebase as an Atom map, then using AAT to surface design pressure, semantic coupling, holes, and repair preconditions.&lt;/p&gt;

&lt;p&gt;It does not replace dependency graphs, lint, coverage, or security tools.&lt;/p&gt;

&lt;p&gt;Those are still important.&lt;/p&gt;

&lt;p&gt;But there are questions they do not answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where do authority and generated output intersect?&lt;/li&gt;
&lt;li&gt;Where does state/effect order diverge?&lt;/li&gt;
&lt;li&gt;Are two paths that create the same artifact really the same architecture operation?&lt;/li&gt;
&lt;li&gt;Would this repair candidate transfer complexity to another boundary?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those are the questions ArchSig is built to make visible.&lt;/p&gt;

&lt;p&gt;Start from Atoms.&lt;br&gt;
Record them in ArchMap.&lt;br&gt;
Read them through AAT.&lt;br&gt;
Analyze them with ArchSig.&lt;/p&gt;

&lt;p&gt;That is the architecture analysis shape I wanted to introduce.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Comes Next: SFT and FieldSig
&lt;/h2&gt;

&lt;p&gt;We are also working on the next layer of this research.&lt;/p&gt;

&lt;p&gt;AAT makes software architecture locally algebraic.&lt;/p&gt;

&lt;p&gt;ArchSig becomes an observation instrument for that local algebra: it takes Atom observations and law-relative structure from a codebase and turns them into an analysis packet.&lt;/p&gt;

&lt;p&gt;Beyond that is SFT, Software Field Theory.&lt;/p&gt;

&lt;p&gt;SFT is about software evolution.&lt;/p&gt;

&lt;p&gt;It does not only ask about the current architecture state.&lt;/p&gt;

&lt;p&gt;It asks how review, AI agents, CI, operational feedback, and organizational decisions change the space of possible future software states.&lt;/p&gt;

&lt;p&gt;FieldSig is the next measurement surface.&lt;/p&gt;

&lt;p&gt;It reads ArchSig analysis packets and workflow evidence in order to make software evolution more computable.&lt;/p&gt;

&lt;p&gt;ArchSig is the entrance.&lt;/p&gt;

&lt;p&gt;That said, ArchSig is still at v0.3.1.&lt;/p&gt;

&lt;p&gt;I do not want it to be judged as a finished product yet.&lt;/p&gt;

&lt;p&gt;I want people to try it on many different repositories and tell us what it reads well, what it misses, and where the model feels wrong.&lt;/p&gt;

&lt;p&gt;Good reads and bad reads are both valuable for the research.&lt;/p&gt;

&lt;p&gt;You can get the ArchSig release bundles here:&lt;/p&gt;

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

</description>
      <category>ai</category>
      <category>softwareengineering</category>
      <category>architecture</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I Open-Sourced the AAT / SFT Research Repository</title>
      <dc:creator>Hiroyuki Nakahata</dc:creator>
      <pubDate>Sun, 24 May 2026 05:13:39 +0000</pubDate>
      <link>https://dev.to/iroha1203/i-open-sourced-the-aat-sft-research-repository-360h</link>
      <guid>https://dev.to/iroha1203/i-open-sourced-the-aat-sft-research-repository-360h</guid>
      <description>&lt;p&gt;I open-sourced the AAT / SFT research repository.&lt;/p&gt;

&lt;p&gt;Repository:&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;

&lt;p&gt;This repository is for building theory and tools that treat software architecture not only as a blueprint or a list of best practices, but as something that keeps evolving through changes, reviews, CI, operations, and proposals from AI agents.&lt;/p&gt;

&lt;p&gt;The larger goal is to make the evolution of software and computers something we can measure, compare, and reason about, instead of only looking back after the fact.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Research Is About
&lt;/h2&gt;

&lt;p&gt;The repository is organized around three ideas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AAT makes architecture locally algebraic.
ArchSig makes architecture observable.
SFT makes software evolution computable.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;AAT&lt;/strong&gt; stands for Algebraic Architecture Theory.&lt;/p&gt;

&lt;p&gt;It treats software architecture as a local algebraic structure.&lt;/p&gt;

&lt;p&gt;In more practical terms, it asks questions like these:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Did this design change preserve dependency direction?&lt;/li&gt;
&lt;li&gt;Did it cross a layer boundary?&lt;/li&gt;
&lt;li&gt;Does it still depend on abstractions instead of concrete details?&lt;/li&gt;
&lt;li&gt;Did it make failures easier to spread?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;ArchSig&lt;/strong&gt; is a set of tools for extracting architecture signals from real codebases and pull requests.&lt;/p&gt;

&lt;p&gt;It is not meant to produce one big "good / bad" score. Instead, it separates different kinds of risk: dependency cycles, boundary violations, abstraction leaks, unmeasured parts of the system, and other signals that should be read separately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SFT&lt;/strong&gt; stands for Software Field Theory.&lt;/p&gt;

&lt;p&gt;It treats software evolution as a sequence of changes and tries to make that evolution computable.&lt;/p&gt;

&lt;p&gt;PRDs, issues, pull requests, reviews, CI, organizations, and AI agents do not only affect the current change. They also shape what kind of change is likely to happen next.&lt;/p&gt;

&lt;p&gt;For example, a vague PRD can invite an ad hoc implementation. A codebase with clear boundaries tends to make the next change easier to place cleanly. SFT develops concepts for reasoning about what futures become easier to reach after a change.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I Am Building This
&lt;/h2&gt;

&lt;p&gt;AI can generate working code very quickly.&lt;/p&gt;

&lt;p&gt;But whether a fast diff makes future changes easier, or instead adds more ad hoc implementation, is a different question.&lt;/p&gt;

&lt;p&gt;The question is not only:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Do the tests pass?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I also want to ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Did this change preserve the design properties we care about?&lt;/li&gt;
&lt;li&gt;If not, what code or dependency shows the problem?&lt;/li&gt;
&lt;li&gt;Is the problem a dependency cycle, a boundary violation, or an abstraction leak?&lt;/li&gt;
&lt;li&gt;Does this PRD, issue, or pull request make the next change easier to move in a good direction?&lt;/li&gt;
&lt;li&gt;Can review and CI stop risky change patterns early?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The motivation behind this repository is to turn those questions into something we can formalize, observe, and eventually support with tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is In The Repository
&lt;/h2&gt;

&lt;p&gt;The repository currently contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lean formalization for AAT&lt;/li&gt;
&lt;li&gt;Research notes for AAT and SFT&lt;/li&gt;
&lt;li&gt;Rust implementation of the ArchSig tools&lt;/li&gt;
&lt;li&gt;Open proof tasks and a Lean theorem index&lt;/li&gt;
&lt;li&gt;A static website for reading AAT, SFT, and ArchSig&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On the Lean side, I am building small theorem packages with explicit assumptions.&lt;/p&gt;

&lt;p&gt;On the Rust tooling side, I am working toward reports that extract design signals from codebases and pull requests, then make them readable in review and CI.&lt;/p&gt;

&lt;p&gt;On the website side, I am preparing public-facing research notes and manuals for AAT, SFT, and ArchSig.&lt;/p&gt;

&lt;h2&gt;
  
  
  This Is Still Research
&lt;/h2&gt;

&lt;p&gt;This repository is a working research space, not a finished product.&lt;/p&gt;

&lt;p&gt;I separate different kinds of claims:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what has been proved mathematically,&lt;/li&gt;
&lt;li&gt;what has only been defined so far,&lt;/li&gt;
&lt;li&gt;what I want to prove later,&lt;/li&gt;
&lt;li&gt;and what should be checked against real development data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, a theorem proved in Lean does not automatically predict the future of a real project.&lt;/p&gt;

&lt;p&gt;There is a difference between a tool saying "this dependency was observed," Lean proving "this property follows under these assumptions," and empirical work saying "this trend seems to appear in real development data."&lt;/p&gt;

&lt;p&gt;The repository keeps those claims separate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where To Start
&lt;/h2&gt;

&lt;p&gt;The README is the best entry point.&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;

&lt;p&gt;If you want to go deeper, I recommend this order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Research goal&lt;/li&gt;
&lt;li&gt;AAT mathematical theory&lt;/li&gt;
&lt;li&gt;AAT / SFT interface&lt;/li&gt;
&lt;li&gt;Software Field Theory&lt;/li&gt;
&lt;li&gt;Lean definitions and theorem index&lt;/li&gt;
&lt;li&gt;ArchSig tooling documentation&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Website
&lt;/h2&gt;

&lt;p&gt;There is also a website for reading AAT, SFT, and ArchSig as connected research notes.&lt;/p&gt;

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

&lt;p&gt;If you want the big picture before reading code or proof details, the website is the easier place to start.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;The short version is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I want to treat software architecture and software evolution as things we can observe, diagnose, and compute.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I do not want design principles to remain slogans.&lt;/p&gt;

&lt;p&gt;I want to ask what properties they preserve, what failures they reveal, and what futures they make easier to reach.&lt;/p&gt;

&lt;p&gt;This repository is where I am building the theory, formalization, tools, and public notes for that direction.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>architecture</category>
      <category>computerscience</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Forecast Cone: A Grand Theorem for Computable Software Evolution</title>
      <dc:creator>Hiroyuki Nakahata</dc:creator>
      <pubDate>Fri, 22 May 2026 17:50:41 +0000</pubDate>
      <link>https://dev.to/iroha1203/forecast-cone-a-grand-theorem-for-computable-software-evolution-521p</link>
      <guid>https://dev.to/iroha1203/forecast-cone-a-grand-theorem-for-computable-software-evolution-521p</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This article starts from the &lt;code&gt;ForecastCone&lt;/code&gt; in Software Field Theory (SFT), then reads modularity, technical debt, review, governance, and learning as parts of one research program.&lt;/p&gt;

&lt;p&gt;The goal is simple to state:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Make it possible to see what futures a change opens, close dangerous futures early, and shape the development environment so good futures become easier to reach.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If this theorem-shaped program works, architecture, technical debt, review, governance, and AI coding safety can all be reread around the same object: the &lt;code&gt;ForecastCone&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We are also formalizing this direction in Lean by breaking concepts such as &lt;code&gt;ForecastCone&lt;/code&gt; and &lt;code&gt;ConsequenceEnvelope&lt;/code&gt; into small records and theorem packages.&lt;/p&gt;


&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  For the Bigger AAT / SFT Picture
&lt;/h2&gt;

&lt;p&gt;I introduced the broader AAT / SFT framing here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://blog.iroha1203.dev/software-architecture-as-a-field" rel="noopener noreferrer"&gt;Software Architecture as a Field: Asking Better Questions About Software Evolution&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://iroha1203.dev/aat/" rel="noopener noreferrer"&gt;Algebraic Architecture Theory&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://iroha1203.dev/sft/" rel="noopener noreferrer"&gt;Software Field Theory&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Problem: Fast Code Is Not the Same as Healthy Evolution
&lt;/h2&gt;

&lt;p&gt;For an AI agent, the codebase itself is the largest prompt.&lt;/p&gt;

&lt;p&gt;If the existing code contains many shortcuts, the agent can easily learn those patterns.&lt;br&gt;
If boundaries are vague, the agent will naturally add the next change in the vague place.&lt;br&gt;
A good structure attracts good changes. A bad structure repeatedly makes bad shortcuts look natural.&lt;/p&gt;

&lt;p&gt;PRDs, issues, review policies, and CI rules do not only decide "this change."&lt;br&gt;
They shape what the next PR tends to look like, which modules feel natural to touch, which boundaries are easy to miss, and which shortcuts are likely to pass.&lt;/p&gt;

&lt;p&gt;In vibe coding, for example, an AI agent can quickly produce a plausible implementation from an underspecified PRD.&lt;/p&gt;

&lt;p&gt;A PRD that only says "make coupons usable" may turn into a small &lt;code&gt;if&lt;/code&gt; inside the checkout flow.&lt;br&gt;
The first demo works.&lt;br&gt;
But if that change leaves pricing policy, refunds, usage limits, and audit logs as vague boundaries, the next PR will often build on the same shortcut.&lt;/p&gt;

&lt;p&gt;The problem is not that AI writes bad code.&lt;br&gt;
The problem is that vague artifacts plus fast generation can open bad future paths very quickly.&lt;br&gt;
A bad field can be amplified by AI into larger technical debt.&lt;/p&gt;

&lt;p&gt;Traditional review, CI, and metrics often look at the current diff or at outcomes that already happened.&lt;br&gt;
In the AI era, that is not enough.&lt;/p&gt;

&lt;p&gt;The question is no longer only:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Does this PR pass right now?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The deeper question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What future does this PRD, this agent, this codebase, and this review rule open next?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;SFT needs &lt;code&gt;ForecastCone&lt;/code&gt; in order to ask that question.&lt;br&gt;
It gives us an object for making software evolution computable, not as a mere sequence of changes, but as a space of reachable futures.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Grand Theorem: A Fundamental Theorem of Software Evolution
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Modularity
  = ForecastCone descent

Technical debt
  = descent obstruction

Review
  = minimal decision-preserving envelope

Governance
  = desired-cone-preserving obstruction cutting

Learning
  = closed-loop boundary-explicit fixed point
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In this article, I will call this theorem-shaped picture the &lt;strong&gt;Fundamental Theorem of Software Evolution&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In everyday engineering language, it says something like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A good architecture boundary lets teams and AI agents work separately, then combine their changes safely later.&lt;/p&gt;

&lt;p&gt;Technical debt is the ability to explain, with a concrete cause, why integration keeps breaking at the same place.&lt;/p&gt;

&lt;p&gt;In review, we do not want every diff line or every possible future. We want the dangerous futures that matter for the decision.&lt;/p&gt;

&lt;p&gt;Governance should not just add rules that stop development. It should close bad shortcuts and make good implementation paths easier to choose.&lt;/p&gt;

&lt;p&gt;Learning means using actual PRs, incidents, and review outcomes to update the next forecast and the next rule.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In more mathematical language:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A good architecture boundary is not merely a static dependency cut. It is a boundary across which future evolution paths can be computed locally and glued into a global future under compatibility conditions.&lt;/p&gt;

&lt;p&gt;Technical debt is an obstruction that appears when that gluing fails.&lt;/p&gt;

&lt;p&gt;Review is not the act of seeing the entire ForecastCone. It is the act of seeing an envelope that preserves the distinctions needed for a decision.&lt;/p&gt;

&lt;p&gt;Governance is a support transformation that removes bad futures while preserving desired futures.&lt;/p&gt;

&lt;p&gt;Learning is a closed-loop update that moves a field estimate toward a boundary-explicit fixed point using PRs, incidents, reviews, and operational outcomes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If such a theorem can be proved, the way we reason about software evolution changes.&lt;/p&gt;

&lt;p&gt;Whether an architecture is good, where technical debt sits, what a reviewer needs to see, which governance rule is effective, and how the field model should be updated next can be studied over the same computational object.&lt;/p&gt;

&lt;p&gt;That object is the &lt;code&gt;ForecastCone&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  ForecastCone: The Range of Reachable Futures
&lt;/h2&gt;

&lt;p&gt;SFT reads the development environment as a &lt;code&gt;field&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;codebase
  + artifacts
  + practices
  + agents
  + governance
  + feedback
  -&amp;gt; reachable software futures
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The range of futures reachable under that field is what SFT calls a &lt;code&gt;ForecastCone&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwz6ro9mjtmuzpvlojxjz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwz6ro9mjtmuzpvlojxjz.png" alt="forecast cone" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A ForecastCone is not a prophecy.&lt;/p&gt;

&lt;p&gt;SFT does not say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This PRD will definitely produce this PR.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead, it asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Under this field model, operation support, policy, observation boundary, and horizon, which future paths are reachable?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Imagine an e-commerce service receives a PRD: "Add limited-time coupons."&lt;/p&gt;

&lt;p&gt;That PRD does not open just one future.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One future adds a small branch to the checkout flow.&lt;/li&gt;
&lt;li&gt;One future adds a discount policy to the pricing service.&lt;/li&gt;
&lt;li&gt;One future introduces an independent coupon domain.&lt;/li&gt;
&lt;li&gt;One future expands into campaign rules and audit logs.&lt;/li&gt;
&lt;li&gt;One future adds a database column for now and leaves cleanup for later.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of these are, in some sense, "coupon support."&lt;br&gt;
But they open very different next futures.&lt;/p&gt;

&lt;p&gt;The ForecastCone is the object that lets us look at that difference.&lt;br&gt;
The same PRD can make different futures easy or hard to reach depending on the current codebase, module boundaries, past workarounds, review rules, CI, and AI agent behavior.&lt;/p&gt;
&lt;h2&gt;
  
  
  Modularity = ForecastCone Descent
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Modularity
  = ForecastCone descent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


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

&lt;blockquote&gt;
&lt;p&gt;The global future of a software system can be computed by gluing compatible local futures.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Traditional modularity is often described in terms of APIs, dependency direction, and responsibility separation.&lt;br&gt;
SOLID, Layered Architecture, Clean Architecture, and Design Patterns have often been used as ways to help humans understand responsibilities, localize change, and control dependencies.&lt;/p&gt;

&lt;p&gt;SFT extends that line of thought by asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Do the futures glue?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If a boundary is truly modular, we should be able to reason about the future of &lt;code&gt;Pricing&lt;/code&gt; and the future of &lt;code&gt;Checkout&lt;/code&gt; locally, then glue them into one checkout future under the right compatibility conditions.&lt;/p&gt;

&lt;p&gt;The boundary is not just a line. It is a place where future evolution should cross without breaking.&lt;/p&gt;

&lt;p&gt;In practice, following SOLID and Layered Architecture already gets us a lot of the way toward this kind of modularity.&lt;/p&gt;
&lt;h2&gt;
  
  
  Technical Debt = Descent Obstruction
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Technical debt
  = descent obstruction
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The intuition is that technical debt can be read as a failure of futures to glue.&lt;/p&gt;

&lt;p&gt;local tests pass.&lt;br&gt;
local reviews pass.&lt;br&gt;
the AI proposal looks reasonable.&lt;br&gt;
then integration breaks.&lt;/p&gt;

&lt;p&gt;SFT does not want to stop at "the design is bad."&lt;br&gt;
It wants to record the failure as an obstruction.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DescentFailure:
  missing interface invariant

Witness:
  Pricing returns a discounted total,
  but Checkout treats it as a tax-included final charge.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now technical debt is no longer just a feeling.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Each team-local change looks reasonable, but the whole system cannot combine them into a valid global future.&lt;br&gt;
The reason is that the boundary rule that should have been preserved was never defined.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is the role of the &lt;code&gt;Descent Obstruction Theorem&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Review = Minimal Decision-Preserving Envelope
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Review
  = minimal decision-preserving envelope
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A ForecastCone can be large.&lt;br&gt;
A reviewer cannot look at every future path.&lt;br&gt;
But a diff alone is often too small.&lt;/p&gt;

&lt;p&gt;Suppose an AI agent produces a PR 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;if coupon_code.present?
  total = total - discount
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The diff is small.&lt;br&gt;
But the reviewer does not only care about these three lines.&lt;/p&gt;

&lt;p&gt;Will this add an unobserved branch to the refund path?&lt;br&gt;
Will usage limits collide with retry behavior?&lt;br&gt;
Is the tax boundary between &lt;code&gt;Pricing&lt;/code&gt; and &lt;code&gt;Checkout&lt;/code&gt; still undefined?&lt;/p&gt;

&lt;p&gt;What we need is not the whole ForecastCone, but the part needed for a review decision.&lt;br&gt;
SFT calls this a &lt;code&gt;ConsequenceEnvelope&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The goal for review tooling is not to show everything.&lt;br&gt;
It is to show the future-relevant differences needed for the decision, no more and no less.&lt;/p&gt;
&lt;h2&gt;
  
  
  Governance = Desired-Cone-Preserving Obstruction Cutting
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Governance
  = desired-cone-preserving obstruction cutting
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;When a risky future appears, the simplest response is to add another rule.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Anything coupon-related must be reviewed by a senior engineer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is a guardrail.&lt;br&gt;
But it is often heavy, and it may not say what future it is actually closing.&lt;/p&gt;

&lt;p&gt;The kind of governance SFT wants is more specific: close bad futures while preserving desired ones.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Introduce separate &lt;code&gt;DiscountedTotal&lt;/code&gt; and &lt;code&gt;FinalCharge&lt;/code&gt; types across the &lt;code&gt;Pricing&lt;/code&gt; / &lt;code&gt;Checkout&lt;/code&gt; boundary.&lt;/li&gt;
&lt;li&gt;Make coupon usage updates idempotent.&lt;/li&gt;
&lt;li&gt;Require coupon invariant checks when touching the refund path.&lt;/li&gt;
&lt;li&gt;Guide AI agents away from ad hoc discount branches under checkout and toward policy objects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We want to close the future where discount logic spreads across checkout.&lt;br&gt;
We still want to preserve the future where coupon policy can evolve independently.&lt;/p&gt;

&lt;p&gt;That difference is what the &lt;code&gt;Governance Synthesis Theorem&lt;/code&gt; is about.&lt;br&gt;
It is not just about adding guardrails. It is about shaping the field.&lt;/p&gt;
&lt;h2&gt;
  
  
  Learning = Closed-Loop Boundary-Explicit Fixed Point
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Learning
  = closed-loop boundary-explicit fixed point
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;SFT is not a theory where we compute one ForecastCone and stop.&lt;/p&gt;

&lt;p&gt;Predicted future paths are compared with actual PRs, incidents, review comments, CI failures, and runtime observations.&lt;br&gt;
When the forecast is wrong, that is not just a failure.&lt;br&gt;
It becomes evidence for updating the model.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Was the field estimate too coarse?&lt;/li&gt;
&lt;li&gt;Was the observation boundary too narrow?&lt;/li&gt;
&lt;li&gt;Did the policy model fail to represent actual review behavior?&lt;/li&gt;
&lt;li&gt;Should the unknown remainder have been made explicit?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As this closed loop progresses, an SFT workbench becomes more than an analyzer.&lt;br&gt;
It becomes a system for continuously calibrating the field model of software evolution.&lt;/p&gt;
&lt;h2&gt;
  
  
  Attractor Engineering and ArchSig
&lt;/h2&gt;

&lt;p&gt;This grand theorem becomes practical only when it connects to AAT and ArchSig.&lt;/p&gt;

&lt;p&gt;AAT gives us a local theory for reading what a change preserves and what it breaks.&lt;br&gt;
ArchSig gives us a signature layer for observing preservation and breakage from repositories, PRs, reviews, CI, and incidents.&lt;br&gt;
SFT uses those observations to compute reachable futures and connect them to governance and learning.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AAT
  -&amp;gt; local laws / invariants / obstruction witnesses

ArchSig
  -&amp;gt; observed signatures / measured axes / evidence boundaries

SFT
  -&amp;gt; ForecastCone / ConsequenceEnvelope / governance update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Attractor Engineering fits here as well.&lt;/p&gt;

&lt;p&gt;A good architecture attracts good changes.&lt;br&gt;
A bad architecture repeatedly makes the same shortcut look natural.&lt;/p&gt;

&lt;p&gt;In SFT language, this means the shape of reachable futures changes.&lt;br&gt;
Governance interventions close bad future paths, type boundaries make good local evolution more natural, and review rules make risky paths observable.&lt;/p&gt;

&lt;p&gt;Attractor Engineering is the practice of shaping the ForecastCone.&lt;br&gt;
ArchSig is a tool for observing that change.&lt;br&gt;
SFT connects those observations back to the theorem family.&lt;/p&gt;
&lt;h2&gt;
  
  
  A Sketch of a Future Development Workflow
&lt;/h2&gt;

&lt;p&gt;SFT is not trying to build a system that decides the future instead of developers.&lt;br&gt;
It is trying to make a development environment where developers, AI agents, reviews, and CI can see the future opened by a change on the same map.&lt;/p&gt;

&lt;p&gt;An ambiguous PRD arrives.&lt;br&gt;
An AI agent quickly proposes an implementation.&lt;br&gt;
At the same time, a workbench sketches the futures that change seems to open and shows only the differences needed for review.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PRD
  -&amp;gt; implementation candidates
  -&amp;gt; reachable future range
  -&amp;gt; review-relevant differences
  -&amp;gt; review / CI / governance
  -&amp;gt; observed outcome
  -&amp;gt; next forecast update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before reading every line of the diff, the reviewer sees which futures look risky.&lt;br&gt;
CI checks not only whether tests pass, but whether a risk we wanted to close is still present.&lt;br&gt;
The AI agent prioritizes implementation candidates that open better futures instead of copying the nearest shortcut.&lt;/p&gt;

&lt;p&gt;Actual PRs, incidents, and review comments then become evidence for the next forecast.&lt;/p&gt;

&lt;p&gt;That is the development workflow SFT is aiming toward.&lt;/p&gt;
&lt;h2&gt;
  
  
  Impact on Computer Science and Software Engineering
&lt;/h2&gt;

&lt;p&gt;Lehman raised a core question of software evolution: long-lived software keeps changing as it adapts to its environment, and that change tends to increase complexity.&lt;/p&gt;

&lt;p&gt;SFT revisits that question in the age of AI-assisted development.&lt;/p&gt;

&lt;p&gt;Software engineering has long developed design and architecture theory around human cognition.&lt;/p&gt;

&lt;p&gt;That makes sense.&lt;br&gt;
Software is complex, and if humans cannot read it, they cannot maintain it.&lt;br&gt;
So we developed ideas such as separation of concerns, information hiding, cohesion, coupling, layering, Clean Architecture, and bounded contexts to make complexity manageable for people.&lt;/p&gt;

&lt;p&gt;That axis remains important.&lt;/p&gt;

&lt;p&gt;But once AI coding agents enter the loop, the bottleneck shifts.&lt;br&gt;
When code can be produced faster, the question is no longer only:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Can humans understand the current structure?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The next question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What futures does this structure make reachable?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A good design is not only one that makes the current code easier to read.&lt;br&gt;
It is also one that makes good futures easier to reach and bad futures harder to reach.&lt;/p&gt;

&lt;p&gt;From this point of view, architecture expands from human comprehensibility to future reachability.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can this boundary glue future paths locally?&lt;/li&gt;
&lt;li&gt;Which direction does this PR make the next change more likely to take?&lt;/li&gt;
&lt;li&gt;Does this metric preserve distinctions that matter for future evolution?&lt;/li&gt;
&lt;li&gt;Does this review rule close bad futures while preserving good ones?&lt;/li&gt;
&lt;li&gt;Which gluing failure does this technical debt represent?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These questions already exist in practice.&lt;br&gt;
They are just scattered across experience, intuition, review comments, incident memory, and organizational culture.&lt;/p&gt;

&lt;p&gt;SFT tries to move them toward computable theory.&lt;/p&gt;

&lt;p&gt;If this direction works, software engineering moves from:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;techniques for making complexity understandable to humans&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;toward:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;a science for observing, computing, and governing software evolution&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The central concepts begin to look different:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;architecture
  -&amp;gt; shape of reachable futures

modularity
  -&amp;gt; descent of future paths

technical debt
  -&amp;gt; obstruction to future gluing

review
  -&amp;gt; minimal consequence envelope

metrics
  -&amp;gt; cone-conservative observations

governance
  -&amp;gt; support transformation

refactoring
  -&amp;gt; evolutionary invariance

AI coordination
  -&amp;gt; agentic confluence

lifecycle
  -&amp;gt; bifurcation of repair feasibility
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Lean Formalization
&lt;/h2&gt;

&lt;p&gt;We are also formalizing this research program in Lean.&lt;/p&gt;

&lt;p&gt;The point is to keep SFT vocabulary from remaining only a metaphor.&lt;/p&gt;

&lt;p&gt;Terms such as &lt;code&gt;field&lt;/code&gt;, &lt;code&gt;ForecastCone&lt;/code&gt;, &lt;code&gt;ConsequenceEnvelope&lt;/code&gt;, and &lt;code&gt;governance update&lt;/code&gt; are being broken into small objects that can become records, types, and theorem packages.&lt;br&gt;
The big research picture gradually becomes something we can touch formally.&lt;/p&gt;

&lt;p&gt;Current formalization work includes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SoftwareFieldEstimate
OperationSupport / StepRelation
ForecastCone / ClockedForecastCone
ConsequenceEnvelope
FieldUpdate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, &lt;code&gt;ForecastCone&lt;/code&gt; is treated as a supported path within a finite horizon.&lt;br&gt;
&lt;code&gt;ClockedForecastCone&lt;/code&gt; introduces a shared clock and idle / stutter steps for descent.&lt;br&gt;
&lt;code&gt;ConsequenceEnvelope&lt;/code&gt; treats review output as a projection from a cone family.&lt;/p&gt;

&lt;p&gt;The final grand theorem is also being assembled from components: descent, obstruction, review, governance, calibration, and agentic confluence.&lt;br&gt;
Under those explicit components, the Lean-side assembly has the shape:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;computably governed
  or
typed boundary failure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This formalization makes SFT a research program where we can track what is a theorem, what belongs to modeling, and what remains on the tooling or empirical side.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;ForecastCone is not a tool for predicting the future.&lt;/p&gt;

&lt;p&gt;It is a way to make reachable software futures computable under explicit modeling boundaries, operation support, policies, observation boundaries, and horizons.&lt;/p&gt;

&lt;p&gt;SFT's bet is that we can rebuild central software engineering concepts from there.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Architecture is not only the shape of present code.
It is the shape of reachable futures.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Architecture is not only the shape of the code we have now.&lt;/p&gt;

&lt;p&gt;It is also the shape of the futures that codebase makes reachable.&lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>computerscience</category>
      <category>architecture</category>
      <category>ai</category>
    </item>
    <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://dev.to/iroha1203/gotanda-style-do-ai-agents-really-need-meetings-7ii</link>
      <guid>https://dev.to/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/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="24" height="24"&gt;
                  &lt;/span&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;10&lt;span class="hidden s:inline"&gt;&amp;nbsp;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;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            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;
  
  
  When stigmergic multi-agent coordination works, and when 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;/p&gt;

&lt;p&gt;&lt;a href="https://blog.iroha1203.dev/ai-agents-don-t-need-meetings-gotanda-style-for-stigmergic-software-maintenance" rel="noopener noreferrer"&gt;https://blog.iroha1203.dev/ai-agents-don-t-need-meetings-gotanda-style-for-stigmergic-software-maintenance&lt;/a&gt;&lt;/p&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://dev.to/iroha1203/when-lean-proved-my-durability-definition-too-easily-20nc</link>
      <guid>https://dev.to/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://dev.to/iroha1203/ai-does-not-only-generate-code-faster-it-changes-the-distribution-of-future-changes-this-post-2e22</link>
      <guid>https://dev.to/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;&amp;nbsp;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;
              

              1&lt;span class="hidden s:inline"&gt;&amp;nbsp;comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            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://dev.to/iroha1203/attractor-engineering-seeing-software-development-as-field-dynamics-16g5</link>
      <guid>https://dev.to/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>
