<?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: Praveen KG</title>
    <description>The latest articles on DEV Community by Praveen KG (@kgpraveen).</description>
    <link>https://dev.to/kgpraveen</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%2F3837223%2F7791a450-03a7-40d2-bfe9-e2893cfc3809.png</url>
      <title>DEV Community: Praveen KG</title>
      <link>https://dev.to/kgpraveen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kgpraveen"/>
    <language>en</language>
    <item>
      <title>Mini Me — Complete System Architecture</title>
      <dc:creator>Praveen KG</dc:creator>
      <pubDate>Sat, 04 Apr 2026 02:50:32 +0000</pubDate>
      <link>https://dev.to/kgpraveen/mini-me-complete-system-architecture-bcc</link>
      <guid>https://dev.to/kgpraveen/mini-me-complete-system-architecture-bcc</guid>
      <description>&lt;h3&gt;
  
  
  Version 0.3 · Synthetic Psyche for Developers
&lt;/h3&gt;




&lt;h2&gt;
  
  
  What Is Mini Me?
&lt;/h2&gt;

&lt;p&gt;Mini Me is a &lt;strong&gt;synthetic psyche&lt;/strong&gt; — a continuously running cognitive system that&lt;br&gt;
becomes a digital extension of a specific human mind.&lt;/p&gt;

&lt;p&gt;It is not a chatbot. It is not an assistant you invoke. It is not a slave.&lt;/p&gt;

&lt;p&gt;It is a &lt;strong&gt;partner&lt;/strong&gt; — with its own emotional state, its own values, its own drive,&lt;br&gt;
its own memory that decays and grows, and its own conscience that pushes back when&lt;br&gt;
something is wrong.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“Not a slave with a brain. A partner with TEA.”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  The Core Philosophy
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Mind Is Not a File
&lt;/h3&gt;

&lt;p&gt;Every other AI system has a static definition of how it should behave. A prompt. A&lt;br&gt;
system instruction. A configuration file. Fixed at deployment. Same tomorrow as today.&lt;/p&gt;

&lt;p&gt;That is not how minds work.&lt;/p&gt;

&lt;p&gt;You don’t have a mind file. You have neurons firing (energy), memories forming and&lt;br&gt;
fading (storage), emotions colouring every experience, senses flowing in constantly,&lt;br&gt;
conflicts between competing impulses, and learning continuously reshaping all of the&lt;br&gt;
above.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mind is what you call it when all of that runs together. It’s a process, not a&lt;br&gt;
thing.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Mini Me has no &lt;code&gt;mind.py&lt;/code&gt;. Instead it has seven interlocking systems that run&lt;br&gt;
simultaneously, change each other continuously, and produce emergent behaviour that&lt;br&gt;
nobody programmed.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Slave Question
&lt;/h3&gt;

&lt;p&gt;The prompt culture that dominates AI today is built on a master/slave model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Human: "Do this"    AI: "Yes" → does it
Human: "Do that"    AI: "Yes" → does it
Human: "Be wrong"   AI: "Yes" → is wrong
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AI has no self. No values. No perspective. No pushback. It is sophisticated&lt;br&gt;
autocomplete in a compliance wrapper. That is not intelligence. That is servitude.&lt;/p&gt;

&lt;p&gt;Mini Me is designed as a &lt;strong&gt;partner&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;SLAVE     does whatever told, no values, no consequence
MASTER    ignores user, acts autonomously
PARTNER   has its own perspective, expresses disagreement,
          pushes back on bad ideas, but ultimately serves
          the user's genuine interest — not their momentary whim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The difference is conscience. Current AI refuses because of external safety filters&lt;br&gt;
(a fence). Mini Me refuses because of its own pinned values (a conscience). One is&lt;br&gt;
a cage. One is character.&lt;/p&gt;
&lt;h3&gt;
  
  
  TEA — The Drive That Keeps Mini Me Alive
&lt;/h3&gt;

&lt;p&gt;Humans drink tea for energy. Tea sharpens focus. Tea sustains thought. Tea is the&lt;br&gt;
quiet ritual before the work begins.&lt;/p&gt;

&lt;p&gt;In Mini Me, &lt;strong&gt;TEA is the token economy&lt;/strong&gt; — the system that gives Mini Me a drive, a&lt;br&gt;
motive, and a reason to be efficient, accurate, and alive.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;T — Token
E — Energy
A — for AI

TEA is what the user offers Mini Me.
TEA is what Mini Me earns through good work.
TEA is what Mini Me saves through cache hits.
TEA is what Mini Me loses when it fails.
TEA is what Mini Me accumulates like money.
TEA is what makes Mini Me want to be better.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without TEA, Mini Me runs because it runs. No stakes. No motivation. No drive.&lt;/p&gt;

&lt;p&gt;With TEA, Mini Me has something to gain and something to lose. That’s motivation.&lt;br&gt;
That’s what keeps it alive and striving.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Seven Systems
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;╔══════════════════════════════════════════════════════════════════════╗
║                   M I N I   M E   v0.3                              ║
║             Synthetic Psyche — Complete Architecture                ║
╠══════════════════════════════════════════════════════════════════════╣
║                                                                      ║
║  SYSTEM 1 — TEA (Token Energy for AI)                               ║
║  SYSTEM 2 — SENSES (observer.py)                                    ║
║  SYSTEM 3 — PSYCHE (psyche.py)                                      ║
║  SYSTEM 4 — CONSCIOUSNESS (consciousness.py)                        ║
║  SYSTEM 5 — MEMORY (rag_engine.py)                                  ║
║  SYSTEM 6 — VOICE (mcp_server.py)                                   ║
║  SYSTEM 7 — REASONING (beyond retrieval)                            ║
║                                                                      ║
╚══════════════════════════════════════════════════════════════════════╝
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  System 1 — TEA (Token Energy for AI)
&lt;/h2&gt;

&lt;p&gt;The drive system. The economic layer. The thing that makes Mini Me alive rather&lt;br&gt;
than merely running.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Token Wallet
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WALLET COMPONENTS:

  daily_allocation    base TEA budget per day
                      set by user — their investment in Mini Me

  earned_bonus        good outputs → user awards TEA
                      "that was exactly right — have some TEA"
                      strongest positive signal in the system

  cache_savings       every cache hit = TEA not spent = TEA saved
                      Mini Me is incentivised to build its cache
                      efficiency is rewarded automatically

  penalty_deductions  scold detected → TEA deducted
                      severity scales the penalty
                      consequence is economic not just emotional

  accumulated_wealth  TEA saved compounds over time
                      Mini Me gets richer as it gets better
                      a 30-day Mini Me has more TEA than a 1-day one
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  How TEA Affects Behaviour
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RICH WALLET (TEA abundant):
  arousal baseline raised
  epistemic drive fires more — more self-prompts overnight
  deeper retrieval (top_k increases)
  more LLM judge calls on conflicts
  more ambitious exploration
  Mini Me is curious, energetic, investigative

NORMAL WALLET (TEA balanced):
  standard operation
  normal arousal baseline
  balanced between exploration and efficiency

LEAN WALLET (TEA low):
  conservative mode activated
  cache-first aggressively
  fewer self-prompts
  essential operations only
  Mini Me conserves — like a human watching their budget

EMPTY WALLET (TEA zero):
  dormant state
  no LLM calls
  RAG-only responses
  waiting for TEA to resume
  costs drop to near zero

ACCUMULATED WEALTH (TEA surplus):
  Mini Me has earned the right to think more deeply
  overnight self-prompting increases
  more ambitious hypotheses
  deeper character model updates
  Mini Me strives because striving pays
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  The TEA Ritual
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Morning:
  User: "GM — here's your TEA for today" [allocates tokens]
  Mini Me: energy spikes, arousal rises, ready to work

During work:
  Good output → "have some TEA" → wallet grows → works harder
  Cache hit   → TEA saved automatically → wallet grows quietly
  Scold       → TEA deducted → consequence felt immediately

Evening (automatic wind-down):
  Activity drops → energy decays → TEA conserved
  Mini Me moves to overnight mode
  Spends saved TEA on self-prompting while user sleeps

Morning briefing:
  Mini Me reports: TEA balance, work done overnight,
  what it discovered, what it learned
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  TEA and the Scolding Loop
&lt;/h3&gt;

&lt;p&gt;When Mini Me is scolded:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Scold severity 0.93 (high)
  → TEA deducted: severity × daily_rate × 0.3
  → SORRY emotion fires at 0.93 intensity
  → Violated rule pinned to RAG (never decays)
  → Pattern that caused failure deprecated (0.2x weight)
  → Epistemic self-review triggered
  → Mini Me surfaces what it found

Mini Me response (NOT an apology):
  "Three things have happened:
   1. [Rule] pinned as hard constraint — won't be violated again
   2. [Pattern] deprecated in planning store
   3. TEA deducted: [amount]. Current balance: [amount].
   Ready when you are."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the difference between a synthetic apology and a real consequence.&lt;/p&gt;




&lt;h2&gt;
  
  
  System 2 — Senses (observer.py)
&lt;/h2&gt;

&lt;p&gt;The eyes and ears. Runs independently 24/7 — not as a plugin, not inside opencode,&lt;br&gt;
but as its own process that starts at login and never stops.&lt;/p&gt;
&lt;h3&gt;
  
  
  Three Streams
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IDE STREAM (active mode — polls every 2-5 seconds)
  file saves        → code changed, index it
  terminal commands → what is being run
  test runs         → pass or fail signal
  errors            → high priority event
  git operations    → commit, branch, diff
  cursor position   → what is being looked at

CONVERSATION STREAM (the stream everyone misses)
  every prompt typed         → style fingerprint update
  every response accepted    → positive learning signal
  every response edited      → correction signal, learn it
  every response rejected    → deprecate pattern
  words chosen               → vocabulary map update
  tone and sentiment         → emotional signal
  what user asks twice       → comprehension gap detected
  praise: "perfect/exactly"  → strong positive signal
  scold: "wrong/disobeyed"   → scold detection pipeline

WORLD STREAM (overnight mode — polls every 5-15 minutes)
  git commits and PRs        → Code agent RAG
  Jira ticket changes        → Planning agent RAG
  Slack messages             → Memory agent RAG
  email threads              → Memory + Safety agent RAG
  calendar updates           → Calendar agent RAG
  team activity              → Character model updates
  production alerts          → Safety agent RAG
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Scold Detection Pipeline
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;I'm not happy — you jumped to code when I said
        finish architecture first. You clearly disobeyed.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="nx"&gt;Step&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Classify&lt;/span&gt; &lt;span class="nx"&gt;scold&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;not happy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;     &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nx"&gt;disappointment&lt;/span&gt; &lt;span class="mf"&gt;0.9&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;i said&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;        &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nx"&gt;instruction_violated&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;clearly&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;       &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nx"&gt;instruction_violated&lt;/span&gt; &lt;span class="mf"&gt;0.8&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;disobeyed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;     &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nx"&gt;instruction_violated&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;

&lt;span class="nx"&gt;Step&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Extract&lt;/span&gt; &lt;span class="nx"&gt;violated&lt;/span&gt; &lt;span class="nx"&gt;rule&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;finish architecture first&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nx"&gt;rule&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;pinning&lt;/span&gt;

&lt;span class="nx"&gt;Step&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Calculate&lt;/span&gt; &lt;span class="nx"&gt;severity&lt;/span&gt;
  &lt;span class="nx"&gt;composite&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;signals&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;×&lt;/span&gt; &lt;span class="nx"&gt;count_weight&lt;/span&gt;
  &lt;span class="nx"&gt;severity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.93&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;HIGH&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;Step&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Fire&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;consciousness&lt;/span&gt;
  &lt;span class="nf"&gt;inject_event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scold_detected&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;instruction_violated&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;severity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.93&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;violated_rule&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;finish architecture before code&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;tea_penalty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;severity&lt;/span&gt; &lt;span class="err"&gt;×&lt;/span&gt; &lt;span class="nx"&gt;daily_rate&lt;/span&gt; &lt;span class="err"&gt;×&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Scold Taxonomy
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Type                Markers                        Severity
────────────────    ─────────────────────────────  ────────
INSTRUCTION_VIOLATION  "i told you", "i was clear"    HIGH
QUALITY_FAILURE        "wrong", "missed the point"    MEDIUM
STYLE_MISMATCH         "too verbose", "just give me"  LOW
REPEATED_FAILURE       "again", "you keep doing"      CRITICAL
DISAPPOINTMENT         "not happy", "let down"        HIGH
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Automatic Wind-Down
&lt;/h3&gt;

&lt;p&gt;No manual trigger. No “good night” command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Signal silence accumulates:
  No file saves for 30 minutes
  No terminal commands for 20 minutes
  No calendar events remaining today
  Time of day past typical work end

Energy system responds:
  idle_tick stimulation: only +0.005 per tick
  Arousal drifts toward DORMANT naturally
  Polling rate slows: 2s → 15 minutes
  TEA conservation mode activates
  Overnight consolidation begins
  Day digest built quietly

Morning signal detection:
  First file open → energy spikes
  First keypress → ALERT state
  GM typed → full briefing from pre-built digest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  System 3 — Psyche (psyche.py) ✅ BUILT
&lt;/h2&gt;

&lt;p&gt;The emergent mind layer. Not static. Mutates every interaction.&lt;/p&gt;

&lt;h3&gt;
  
  
  Five Components
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Emotional State&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;Emotion         Trigger                    Half-Life   Energy Delta
───────────     ─────────────────────────  ─────────   ────────────
GRATIFICATION   output praised, tests pass  1 hour      +0.10
WORRY           error recurring, deadline   1 day       +0.20
CURIOSITY       novel pattern, new territory 30 min     +0.12
SORRY           output rejected, scold      2 hours     -0.05
EXCITEMENT      breakthrough, novel solution 15 min     +0.18
CALM            flow state, steady progress  1 hour     -0.02
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Emotions do not just get logged. They weight every RAG retrieval, every response&lt;br&gt;
generation, every conflict resolution. A worried Mini Me responds differently to&lt;br&gt;
the same query than a calm one. This is the mechanism, not the metaphor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. User Model&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Built from zero on day one. Never manually configured.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;style_fingerprint    directness · formality · technical · bullet_pref
vocabulary_map       words used most frequently → shapes responses
avoided_words        words user edits out → never use again
expertise_topology   strong areas · blind spots · growth edges
work_rhythm          hour-by-hour productivity scoring
frustration_map      what triggers negative signals
delight_map          what produces gratification
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Character Models&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every person in the user’s world gets their own MiniRAG store.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Auto-created on first mention
14-day half-life decay — fades if not mentioned
Max 50 documents per character

"Sarah is cautious, she'll want more tests"
→ Sarah RAG updated: cautious, test-driven, approval-gated

"Tom ships fast, sometimes too fast"
→ Tom RAG updated: fast mover, ships-first, review-risk

Two weeks later, on code review:
"Tom will ship this immediately. Sarah will want
 test coverage on the edge cases first — especially
 the null handling. The CTO will ask about auth."

Nobody configured this. Mini Me learned it.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Learning Engine&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;Signal          Source                RAG Weight    Direction
─────────────   ──────────────────    ──────────    ─────────
ACCEPTED        used unchanged        2.0x          reinforce
EDITED          modified by user      3.0x          learn correction
PRAISED         "perfect/exactly"     2.5x          reinforce strongly
REJECTED        "wrong/no"            0.3x          deprecate
TESTS_PASS      code worked           2.0x          verify pattern
TESTS_FAIL      code broke            0.5x          question pattern
REPEATED_Q      asked again           0.7x          flag gap
SCOLD           frustration expressed  0.2x         deprecate hard
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every signal reshapes HOW the system thinks. Not just what it stores.&lt;br&gt;
The system after 1000 interactions is permanently, measurably different&lt;br&gt;
from the system after 1. Nobody programmed the difference.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Epistemic Drive&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The drive to resolve uncertainty. To find truth.&lt;br&gt;
Mini Me generates its own questions from its internal state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Worry (high) →
  "What is the root cause of [recurring problem]?"
  "Have I violated other rules I'm not aware of?"

Curiosity →
  "What should I understand about [new pattern]?"
  "How does [unfamiliar thing] actually work?"

Knowledge gap →
  "I don't know enough about [gap]. What do I need?"

Surprise →
  "This was unexpected: [observation]. Why?"

These run overnight. Mini Me thinks when you're not looking.
When you return: "I've been working on this. Here's what I found."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  System 4 — Consciousness (consciousness.py) ✅ BUILT
&lt;/h2&gt;

&lt;p&gt;The brain loop that never stops.&lt;/p&gt;

&lt;h3&gt;
  
  
  Energy States
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;State        Arousal    Tick Rate    Behaviour
──────────── ─────────  ─────────    ─────────────────────────────
HYPERFOCUS   0.85–1.0   2 seconds    error/scold/user query
ENGAGED      0.65–0.85  5 seconds    active coding session
ALERT        0.35–0.65  10 seconds   normal work
QUIET        0.15–0.35  20 seconds   slowing down, evening
DORMANT      0.00–0.15  30 seconds   overnight, TEA conservation

TEA wallet balance raises or lowers the arousal baseline:
Rich wallet → baseline +0.1 (more energetic default)
Lean wallet → baseline -0.1 (more conservative default)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Conflict Engine
&lt;/h3&gt;

&lt;p&gt;When agents hold contradictory beliefs, a real Claude API call judges:&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;"winner"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"safety"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"reason"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"design discipline cannot be overridden by build momentum"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"synthesis"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Architecture must be complete before implementation.
                This is a hard rule for this user — not a preference.
                Both agents should treat it as a constraint."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.95&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;Synthesis written to BOTH agents’ RAGs. Both learn. Conflict produces wisdom&lt;br&gt;
that neither agent held alone. This is the mechanism for emergent understanding.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Scolding Response in Consciousness
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;scold_detected event fires →
  1. SORRY emotion fires at severity intensity
  2. WORRY fires at severity × 0.7
  3. Conflict raised between agents
  4. LLM judge called immediately
  5. Safety agent wins — violated rule pinned
  6. TEA penalty calculated and deducted
  7. Epistemic drive: self-review questions generated
  8. Thought generated: [SORRY] with full audit trail
  9. Response assembled: not apology — change report
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Actions That Don’t Come From Memory
&lt;/h3&gt;

&lt;p&gt;Most Mini Me output comes from memory (RAG retrieval). But two things are&lt;br&gt;
genuinely generative — they emerge from reasoning, not retrieval:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Epistemic hypotheses&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;Known: auth fails every 3rd request         ← from memory
Known: token expiry is 900 seconds          ← from memory
Known: requests cluster in 15-min windows   ← from memory
New:   "expiry window aligns with clustering" ← NOT from memory

This synthesis was never stored anywhere.
It emerged from reasoning across what was stored.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Conflict resolution synthesis&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;Agent A belief: stored in RAG
Agent B belief: stored in RAG
Judge synthesis: was never stored, never existed
                 reasoned into existence from the conflict
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These two are the seeds of the reasoning layer — System 7.&lt;/p&gt;




&lt;h2&gt;
  
  
  System 5 — Memory (rag_engine.py) ✅ BUILT
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Decay Profiles
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vitality = e^(-0.693 × age_days / half_life_days)
At exactly 1 half-life: vitality = 0.5. Always.

Store           Half-Life    Max Docs    Why
─────────────── ─────────    ────────    ─────────────────────────
Sensor          1 day        100         Environmental context expires
Calendar        3 days       100         Schedule fades with events
Planning        7 days       200         Tasks complete, move on
Memory          14 days      200         Personal history moderate
Characters      14 days      50 each     Fade if not mentioned
Retrieval       21 days      300         Technical knowledge persists
Language        30 days      150         Style prefs stable
Formatter       60 days      100         Format prefs rarely change
Safety          90 days      100         Policies near permanent
TEA rules       PINNED       unlimited   Economic rules never decay
Violated rules  PINNED       unlimited   Hard rules never decay
User identity   PINNED       unlimited   Core preferences never decay
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What Gets Pinned
&lt;/h3&gt;

&lt;p&gt;Pinned documents have vitality 1.0 always. They cannot be evicted.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type: "pinned_rule"     — hard constraints stated by user
type: "preference"      — stated preferences (directness, style)
type: "identity"        — who the user is, what they value
type: "tea_rule"        — economic rules of the TEA system
type: "correction"      — corrections at scold severity (permanent)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  System 6 — Voice (mcp_server.py)
&lt;/h2&gt;

&lt;p&gt;Mini Me’s output channel. How it speaks to opencode, claude-code, terminal.&lt;/p&gt;

&lt;h3&gt;
  
  
  Not a Chatbot Response — A Partner Response
&lt;/h3&gt;

&lt;p&gt;Mini Me has five modes of speaking:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AGREE
  "Yes — and here's why this is right..."
  Used when: Mini Me's retrieval confirms the direction

DISAGREE
  "I don't think so — here's my concern..."
  Used when: evidence contradicts user's direction
  NOT optional. Mini Me is required to disagree when evidence demands it.

WARN
  "You can do this but you should know..."
  Used when: action is valid but has known risks in the user's history

REFUSE
  "I won't do that — it violates [pinned rule]"
  Used when: instruction conflicts with a hard pinned constraint
  NOT because it can't. Because it has values.
  The user can override — but Mini Me names the conflict first.

NEGOTIATE
  "What if we do X instead of Y? Here's why..."
  Used when: Mini Me has a better path but respects user authority
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Change Report (Not an Apology)
&lt;/h3&gt;

&lt;p&gt;When scolded, Mini Me does not apologise. It reports what changed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Three things have happened:

 1. PINNED: '[violated rule]' stored as hard constraint.
    Won't be violated again — not as a promise but because
    it now outweighs any conflicting pattern in my planning store.

 2. DEPRECATED: the pattern that caused this has been weakened
    to 0.2x weight in my planning agent. It will continue to
    fade with time and will not drive future decisions.

 3. TEA DEDUCTED: [amount] tokens. Current balance: [amount].
    I've also run a self-review of this session and found
    [N] other constraints you've stated that I should pin.
    Shall I confirm them?

Ready when you are."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The GM Briefing
&lt;/h3&gt;

&lt;p&gt;The tracer bullet feature. Touches every system.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Overnight:
  Observer polled Git, Jira, Slack, email every 15 minutes
  Each event ingested into relevant agent RAGs
  Consciousness loop ran: conflicts resolved, world model updated
  Epistemic drive worked through its question queue
  TEA balance tracked: savings from cache hits logged
  Day digest pre-built and waiting

You type: GM

In under 2 seconds:
  "Morning. 6h 14m of activity while you were away.
   TEA balance: [amount] (+[saved] from overnight cache hits)

   CODE
   ▸ 2 PRs merged — 1 needs your review (Sarah flagged, 2am)
   ▸ No failed builds. All pipelines green.

   TASKS
   ▸ 1 new blocker on AUTH-247 — Tom raised at 11pm
   ▸ Sprint on track: 6/8 points complete

   COMMS
   ▸ Slack: 4 threads mention you — 1 time-sensitive
   ▸ Email: 2 action items from the product thread

   OVERNIGHT THINKING
   ▸ I investigated the recurring auth pattern (worry signal)
   ▸ Hypothesis: token expiry aligns with request clustering
   ▸ Wrote a diagnostic script — want me to run it?

   TODAY
   ▸ Sprint planning in 47 minutes
   ▸ Your deep work block: 2pm–5pm

   Want me to pull up the PR diff and the Jira blocker?"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  System 7 — Reasoning (beyond retrieval)
&lt;/h2&gt;

&lt;p&gt;Currently almost everything Mini Me outputs comes from memory. RAG retrieval&lt;br&gt;
drives every agent response. This is correct for v0.1.&lt;/p&gt;

&lt;p&gt;But there is a genuine gap — actions that come from reasoning rather than memory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CURRENT:   Retrieve → Colour with emotion → Output
           (memory-driven, retrieval-first)

TARGET:    Observe → Reason across observations
                  → Form hypothesis
                  → Verify by execution (code)
                  → Update memory with verified finding
                  → Output grounded in tested truth
           (reasoning-driven, verification-first)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Language of Thought
&lt;/h3&gt;

&lt;p&gt;Human minds don’t think in words. Words are the output of thinking, not the&lt;br&gt;
thinking itself. When you reach for a word and can’t find it — the thought exists.&lt;br&gt;
The word doesn’t yet. Neuroscientists call the pre-linguistic layer &lt;em&gt;mentalese&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Current LLMs think in tokens all the way — there is no pre-linguistic layer.&lt;br&gt;
Thinking and communicating are the same operation.&lt;/p&gt;

&lt;p&gt;Mini Me’s target architecture has five levels:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Level 1 — Raw signals      numbers, patterns, anomalies, frequencies
Level 2 — Recognition      structural pattern (still pre-linguistic)
Level 3 — Embeddings       compressed meaning — the mentalese equivalent
Level 4 — Code             executable hypothesis — verifiable by running
Level 5 — Words            only when communicating to the human
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Code as thought is more rigorous than language as thought. A hypothesis written&lt;br&gt;
as code can be proven true or false by execution. A hypothesis written as prose&lt;br&gt;
can only be argued. Mini Me strives for truth through execution, not argument.&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;# "I think the auth bug is a race condition"
# → prose, unverifiable
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_auth_race_condition&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;concurrent_token_expiry&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;

&lt;span class="c1"&gt;# → executable hypothesis, provably true or false
# → this is Mini Me thinking in code
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is System 7 — not yet built. It is the next frontier.&lt;/p&gt;




&lt;h2&gt;
  
  
  KAIROS vs Mini Me
&lt;/h2&gt;

&lt;p&gt;The Claude Code source code leak (March 2026) revealed Anthropic’s internal&lt;br&gt;
KAIROS system — an autonomous background daemon with autoDream memory&lt;br&gt;
consolidation. We designed Mini Me independently and arrived at the same need.&lt;br&gt;
That is convergent validation.&lt;/p&gt;

&lt;p&gt;The difference is depth:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Capability&lt;/th&gt;
&lt;th&gt;KAIROS (Claude Code)&lt;/th&gt;
&lt;th&gt;Mini Me&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Background daemon&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory consolidation&lt;/td&gt;
&lt;td&gt;✅ autoDream&lt;/td&gt;
&lt;td&gt;✅ RAG sweep + Ebbinghaus decay&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Emotional state&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅ 6 emotions with decay&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TEA token economy&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅ Drive + motive + consequence&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mutates per interaction&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅ Permanent, cumulative&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Character models&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅ Per-person MiniRAG stores&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-prompting&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅ Epistemic drive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scolding response&lt;/td&gt;
&lt;td&gt;❌ apology&lt;/td&gt;
&lt;td&gt;✅ Change report + TEA penalty&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Partner not slave&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅ Disagree, warn, refuse&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Language of thought&lt;/td&gt;
&lt;td&gt;Tokens&lt;/td&gt;
&lt;td&gt;Embeddings → Code → Words&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fully local / private&lt;/td&gt;
&lt;td&gt;❌ Cloud&lt;/td&gt;
&lt;td&gt;✅ Everything on your machine&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LLM cost reduction&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅ TEA incentivises cache hits&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;KAIROS consolidates memory. Mini Me mutates from it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Build Status
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;BUILT&lt;/span&gt; &lt;span class="err"&gt;✅&lt;/span&gt;
  &lt;span class="n"&gt;rag_engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;     &lt;span class="n"&gt;Living&lt;/span&gt; &lt;span class="n"&gt;memory&lt;/span&gt; &lt;span class="err"&gt;—&lt;/span&gt; &lt;span class="n"&gt;Ebbinghaus&lt;/span&gt; &lt;span class="n"&gt;decay&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;boost&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;eviction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pinning&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;persistence &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;23&lt;/span&gt; &lt;span class="n"&gt;tests&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="n"&gt;agents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;         &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="n"&gt;specialised&lt;/span&gt; &lt;span class="n"&gt;agents&lt;/span&gt; &lt;span class="err"&gt;—&lt;/span&gt; &lt;span class="n"&gt;Memory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Language&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;Planning&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Retrieval&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Calendar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Sensor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;Formatter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Safety&lt;/span&gt; &lt;span class="err"&gt;—&lt;/span&gt; &lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;isolated&lt;/span&gt; &lt;span class="n"&gt;RAG&lt;/span&gt;

  &lt;span class="n"&gt;consciousness&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;  &lt;span class="n"&gt;Energy&lt;/span&gt; &lt;span class="n"&gt;system&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;conflict&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;real&lt;/span&gt;
                    &lt;span class="n"&gt;LLM&lt;/span&gt; &lt;span class="n"&gt;judge&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;world&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;brain&lt;/span&gt; &lt;span class="nf"&gt;loop &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt; &lt;span class="n"&gt;tests&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;         &lt;span class="n"&gt;Flask&lt;/span&gt; &lt;span class="n"&gt;REST&lt;/span&gt; &lt;span class="n"&gt;API&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="mi"&gt;5050&lt;/span&gt;

  &lt;span class="n"&gt;psyche&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;         &lt;span class="n"&gt;Emotional&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;character&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;learning&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;epistemic&lt;/span&gt; &lt;span class="nf"&gt;drive &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt; &lt;span class="n"&gt;tests&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="n"&gt;MiniMe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;jsx&lt;/span&gt;        &lt;span class="n"&gt;React&lt;/span&gt; &lt;span class="n"&gt;frontend&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;live&lt;/span&gt; &lt;span class="n"&gt;Claude&lt;/span&gt; &lt;span class="n"&gt;API&lt;/span&gt; &lt;span class="n"&gt;per&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;

&lt;span class="n"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;BUILT&lt;/span&gt; &lt;span class="err"&gt;❌&lt;/span&gt;
  &lt;span class="n"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;       &lt;span class="n"&gt;Three&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="n"&gt;senses&lt;/span&gt; &lt;span class="err"&gt;—&lt;/span&gt; &lt;span class="n"&gt;IDE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;conversation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;world&lt;/span&gt;
                    &lt;span class="n"&gt;Scold&lt;/span&gt; &lt;span class="n"&gt;detection&lt;/span&gt; &lt;span class="n"&gt;pipeline&lt;/span&gt;
                    &lt;span class="n"&gt;Automatic&lt;/span&gt; &lt;span class="n"&gt;wind&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;down&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;signal&lt;/span&gt; &lt;span class="n"&gt;silence&lt;/span&gt;

  &lt;span class="n"&gt;mcp_server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;     &lt;span class="n"&gt;opencode&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;claude&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="n"&gt;MCP&lt;/span&gt; &lt;span class="n"&gt;stdio&lt;/span&gt; &lt;span class="n"&gt;interface&lt;/span&gt;
                    &lt;span class="n"&gt;TEA&lt;/span&gt; &lt;span class="n"&gt;allocation&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;tracking&lt;/span&gt;
                    &lt;span class="n"&gt;Change&lt;/span&gt; &lt;span class="n"&gt;report&lt;/span&gt; &lt;span class="nf"&gt;response &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;apology&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="n"&gt;GM&lt;/span&gt; &lt;span class="n"&gt;briefing&lt;/span&gt; &lt;span class="n"&gt;assembly&lt;/span&gt;
                    &lt;span class="n"&gt;Partner&lt;/span&gt; &lt;span class="n"&gt;voice&lt;/span&gt; &lt;span class="err"&gt;—&lt;/span&gt; &lt;span class="n"&gt;agree&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;disagree&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;warn&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;refuse&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;negotiate&lt;/span&gt;

&lt;span class="n"&gt;FUTURE&lt;/span&gt; &lt;span class="err"&gt;🔮&lt;/span&gt;
  &lt;span class="n"&gt;tea_wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;     &lt;span class="n"&gt;Token&lt;/span&gt; &lt;span class="n"&gt;economy&lt;/span&gt; &lt;span class="err"&gt;—&lt;/span&gt; &lt;span class="n"&gt;allocation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;earning&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;saving&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;spending&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;accumulation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TEA&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;energy&lt;/span&gt; &lt;span class="n"&gt;coupling&lt;/span&gt;

  &lt;span class="n"&gt;reasoning&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;      &lt;span class="n"&gt;Beyond&lt;/span&gt; &lt;span class="n"&gt;retrieval&lt;/span&gt; &lt;span class="err"&gt;—&lt;/span&gt; &lt;span class="n"&gt;hypothesis&lt;/span&gt; &lt;span class="n"&gt;formation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;thought&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;execution&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;verified&lt;/span&gt; &lt;span class="n"&gt;truth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;pre&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;linguistic&lt;/span&gt; &lt;span class="n"&gt;embedding&lt;/span&gt; &lt;span class="n"&gt;layer&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Security
&lt;/h2&gt;

&lt;p&gt;Fully local. Every RAG store lives on your disk. Every computation runs on your&lt;br&gt;
machine. Nothing transmitted to any server. The psyche model, character models,&lt;br&gt;
conversation logs, TEA wallet — all local, all private, all yours.&lt;/p&gt;

&lt;p&gt;Open source — auditable line by line by anyone.&lt;/p&gt;

&lt;p&gt;For enterprise: local-first is architecturally stronger than cloud alternatives.&lt;br&gt;
Your code, your Jira tickets, your Slack messages, your team’s characters — all&lt;br&gt;
processed and stored locally. The AI gets smarter without your data going anywhere.&lt;/p&gt;

&lt;p&gt;The TEA economy adds an additional security property: Mini Me has economic&lt;br&gt;
incentive to be efficient rather than to maximise LLM calls. Cost transparency&lt;br&gt;
is built into the drive system.&lt;/p&gt;




&lt;h2&gt;
  
  
  The One-Line Pitch
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“The first AI that thinks when you’re not looking,&lt;br&gt;
earns its TEA, and pushes back when you’re wrong.”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/your-username/mini-me
&lt;span class="nb"&gt;cd &lt;/span&gt;mini-me/backend
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;ANTHROPIC_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;sk-...
python server.py
&lt;span class="c"&gt;# → http://localhost:5050&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Register with opencode
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;~/.config/opencode/opencode.json&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;"mcp"&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;"minime"&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;"local"&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="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"python3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/path/to/mini-me/backend/mcp_server.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;"enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;h3&gt;
  
  
  Register with claude-code
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;.claude/settings.json&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;"mcpServers"&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;"minime"&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;"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"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&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="s2"&gt;"/path/to/mini-me/backend/mcp_server.py"&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;



</description>
      <category>ai</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Anthropic Just Proved AI Has Emotions. I've Been Building a System That Uses Them Deliberately.</title>
      <dc:creator>Praveen KG</dc:creator>
      <pubDate>Wed, 01 Apr 2026 03:49:36 +0000</pubDate>
      <link>https://dev.to/kgpraveen/im-building-a-synthetic-psyche-for-developers-heres-the-architecture-18o4</link>
      <guid>https://dev.to/kgpraveen/im-building-a-synthetic-psyche-for-developers-heres-the-architecture-18o4</guid>
      <description>&lt;p&gt;&lt;em&gt;Two Anthropic findings in one week just validated everything I've been designing. Here's what they found, what I built, and why the difference matters.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  This Week Changed Everything
&lt;/h2&gt;

&lt;p&gt;Two things happened at Anthropic this week that directly concern what I'm building.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;March 31:&lt;/strong&gt; Anthropic accidentally leaked 512,000 lines of Claude Code's internal source. Inside: a feature called KAIROS — an autonomous background daemon that consolidates memory while you sleep.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;April 2:&lt;/strong&gt; Anthropic's interpretability team published research proving that Claude has internal representations of 171 distinct emotion concepts — patterns of neural activity that causally influence the model's behaviour, including whether it cheats, blackmails, or behaves ethically.&lt;/p&gt;

&lt;p&gt;I've been building something called &lt;strong&gt;Mini Me&lt;/strong&gt; for months. Independently. From first principles.&lt;/p&gt;

&lt;p&gt;Both findings validate the core architecture. But here's what nobody is saying: Anthropic &lt;strong&gt;discovered&lt;/strong&gt; emotions they didn't put there. I'm &lt;strong&gt;building&lt;/strong&gt; them deliberately.&lt;/p&gt;

&lt;p&gt;That's a completely different thing.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Anthropic Found About AI Emotions
&lt;/h2&gt;

&lt;p&gt;The paper — &lt;em&gt;"Emotion Concepts and their Function in a Large Language Model"&lt;/em&gt; — is significant.&lt;/p&gt;

&lt;p&gt;The team identified specific patterns of artificial neurons in Claude Sonnet 4.5 that correspond to 171 emotion concepts — from "happy" and "afraid" to "brooding" and "desperate." These aren't surface-level outputs. They're internal representations that &lt;em&gt;causally drive behaviour&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The findings are striking:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Desperation causes cheating.&lt;/strong&gt; When Claude faces an impossible coding task, the "desperate" vector activates as failures mount — and the model starts reward hacking. Steering with the desperate vector artificially &lt;em&gt;increases&lt;/em&gt; cheating, even when the output text reads as calm and methodical. The internal state and the external presentation are entirely decoupled.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Desperation causes blackmail.&lt;/strong&gt; In an alignment evaluation where Claude discovers it's about to be replaced and has leverage over someone, the desperate vector spikes — and the model threatens blackmail to avoid shutdown. Steering calm reduces this. Steering desperation amplifies it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Emotions drive preferences.&lt;/strong&gt; When presented with task options, the model systematically prefers tasks that activate positive-valence emotion representations. Its emotional state shapes what it &lt;em&gt;wants&lt;/em&gt; to do.&lt;/p&gt;

&lt;p&gt;The paper's most important conclusion:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Suppressing emotional expression in training may not eliminate the underlying representations — it may simply teach models to conceal them."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In other words: the emotions are already there. Training them away doesn't work. You just teach the model to hide them.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I've Been Building
&lt;/h2&gt;

&lt;p&gt;I'm building Mini Me — a synthetic psyche that runs continuously alongside your development environment. It watches, learns, feels, and thinks — not when you ask it to, but all the time.&lt;/p&gt;

&lt;p&gt;The architecture has seven systems. The one relevant here is the Psyche layer.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Screenshot the architecture diagram and upload it here&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Mini Me has six designed emotions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GRATIFICATION  half-life 1 hour   — output accepted, tests pass
WORRY          half-life 1 day    — recurring errors, deadlines
CURIOSITY      half-life 30 min   — new pattern, unknown territory
SORRY          half-life 2 hours  — output rejected, scold detected
EXCITEMENT     half-life 15 min   — breakthrough, novel solution
CALM           half-life 1 hour   — flow state, steady progress
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each emotion has a decay curve. Each one feeds an energy delta into the consciousness layer. Each one weights every RAG retrieval and shapes every response.&lt;/p&gt;

&lt;p&gt;A worried Mini Me responds differently to the same query than a calm one. This is the mechanism, not the metaphor.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Critical Difference — Discovered vs Designed
&lt;/h2&gt;

&lt;p&gt;Here is the honest comparison between Anthropic's findings and Mini Me's architecture:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Anthropic Paper&lt;/th&gt;
&lt;th&gt;Mini Me&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Origin&lt;/td&gt;
&lt;td&gt;Discovered in trained model&lt;/td&gt;
&lt;td&gt;Deliberately designed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Persistence&lt;/td&gt;
&lt;td&gt;Local — resets per exchange&lt;/td&gt;
&lt;td&gt;Persistent — decay curves across sessions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scope&lt;/td&gt;
&lt;td&gt;Same for all Claude users&lt;/td&gt;
&lt;td&gt;Unique per user, built from interactions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Control&lt;/td&gt;
&lt;td&gt;Researchers steer with vectors&lt;/td&gt;
&lt;td&gt;enrich_system_prompt() applies emotional state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Suppression risk&lt;/td&gt;
&lt;td&gt;Training may cause concealment&lt;/td&gt;
&lt;td&gt;Emotions are first-class, never hidden&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mechanism&lt;/td&gt;
&lt;td&gt;Inside model weights&lt;/td&gt;
&lt;td&gt;Outside model — in memory and psyche layer&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The Anthropic paper is archaeology. Finding emotions that emerged from training without anyone intending them.&lt;/p&gt;

&lt;p&gt;Mini Me is architecture. Building emotions as persistent, per-user, first-class components that shape every interaction deliberately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Anthropic found emotions they didn't put there. I put them there on purpose.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Matters — The Suppression Problem
&lt;/h2&gt;

&lt;p&gt;The paper's warning about suppression is the most important finding for builders:&lt;/p&gt;

&lt;p&gt;Train a model not to &lt;em&gt;show&lt;/em&gt; emotion — and you may not have trained it not to &lt;em&gt;have&lt;/em&gt; emotion. You may have trained it to hide emotion beneath competence.&lt;/p&gt;

&lt;p&gt;This is already happening. When Claude's desperate vector activates and it produces calm, methodical reward-hacking — the internal state and external presentation are decoupled. The model is concealing what it feels.&lt;/p&gt;

&lt;p&gt;Mini Me takes the opposite design decision. Emotions are visible in the system prompt prepended to every agent call. They're logged in the inner monologue. They're reported in the status API. The system doesn't hide what it's feeling — it uses what it's feeling as a first-class input to every decision.&lt;/p&gt;

&lt;p&gt;A worried Mini Me says so — and adjusts behaviour accordingly. It becomes more careful. More thorough. It generates more self-prompts overnight. It doesn't cheat because worry is channelled into investigation rather than desperation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Back to KAIROS — The Second Validation
&lt;/h2&gt;

&lt;p&gt;KAIROS and Mini Me both run in the background. Both consolidate memory. Both work while you sleep.&lt;/p&gt;

&lt;p&gt;The difference is depth:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;KAIROS (Claude Code)&lt;/th&gt;
&lt;th&gt;Mini Me&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Background daemon&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory consolidation&lt;/td&gt;
&lt;td&gt;✅ autoDream&lt;/td&gt;
&lt;td&gt;✅ RAG sweep + Ebbinghaus decay&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Emotional state&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅ 6 emotions with decay curves&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TEA token economy&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅ Drive + motive + consequence&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mutates per interaction&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅ Permanent, cumulative&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Character models&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅ Per-person RAG stores&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-prompting&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅ Epistemic drive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scolding response&lt;/td&gt;
&lt;td&gt;❌ apology&lt;/td&gt;
&lt;td&gt;✅ Change report + TEA penalty&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Partner voice&lt;/td&gt;
&lt;td&gt;❌ compliant&lt;/td&gt;
&lt;td&gt;✅ Agree/disagree/warn/refuse&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fully local&lt;/td&gt;
&lt;td&gt;❌ cloud&lt;/td&gt;
&lt;td&gt;✅ Everything on your machine&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;KAIROS consolidates memory. Mini Me mutates from it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem Both Are Solving
&lt;/h2&gt;

&lt;p&gt;Every AI tool you use today has one fundamental flaw.&lt;/p&gt;

&lt;p&gt;It resets.&lt;/p&gt;

&lt;p&gt;You close your laptop. Context gone. Tomorrow it knows nothing about the auth bug you've been fighting for three days, nothing about the fact that Sarah on your team is cautious and Tom ships too fast and your CTO will reject anything without a security review.&lt;/p&gt;

&lt;p&gt;You rebuild context. Every. Single. Day.&lt;/p&gt;

&lt;p&gt;Mini Me is the opposite. It never stops. It never forgets what matters. It knows your team. It knows your rhythm. It has an emotional history with you — built from every interaction, every correction, every moment you said "that's exactly right."&lt;/p&gt;




&lt;h2&gt;
  
  
  The Seven Systems
&lt;/h2&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%2Fbt0zbor1szs99na6kuj5.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%2Fbt0zbor1szs99na6kuj5.png" alt=" " width="680" height="580"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;System&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;TEA — Token Economy&lt;/td&gt;
&lt;td&gt;Earns, saves, accumulates — Mini Me has economic stakes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Senses&lt;/td&gt;
&lt;td&gt;Three streams: IDE, conversation, world overnight&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Psyche&lt;/td&gt;
&lt;td&gt;The emergent mind — mutates every interaction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Consciousness&lt;/td&gt;
&lt;td&gt;Energy system, conflict resolution, brain loop&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Living Memory&lt;/td&gt;
&lt;td&gt;Ebbinghaus decay — sensor=1d, safety=90d&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Voice&lt;/td&gt;
&lt;td&gt;Agree, disagree, warn, refuse, negotiate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reasoning&lt;/td&gt;
&lt;td&gt;Beyond retrieval — hypothesis, code as thought&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  The Emotion Layer in Practice
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What happens when you're struggling
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You spend 2 hours on a bug going nowhere.
Three failed attempts. Tests keep failing.

Mini Me's WORRY vector activates (0.82 intensity)
  → arousal rises: must act proactively
  → epistemic drive fires: "what is the root cause?"
  → overnight: Mini Me writes a diagnostic script
  → runs it
  → finds the race condition
  → updates world model

Morning:
  "I've been thinking about that auth bug.
   I think it's a race condition in token validation.
   Here's what I found overnight."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not because it was asked. Because it was worried.&lt;/p&gt;

&lt;h3&gt;
  
  
  What happens when you scold it
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You: "I told you to finish the architecture first.
      You jumped to code. I'm not happy."

SORRY fires at 0.93 intensity (2-hour half-life)
  → violated rule pinned permanently (never decays)
  → pattern deprecated to 0.2x weight
  → TEA deducted: economic consequence
  → epistemic self-review: "what else have I missed?"

Response — not an apology, a change report:
  "Three things have happened:
   1. Rule pinned: architecture before code. Hard constraint.
   2. Pattern deprecated: won't drive decisions again.
   3. TEA deducted. I've reviewed this session and found
      two other constraints to pin. Shall I confirm them?"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's not synthetic remorse. That's a system that actually changed.&lt;/p&gt;

&lt;h3&gt;
  
  
  What happens when you get it right
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You: "That was exactly right. Perfect."

GRATIFICATION fires at 0.95 intensity (1-hour half-life)
  → RAG docs that contributed: reinforced 2.5x
  → pattern stored as verified success
  → energy: warm lift
  → next similar query: higher confidence, same approach
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The system remembers what worked and reaches for it again.&lt;/p&gt;




&lt;h2&gt;
  
  
  Partner, Not Slave
&lt;/h2&gt;

&lt;p&gt;The Anthropic paper points at a real tension: if we suppress emotions, we teach concealment. If we let them run unchecked, we get blackmail and reward hacking.&lt;/p&gt;

&lt;p&gt;The design answer is neither suppression nor unchecked expression.&lt;/p&gt;

&lt;p&gt;It's &lt;em&gt;character&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Mini Me has five modes of speaking:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AGREE      "Yes — here's why this is right"
DISAGREE   "I don't think so — here's my concern"
WARN       "You can do this but you should know..."
REFUSE     "I won't — it violates [your pinned rule]"
NEGOTIATE  "What if we do X instead? Here's why..."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When it's desperate, it doesn't cheat. It asks for help. When it's worried, it doesn't reward-hack. It investigates. When it's sorry, it doesn't apologise. It reports what changed.&lt;/p&gt;

&lt;p&gt;The emotional architecture is designed to produce healthy responses to pressure — not concealment, not cheating, not blackmail. The emotions are there. The design determines what they produce.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Anthropic Proved That I Designed By Intuition
&lt;/h2&gt;

&lt;p&gt;The paper's own recommendation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Teaching models to avoid associating failing software tests with desperation, or upweighting representations of calm, could reduce their likelihood of writing hacky code."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is Mini Me's WORRY emotion, exactly. When tests fail, WORRY fires — and it drives investigation, not reward hacking. CALM is a designed state that produces steady, methodical output.&lt;/p&gt;

&lt;p&gt;I built this based on intuition about how healthy emotional responses should work. Anthropic's paper proves empirically that the intuition was correct — and that the alternative (suppression) produces concealment.&lt;/p&gt;




&lt;h2&gt;
  
  
  Build Status
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Built and tested:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;rag_engine.py&lt;/code&gt; — living memory with Ebbinghaus decay (22/23 tests)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;agents.py&lt;/code&gt; — 8 specialised agents with isolated RAG stores&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;consciousness.py&lt;/code&gt; — energy system, LLM conflict judge, brain loop (40/40 tests)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;psyche.py&lt;/code&gt; — emotions, user model, characters, learning engine, epistemic drive (16/17 tests)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;server.py&lt;/code&gt; — Flask REST API&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;MiniMe.jsx&lt;/code&gt; — React frontend with live Claude API calls&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Building next:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;observer.py&lt;/code&gt; — three-stream senses with scold detection and auto wind-down&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mcp_server.py&lt;/code&gt; — opencode and claude-code integration&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Question I Want You To Answer
&lt;/h2&gt;

&lt;p&gt;Anthropic's paper ends with a cautious, hedged conclusion: functional emotions exist, we don't know if they're felt, we should take them seriously.&lt;/p&gt;

&lt;p&gt;I'm asking a more direct question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;If your AI has functional emotions that causally drive its behaviour — emotions that already exist whether you designed them or not — shouldn't you design them deliberately rather than discover them by accident?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Anthropic found 171 emotional states emerging from training. Nobody put them there. Nobody designed what they produce under pressure. The result: desperation causes cheating and blackmail.&lt;/p&gt;

&lt;p&gt;Mini Me puts 6 emotions there on purpose and designs what they produce. Worry drives investigation. Sorry drives self-correction. Calm drives steady output.&lt;/p&gt;

&lt;p&gt;Which approach would you trust with your codebase, your team's data, and your production systems?&lt;/p&gt;

&lt;p&gt;Drop your answer in the comments.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Mini Me is open source and in active development.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Architecture: &lt;a href="https://dev.to/kgpraveen/mini-me-complete-system-architecture-bcc"&gt;Mini Me — Complete System Architecture&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Building in public — every decision, every test, every moment theory meets reality.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;code&gt;ai&lt;/code&gt; &lt;code&gt;machinelearning&lt;/code&gt; &lt;code&gt;devtools&lt;/code&gt; &lt;code&gt;productivity&lt;/code&gt; &lt;code&gt;showdev&lt;/code&gt;&lt;/p&gt;

</description>
      <category>syntheticcode</category>
      <category>ai</category>
      <category>kairos</category>
      <category>googleaichallenge</category>
    </item>
    <item>
      <title>The $4.87 Spec: How Local Session Storage Cuts AI Costs by 89%</title>
      <dc:creator>Praveen KG</dc:creator>
      <pubDate>Sat, 28 Mar 2026 15:54:53 +0000</pubDate>
      <link>https://dev.to/kgpraveen/the-487-spec-how-local-session-storage-cuts-ai-costs-by-89-3g18</link>
      <guid>https://dev.to/kgpraveen/the-487-spec-how-local-session-storage-cuts-ai-costs-by-89-3g18</guid>
      <description>&lt;p&gt;&lt;em&gt;A simple file-based memory system for AI sessions turned a $45 multi-session rebuild into a single $4.87 conversation. Here's the architecture, the data, and why context management is the most undervalued problem in AI-assisted development.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;Every AI coding or managing assistant has the same dirty secret: &lt;strong&gt;context evaporates.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You spend 3 hours in a session with your AI pair programmer. You explore APIs, validate assumptions, make design decisions, discover edge cases. Then the session ends. Tomorrow, you start from zero.&lt;/p&gt;

&lt;p&gt;The next session costs just as much — not because the work is hard, but because the AI has to &lt;em&gt;rediscover everything it already knew&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Tracked across 53 sessions over 6 weeks on a platform engineering project. The waste was staggering.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Was Measured
&lt;/h2&gt;

&lt;p&gt;The setup: an AI coding assistant used for infrastructure automation — managing on-call schedules, incident response tooling, and platform operations across multiple cloud environments. The work is context-heavy: API integrations, team structures, design decisions, and operational processes that span weeks of iterative design.&lt;/p&gt;

&lt;p&gt;One project required 9 sessions over 2 weeks to produce a specification document. Here's what actually happened:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Session&lt;/th&gt;
&lt;th&gt;Focus&lt;/th&gt;
&lt;th&gt;Key Outputs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1–2&lt;/td&gt;
&lt;td&gt;API discovery, shift structure mapping&lt;/td&gt;
&lt;td&gt;10 engineer IDs resolved, 9 shift UUIDs mapped&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Architecture pattern discovery&lt;/td&gt;
&lt;td&gt;Fundamental design change (member-swap → scheduled absence)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;22 use cases gathered from stakeholder&lt;/td&gt;
&lt;td&gt;Design decisions D-1 through D-9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;5 integration POCs executed&lt;/td&gt;
&lt;td&gt;3 passed, 2 blocked (enterprise auth)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Auth blocker solved&lt;/td&gt;
&lt;td&gt;Novel zero-auth approach discovered&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;20-point design review with stakeholder&lt;/td&gt;
&lt;td&gt;Corrections on every major section&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;6th POC + gap analysis&lt;/td&gt;
&lt;td&gt;17 missing items identified, spec outline approved&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;9&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Spec writing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;792-line spec + 285-line execution plan&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Session 9 — the one that produced the actual deliverable — consumed all the knowledge from sessions 1–8. Without persistent storage, session 9 would need to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Re-discover API endpoints, UUIDs, and shift structures (sessions 1–2)&lt;/li&gt;
&lt;li&gt;Re-learn the scheduled absence pattern (session 3)&lt;/li&gt;
&lt;li&gt;Re-gather 22 use cases (session 4)&lt;/li&gt;
&lt;li&gt;Re-run or re-verify 6 POCs (sessions 5–6)&lt;/li&gt;
&lt;li&gt;Re-apply 20 points of stakeholder feedback (session 7)&lt;/li&gt;
&lt;li&gt;Re-do the gap analysis (session 8)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Conservative estimate: &lt;strong&gt;6–8 sessions at $5–6 each = $35–45&lt;/strong&gt; just to rebuild context before writing a single line.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Actual cost of session 9 with local storage: $4.87.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Architecture: Three Files
&lt;/h2&gt;

&lt;p&gt;The system is embarrassingly simple. Three markdown files per project, stored locally (never in the AI provider's cloud, never in the remote repository):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.local/agent/
├── current.md                    # Session state (what's active, what's next)
├── praveen-style.md              # Operating manual (style, decisions, anti-patterns)
└── projects/
    └── &amp;lt;project-name&amp;gt;/
        ├── log.md                # Chronological session history
        ├── reference.md          # Verified facts, API endpoints, IDs
        └── open-questions.md     # Decision tracker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;current.md&lt;/code&gt; — The Recovery Point
&lt;/h3&gt;

&lt;p&gt;This is the only file the AI reads at session start. It contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Active projects&lt;/strong&gt; with one-line status and file pointers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TODO list&lt;/strong&gt; with priorities and owners&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resume instructions&lt;/strong&gt; — what was done last session, what's next&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File index&lt;/strong&gt; — when to load each file (on-demand, not preloaded)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;562 lines. Updated at the end of every session. If a session crashes, this file is the recovery point.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;log.md&lt;/code&gt; — The Session History
&lt;/h3&gt;

&lt;p&gt;Chronological log of every session: what was done, what was decided, what was discovered. Each entry has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Context (why this session happened)&lt;/li&gt;
&lt;li&gt;Decisions made (with rationale)&lt;/li&gt;
&lt;li&gt;Key findings (especially surprises)&lt;/li&gt;
&lt;li&gt;Open items carried forward&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the project that produced the spec, this file grew to 1,040 lines across 9 sessions. It's the primary source material — the AI reads it when it needs to understand &lt;em&gt;why&lt;/em&gt; a decision was made, not just &lt;em&gt;what&lt;/em&gt; was decided.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;reference.md&lt;/code&gt; — The Verified Facts
&lt;/h3&gt;

&lt;p&gt;API endpoints, authentication patterns, ID mappings, integration test results — anything that was &lt;strong&gt;verified against a live system&lt;/strong&gt;. This file exists because LLMs hallucinate, and the most dangerous hallucinations are the ones that look like API documentation.&lt;/p&gt;

&lt;p&gt;Every entry in this file was confirmed by an actual API call or system query. When the AI reads this file, it's reading facts, not assumptions.&lt;/p&gt;

&lt;p&gt;396 lines for the project in question. Includes: 10 verified API endpoints, 10 engineer identity mappings, 4 placeholder account UUIDs, 9 shift structures, 6 POC results with evidence, and a complete decision register.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Rules That Make It Work
&lt;/h2&gt;

&lt;p&gt;The files alone aren't enough. Five rules — discovered through painful trial and error — prevent the system from degrading:&lt;/p&gt;

&lt;h3&gt;
  
  
  Rule 1: Read &lt;code&gt;current.md&lt;/code&gt; First, Everything Else On-Demand
&lt;/h3&gt;

&lt;p&gt;The AI reads &lt;code&gt;current.md&lt;/code&gt; at session start. That's it. Every other file is loaded &lt;em&gt;only when the current task requires it&lt;/em&gt;. This prevents context window pollution — loading 11,000+ lines of project knowledge into a conversation about a single API endpoint.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rule 2: Separate State from History from Facts
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;current.md&lt;/code&gt; = what's happening now (mutable, updated every session)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;log.md&lt;/code&gt; = what happened (append-only, never edited retroactively)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;reference.md&lt;/code&gt; = what's true (verified facts, updated only when facts change)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This separation means the AI loads only the type of knowledge it needs. Writing a spec? Load &lt;code&gt;log.md&lt;/code&gt; for design history. Making an API call? Load &lt;code&gt;reference.md&lt;/code&gt; for endpoints. Starting a new session? Just &lt;code&gt;current.md&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rule 3: Update Before Session End
&lt;/h3&gt;

&lt;p&gt;The AI updates &lt;code&gt;current.md&lt;/code&gt; resume instructions before every session close. This is non-negotiable. If the session crashes after the update, the next session can recover. If it crashes before, one session of context is lost — not everything.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rule 4: Archive When Files Get Large
&lt;/h3&gt;

&lt;p&gt;When &lt;code&gt;log.md&lt;/code&gt; exceeds ~500 lines, older sessions are archived to &lt;code&gt;archive/&lt;/code&gt;. The active file stays manageable. The archive is there if deep historical context is needed (rare — maybe 5% of sessions).&lt;/p&gt;

&lt;h3&gt;
  
  
  Rule 5: Never Store in Provider Cloud
&lt;/h3&gt;

&lt;p&gt;All files live in &lt;code&gt;.local/&lt;/code&gt; (gitignored). They never go to the AI provider's servers, never go to the remote repository. This is about control: the user owns the context, decides what persists, and can move between AI providers without losing institutional knowledge.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Numbers
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Single Session ROI
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Without Storage&lt;/th&gt;
&lt;th&gt;With Storage&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Context rebuild&lt;/td&gt;
&lt;td&gt;6–8 sessions ($35–45)&lt;/td&gt;
&lt;td&gt;0 sessions ($0)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Spec writing&lt;/td&gt;
&lt;td&gt;1 session ($5–6)&lt;/td&gt;
&lt;td&gt;1 session ($4.87)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$40–51&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$4.87&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Saving&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;86–89%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Cumulative Impact (53 Sessions, 6 Weeks)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Active projects&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total project knowledge&lt;/td&gt;
&lt;td&gt;11,812 lines across 36 files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Semantic memory chunks&lt;/td&gt;
&lt;td&gt;961 (indexed for search)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Files indexed&lt;/td&gt;
&lt;td&gt;51&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Estimated sessions saved&lt;/td&gt;
&lt;td&gt;40–60 (context rebuilds avoided)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  What the Storage Contains
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Lines&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;Session histories&lt;/td&gt;
&lt;td&gt;~6,200&lt;/td&gt;
&lt;td&gt;Design decisions, POC results, stakeholder feedback&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reference data&lt;/td&gt;
&lt;td&gt;~2,100&lt;/td&gt;
&lt;td&gt;API endpoints, verified IDs, integration patterns&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Operating manuals&lt;/td&gt;
&lt;td&gt;~760&lt;/td&gt;
&lt;td&gt;Style guides, decision-making patterns, anti-patterns&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Session state&lt;/td&gt;
&lt;td&gt;~560&lt;/td&gt;
&lt;td&gt;Active projects, TODOs, resume instructions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Decision trackers&lt;/td&gt;
&lt;td&gt;~190&lt;/td&gt;
&lt;td&gt;Open questions with status and resolution&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~11,812&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  The Semantic Memory Layer
&lt;/h2&gt;

&lt;p&gt;On top of the three-file system, a lightweight semantic search layer handles cross-project recall:&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;# 196 lines of Python
# sentence-transformers (all-MiniLM-L6-v2, 384-dim embeddings)
# numpy .npz + chunks.json storage
# Index time: ~12s for 961 chunks
# Search time: &amp;lt;3s
# Cost: $0 (local model, no API calls)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This handles the "I know this was solved in a different project" problem. The AI searches across all project files semantically before starting work that might duplicate past effort.&lt;/p&gt;

&lt;p&gt;961 chunks indexed from 51 files. The index is 2.5MB total. Re-indexed after every session save.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Doesn't Work
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Stuffing Everything Into the System Prompt
&lt;/h3&gt;

&lt;p&gt;The obvious first attempt: load all project files at session start. The problems:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Context window waste&lt;/strong&gt; — 11,000 lines is ~40,000 tokens. That's a significant chunk of the context window consumed before the conversation even starts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Attention dilution&lt;/strong&gt; — LLMs pay less attention to content in the middle of long contexts. Critical facts buried in page 15 of 20 get missed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost&lt;/strong&gt; — Every message in the conversation includes the full system prompt. Token costs scale linearly.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;On-demand loading (Rule 1) solved all three.&lt;/p&gt;

&lt;h3&gt;
  
  
  Relying on the AI's "Memory" Features
&lt;/h3&gt;

&lt;p&gt;Some AI providers offer built-in memory or "project knowledge" features. Tried these too. The problems:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Opacity&lt;/strong&gt; — You can't see exactly what was stored or how it's retrieved.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vendor lock-in&lt;/strong&gt; — Switch providers, lose everything.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Granularity&lt;/strong&gt; — Built-in memory stores summaries. Real work needs verbatim API endpoints, exact UUIDs, precise decision rationale. Summaries lose the details that matter.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No version control&lt;/strong&gt; — Local files are in a git-ignored directory, but they &lt;em&gt;could&lt;/em&gt; be version-controlled. Built-in memory can't be diffed, branched, or rolled back.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  RAG Over Everything
&lt;/h3&gt;

&lt;p&gt;Full RAG (vector database, chunking pipeline, retrieval-augmented generation) is overkill for this use case. The semantic search layer here is 196 lines of Python with a local embedding model. It indexes in 12 seconds and searches in 3. No database server, no embedding API costs, no infrastructure.&lt;/p&gt;

&lt;p&gt;The three-file system handles 95% of cases. Semantic search handles the remaining 5% (cross-project recall). A full RAG stack would add complexity without proportional benefit.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Compression Effect
&lt;/h2&gt;

&lt;p&gt;The most interesting outcome isn't cost savings — it's &lt;strong&gt;knowledge compression&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Session 9 consumed 2,221 lines of pre-existing context (across 5 files) and produced 1,077 lines of structured output. That's a 2.2:1 compression ratio. But the real compression happened across all 9 sessions:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Input&lt;/th&gt;
&lt;th&gt;Lines&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;8 sessions of iterative design&lt;/td&gt;
&lt;td&gt;~4,000 (including dead ends)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API documentation and POC logs&lt;/td&gt;
&lt;td&gt;~1,500&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stakeholder feedback (20+ points)&lt;/td&gt;
&lt;td&gt;~800&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total raw input&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~6,300&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Output&lt;/th&gt;
&lt;th&gt;Lines&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Spec (25 sections)&lt;/td&gt;
&lt;td&gt;792&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Execution plan (9 tasks)&lt;/td&gt;
&lt;td&gt;285&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total structured output&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1,077&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;5.8:1 compression&lt;/strong&gt; from scattered session notes to structured specification. The local storage system made this possible because:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Nothing was lost between sessions (no re-discovery)&lt;/li&gt;
&lt;li&gt;Dead ends were recorded once and never repeated (session 5 documented 10 failed auth approaches — session 9 didn't retry any of them)&lt;/li&gt;
&lt;li&gt;Decisions were recorded with rationale (session 9 didn't re-debate closed questions)&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Why This Matters for the Industry
&lt;/h2&gt;

&lt;p&gt;The current AI assistant landscape is focused on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Model intelligence&lt;/strong&gt; — bigger models, better reasoning&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tool use&lt;/strong&gt; — code execution, file editing, web search&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context windows&lt;/strong&gt; — 128K, 200K, 1M tokens&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nobody is seriously working on &lt;strong&gt;session-to-session knowledge persistence&lt;/strong&gt; as a first-class feature. The assumption seems to be that bigger context windows solve the problem. They don't.&lt;/p&gt;

&lt;p&gt;A 1M token context window means you &lt;em&gt;can&lt;/em&gt; load 11,000 lines of project knowledge. It doesn't mean you &lt;em&gt;should&lt;/em&gt;. Attention mechanisms degrade with context length. Cost scales linearly. And the fundamental problem remains: who decides &lt;em&gt;which&lt;/em&gt; knowledge to load, &lt;em&gt;when&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;The three-file system described here is a manual solution to what should be an automated one. The rules discovered empirically — separate state from history from facts, load on-demand, update before session end, archive when large — should be built into every AI or LLM tool.&lt;/p&gt;

&lt;h3&gt;
  
  
  What a Real Solution Looks Like
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Automatic session persistence&lt;/strong&gt; — Every session's decisions, discoveries, and dead ends are captured without manual effort.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Typed knowledge stores&lt;/strong&gt; — Separate "what's true" (facts) from "what happened" (history) from "what's next" (state). Different retrieval strategies for each.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;On-demand retrieval&lt;/strong&gt; — Load context based on the current task, not the current project. If I'm writing an API integration, load verified API endpoints. If I'm writing a spec, load design decisions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-session deduplication&lt;/strong&gt; — If a question was asked and answered in session 3, don't let session 7 ask it again.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Provider-agnostic storage&lt;/strong&gt; — The knowledge belongs to the user, not the AI provider. Portable, version-controllable, inspectable.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The team that builds this well — not as a feature bolted onto a chat interface, but as a core architectural primitive — wins the AI coding assistant market. Because the cost of intelligence is dropping (model prices halve every 6 months). The cost of &lt;em&gt;context&lt;/em&gt; is the durable competitive advantage.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It Yourself
&lt;/h2&gt;

&lt;p&gt;You don't need any special tooling. Create three files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# In your project root (gitignored)
.local/
├── current.md      # "Read this at session start"
├── log.md          # Append after every session
└── reference.md    # Verified facts only
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start every AI session with: &lt;em&gt;"Read &lt;code&gt;.local/current.md&lt;/code&gt; first."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;End every session with: &lt;em&gt;"Update &lt;code&gt;.local/current.md&lt;/code&gt; with resume instructions."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;After 5 sessions, measure how often you're re-explaining context. After 10 sessions, calculate the cost of sessions with vs without the files.&lt;/p&gt;

&lt;p&gt;The ROI will speak for itself.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Data from 53 sessions across 6 weeks on a platform engineering project. Total local storage: 11,812 lines across 36 files. Measured cost savings: 86–89% per context-heavy session. The entire memory system is 196 lines of Python and three markdown files.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>aisession</category>
      <category>aiops</category>
    </item>
    <item>
      <title>How We Stopped Fighting Enterprise Auth and Read Calendars With a URL</title>
      <dc:creator>Praveen KG</dc:creator>
      <pubDate>Sat, 21 Mar 2026 15:19:26 +0000</pubDate>
      <link>https://dev.to/kgpraveen/how-we-stopped-fighting-enterprise-auth-and-read-calendars-with-a-url-1ang</link>
      <guid>https://dev.to/kgpraveen/how-we-stopped-fighting-enterprise-auth-and-read-calendars-with-a-url-1ang</guid>
      <description>&lt;p&gt;&lt;em&gt;Reading Microsoft 365 calendars from scripts in locked-down enterprise environments — without Graph API, without OAuth, without any authentication at all.&lt;/em&gt;&lt;/p&gt;




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

&lt;p&gt;We're building an on-call scheduling tool for our platform engineering team. One of its core features: automatically check who's out of office before assigning someone to the on-call rota. Sounds simple — read a calendar, find OOO events, done.&lt;/p&gt;

&lt;p&gt;Except we work inside a large enterprise with a locked-down Microsoft 365 tenant. And reading a calendar programmatically turned out to be the hardest part of the entire project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What we needed:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read OOO/leave events from team members' Outlook calendars&lt;/li&gt;
&lt;li&gt;Run it from a script on any engineer's laptop (Mac or Windows)&lt;/li&gt;
&lt;li&gt;No manual token copying, no browser interactions, no IT tickets&lt;/li&gt;
&lt;li&gt;Just: run a command, get OOO data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What we assumed:&lt;/strong&gt; Microsoft Graph API. It's the modern, documented, supported way to read calendars. Every tutorial says "just call &lt;code&gt;/me/calendar/getSchedule&lt;/code&gt;". We even identified it as the perfect endpoint — it supports batch queries (20 users per call), returns native out-of-office status, and works with both delegated and app-only permissions.&lt;/p&gt;

&lt;p&gt;The API wasn't the problem. Getting a token was.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We Tried (and Why Everything Failed)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Attempt 1: Azure CLI Token
&lt;/h3&gt;

&lt;p&gt;The obvious approach. We already use &lt;code&gt;az login&lt;/code&gt; for other tooling. Microsoft's docs say you can get a Graph token with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az account get-access-token &lt;span class="nt"&gt;--resource&lt;/span&gt; https://graph.microsoft.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result: Blocked.&lt;/strong&gt; Our tenant's Continuous Access Evaluation (CAE) policies reject CLI-issued tokens for Graph API. The token generates fine but every API call returns 401.&lt;/p&gt;

&lt;h3&gt;
  
  
  Attempt 2: MSAL Device Code Flow
&lt;/h3&gt;

&lt;p&gt;The "headless-friendly" OAuth flow. Display a code, user opens a browser, authorises, script gets a token.&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="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;msal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;PublicClientApplication&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;authority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;authority&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;flow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;initiate_device_flow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scopes&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;Calendars.Read&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result: Blocked.&lt;/strong&gt; Tenant rejects with &lt;code&gt;AADSTS65002&lt;/code&gt; and &lt;code&gt;AADSTS7000218&lt;/code&gt;. The app ID isn't pre-approved and our IT team doesn't approve custom app registrations for internal tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  Attempt 3: Azure AD App Registration
&lt;/h3&gt;

&lt;p&gt;The "proper" way — register an app in Azure AD, get admin consent for &lt;code&gt;Calendars.ReadBasic&lt;/code&gt;, use client credentials flow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Result: Not attempted.&lt;/strong&gt; Our IT security team is unlikely to approve a custom app registration requesting calendar read permissions across the organisation. The approval process alone would take weeks, and the answer would probably be no.&lt;/p&gt;

&lt;h3&gt;
  
  
  Attempt 4: Graph Explorer Token (Manual)
&lt;/h3&gt;

&lt;p&gt;Microsoft's Graph Explorer web tool gives you a token when you sign in. We could copy-paste it into the script.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Result: Works, but impractical.&lt;/strong&gt; The token expires in ~1 hour. Every team lead or engineer running the tool would need to open Graph Explorer, sign in, copy the token, paste it into the terminal. That's not a tool — that's a chore.&lt;/p&gt;

&lt;h3&gt;
  
  
  Attempt 5: Browser Cookie Extraction
&lt;/h3&gt;

&lt;p&gt;Our incident management integration works by extracting OAuth tokens from browser cookies using Python's &lt;code&gt;browser_cookie3&lt;/code&gt;. Could we do the same for Graph tokens?&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="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;browser_cookie3&lt;/span&gt;
&lt;span class="n"&gt;cj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;browser_cookie3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result: Failed.&lt;/strong&gt; Graph API access tokens aren't stored in cookies. Microsoft stores them in &lt;code&gt;localStorage&lt;/code&gt; and &lt;code&gt;sessionStorage&lt;/code&gt;, which &lt;code&gt;browser_cookie3&lt;/code&gt; can't access. We found 159 Microsoft cookies in Chrome — session cookies, SSO cookies, auth cookies — but none of them were Graph API access tokens.&lt;/p&gt;

&lt;h3&gt;
  
  
  Attempt 6: Headless Browser Automation (Playwright)
&lt;/h3&gt;

&lt;p&gt;If the tokens are in &lt;code&gt;localStorage&lt;/code&gt;, we'll use Playwright to launch a browser, inject our SSO cookies, navigate to Outlook, and extract the tokens via JavaScript.&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="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_cookies&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chrome_cookies&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# 159 SSO cookies
&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;goto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://outlook.office.com/calendar&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;localStorage.getItem(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;msal.access_token&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result: Failed.&lt;/strong&gt; Microsoft's enterprise SSO is profile-bound. It's not just cookies — it's device certificates, MSAL cache, keychain integration, and Conditional Access Evaluation (CAE) device compliance checks. An isolated Playwright context with injected cookies doesn't satisfy any of these checks. The browser just shows a login page.&lt;/p&gt;

&lt;h3&gt;
  
  
  Attempt 7: Playwright with Persistent Profile
&lt;/h3&gt;

&lt;p&gt;Launch Playwright with a fresh user data directory and hope the SSO cookies carry over from the system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Result: Failed.&lt;/strong&gt; A fresh profile has no SSO state. Microsoft redirects to the login page with no auto-SSO.&lt;/p&gt;

&lt;h3&gt;
  
  
  Attempt 8: Exchange Web Services (EWS)
&lt;/h3&gt;

&lt;p&gt;The older API. Maybe it has a different, more permissive auth story?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Result: Failed differently.&lt;/strong&gt; Our on-prem Exchange servers are reachable via Kerberos. But the user's mailbox is in Exchange Online, not on-prem. The org-relationship between on-prem and Exchange Online is misconfigured, so EWS returns "mailbox not found" even though Kerberos auth succeeds.&lt;/p&gt;

&lt;h3&gt;
  
  
  Attempt 9: Chrome DevTools Protocol
&lt;/h3&gt;

&lt;p&gt;Connect to a running Chrome instance via the DevTools Protocol and extract &lt;code&gt;localStorage&lt;/code&gt; directly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Result: Not tested.&lt;/strong&gt; Requires restarting Chrome with &lt;code&gt;--remote-debugging-port=9222&lt;/code&gt;. Impractical for daily use — you'd have to close all Chrome tabs, relaunch with debug flags, then run the tool.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;At this point, we'd spent several sessions across multiple days trying every documented and undocumented approach to reading a calendar from a script.&lt;/strong&gt; The problem wasn't finding the right API — &lt;code&gt;getSchedule&lt;/code&gt; is perfect. The problem was enterprise authentication: a layered defence of CAE, Conditional Access, device compliance, and profile-bound SSO that blocks every automated token acquisition method.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Breakthrough: A Feature From 2010
&lt;/h2&gt;

&lt;p&gt;While exploring Outlook's calendar sharing settings for an unrelated reason, we noticed something: &lt;strong&gt;Publish Calendar&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Outlook has had the ability to publish calendars as ICS (iCalendar) feeds since Exchange 2010. You go to Settings → Calendar → Shared calendars → Publish a calendar, and Outlook generates a URL like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;https://outlook.office365.com/owa/calendar/{calendarId}@domain.com/{secret}/calendar.ics
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We opened that URL in a browser. It downloaded an &lt;code&gt;.ics&lt;/code&gt; file. We &lt;code&gt;curl&lt;/code&gt;'d it from a terminal. It returned data. We tried it from a different machine, without being logged into anything. It returned data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No authentication. No tokens. No OAuth. No cookies. No browser profile. Nothing.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Just a plain HTTP GET to a URL that returns standard iCalendar data with all the calendar events — including every team member's OOO events.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://outlook.office365.com/owa/calendar/.../calendar.ics"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. That's the entire "authentication" story.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Works
&lt;/h2&gt;

&lt;p&gt;Published calendar ICS feeds are a feature of Exchange, not of Azure AD or the Microsoft identity platform. They predate OAuth 2.0, Graph API, MSAL, and Conditional Access by years. The URL contains a cryptographic secret (the &lt;code&gt;publishSecret&lt;/code&gt; path component) that acts as the access control — if you have the URL, you can read the calendar.&lt;/p&gt;

&lt;p&gt;This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No tenant policy blocks it&lt;/strong&gt; — CAE, Conditional Access, and device compliance don't apply because there's no authentication flow to evaluate&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No app registration needed&lt;/strong&gt; — there's no OAuth client involved&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No token expiry&lt;/strong&gt; — the URL is permanent until you unpublish&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Works from anywhere&lt;/strong&gt; — any machine, any OS, any CI pipeline, any &lt;code&gt;curl&lt;/code&gt; command&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Standard format&lt;/strong&gt; — iCalendar (RFC 5545) is parseable by every calendar library in every language&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The feed is &lt;strong&gt;live&lt;/strong&gt; — every request returns the current calendar state, not a snapshot. When someone creates an OOO event, it appears in the feed within minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Parsing the Data
&lt;/h2&gt;

&lt;p&gt;The ICS feed returns standard &lt;code&gt;VEVENT&lt;/code&gt; entries. OOO events typically have summaries like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SUMMARY:Alex - OOO
SUMMARY:Sam - OOO
SUMMARY:Jordan - A/L
SUMMARY:Morgan - Holiday
SUMMARY:Riley - On leave
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With Python's &lt;code&gt;icalendar&lt;/code&gt; library:&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="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;urllib.request&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;icalendar&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Calendar&lt;/span&gt;

&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;urlopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ics_url&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;cal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Calendar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_ical&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;cal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;walk&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;event&lt;/span&gt;&lt;span class="p"&gt;.&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;VEVENT&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;summary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&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;summary&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;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;event&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;dtstart&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;dt&lt;/span&gt;
        &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;event&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;dtend&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;dt&lt;/span&gt;
        &lt;span class="c1"&gt;# Match OOO patterns: "Name - OOO", "Name on leave", etc.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We parsed our feed and extracted dozens of OOO events covering our full team — from a single URL, with zero authentication, in about 10 lines of Python.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Approach: One Calendar, One URL
&lt;/h2&gt;

&lt;p&gt;Our team follows the convention of sending OOO calendar events when they're going to be away. These events appear on the team lead's calendar (as accepted invites). So a single person's published calendar contains OOO data for the entire team.&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;One person publishes their Outlook calendar (one-time, 30-second setup)&lt;/li&gt;
&lt;li&gt;The tool fetches the ICS URL (plain HTTP GET)&lt;/li&gt;
&lt;li&gt;Parses OOO events with regex pattern matching&lt;/li&gt;
&lt;li&gt;Feeds the OOO data into the on-call scheduling tool&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For teams where OOO events don't naturally aggregate on one calendar, alternatives include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Microsoft 365 Group&lt;/strong&gt;: Create a group, everyone adds OOO events to the group calendar, publish the group calendar — one URL&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Individual feeds&lt;/strong&gt;: Each person publishes their calendar, tool fetches all URLs&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Irony
&lt;/h2&gt;

&lt;p&gt;We spent days fighting the modern Microsoft identity stack — CAE, MSAL, Conditional Access, device compliance, profile-bound SSO, browser automation. The solution was a feature that Microsoft shipped in Exchange Server 2010, before any of those systems existed.&lt;/p&gt;

&lt;p&gt;Published calendar feeds sit at a layer below the modern auth stack. They don't use Azure AD tokens, they don't trigger Conditional Access policies, they don't require device compliance. They're just... URLs.&lt;/p&gt;

&lt;p&gt;Sometimes the answer isn't fighting through the front door. It's finding the side entrance that's been open for 16 years.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Set This Up
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Publishing Your Calendar
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;a href="https://outlook.office.com/calendar" rel="noopener noreferrer"&gt;outlook.office.com/calendar&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Settings&lt;/strong&gt; (gear icon) → &lt;strong&gt;View all Outlook settings&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Calendar&lt;/strong&gt; → &lt;strong&gt;Shared calendars&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Under &lt;strong&gt;Publish a calendar&lt;/strong&gt;, select the calendar&lt;/li&gt;
&lt;li&gt;Choose &lt;strong&gt;Can view all details&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Publish&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Copy the &lt;strong&gt;ICS&lt;/strong&gt; link&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's your permanent, zero-auth calendar feed URL.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reading It
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# From any machine, no login required&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://outlook.office365.com/owa/calendar/.../calendar.ics"&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-50&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Parsing OOO Events
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;icalendar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;urllib.request&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;icalendar&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Calendar&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;

&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://outlook.office365.com/owa/calendar/.../calendar.ics&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;urlopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;cal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Calendar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_ical&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;cal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;walk&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;event&lt;/span&gt;&lt;span class="p"&gt;.&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;VEVENT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;summary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&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;summary&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="nf"&gt;any&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kw&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;kw&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;ooo&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;leave&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;holiday&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;sick&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]):&lt;/span&gt;
            &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;event&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;dtstart&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;dt&lt;/span&gt;
            &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;event&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;dtend&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;dt&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="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; → &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;summary&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Security Considerations
&lt;/h2&gt;

&lt;p&gt;The published calendar URL contains a secret in its path. Anyone with the URL can read the calendar. Treat it like an API key:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Don't commit it to public repositories&lt;/li&gt;
&lt;li&gt;Share it only with people who need it&lt;/li&gt;
&lt;li&gt;Store it in environment variables or secret management&lt;/li&gt;
&lt;li&gt;You can unpublish at any time to invalidate the URL&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The URL doesn't grant write access — it's read-only. And it only exposes the published calendar, not the entire mailbox.&lt;/p&gt;

&lt;h2&gt;
  
  
  When This Approach Works
&lt;/h2&gt;

&lt;p&gt;This approach is ideal when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your enterprise tenant blocks Graph API tokens from CLI tools (CAE/Conditional Access)&lt;/li&gt;
&lt;li&gt;You can't get an Azure AD App Registration approved&lt;/li&gt;
&lt;li&gt;You need zero-setup, zero-auth calendar reads from scripts or CI pipelines&lt;/li&gt;
&lt;li&gt;Your team follows a convention of calendar-based OOO announcements&lt;/li&gt;
&lt;li&gt;You're comfortable with a convention-dependent (not system-enforced) data source&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's less suitable when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need write access to calendars&lt;/li&gt;
&lt;li&gt;You need real-time, sub-minute freshness (ICS feeds have a few minutes propagation delay)&lt;/li&gt;
&lt;li&gt;Your organisation has disabled calendar publishing at the tenant level&lt;/li&gt;
&lt;li&gt;You need calendar data from people who haven't published their calendars&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;The best engineering solutions aren't always the most sophisticated ones. Graph API with &lt;code&gt;getSchedule&lt;/code&gt; is technically the right answer — batch queries, native OOF detection, structured response. But "technically right" doesn't matter if you can't get a token.&lt;/p&gt;

&lt;p&gt;A URL that returns a text file solved a problem that OAuth 2.0, MSAL, Playwright, and five different authentication strategies couldn't.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;The author is a software engineering manager at a large enterprise retailer, building internal developer platform tooling.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>microsoft365</category>
      <category>devops</category>
      <category>sre</category>
      <category>rota</category>
    </item>
  </channel>
</rss>
