Worktree: .claude/worktrees/ai-agent-foundation
Branch: feat/ai-agent-foundation
Strategy reference: v0.5 gist (supersedes v0.1–v0.4)
Date: 2026-04-15
Status: plan draft — no code yet, pending ChefFamille review
This plan covers: 8 foundation primitives · 2 proof samples · documentation (in-repo + sibling site) · 6 test surfaces (unit, contract, integration, Playwright E2E, OpenClaw compat, chrome-devtools MCP validation) · release prep. Target size ~24 hours across 3 focused sessions.
Before any code runs in the worktree, deal with the Maven cache staleness issue (per feedback_stale_maven_cache.md):
cd .claude/worktrees/ai-agent-foundation
git config core.hooksPath .githooks # session-start hook per CLAUDE.md
./mvnw install -am -q -pl modules/ai -DskipTests # warm the local cacheVerify baseline is green:
./mvnw compile -pl modules/ai # zero warnings (mandatory)
./mvnw test -pl modules/ai -DskipITs # existing tests still passIf warnings or failures: stop, fix, then proceed. We never start a new feature on a red baseline.
Earlier primitives enable later ones:
AgentState— foundation of every other primitive that touches stateAgentWorkspace— consumesAgentStatefor its OpenClaw / Claude-Code adapter readsProtocolBridge— architectural relocate of existing transports (MCP, A2A, AG-UI, gRPC) + elevation ofInMemoryProtocolBridge. Must be in place beforeAiGatewayandAgentIdentitywire into it.AiGateway— facade over existing router + budget + credentials. Small consolidation; needsProtocolBridgenamed so gateway boundary is unambiguous.AgentIdentity— per-user identity / credentials / permissions / audit. UsesAgentStatefor audit storage,AiGatewayfor per-user credential lookup.ToolExtensibilityPoint— per-user MCP client, pluggable trust, dynamic tool discovery. UsesAgentIdentityfor trust provider resolution.Sandbox— standalone SPI + Docker default. Doesn't depend on other v0.5 primitives but needsAgentIdentityfor per-user sandbox credential scoping.AgentResumeHandle— needsProtocolBridgein place (bridge-agnostic reattach semantics) andAgentState(reconstituted conversation + run state). Last because it depends on most of the others.
Every primitive lands through the same five-step cycle. No primitive is "done" until all five steps are green.
- SPI design — write the interface + the Javadoc contract + the package-info.
- Default implementation — the Atmosphere-house default (e.g.,
FileSystemAgentState,InMemoryProtocolBridge,DockerSandbox). - Contract test — run against all seven runtimes in CI. Test harness extends
AbstractAgentRuntimeContractTestor a new parallel harness per primitive. - Wire existing code — relocate / delegate / deprecate whatever the primitive supersedes. No backward-compat shims except the documented
AiConversationMemorythin delegation. - Full compile with zero warnings —
./mvnw compile -pl modules/aibefore commit.
Files:
modules/ai/src/main/java/org/atmosphere/ai/state/AgentState.java— SPImodules/ai/src/main/java/org/atmosphere/ai/state/FileSystemAgentState.java— default backendmodules/ai/src/main/java/org/atmosphere/ai/state/DatabaseAgentState.java— optional SQLite/Redis backendmodules/ai/src/main/java/org/atmosphere/ai/state/AutoMemoryStrategy.java— sub-SPI + 4 built-insmodules/ai/src/main/java/org/atmosphere/ai/state/MemoryEntry.java— recordmodules/ai/src/main/java/org/atmosphere/ai/state/RuleSet.java— recordmodules/ai/src/main/java/org/atmosphere/ai/state/package-info.javamodules/admin/src/main/java/org/atmosphere/admin/state/StateController.java— inspection endpointsmodules/ai/src/main/java/org/atmosphere/ai/AiConversationMemory.java— edit to delegatemodules/adk/src/main/java/org/atmosphere/ai/adk/AdkAgentRuntime.java— fix latent capability lie (honorcontext.history())
Contract test: modules/ai-test/src/test/java/org/atmosphere/ai/test/AgentStateContractTest.java — write fact, restart, recall, delete, recall-empty loop per runtime.
Deliverable gate: seven green runs in CI.
Files:
modules/ai/src/main/java/org/atmosphere/ai/workspace/AgentWorkspace.java— SPImodules/ai/src/main/java/org/atmosphere/ai/workspace/OpenClawWorkspaceAdapter.javamodules/ai/src/main/java/org/atmosphere/ai/workspace/ClaudeCodeWorkspaceAdapter.javamodules/ai/src/main/java/org/atmosphere/ai/workspace/AtmosphereNativeWorkspaceAdapter.javamodules/ai/src/main/java/org/atmosphere/ai/workspace/package-info.javacli/atmosphere— add--workspace <path>flag
Contract test: AgentWorkspaceContractTest — load OpenClaw workspace, load Claude Code workspace, load native workspace, assert identical AgentState population across the three and identical behavior under each of the seven runtimes.
OpenClaw fixture: check in a minimal OpenClaw-format workspace under modules/ai-test/src/test/resources/fixtures/openclaw-workspace/ with AGENTS.md, SOUL.md, USER.md, IDENTITY.md, MEMORY.md, memory/2026-04-15.md, skills/example/SKILL.md, and a JSONL session file.
Files:
modules/ai/src/main/java/org/atmosphere/ai/bridge/ProtocolBridge.java— SPImodules/ai/src/main/java/org/atmosphere/ai/bridge/InMemoryProtocolBridge.java— promoted fromLocalAgentTransportmodules/mcp/src/main/java/org/atmosphere/ai/mcp/McpProtocolBridge.java— wrap existing server hostmodules/a2a/src/main/java/org/atmosphere/ai/a2a/A2aProtocolBridge.java— wrap existing JSON-RPCmodules/agui/src/main/java/org/atmosphere/ai/agui/AgUiProtocolBridge.java— wrap existing event mappermodules/grpc/src/main/java/org/atmosphere/ai/grpc/GrpcProtocolBridge.java— wrap existing servicemodules/coordinator/src/main/java/org/atmosphere/coordinator/transport/LocalAgentTransport.java— delete, migrated toInMemoryProtocolBridge
Contract test: ProtocolBridgeContractTest — invoke the same @Agent through all five bridges, assert identical AgentLifecycleListener event sequence, identical AiInterceptor application, identical tracing, identical response content.
Architectural discipline: no special case for "local". @Coordinator dispatch, @Prompt invocations, MCP calls, A2A calls all enter through ProtocolBridge.dispatch(...).
Files:
modules/ai/src/main/java/org/atmosphere/ai/gateway/AiGateway.java— facademodules/ai/src/main/java/org/atmosphere/ai/gateway/PerUserRateLimiter.java— new, smallmodules/ai/src/main/java/org/atmosphere/ai/gateway/UnifiedTraceExporter.java— new, small- Existing
DefaultModelRouter,StreamingTextBudgetManager,MicrometerAiMetrics— wire behindAiGateway, no behavior change
Contract test: AiGatewayContractTest — every LLM call traverses the gateway, per-user rate limit gates fire, unified trace export emits across all seven runtimes.
Files:
modules/ai/src/main/java/org/atmosphere/ai/identity/AgentIdentity.java— SPImodules/ai/src/main/java/org/atmosphere/ai/identity/PermissionMode.java— enummodules/ai/src/main/java/org/atmosphere/ai/identity/CredentialStore.java— pluggable sub-SPImodules/ai/src/main/java/org/atmosphere/ai/identity/AtmosphereEncryptedCredentialStore.javamodules/ai/src/main/java/org/atmosphere/ai/identity/OsKeychainCredentialStore.javamodules/ai/src/main/java/org/atmosphere/ai/identity/OAuthDelegatedCredentialStore.javamodules/durable-sessions/src/main/java/org/atmosphere/session/DurableSession.java— addpermissionModefieldmodules/admin/src/main/java/org/atmosphere/admin/identity/IdentityController.java— audit + session share endpoints
Contract test: AgentIdentityContractTest — per-user credentials resolve correctly on each runtime, permission modes gate tool execution correctly, audit log captures all tool calls per user, read-only session share produces a replay-only view.
Files:
modules/ai/src/main/java/org/atmosphere/ai/tool/ToolExtensibilityPoint.java— SPImodules/ai/src/main/java/org/atmosphere/ai/tool/ToolIndex.java— semantic search over tool descriptionsmodules/ai/src/main/java/org/atmosphere/ai/tool/DynamicToolSelector.java—maxToolsPerRequestselectormodules/mcp/src/main/java/org/atmosphere/ai/mcp/PerUserMcpClientConfig.java— parseMCP.mdmodules/ai/src/main/java/org/atmosphere/ai/tool/McpTrustProvider.java— pluggable sub-SPI (reusesAgentIdentity.CredentialStorebackends)
Contract test: ToolExtensibilityContractTest — add 100 synthetic tools, agent request selects top-N correctly, per-user MCP tools load correctly with each of the three trust providers, dynamic discovery works across all seven runtimes.
Files:
modules/sandbox/pom.xml— new modulemodules/sandbox/src/main/java/org/atmosphere/ai/sandbox/Sandbox.java— SPImodules/sandbox/src/main/java/org/atmosphere/ai/sandbox/DockerSandbox.java— default backendmodules/sandbox/src/main/java/org/atmosphere/ai/sandbox/SandboxExec.java— recordmodules/sandbox/src/main/java/org/atmosphere/ai/sandbox/SandboxFs.java— recordmodules/sandbox/src/main/java/org/atmosphere/ai/sandbox/SandboxSnapshot.java— recordmodules/sandbox/src/main/java/org/atmosphere/ai/sandbox/@SandboxTool.java— annotation
Contract test: SandboxContractTest — spawn a Docker sandbox, execute shell, read/write files, expose a port, snapshot + restore, hibernate + resume. Run across all seven runtimes (sandbox behavior is runtime-independent but we prove the cross-runtime hookup).
Backlog (not in v0.5): Firecracker, Kata, Vercel Sandbox, E2B, Modal, Blaxel — all land as separate optional modules later.
Files:
modules/ai/src/main/java/org/atmosphere/ai/resume/AgentResumeHandle.java— SPImodules/ai/src/main/java/org/atmosphere/ai/resume/RunRegistry.java—runId → ExecutionHandlemodules/ai/src/main/java/org/atmosphere/ai/resume/RunEventReplayBuffer.java— reuseBroadcasterCacheif the shape fitsmodules/durable-sessions/src/main/java/org/atmosphere/session/DurableSession.java— addactiveRunsfieldmodules/durable-sessions/src/main/java/org/atmosphere/session/DurableSessionInterceptor.java— reattach on reconnect whenrunIdheader presentmodules/ai/src/main/java/org/atmosphere/ai/StreamingSession.java— exposerunId()
Contract test: AgentResumeHandleContractTest — start a long-running tool call, disconnect mid-stream, wait 5 seconds, reconnect with runId header, assert missed events replay correctly and the in-flight run continues, assert cancellation cleanup fires if client never reconnects before TTL.
Exercises: AgentState, AgentWorkspace, AgentIdentity, ToolExtensibilityPoint, AiGateway, ProtocolBridge (crew members via InMemoryProtocolBridge), multi-channel continuity.
Files:
samples/personal-assistant/pom.xmlsamples/personal-assistant/src/main/java/org/atmosphere/samples/personalassistant/PrimaryAssistant.javasamples/personal-assistant/src/main/java/org/atmosphere/samples/personalassistant/SchedulerAgent.javasamples/personal-assistant/src/main/java/org/atmosphere/samples/personalassistant/ResearchAgent.javasamples/personal-assistant/src/main/java/org/atmosphere/samples/personalassistant/DrafterAgent.javasamples/personal-assistant/src/main/java/org/atmosphere/samples/personalassistant/Application.javasamples/personal-assistant/.agent-workspace/AGENTS.mdsamples/personal-assistant/.agent-workspace/SOUL.mdsamples/personal-assistant/.agent-workspace/USER.mdsamples/personal-assistant/.agent-workspace/IDENTITY.mdsamples/personal-assistant/.agent-workspace/MEMORY.md(example seed)samples/personal-assistant/.agent-workspace/skills/README.mdsamples/personal-assistant/.agent-workspace/atmosphere/CHANNELS.mdsamples/personal-assistant/.agent-workspace/atmosphere/MCP.mdsamples/personal-assistant/.agent-workspace/atmosphere/PERMISSIONS.mdsamples/personal-assistant/README.md
Default runtime: Spring AI. Flag --runtime=<name> switches to any of the other six.
Demo flow (documented in README):
- Run with Spring AI, have a conversation with the primary assistant.
- The assistant asks the user's name, remembers it.
- User asks the assistant to schedule a meeting →
SchedulerAgentcrew member fires viaInMemoryProtocolBridge. - Restart on LangChain4j → conversation history + user name preserved.
- Switch channel to Slack → same session, same memory.
- User inspects memory via admin control plane.
Exercises: Sandbox, AgentResumeHandle, plus inherits everything from sample #1 through the shared foundation.
Files:
samples/coding-agent/pom.xmlsamples/coding-agent/src/main/java/org/atmosphere/samples/codingagent/CodingAgent.javasamples/coding-agent/src/main/java/org/atmosphere/samples/codingagent/RepoCloneTool.java—@SandboxToolsamples/coding-agent/src/main/java/org/atmosphere/samples/codingagent/FileReadTool.java—@SandboxToolsamples/coding-agent/src/main/java/org/atmosphere/samples/codingagent/PatchProposeTool.java—@SandboxToolsamples/coding-agent/src/main/java/org/atmosphere/samples/codingagent/GitCommitTool.java—@SandboxToolsamples/coding-agent/src/main/java/org/atmosphere/samples/codingagent/Application.javasamples/coding-agent/.agent-workspace/AGENTS.md(instructions for code tasks)samples/coding-agent/README.md
Demo flow:
- Run the coding agent, ask it to clone a small public repo (e.g., a "hello world" project).
- Sandbox spawns a Docker container, repo clones, files are readable.
- User asks the agent to fix a specific typo in a file.
- Disconnect mid-patch (kill the client).
- Reconnect with the same
runId→AgentResumeHandlereattaches, patch proposal continues. - Agent proposes the patch as a diff.
- User approves via
PermissionMode.PLANflow. - Agent commits and the sandbox preserves the change.
Two documentation surfaces. Both must be updated before release.
- Update
AGENTS.mdtop-level to reference the eight primitives and two samples. - Update
modules/ai/README.mdwith the new primitives:AgentState,AgentWorkspace,AgentIdentity,ToolExtensibilityPoint,AiGateway,AgentResumeHandle. - Update
modules/sandbox/README.md(new module). - Update
modules/coordinator/README.mdto surface the existingResultEvaluatorSPI +LlmResultEvaluator+SanityCheckEvaluatorprominently under a new "Evaluation" section (this machinery exists and is under-documented, not missing). - Update
samples/README.mdto add the two new samples. - Update module READMEs wherever the primitive touches:
modules/admin/README.md,modules/durable-sessions/README.md. - Update
CHANGELOG.md— perfeedback_no_fabricated_stats.md, every bullet must correspond to a real commit with a reachable hash. Compose after implementation, not before.
The site is Astro/Starlight under docs/ and the marketing site under website/. Per reference_atmosphere_github_io.md, updates there are release-gating. All edits confirmed with ChefFamille before we switch to the sibling repo.
docs/src/content/docs/reference/ updates:
ai.md— add sections for each of the eight primitives with SPI signatures + contract test commands.agents/— expand agents subdirectory with workspace / state / identity reference pages.evaluation.md— new page documenting the existingLlmJudge/ResultEvaluator/LlmResultEvaluator/SanityCheckEvaluatorsurface with example code paths for online (async-journaled) and offline (explicitAgentFleet.evaluate()) modes.
docs/src/content/docs/tutorial/ updates:
- Add
personal-assistant.mdtutorial walking through sample #1. - Add
coding-agent.mdtutorial walking through sample #2. - Add
openclaw-workspace.mdtutorial explaining zero-config OpenClaw compatibility.
docs/src/content/docs/architecture.md — add a section on the eight primitives + the Atmosphere 1.0 analogy (foundation, not product). Update the architecture diagram if any exists.
website/ — no public announcement yet (under-the-radar cadence per v0.5). Marketing site stays as-is until the quiet tease window.
- Every factual claim maps to source in the worktree OR a real git commit hash (per
feedback_no_fabricated_stats.md). - No invented API signatures — every signature block is copy-pasted from the real source.
- No "best-in-class" / "most sophisticated" superlatives — the v2-gist failure mode is banned.
- Every number is verified (sample count, primitive count, runtime count).
Six test surfaces. Each one gates release.
Per-primitive unit tests using JUnit 5. Already scoped inside each primitive's implementation time.
Each primitive ships its own contract test extending the existing pattern (AbstractAgentRuntimeContractTest.expectedCapabilities() discipline). No primitive is done until seven green runs in CI.
modules/integration-tests/ gains new test classes for the foundation primitives + the two samples' happy paths. Runs as part of ./mvnw install.
New: modules/playwright-e2e/ (or equivalent scaffolded under the CI lane). Tests run against the sample apps via a real browser.
Test targets:
- Admin control plane UI (
modules/quarkus-admin-extension/runtime/src/main/resources/META-INF/resources/admin/index.html) — user can browse memory, edit a memory entry, delete a memory entry, view audit log, share a session read-only, view the trace timeline, view the eval results tab. - Personal assistant sample web UI — full conversation flow, memory recall after restart, channel switch.
- Coding agent sample web UI — submit a task, see sandbox provision, view patch proposal, approve via PLAN mode.
Flow:
playwright.config.ts— target base URLhttp://localhost:8080(default Spring Boot port).tests/admin.spec.ts— admin UI smoke.tests/personal-assistant.spec.ts— sample #1 happy path.tests/coding-agent.spec.ts— sample #2 happy path.- CI lane: spin up each sample, run Playwright against it, teardown.
New: modules/ai-test/src/test/java/org/atmosphere/ai/test/OpenClawCompatTest.java.
Approach:
- Check in a known-good OpenClaw workspace fixture under
modules/ai-test/src/test/resources/fixtures/openclaw/— realisticAGENTS.md+SOUL.md+USER.md+IDENTITY.md+MEMORY.md+memory/*.md+skills/*/SKILL.md+ JSONL sessions. - Point Atmosphere at the fixture via
OpenClawWorkspaceAdapter. - Assert:
- System prompt assembled from
AGENTS.md+SOUL.md+USER.md+IDENTITY.mdmatches expected. MEMORY.mdfacts load asAgentState.getFacts().memory/YYYY-MM-DD.mdloads as daily notes.- Skills load via the precedence chain.
- JSONL session transcripts load as
AgentState.getConversation().
- System prompt assembled from
- Run on all seven runtimes — same fixture, seven runtime configs, identical behavior.
Stretch: pull a real OpenClaw repo workspace via gh api in CI and run the compat test against it. Reject the build if OpenClaw upgrades a field Atmosphere can't parse.
Purpose: browser-driven full-stack validation that the documentation matches what the user actually sees. Tests the integration surface, not the unit surface.
Tooling: Use the mcp__chrome-devtools__* tools already available in this Claude session to:
- Launch the personal assistant sample and the coding agent sample in separate browser pages.
- Drive the UI exactly as the documentation describes (step-by-step from the tutorial pages).
- Monitor console for unexpected errors (
mcp__chrome-devtools__list_console_messages). - Capture network requests (
mcp__chrome-devtools__list_network_requests) — assert every documented endpoint is actually called, actually returns 200 with the documented shape. - Take screenshots (
mcp__chrome-devtools__take_screenshot) for each tutorial step — check they match the written doc. Screenshots go into the siblingatmosphere.github.io/docs/src/assets/for publication. - Run a Lighthouse audit on each sample (
mcp__chrome-devtools__lighthouse_audit) — admin UI + both samples should score ≥ 90 on accessibility and performance. - Final acceptance: the ChefFamille demo flow runs end-to-end in a real browser with zero console errors.
Exit criteria: all three UI flows (admin, sample #1, sample #2) complete without any red events.
These are NOT deferred to a future version — they are explicit non-goals for v0.5. If they prove valuable later, they become their own plan, not a backlog promise.
- Eval dataset abstraction (
EvalDatasetrecord or similar). Users composeList<AgentCall>explicitly. No new type. - Eval run / regression tracking across time. Coordination journal logs individual runs; framework-level regression tooling is LangSmith product territory, not Atmosphere foundation.
- Human feedback calibration / annotation UI. LangSmith product feature, not a foundation primitive.
- Dedicated eval CLI commands (
atmosphere eval run <dataset>etc.). Users invokeAgentFleet.evaluate()via code.
- Zero-warning compile:
./mvnw compileat worktree root. No new@SuppressWarningsexcept explicitly justified. - Checkstyle + PMD:
./mvnw checkstyle:checkstyle pmd:check. Must pass across all touched modules. - Full build:
./mvnw install. Must be green. - Pre-push validation:
./scripts/pre-push-validate.sh. Required before any push. - Cancel stale CI runs:
gh run list --branch feat/ai-agent-foundation --json databaseId,status -q '.[] | select(.status == "queued" or .status == "in_progress") | .databaseId' | xargs -I{} gh run cancel {}before the push lands. - Commit strategy: one commit per primitive + one per sample + one for docs + one for tests. Conventional-commit prefixes (
feat(ai),feat(sandbox),docs,test). No AI attribution trailers ever (perCLAUDE.mdandfeedback_commit_messages.md). - PR stays open for review: ChefFamille approves before merge. No auto-merge.
- Release timing: nothing public until the full six-primitive test matrix is green on main. Per v0.5 under-the-radar cadence.
| # | Risk | Probability | Mitigation |
|---|---|---|---|
| 1 | ProtocolBridge rename breaks existing MCP / A2A / AG-UI consumers |
Medium | Thin delegation layer for old symbols during the migration commit; deprecate-and-delete in a follow-up release |
| 2 | ADK latent capability lie fix reveals deeper integration bug | Low–Medium | Keep the fix scoped; if it expands, extract to a separate commit with its own regression test |
| 3 | OpenClaw canonical spec changes during implementation | Low | Pin the fixture to a specific OpenClaw tag; document the pin; upgrade deliberately |
| 4 | Docker sandbox fails in CI where no Docker daemon is available | High | Skip the sandbox contract test when DOCKER_HOST is unreachable; CI runner configured with Docker service |
| 5 | AgentResumeHandle event replay buffer interacts badly with BroadcasterCache |
Medium | If reuse doesn't work cleanly, ship a dedicated buffer — don't force the fit |
| 6 | Playwright tests flake on CI due to timing | Medium | Use explicit waitFor assertions everywhere; no sleep calls; per feedback_no_flaky_tests.md — if a test flakes, fix the test, don't quarantine |
| 7 | Sibling atmosphere.github.io repo is release-gating but might be out of sync |
Low | Before any docs commit, cd ../atmosphere.github.io && git pull && git status — confirm clean working tree, then edit |
| 8 | The javap worry from v0.3 resurfaces for some runtime we missed |
Low | The Action 1 verification already covered all seven; if it surfaces, the fix is one-runtime-at-a-time and we stay honest via contract tests |
| 9 | Total time blows past the 24 h estimate | Medium | Commit after each primitive so we never lose progress; split into three 8-hour sessions rather than one marathon |
These need ChefFamille's call before we start code:
- Sandbox default resource limits — what CPU / memory / wall-time per sandbox by default? My lean: 1 CPU · 512 MB · 5 min wall-time · no network by default. User overrides in
.agent/atmosphere/SANDBOX.mdor equivalent. @SandboxToolsemantics when no Docker — fail hard or fall back to in-JVM execution with a warning? My lean: fail hard. Non-deterministic backend swap is a footgun.- Per-user credential store encryption — what cipher / KDF for
AtmosphereEncryptedCredentialStore? My lean: AES-GCM with an OS-level keychain-derived key, no plaintext fallback. - Read-only session share token TTL — default how long? My lean: 24 hours, admin can revoke earlier.
- Chrome DevTools validation on CI — is the MCP tool set available in CI runners, or is this only a local-dev validation step? If CI-only, we document the acceptance test as a manual gate per release. My lean: manual gate, documented, performed by release engineer (ChefFamille).
Once ChefFamille approves this plan:
- Clean up stale TODOs (session memory).
- Warm the Maven cache in the worktree per Phase 0.
- Start Primitive 1 (
AgentState) with the five-step cycle. - Report at each primitive completion; ChefFamille can re-prioritize or adjust between primitives.
No code runs before plan approval. No code runs on the main worktree — everything happens in .claude/worktrees/ai-agent-foundation.