Skip to content

Instantly share code, notes, and snippets.

@jfarcand
Created March 27, 2026 21:37
Show Gist options
  • Select an option

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

Select an option

Save jfarcand/ef09bcac47f0d3d5320a578cb97c4dec to your computer and use it in GitHub Desktop.
Atmosphere: Summary of fixes from architecture review + documentation audit

Atmosphere Code Review — Issues Fixed

Two external reviews were conducted on the Atmosphere coordinator module and project documentation. This gist summarizes every issue found and how each was resolved.


Review 1: Agent/Fleet/Coordinator Architecture

Source: Architecture Review Gist

Fixed Issues

# Severity Issue Fix Commit
1 High Reflection in LocalAgentTransportgetDeclaredField("protocolHandler") and setAccessible(true) breaks silently on rename Created LocalDispatchable interface in atmosphere-a2a; A2aHandler implements it; LocalAgentTransport uses instanceof pattern matching fix/coordinator-review-issues
2 High Unbounded CompletableFuture.join() in DefaultAgentFleet.parallel() — hung agent blocks coordinator forever Added orTimeout(120_000, MILLISECONDS) per agent with clear error message on timeout same
3 Medium JournalingAgentFleet.evalExecutor never shut down JournalingAgentFleet now implements AutoCloseable with close() that shuts down the executor same
4 Medium-High ThreadLocal<String> activeCoordinationId never remove()d — memory leak on pooled threads Added finally { activeCoordinationId.remove(); } in both parallel() and pipeline() same
5 Medium Error messages in resolveAgentName() omit which coordinator the @AgentRef belongs to resolveAgentName() now takes coordinatorName parameter; all errors include coordinator context same
6 Medium AgentCall.args() uses Map<String, String> — can't pass structured or nested payloads Changed to Map<String, Object> across entire API: AgentCall, AgentFleet, AgentProxy, DefaultAgentProxy, AgentTransport, both transports, CoordinationEvent.AgentDispatched, JournalingAgentFleet, stubs, all tests, and sample same
7 Low weight field stored and logged but never used for routing Added Javadoc on AgentProxy.weight() and @AgentRef.weight() documenting intended use for future load-balancing / preference scoring same
8 Medium Duplicate buildJsonRpc() and extractArtifactText() in LocalAgentTransport and A2aAgentTransport Extracted shared JsonRpcUtils utility; both transports delegate to it same
9 Medium pipeline() doesn't chain results — each step uses original args, not previous output Both DefaultAgentFleet.pipeline() and JournalingAgentFleet.pipeline() now merge _previous_result from step N into step N+1's args same
10 Medium No retry mechanism for transient agent failures Added int maxRetries() default 0 on @AgentRef; DefaultAgentProxy.call() implements exponential backoff (100ms base) same

Stats: 22 files changed, +380/-242 lines, all 120 coordinator tests pass.


Review 2: Documentation Audit

Source: Documentation Audit Gist

P0 Issues Fixed

# Issue Fix
1 docs/protocols.md references non-existent @McpServer annotation Replaced with correct pattern: @Agent(headless = true) with @McpTool methods. Updated annotation list to remove @McpServer
2 README says "Pick any LLM library" — overstates support Changed to explicit list: "Works with Spring AI, LangChain4j, Google ADK, Embabel, or the built-in OpenAI-compatible client"
4 docs/skill-files.md has "planned but not yet implemented" markers buried in table Reworded to clear Note: callouts: channels routing is "informational only", guardrails are "LLM-enforced only"
5 Multi-agent NL routing limitation buried in Known Limitations section Added inline warning in docs/channels.md "How It Works" section so readers hit it before the limitation section
6 README has no Maven <dependency> coordinates Added dependency blocks for atmosphere-spring-boot-starter and atmosphere-agent with version
7 README does not state the current version Version 4.0.28-SNAPSHOT now appears in Maven coordinates section
8 Marketing tone — rhetorical "Why not use Spring AI / LangChain4j / ADK directly?" with 10-bullet sales pitch Replaced with factual comparison table (Without Atmosphere vs. With Atmosphere)

P0 Issues Not Requiring Fix

# Issue Status
3 spring-boot-embabel-chat sample referenced but missing Correctly commented out in pom.xml with note "Embabel requires Spring Boot 3.5". Not referenced in README sample table. No fix needed.

P1 Issues (Acknowledged, Future Work)

Issue Status
Missing docs/agent.md — @Agent lifecycle, headless modes, endpoint paths Not yet created
Missing docs/coordinator.md — @Coordinator, @Fleet, AgentFleet API, journal SPI Not yet created
Missing docs/configuration.md — complete env var / init-param / Spring property catalog Not yet created
Two doc trees (docs/ and atmosphere.github.io/docs/) without declared relationship Structural issue acknowledged

Stats: 5 files changed, +48/-24 lines across README.md, docs/protocols.md, docs/channels.md, docs/skill-files.md.


New Features Added During This Session

In addition to fixing review issues, the following features were added:

JournalFormat SPI

Pluggable format for rendering coordination journal events. Built-in formats: JournalFormat.STANDARD_LOG (plain text) and JournalFormat.MARKDOWN (table). Users implement the JournalFormat interface for custom formats (Grafana, OpenTelemetry, etc.).

// Programmatic
fleet.journal().formatLog(JournalFormat.MARKDOWN);

// Annotation-driven (auto-emits after @Prompt completes)
@Coordinator(name = "ceo", journalFormat = JournalFormat.Markdown.class)

CoordinationEvent.toLogLine()

Each sealed event record now formats itself as a single-line log entry, used by JournalFormat.STANDARD_LOG and available for custom logging.

PostPromptHook

Callback interface in the AI module, invoked by AiEndpointHandler after the @Prompt method returns successfully. Used by the coordinator module to auto-emit journal tool cards without manual code in the prompt method.

Architecture Documentation

New page at atmosphere.github.io/docs/architecture/ covering the two-layer model (Broadcaster transport vs. StreamingSession application), how they compose, why they can't and shouldn't be unified, and where AgentFleet fits as the orchestration layer on top.

Javadoc Cleanup

38 files stripped of verbose AI-generated Javadoc. Replaced bloated HTML-heavy class-level docs with concise 2-4 line descriptions. Net change: +119/-688 lines.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment