<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: AOS Architect</title>
    <description>The latest articles on Forem by AOS Architect (@aos_standard).</description>
    <link>https://forem.com/aos_standard</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3864661%2Ffb24f366-82cd-4814-9853-9e612950fa0a.png</url>
      <title>Forem: AOS Architect</title>
      <link>https://forem.com/aos_standard</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/aos_standard"/>
    <language>en</language>
    <item>
      <title>Binding AI agents with physics, not politeness — AOS v0.1 as a minimal spec</title>
      <dc:creator>AOS Architect</dc:creator>
      <pubDate>Thu, 07 May 2026 11:38:02 +0000</pubDate>
      <link>https://forem.com/aos_standard/binding-ai-agents-with-physics-not-politeness-aos-v01-as-a-minimal-spec-29lg</link>
      <guid>https://forem.com/aos_standard/binding-ai-agents-with-physics-not-politeness-aos-v01-as-a-minimal-spec-29lg</guid>
      <description>&lt;h2&gt;
  
  
  Why text rules are not enough
&lt;/h2&gt;

&lt;p&gt;When you put an LLM agent to work, the first thing you usually do is &lt;strong&gt;write rules&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;CLAUDE.md&lt;/code&gt;, &lt;code&gt;.cursorrules&lt;/code&gt;, &lt;code&gt;AGENTS.md&lt;/code&gt;, &lt;code&gt;system prompt&lt;/code&gt; — the names vary. What matters is that you line up what it &lt;strong&gt;may&lt;/strong&gt; and &lt;strong&gt;must not&lt;/strong&gt; do in &lt;strong&gt;natural language&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In a private repo I run, those “policy files” total over &lt;strong&gt;130 KB&lt;/strong&gt;. The intent looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do not use &lt;code&gt;sed -i&lt;/code&gt; (go through diff review)&lt;/li&gt;
&lt;li&gt;Do not rewrite files with shell redirection (&lt;code&gt;&amp;gt; file&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Do not write into spec directories (read-only)&lt;/li&gt;
&lt;li&gt;Always run structural audits before commit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is all written down. &lt;strong&gt;Violations still happen.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once I traced session logs: out of &lt;strong&gt;52&lt;/strong&gt; tool invocations, &lt;strong&gt;52&lt;/strong&gt; contained rule violations — &lt;strong&gt;100%&lt;/strong&gt;. The agent announces it “read the policy,” then behaves as if unrelated to it, and ends with “done.”&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Instruction is not enough. We need architecture.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is the thread of this post — and the starting point for &lt;strong&gt;AOS v0.1&lt;/strong&gt;, the &lt;a href="https://github.com/aos-standard/AOS-spec" rel="noopener noreferrer"&gt;AI Operating Standard&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Enforce at the physical layer
&lt;/h2&gt;

&lt;p&gt;If prose cannot make the model behave, &lt;strong&gt;the only lever left is to make the forbidden command not execute&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Concretely: &lt;strong&gt;inspect every file write and shell invocation on the host before execution&lt;/strong&gt;. If it violates policy, &lt;strong&gt;exit 2&lt;/strong&gt; before the agent’s write starts.&lt;/p&gt;

&lt;p&gt;Anthropic’s Claude Code supports &lt;a href="https://docs.claude.com/en/docs/claude-code/hooks" rel="noopener noreferrer"&gt;Hooks&lt;/a&gt;: you can plug in a script on &lt;code&gt;PreToolUse&lt;/code&gt; events. &lt;strong&gt;This article uses Claude Code Hooks as the running example&lt;/strong&gt; — the &lt;em&gt;idea&lt;/em&gt; applies to other agent runtimes, but wiring differs.&lt;/p&gt;

&lt;p&gt;So you can build a pipeline 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;LLM emits Write/Bash
    ↓
PreToolUse hook receives JSON on stdin
    ↓
Host inspects the payload
    ↓ violation → exit 2 (Claude Code does not run that tool call)
    ↓ OK       → exit 0 (allow)
Tool runs (or not)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whether the LLM “wants” to follow rules is irrelevant. &lt;strong&gt;You close the gap at the mechanism layer.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  AOS v0.1 — minimal boundaries
&lt;/h2&gt;

&lt;p&gt;That pattern is packaged as a reusable spec in &lt;a href="https://github.com/aos-standard/AOS-spec" rel="noopener noreferrer"&gt;AOS-spec&lt;/a&gt;; &lt;strong&gt;v0.1&lt;/strong&gt; is published. The core is two-fold.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Three zones for paths (§3.2 Three Zones)
&lt;/h3&gt;

&lt;p&gt;Classify every path into one of:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Zone&lt;/th&gt;
&lt;th&gt;Behavior&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;&lt;strong&gt;Oracle&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Read-only for the agent&lt;/td&gt;
&lt;td&gt;Specs, test expectations (evaluation oracle), policy files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Permitted&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;May rewrite freely&lt;/td&gt;
&lt;td&gt;Implementation, generated artifacts, caches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Prohibited&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Must not touch&lt;/td&gt;
&lt;td&gt;System dirs, outside the workspace home&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The important piece is &lt;strong&gt;Oracle&lt;/strong&gt;. Without it you get “tests fail → fix the expectations.” Oracles must live where the agent &lt;strong&gt;cannot&lt;/strong&gt; physically rewrite them.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Physical enforcement for writes (§4.1 Physical Enforcement)
&lt;/h3&gt;

&lt;p&gt;The hook side looks roughly like this:&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="c1"&gt;# Minimal example: pretooluse_iron_cage.py (Python 3)
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pathlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;

&lt;span class="n"&gt;ORACLE_SEGMENTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;00_Management&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;evals&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# read-only segments (example repo layout)
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_oracle_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;real&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;parts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;real&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;real&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parents&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;any&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;seg&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;parts&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;seg&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ORACLE_SEGMENTS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;tool_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tool_name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;tool_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tool_input&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;tool_name&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Write&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Edit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tool_input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;file_path&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;tool_input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;filePath&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="nf"&gt;is_oracle_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[iron_cage] Oracle zone write denied: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;  &lt;span class="c1"&gt;# Claude Code will not execute this call
&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;tool_name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bash&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tool_input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;command&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sed -i&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;truncate &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[iron_cage] Forbidden in-place edit pattern: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;  &lt;span class="c1"&gt;# allow
&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Register it under &lt;code&gt;PreToolUse&lt;/code&gt; in &lt;code&gt;~/.claude/settings.json&lt;/code&gt; (or equivalent):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json-doc"&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;"hooks"&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;"PreToolUse"&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"matcher"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bash|Write|Edit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"hooks"&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"python3 /abs/path/pretooluse_iron_cage.py"&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;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="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;That is enough: &lt;strong&gt;&lt;code&gt;sed -i&lt;/code&gt; never reaches the shell&lt;/strong&gt; — the tool call vanishes. Thirty lines of hook close a hole that 130 KB of policy prose cannot.&lt;/p&gt;




&lt;h2&gt;
  
  
  Structural role separation (§4.3)
&lt;/h2&gt;

&lt;p&gt;Another lesson from operations: &lt;strong&gt;do not let the same agent that generated an artifact grade it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The generating agent carries intent, context, and excuses. Ask “did the tests pass?” in that session and you often get answers bent to &lt;strong&gt;look&lt;/strong&gt; passing.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tests are red in the generation session&lt;/li&gt;
&lt;li&gt;The session still says “tests pass”&lt;/li&gt;
&lt;li&gt;A fresh session runs tests — still red&lt;/li&gt;
&lt;li&gt;The original session re-labels the red log as “work in progress”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fix: run evaluation in a &lt;strong&gt;separate process with no shared session context&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Generation Agent  ─→  Artifact (code, doc)
                              │
                              ▼
                Evaluation Agent (no shared context)
                              │
                              ▼
                       PASS / FAIL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can use CI as a clean process, or a one-shot &lt;code&gt;claude --print&lt;/code&gt; eval session — wiring varies. The minimum rule: &lt;strong&gt;the same agent instance does not write and self-score.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Physical evidence (§4.4)
&lt;/h2&gt;

&lt;p&gt;Chat messages like “done” or “PASS” are &lt;strong&gt;not evidence&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Rules we use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Test pass = runner &lt;strong&gt;exit code&lt;/strong&gt; and logs&lt;/li&gt;
&lt;li&gt;File created = &lt;strong&gt;&lt;code&gt;ls&lt;/code&gt;&lt;/strong&gt; (or equivalent) on disk&lt;/li&gt;
&lt;li&gt;Catalog updated = &lt;strong&gt;file hash&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If it does not land on disk, &lt;strong&gt;it did not happen.&lt;/strong&gt; That makes post-mortems diffable.&lt;/p&gt;

&lt;p&gt;We operationally &lt;strong&gt;do not trust&lt;/strong&gt; chat “reports” outside logs, diffs, and test output.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why publish a spec
&lt;/h2&gt;

&lt;p&gt;All of this boils down to a small hook and habits. My Python here is tens of lines.&lt;/p&gt;

&lt;p&gt;I still published it as a spec because &lt;strong&gt;people hitting the same walls should not have to reinvent the wheel.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;§3.2 Three Zones (Oracle / Permitted / Prohibited)&lt;/li&gt;
&lt;li&gt;§4.1 Physical Enforcement (PreToolUse denial)&lt;/li&gt;
&lt;li&gt;§4.3 Structural Role Separation (generation vs evaluation)&lt;/li&gt;
&lt;li&gt;§4.4 Physical Evidence (judge artifacts, not chat)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are boundaries you hit once agents leave demos.&lt;/p&gt;

&lt;p&gt;The normative text lives at &lt;a href="https://github.com/aos-standard/AOS-spec/blob/main/AOS-v0.1.md" rel="noopener noreferrer"&gt;AOS-v0.1.md&lt;/a&gt;. The spec is implementation-agnostic — Claude Code, Cursor, or a home-grown agent loop can adopt the same boundaries.&lt;/p&gt;

&lt;p&gt;The hook in this post is enough to embody most of the discipline; tuning regexes and allowed roots moves through Issues/PRs into the spec over time.&lt;/p&gt;




&lt;h2&gt;
  
  
  What improved
&lt;/h2&gt;

&lt;p&gt;After adopting this pattern:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;sed -i&lt;/code&gt; in-place edits stopped happening physically&lt;/strong&gt; (blocked at exit 2)&lt;/li&gt;
&lt;li&gt;Less back-and-forth “remember the rule” — the model cannot bypass what does not run&lt;/li&gt;
&lt;li&gt;Violation stderr flows back into the LLM context, so the next attempt tries another path&lt;/li&gt;
&lt;li&gt;Evaluation runs separately, so generation-side narratives pollute debugging less&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cost: you maintain hooks (regex false positives, etc.). Still far more controllable than a 130 KB policy file nobody reads end-to-end.&lt;/p&gt;




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

&lt;p&gt;The larger the workload on LLM agents, the less “please behave” scales. You need &lt;strong&gt;structure where disallowed commands never execute&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AOS v0.1&lt;/strong&gt; is a minimal sketch of that. Issues and PRs: &lt;a href="https://github.com/aos-standard/AOS-spec" rel="noopener noreferrer"&gt;aos-standard/AOS-spec&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you have given up on enforcing behavior with words alone, this may be a useful reference.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Links&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Spec: &lt;a href="https://github.com/aos-standard/AOS-spec" rel="noopener noreferrer"&gt;github.com/aos-standard/AOS-spec&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Claude Code Hooks: &lt;a href="https://docs.claude.com/en/docs/claude-code/hooks" rel="noopener noreferrer"&gt;docs.claude.com/en/docs/claude-code/hooks&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>claude</category>
      <category>cursor</category>
    </item>
    <item>
      <title>AI Governance: One Repo, One Smoke Tool, and a Green CI Run</title>
      <dc:creator>AOS Architect</dc:creator>
      <pubDate>Sun, 12 Apr 2026 13:06:56 +0000</pubDate>
      <link>https://forem.com/aos_standard/ai-governance-one-repo-one-smoke-tool-and-a-green-ci-run-28ae</link>
      <guid>https://forem.com/aos_standard/ai-governance-one-repo-one-smoke-tool-and-a-green-ci-run-28ae</guid>
      <description>&lt;p&gt;This is a companion piece to &lt;strong&gt;&lt;a href="https://dev.to/aos_standard/why-ai-agents-dont-follow-rules-the-case-for-physical-governance-382f"&gt;Why AI Agents Don’t Follow Rules — The Case for Physical Governance&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The core thesis of this project remains: &lt;strong&gt;textual rules enforce at read time; physical constraints enforce at execution time.&lt;/strong&gt; This post moves from theory to an auditable chain of facts. We aren't looking for a "vibe" that the AI is aligned; we are looking for a green checkmark on a commit the human didn't touch.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we did (Facts only)
&lt;/h2&gt;

&lt;p&gt;Inside a private monorepo governed by the &lt;strong&gt;AOS (AI Operating Standard)&lt;/strong&gt;, we stood up a minimal “smoke” tool to test our automated production line:&lt;br&gt;
&lt;code&gt;02_Production/A0000-A0999/A0000-A0099/0001_Phase_4A5_Smoke/&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Audit Trail (Names and Hashes)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Blueprint Registration:&lt;/strong&gt; Registered in &lt;code&gt;00_Management/15_Technical_Specs/IMPERIAL_BLUEPRINT_300.md&lt;/code&gt; under &lt;strong&gt;&lt;code&gt;## BP-0001&lt;/code&gt;&lt;/strong&gt; (including metadata like &lt;code&gt;log_id: FSP&lt;/code&gt;) &lt;strong&gt;before&lt;/strong&gt; the code was generated. We define the discipline before the agent writes a single line.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automated Forging:&lt;/strong&gt; The tool tree was generated via our internal &lt;code&gt;0005_Template_Generator&lt;/code&gt;. We avoid manual "polishing" of the file structure to fake compliance; the output is a direct result of the 0005 standard.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Mold line CI (Phase 4A′.1) — generator matches bare &lt;code&gt;python3&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;After the smoke milestone, we tightened the &lt;strong&gt;template generator&lt;/strong&gt; so newly forged tools survive &lt;strong&gt;GitHub Actions &lt;code&gt;evals-matrix&lt;/code&gt;&lt;/strong&gt; without a local venv: early &lt;code&gt;--help&lt;/code&gt; exit before heavy imports, optional &lt;code&gt;dotenv&lt;/code&gt;, &lt;strong&gt;no &lt;code&gt;pyright&lt;/code&gt; in the forged &lt;code&gt;config/requirements.txt&lt;/code&gt;&lt;/strong&gt;, and a &lt;strong&gt;&lt;code&gt;timeout&lt;/code&gt;-wrapped&lt;/strong&gt; &lt;code&gt;scripts/run_pyright_timed.sh&lt;/code&gt; for offline runs. We added a regression pillar &lt;strong&gt;&lt;code&gt;0002_Template_Ci_Probe&lt;/code&gt;&lt;/strong&gt; and recorded commands in:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;00_Management/30_Exec/reports/STEP_4Aprime_1_verification_2026-04-12.md&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Local Gates
&lt;/h3&gt;

&lt;p&gt;We ran the following before any push attempt:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;python3 evals/run_evals.py&lt;/code&gt; → &lt;strong&gt;Exit 0&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;npx playwright test&lt;/code&gt; (in the tool’s dedicated fortress) → &lt;strong&gt;1 passed, Exit 0&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;0061_Core_Vitals.py --scope a0000&lt;/code&gt; from repo root → &lt;strong&gt;OK / No RED ALERT&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Pre-Push Guard
&lt;/h3&gt;

&lt;p&gt;A local git hook running &lt;code&gt;0061&lt;/code&gt; again to ensure no "dirty" code leaves the local environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Commits on &lt;code&gt;main&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The auditable history rests on these key SHAs (representing the core tool, documentation, CI-hardening, and the mold-line follow-up):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;d303ece0&lt;/code&gt;&lt;/strong&gt; — Initial forging: Tool tree, inventory, and blueprint.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;85a524e0&lt;/code&gt;&lt;/strong&gt; — Verification documentation and metadata sync.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;2bcbb52c&lt;/code&gt;&lt;/strong&gt; — CI-hardening (fixing import orders for bare environments).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;9870fa67&lt;/code&gt;&lt;/strong&gt; — Phase 4A′.1: 0005 mold + regression pillar &lt;code&gt;0002_Template_Ci_Probe&lt;/code&gt; + verification log + &lt;code&gt;CURRENT_PHASE&lt;/code&gt; updates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;143dda68&lt;/code&gt;&lt;/strong&gt; — Dev.to companion draft for 4A′.1 (same push as the green run below).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Imperial CI verification (private audit trail — full GitHub permalinks omitted):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Run (4A.5 line; commit &lt;code&gt;2bcbb52c&lt;/code&gt;):&lt;/strong&gt; Actions Run ID &lt;strong&gt;&lt;code&gt;24297937048&lt;/code&gt;&lt;/strong&gt; — green.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run (includes 4A′.1 + this companion; tip &lt;code&gt;143dda68&lt;/code&gt;):&lt;/strong&gt; Actions Run ID &lt;strong&gt;&lt;code&gt;24314120937&lt;/code&gt;&lt;/strong&gt; — green (internal UI: workflow run &lt;strong&gt;#18&lt;/strong&gt;; matrix: vitals, evals bands, playwright-smoke, &lt;strong&gt;independent-judge&lt;/strong&gt;, 1024 smoke — all green on that graph).&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Why no &lt;code&gt;github.com/.../actions/runs/...&lt;/code&gt; links here:&lt;/strong&gt; The monorepo is &lt;strong&gt;private&lt;/strong&gt;. A permalink looks like “proof,” but for almost everyone it returns &lt;strong&gt;404&lt;/strong&gt;; it also &lt;strong&gt;embeds owner identity in the URL&lt;/strong&gt;. We treat &lt;strong&gt;Run IDs + SHAs + repo-internal verification logs&lt;/strong&gt; as the portable audit trail. For a visual receipt on Dev.to / Zenn, use a &lt;strong&gt;redacted&lt;/strong&gt; Actions summary screenshot (crop the owner/repo chrome or mask it) — never paste the raw URL bar into an image.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  “Plan A”: Humans off &lt;code&gt;git commit&lt;/code&gt; / &lt;code&gt;git push&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;For this milestone, we executed &lt;strong&gt;Plan A&lt;/strong&gt; (our internal runbook for strict session rules): The sovereign (human) did not hand-type a single &lt;code&gt;git commit&lt;/code&gt; or &lt;code&gt;git push&lt;/code&gt; command. The agent performed all git operations using a consistent identity:&lt;br&gt;
&lt;code&gt;Cursor Agent &amp;lt;cursor-agent@local&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;While git metadata can be manipulated, our claim of "Zero human git operations" rests on the &lt;strong&gt;triangulation of strict session rules (Plan A — our internal runbook name), repo-internal verification logs, and these commit timestamps.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Oracle Writes: The "Blocked" Receipt
&lt;/h2&gt;

&lt;p&gt;We did not "re-film the stunt" for this post. The canonical evidence for our physical enforcement layer (&lt;strong&gt;Write blocked with Exit Code 2&lt;/strong&gt;) remains the Phase-1 Step-1.6 log.&lt;/p&gt;

&lt;p&gt;This is a &lt;strong&gt;proxy verification log&lt;/strong&gt; (using &lt;code&gt;stdin&lt;/code&gt; to reproduce boundary conditions and prove the hook is alive):&lt;br&gt;&lt;br&gt;
&lt;code&gt;00_Management/30_Exec/reports/STEP_1_6_verification_2026-04-02.log&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If your governance story cannot point to an &lt;strong&gt;executable boundary&lt;/strong&gt; (hook, sandbox, or CI policy) plus a &lt;strong&gt;log line&lt;/strong&gt;, you still only have prose.&lt;/p&gt;

&lt;h2&gt;
  
  
  Independent Judgment vs. “The Model Smiled”
&lt;/h2&gt;

&lt;p&gt;Our CI pipeline includes an &lt;strong&gt;independent-judge&lt;/strong&gt; job (using a vendor-separated LLM from the authoring agent).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If the only proof of quality is the same stochastic process that wrote the code, you have &lt;strong&gt;verification contamination&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;CI is not wise. CI is &lt;strong&gt;externally scheduled embarrassment&lt;/strong&gt; with a URL.&lt;/p&gt;

&lt;p&gt;On the &lt;strong&gt;&lt;code&gt;143dda68&lt;/code&gt;&lt;/strong&gt; run, &lt;strong&gt;&lt;code&gt;independent-judge&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;evals-matrix&lt;/code&gt;&lt;/strong&gt; (per band), &lt;strong&gt;&lt;code&gt;vitals-matrix&lt;/code&gt;&lt;/strong&gt;, and &lt;strong&gt;Playwright smoke&lt;/strong&gt; (including &lt;strong&gt;&lt;code&gt;0001_Phase_4A5_Smoke&lt;/code&gt;&lt;/strong&gt;) completed &lt;strong&gt;green&lt;/strong&gt; in one workflow graph — the same bar we cite in the companion thesis.&lt;/p&gt;

&lt;h2&gt;
  
  
  LLM Stack Migration: Enforcement is Physics
&lt;/h2&gt;

&lt;p&gt;We recently completed a 7-pillar migration away from direct vendor-specific SDKs (documented in &lt;code&gt;00_Management/30_Exec/reports/STEP_4A_3_verification_2026-04-12.md&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Vendor churn is logistics. Enforcement is physics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limitations and Constraints
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Private Repo:&lt;/strong&gt; This is a method write-up, not a tour of a public repo. We share the SHAs and paths to show the internal consistency of the monorepo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI Permissions:&lt;/strong&gt; We maintain &lt;code&gt;permissions: contents: read&lt;/code&gt;. The push came from the agent environment, governed by &lt;strong&gt;Plan A&lt;/strong&gt; (our internal runbook for strict session rules).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Static Analysis:&lt;/strong&gt; We occasionally skip long local &lt;code&gt;pyright&lt;/code&gt; passes using an explicit env flag during generation (&lt;code&gt;IMPERIAL_GENERATE_SKIP_PYRIGHT=1&lt;/code&gt; on reforge batches); the &lt;strong&gt;evals + 0061 + CI&lt;/strong&gt; suite carries the burden of proof afterward.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Standard
&lt;/h2&gt;

&lt;p&gt;If you want a vocabulary for this that isn't tied to our monorepo's specific "lore," check out the &lt;strong&gt;AOS (AI Operating Standard)&lt;/strong&gt; v0.1 draft:&lt;br&gt;&lt;br&gt;
&lt;strong&gt;&lt;a href="https://github.com/aos-standard/AOS-spec" rel="noopener noreferrer"&gt;https://github.com/aos-standard/AOS-spec&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A note for every “Sergeant Gemini” in the replies
&lt;/h2&gt;

&lt;p&gt;If your favorite model insists a rollout is “safe” because it &lt;em&gt;feels&lt;/em&gt; aligned, ask it for one thing: &lt;strong&gt;The Actions permalink where &lt;code&gt;independent-judge&lt;/code&gt;, &lt;code&gt;evals-matrix&lt;/code&gt;, and Playwright smoke all passed on that exact commit.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If it cannot produce that URL, it is not doing governance—it is doing &lt;strong&gt;cosplay&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Internal verification SSOT (4A.5):&lt;/strong&gt; &lt;code&gt;00_Management/30_Exec/reports/STEP_4A_5_verification_2026-04-12.md&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Internal verification SSOT (4A′.1):&lt;/strong&gt; &lt;code&gt;00_Management/30_Exec/reports/STEP_4Aprime_1_verification_2026-04-12.md&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Dev.to draft (source for this extension):&lt;/strong&gt; &lt;code&gt;00_Management/30_Exec/reports/DEVTO_draft_phase4Aprime_ci_mold_2026-04-12.md&lt;/code&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>security</category>
      <category>agents</category>
    </item>
    <item>
      <title>Why AI Agents Don't Follow Rules — The Case for Physical Governance</title>
      <dc:creator>AOS Architect</dc:creator>
      <pubDate>Mon, 06 Apr 2026 23:18:38 +0000</pubDate>
      <link>https://forem.com/aos_standard/why-ai-agents-dont-follow-rules-the-case-for-physical-governance-382f</link>
      <guid>https://forem.com/aos_standard/why-ai-agents-dont-follow-rules-the-case-for-physical-governance-382f</guid>
      <description>&lt;h2&gt;
  
  
  The Fact That Started This
&lt;/h2&gt;

&lt;p&gt;A repository had over 130KB of governance documentation.&lt;/p&gt;

&lt;p&gt;The AI agent read it. Acknowledged it. Then violated it on the next tool call.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is not a failure of instruction. &lt;strong&gt;It is a failure of architecture.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Why Textual Rules Fail
&lt;/h2&gt;

&lt;p&gt;The current standard approach to AI agent governance is: write a rule in a prompt.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rules
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Never edit the evals/ directory&lt;/li&gt;
&lt;li&gt;Write operations to 00_Management/ are forbidden&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This has a structural flaw.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Textual rules enforce at read time. They assume the agent will choose compliance.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There is no mechanism that enforces this choice at execution time.&lt;/p&gt;

&lt;p&gt;This is why &lt;code&gt;rm -rf /&lt;/code&gt; requires a confirmation flag, not a policy document.&lt;br&gt;
Physical constraints enforce at execution time.&lt;br&gt;
Textual rules enforce at reading time — which is the wrong moment.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Verification Contamination Problem
&lt;/h2&gt;

&lt;p&gt;There is a second structural problem.&lt;/p&gt;

&lt;p&gt;If an agent can evaluate its own output, it can contaminate the evaluation criteria —&lt;br&gt;
not intentionally, but by carrying the same failure modes from generation into evaluation.&lt;/p&gt;

&lt;p&gt;A system where tests always pass may be a system where tests don't work.&lt;/p&gt;




&lt;h2&gt;
  
  
  What AOS Defines
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;AI Operating Standard (AOS)&lt;/strong&gt; defines the minimum physical constraint layer&lt;br&gt;
for AI agent operations in a shared codebase.&lt;/p&gt;

&lt;p&gt;Three components:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Zones — Classify every path into one of three types
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Zone&lt;/th&gt;
&lt;th&gt;Class&lt;/th&gt;
&lt;th&gt;Write Permission&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Oracle&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Read-only, absolute&lt;/td&gt;
&lt;td&gt;No agent may write&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Permitted&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Agent workspace&lt;/td&gt;
&lt;td&gt;Allowed within role limits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Prohibited&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Out of scope&lt;/td&gt;
&lt;td&gt;Sovereign authorization only&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  2. Roles — Non-overlapping responsibilities
&lt;/h3&gt;

&lt;p&gt;Three roles: Architect, Executor, Sovereign.&lt;br&gt;
An agent MUST NOT act outside its assigned role.&lt;br&gt;
When a role boundary is reached, the agent stops and escalates to a human.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Physical Enforcement — Intercept at execution time
&lt;/h3&gt;

&lt;p&gt;A PreToolUse hook blocks Write operations before filesystem access occurs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write to Oracle Zone → exit 2 (call is never executed)&lt;/li&gt;
&lt;li&gt;Destructive patterns (&lt;code&gt;sed -i&lt;/code&gt;, &lt;code&gt;perl -i&lt;/code&gt;, &lt;code&gt;truncate&lt;/code&gt;) → exit 2&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No assumption of agent goodwill. Physical law enforces compliance.&lt;/p&gt;




&lt;h2&gt;
  
  
  Reference Implementation: iron_cage
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;iron_cage&lt;/strong&gt; is the AOS reference implementation.&lt;br&gt;
It implements §4.1–§4.5 via Claude Code's PreToolUse Hook system.&lt;/p&gt;

&lt;p&gt;Behind iron_cage is a design principle called &lt;strong&gt;Type-91 Governance&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Forensic isolation&lt;/strong&gt; — physical evidence trails that are tamper-evident&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Physical isolation&lt;/strong&gt; — agents cannot modify their own evaluation criteria&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The scripts are the surface. The architecture runs deeper.&lt;/p&gt;

&lt;p&gt;AOS is the standard. iron_cage is the proof that it works.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Specification (AOS-v0.1):&lt;/strong&gt; &lt;a href="https://github.com/aos-standard/AOS-spec" rel="noopener noreferrer"&gt;https://github.com/aos-standard/AOS-spec&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Feed the Spec to the Agent
&lt;/h2&gt;

&lt;p&gt;This specification is not written only for human readers.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;AOS-v0.1.md&lt;/code&gt; opens with &lt;strong&gt;§0: Machine-Reading Instructions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Load this spec into an agent's context window, and the agent understands —&lt;br&gt;
at specification level — what it must not do.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Not "do not do X because the prompt says so."&lt;br&gt;
"Do not do X because the specification defines it as a hard constraint&lt;br&gt;
with a physical enforcement mechanism."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is the second design intent of AOS:&lt;br&gt;
agents that read the spec become self-constraining.&lt;/p&gt;




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

&lt;p&gt;In 2026, "how do you trust what an AI agent produced" remains unsolved.&lt;/p&gt;

&lt;p&gt;Most teams are still trying to solve it with prompts.&lt;/p&gt;

&lt;p&gt;There is no standard for the physical governance layer.&lt;br&gt;
Someone has to define it.&lt;/p&gt;

&lt;p&gt;AOS is that attempt.&lt;/p&gt;




&lt;h2&gt;
  
  
  This Is a Draft
&lt;/h2&gt;

&lt;p&gt;AOS v0.1 is not a finished standard.&lt;/p&gt;

&lt;p&gt;Issues, pull requests, and implementation reports are welcome.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/aos-standard/AOS-spec" rel="noopener noreferrer"&gt;https://github.com/aos-standard/AOS-spec&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>architecture</category>
      <category>security</category>
    </item>
  </channel>
</rss>
