Skip to content

Instantly share code, notes, and snippets.

@jfarcand
Created April 14, 2026 19:01
Show Gist options
  • Select an option

  • Save jfarcand/aa05b86a348abcce23b94ca21ecd931a to your computer and use it in GitHub Desktop.

Select an option

Save jfarcand/aa05b86a348abcce23b94ca21ecd931a to your computer and use it in GitHub Desktop.
Atmosphere — Personal Agent Platform Strategy v0.4 (post-audit reorientation, file-first, supersedes v0.3)

Atmosphere — Personal Agent Platform Strategy (v0.4)

Working draft. Secret gist. Iterated with ChefFamille.

Date: 2026-04-14 Status: v0.4 — post-audit reorientation. Action 1 (architectural bet) and Action 2 (OpenClaw spec fetch) completed, both findings reshape Theme 1. Ready to execute the revised plan. Predecessors: v0.1 · v0.2 · v0.3


Thesis (unchanged)

Atmosphere is the Java platform layer for personal agents. Pick any of the seven runtimes (Spring AI, LangChain4j, Google ADK, Koog, Semantic Kernel, Embabel, Built-in), point Atmosphere at an OpenClaw-compatible agent workspace, and inherit memory, identity, multi-channel continuity, auditable permissions, MCP / A2A / AG-UI endpoints, and durable streaming.

You don't pick Atmosphere instead of your framework. You pick Atmosphere on top of it.

Sharpened value prop: "Point Atmosphere at your OpenClaw workspace. Your agent runs in Java on any of the seven runtimes, with memory, identity, skills, and sessions preserved."


Action 1 — architectural bet: resolved

Verdict: the reflection-federation bet from v0.3 was unnecessary. Memory already lives in the Atmosphere platform layer for six of the seven runtimes.

Evidence (all line-cited against current main):

  • AgentExecutionContext.java:56 — the context record carries history: List<ChatMessage> and memory: AiConversationMemory as first-class fields. Both Atmosphere-owned.
  • AbstractAgentRuntime.java:359assembleMessages(context) threads context.history() into every runtime's outbound request. Called by Built-in directly.
  • BuiltInAgentRuntime.java:126 — calls assembleMessages(context) in buildRequest().
  • SpringAiAgentRuntime.java:105context.history().stream() folds prior turns into the Spring AI Prompt.
  • LangChain4jAgentRuntime.java:144assembleMessages(context).stream() folds prior turns into LC4j ChatRequest.
  • SemanticKernelAgentRuntime.java:157for (var msg : context.history()) folds prior turns into SK ChatHistory.
  • KoogAgentRuntime.kt:490for (msg in context.history()) folds prior turns into Koog's prompt.
  • EmbabelAgentRuntime.kt:264context.history().forEach folds prior turns into Embabel's chat messages.

Write path (proves the cycle closes):

  • MemoryCapturingSession.java:99,125,127 — wraps the streaming session, calls memory.addMessage() on user + assistant messages after every turn.
  • PersistentConversationMemory.java — already implements AiConversationMemory with a backing ConversationPersistence store.
  • SqliteConversationPersistence and Redis backends already ship in durable-sessions-sqlite / durable-sessions-redis.

The lone outlier — ADK:

AdkAgentRuntime.java:272-414 declares AiCapability.CONVERSATION_MEMORY at line 423 but never threads context.history() into runAsync(). It calls ensureSession() which creates an ADK session via adkRunner.sessionService() and relies on ADK's internal session service to own the history. Atmosphere-persisted memory is silently dropped when the runtime is ADK.

This is a latent capability lie — Correctness Invariant #5 (Runtime Truth). ADK claims CONVERSATION_MEMORY but doesn't honor it. It's a ~20-line fix, not an architectural constraint: seed the ADK Session from context.history() on first turn of a conversation, or thread history into each runAsync call.

Implication: delete the reflection-federation bet from v0.3 entirely. No javap -p needed. Theme 1 becomes simpler: extend the existing AiConversationMemory abstraction rather than replace it, and fix ADK's honesty as part of the contract-test pass.


Action 2 — OpenClaw spec: resolved

Verdict: OpenClaw is much more opinionated and mature than the v2 gist described. Following them means adopting their file-based workspace model, not inventing YAML.

OpenClaw canonical layout (read from the live openclaw/openclaw repo):

~/.openclaw/workspace/              # agent home, user-editable
  AGENTS.md                         # operating instructions (loaded every session)
  SOUL.md                           # persona, tone, boundaries
  USER.md                           # who the user is, preferred address
  IDENTITY.md                       # agent name, vibe, emoji
  TOOLS.md                          # user-maintained tool notes
  BOOTSTRAP.md                      # one-time first-run ritual (deleted after use)
  MEMORY.md                         # durable facts, loaded every DM session
  memory/YYYY-MM-DD.md              # daily notes, today + yesterday auto-loaded
  DREAMS.md                         # optional dream diary
  skills/                           # workspace-level skills (highest precedence)
  .agents/skills/                   # project-scoped skills
~/.agents/skills/                   # personal-scoped skills
~/.openclaw/skills/                 # managed/local skills
~/.openclaw/agents/<agentId>/sessions/<sessionId>.jsonl   # session transcripts

OpenClaw's memory philosophy — the reframe that matters:

"The model only 'remembers' what gets saved to disk — there is no hidden state. Plain Markdown files."

Not a database. Not a schema. Files you can cat, grep, vim, git commit, scp, rsync.

Memory tools (provided by OpenClaw's memory plugin):

  • memory_search — semantic + keyword hybrid search
  • memory_get — read specific file or line range

Skill precedence chain (highest to lowest):

  1. <workspace>/skills
  2. <workspace>/.agents/skills
  3. ~/.agents/skills
  4. ~/.openclaw/skills
  5. Bundled
  6. skills.load.extraDirs

Runtime split: OpenClaw runs on top of the Pi agent core (models, tools, prompt pipeline). Sessions, discovery, tool wiring, channel delivery are OpenClaw-owned layers on top. This is exactly Atmosphere's shapeAgentRuntime SPI at the bottom, platform layer on top.


Reorientation: Theme 1 pivots from SQLite to files

v0.3 Theme 1 was wrong on the storage choice. A greenfield PersonalMemory SPI with SQLite/Redis backends is over-engineered in the wrong direction. OpenClaw deliberately chose files over databases for transparency, portability, and user trust. Claude Code's CLAUDE.md is the same pattern.

v0.4 Theme 1 — file-first personal memory:

PersonalMemory SPI (still greenfield, but file-oriented)

public interface PersonalMemory {
    // Conversation — JSONL file per session
    List<ChatMessage> getConversation(String agentId, String sessionId);
    void appendConversation(String agentId, String sessionId, ChatMessage msg);
    void clearConversation(String agentId, String sessionId);

    // Facts — MEMORY.md file, append-only by default
    List<MemoryEntry> getFacts(String userId, String agentId);
    void addFact(String userId, String agentId, String fact);
    void removeFact(String userId, String agentId, String factId);

    // Daily notes — memory/YYYY-MM-DD.md files
    List<MemoryEntry> getDailyNotes(String userId, String agentId, LocalDate date);
    void addDailyNote(String userId, String agentId, String note);

    // Hierarchical rules — AGENTS.md + SOUL.md + USER.md + IDENTITY.md
    RuleSet getRules(String userId, String agentId);

    // Workspace metadata
    Path workspaceRoot(String agentId);
}

Backends

  • FileSystemPersonalMemory (default) — reads/writes the OpenClaw workspace layout directly. Default root: ~/.atmosphere/workspace/ (or ~/.openclaw/workspace/ if it exists and user opts in via config). OpenClaw-compatible: an agent workspace authored in OpenClaw runs on Atmosphere without any conversion.
  • DatabasePersonalMemory (optional) — SQLite / Redis for enterprise users who need multi-tenant or audit-grade storage. Same SPI, different backing.

Migration path

  • AiConversationMemory deprecated — becomes a compatibility shim over PersonalMemory.getConversation() / appendConversation() for existing code paths.
  • PersistentConversationMemory repurposed as an adapter: reads the JSONL files via PersonalMemory instead of its current custom JSON-in-SQLite format.
  • Existing samples keep working because AiConversationMemory keeps working.
  • New samples use PersonalMemory directly.

Atmosphere extensions to the workspace

Instead of .agent/atmosphere/*.yaml from v0.3 (now deleted), Atmosphere reads optional Markdown files in the same workspace:

  • CHANNELS.md — channel bindings (Slack, web, mobile, etc.)
  • MCP.md — per-user MCP personal server config
  • RUNTIME.md — preferred runtime, fallback chain, model routing
  • PERMISSIONS.md — session permission mode defaults, per-tool overrides
  • SKILLS.md — skill overrides on top of the discovery chain

OpenClaw ignores these; Atmosphere reads them. Zero configuration collision. Fully transparent. User-editable.

Auto-memory strategies (pluggable, from v0.3)

AutoMemoryStrategy SPI — writes memory during conversation. Built-ins:

  • LlmDecided — agent calls a remember tool to append to MEMORY.md. Default for OpenClaw compatibility.
  • EveryNTurns(n) — every N turns, LLM summarizes the conversation and appends to memory/YYYY-MM-DD.md.
  • SessionEnd — summarize the session and append on close.
  • Hybrid — all three at once.

Admin inspection endpoints

Added to the existing admin control plane:

  • GET /atmosphere/admin/agents/{agent}/workspace — list files in workspace with size/mtime
  • GET /atmosphere/admin/agents/{agent}/workspace/{file} — read a file (AGENTS.md, MEMORY.md, etc.)
  • PUT /atmosphere/admin/agents/{agent}/workspace/{file} — edit a file (user-initiated)
  • DELETE /atmosphere/admin/agents/{agent}/workspace/{file} — delete a file
  • GET /atmosphere/admin/agents/{agent}/sessions/{userId} — list session JSONL files
  • GET /atmosphere/admin/agents/{agent}/sessions/{userId}/{sessionId} — read session transcript

The inspection UX: user opens admin, sees their agent's workspace as a file tree, clicks MEMORY.md, sees what the agent remembers, edits or deletes entries. Exactly the Claude-Code-pilled UX we're targeting. No new frontend stack — the existing admin UI renders Markdown.

Contract test (unchanged in shape, simplified in substance)

Run against all seven runtimes in CI. Per runtime:

  1. Start agent on runtime X pointing at workspace W.
  2. Send message that triggers auto-memory ("I prefer dark mode").
  3. Assert MEMORY.md in workspace W contains the fact.
  4. Restart agent.
  5. Send new message ("what do I prefer for themes").
  6. Assert the response references the stored fact.
  7. Delete the fact via admin endpoint.
  8. Assert MEMORY.md no longer contains the fact.
  9. Send the same message again.
  10. Assert the response no longer references it.

The ADK fix lives inside this test: if ADK doesn't honor context.history(), the step 5 assertion fails, we fix it, test goes green, contract is honest.


What survives from v0.3

  • Thesis: unchanged.
  • Two definitions of "personal agent": unchanged.
  • Five references to study, four to skip: unchanged.
  • Theme 2 (manifest → workspace adoption): reoriented from YAML to OpenClaw file layout, but same intent.
  • Theme 3 (multi-agent personal assistant flagship sample, Spring AI default): unchanged.
  • Theme 4 (permission modes + audit): unchanged.
  • Theme 5 (per-user MCP personal servers, pluggable trust): unchanged — config lives in MCP.md now.
  • Theme 6 (skill polish): unchanged, but aligned to OpenClaw's skill precedence chain instead of atmosphere-specific registry overrides.
  • Non-goals: unchanged.
  • Success measure: unchanged.
  • Under-the-radar pace: unchanged (quiet tease at month 3 → "session 3" in hours).
  • Pluggable memory strategy / pluggable MCP trust: unchanged.
  • Contract tests across all seven runtimes: unchanged.

What changes from v0.3

  • v0.3 reflection-federation bet: deleted. Memory already lives above the runtime for six runtimes. ADK is a latent-lie fix.
  • v0.3 greenfield SQLite/Redis-first memory: replaced with file-first FileSystemPersonalMemory + optional DatabasePersonalMemory.
  • v0.3 .agent/atmosphere/*.yaml manifest extensions: replaced with Markdown files in the OpenClaw workspace (CHANNELS.md, MCP.md, RUNTIME.md, PERMISSIONS.md, SKILLS.md).
  • v0.3 agent.atmosphere.yaml single-file manifest: deleted. OpenClaw's workspace layout IS the manifest.
  • javap -p audit action: deleted. Unnecessary.
  • Theme 2 CLI changes: atmosphere agent --workspace <path> instead of atmosphere agent import/export/validate. The workspace IS the portable artifact. No import/export step — just point at the directory.

Sequencing — still hours, now tighter

Not months. Not weeks. Hours. Actions 1 and 2 are already complete (~1 hour total). Remaining:

  • Action 3 — Atmosphere memory audit (~20 min): map existing AiConversationMemory, PersistentConversationMemory, LongTermMemory, SemanticRecallInterceptor, EmbeddingRuntime, ConversationPersistence to what PersonalMemory absorbs vs deprecates. Mostly done inline during Action 1.
  • Action 4 — admin control plane audit (~15 min): map existing endpoints, routing, UI rendering.
  • Action 5 — credential handling audit (~15 min): existing secret storage for Theme 5 trust providers.
  • Theme 1 — file-first PersonalMemory (~2h): SPI, FileSystemPersonalMemory, admin endpoints, auto-memory strategies, ADK fix, contract test.
  • Theme 2 — OpenClaw workspace loader (~1h): --workspace CLI, workspace parser, Atmosphere extension file readers.
  • Theme 3 — multi-agent personal assistant sample (~2h): samples/personal-assistant/, fleet composition, ships with an example workspace.
  • Theme 4 — permissions + audit (~1h): session permission modes, per-user audit endpoint.
  • Theme 5 — MCP personal servers with pluggable trust (~1h): McpTrustProvider SPI, three built-ins, MCP.md loader.
  • Theme 6 — skill polish (~1h): argument substitution, scoping, OpenClaw-compatible skill precedence chain.

Total remaining: ~9 hours. One long focused session or two shorter ones.

Quiet tease after all six themes hold together. Not before.


Non-goals (unchanged)

  • No graph workflow DSL.
  • No voice / realtime pipeline.
  • No code execution sandbox.
  • No new LLM client abstraction.
  • No Python / TS feature-parity chasing.
  • No backward-compatibility shims for deprecated memory SPIs (except the thin AiConversationMemory shim over PersonalMemory).
  • No custom Atmosphere YAML manifest format. OpenClaw's workspace IS the manifest.

Success measure (unchanged)

  1. Point Atmosphere at an OpenClaw workspace on Spring AI, then on LangChain4j, agent keeps memory + identity?
  2. User sees what agent remembers and edits it via admin control plane?
  3. Start conversation in Slack, pick up on web, agent doesn't forget?
  4. User brings own MCP tools via MCP.md without touching agent code?
  5. Audit per-user agent actions via admin control plane?
  6. Switch Spring AI → ADK → Koog with zero personal-agent code changes?

Contract tests enforce each in CI across all seven runtimes.


Key insight from v0.4 — files, not databases

OpenClaw taught us the right answer. Memory isn't a database problem. It's a file visibility problem. Users trust memory when they can see it, edit it, grep it, back it up, commit it to git, copy it to another machine. A SQLite blob in ~/.atmosphere/db/memory.db is not that. A Markdown file at ~/.openclaw/workspace/MEMORY.md is.

Atmosphere adopts the file-first model as default, keeps SQLite / Redis as optional backends for users who need enterprise-grade audit or multi-tenant isolation.

This also collapses Themes 1 and 2 into a single consistent story: the OpenClaw workspace IS the personal agent, IS the manifest, IS the memory, IS the identity. Atmosphere is the Java runtime layer that makes it run on any of the seven frameworks.


Status log

  • 2026-04-14 — v0.1 (gist) — thesis locked, six themes sketched.
  • 2026-04-14 — v0.2 (gist) — schema / manifest / pace / flagship / UI / contract scope resolved. Raised architectural bet about memory above the runtime.
  • 2026-04-14 — v0.3 (gist) — memory strategy and trust model made pluggable. OpenClaw adopted (assumed YAML manifest). Reflection-federation bet accepted as mitigation for "memory above the runtime" concern.
  • 2026-04-14 — v0.4 (this gist) — Actions 1 and 2 complete. Reflection-federation bet proven unnecessary (memory already lives above the runtime for 6 of 7 runtimes; ADK is a 20-line fix). OpenClaw proven to use file-first Markdown workspace, not YAML manifest. Theme 1 pivoted from SQLite-first to file-first. Atmosphere extensions relocated from .agent/atmosphere/*.yaml to Markdown files in the OpenClaw workspace. Next: execute Actions 3-5 inline with Theme 1 implementation and start the six-theme build.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment