Releases: Atmosphere/atmosphere
Releases · Atmosphere/atmosphere
Atmosphere 4.0.46
Immutable
release. Only release title and notes can be modified.
Added
- Spring AI Alibaba: unconditional
TOOL_CALLING/TOOL_APPROVAL/
TOKEN_USAGE(534317f03d) —UsageCapturingChatModelwraps the
configured Spring AIChatModelbean at auto-configuration time;
per-thread accumulator capturesChatResponseMetadata.getUsage()across
every step of the ReAct graph and emits a single
session.usage(TokenUsage)after each dispatch. Tool calling is no
longer gated onstaticChatModel != null—SpringAiAlibabaToolBridge
is wired on every dispatch with tools, and the runtime fails fast with
configurationHint()ifChatModelis missing. Closes the last
conditional capability gap from the runtime parity push (62a9b7e6af). - RAG vector-store matrix expanded with three direct connectors
(31d6455a75):PgVectorContextProvider(Postgres + pgvector via
JDBC),QdrantContextProvider(Qdrant REST over
java.net.http.HttpClient), andPineconeContextProvider(Pinecone
REST). Each connector embeds the user query through
EmbeddingRuntime, validates caller-controlled identifiers at
construction time per Boundary-Safety invariant, and ships with a
Mockito-backed unit-test suite.modules/rag/README.mdadds a
reachability matrix showing the six direct providers plus the
Spring AI / LangChain4j bridges covering the long tail (Weaviate,
Milvus, Chroma, Elasticsearch, Redis Stack, MongoDB Atlas, OpenSearch,
Cassandra). - Workflow authoring inside the admin control plane (
81ff454177) —
WorkflowManifestJSON record,WorkflowStoreSPI with
InMemoryWorkflowStoredefault and optimistic-concurrency version
conflict detection,WorkflowControllerwithControlAuthorizer
gating plus audit-log entries on every save / delete, Spring Boot
endpoint exposesGET/POST/DELETE /api/admin/workflow, and
/atmosphere/admin/workflow.htmlships a vanilla-JS authoring UI
that lists / creates / edits manifests against the REST surface. - Eval dashboard inside the admin control plane (
38e2a45920) —
EvalRunJSON record,EvalRunStoreSPI with bounded-ring-buffer
InMemoryEvalRunStoredefault (500 runs per baseline,
oldest-evicted),EvalControlleraggregates pass-rate per baseline,
Spring Boot endpoint exposes
GET/POST/DELETE /api/admin/evals/{runs,baselines}, and
/atmosphere/admin/evals.htmlsurfaces pass-rate meters + recent-run
table with auto-refresh. CI submits a JSON body per LLM-as-judge run
and the dashboard surfaces the trend without leaving the control
plane. atmosphere-admin-bundleenterprise console aggregator
(eaad0df089) — single Mavenpom-packaging artifact that
transitively pulls inatmosphere-spring-boot-starter,
atmosphere-admin,atmosphere-ai,atmosphere-coordinator,
atmosphere-agent,atmosphere-rag,atmosphere-checkpoint,
atmosphere-durable-sessions, and
atmosphere-durable-sessions-sqlite. Adding one dep gives operators
the dashboard, journal flow viewer, workflow authoring, eval
dashboard, and governance decision viewer; deliberately does not pin
anAgentRuntimeadapter or a vector-store driver so operators
choose those independently.docs/runtime-selection.md(97130eeeeb) — nine-runtime decision
tree walking the questions an architect should answer before picking
anAgentRuntime, cross-referenced against the pinned capability
snapshot. Companion to the cli / samples "flagship enterprise
templates" promotion that calls outrag,ai-tools,
guarded-agent,coding-agent, andms-governanceas the canonical
agent shapes.
Tests
- AI gap Playwright coverage (
e91b8084fd) —ai-gap-coverage.spec.ts
exercises the deterministic RAG, input-assembly telemetry, and evaluator
artifact paths throughAiFeatureTestServer; Vue, Svelte, and React Native
hook tests pin the new chat-hook parity surface. UsageCapturingChatModelTest,SpringAiAlibabaRuntimeContractTest
(TC/TA/TU pinned),WorkflowManifestTest,WorkflowControllerTest,
EvalControllerTest,PgVectorContextProviderTest,
QdrantContextProviderTest,PineconeContextProviderTest
(534317f03d,31d6455a75,81ff454177,38e2a45920).
Atmosphere 4.0.45
Immutable
release. Only release title and notes can be modified.
Added
- capability-matrix snapshot + drift gate (
d22d18a7cd) — new.harness/capabilities.snapshot.jsonis the canonical aggregate of theAiCapabilityenum (20 capabilities) and each runtime's pinnedexpectedCapabilities()(9 runtimes). Regenerated byscripts/regen-capability-snapshot.shand validated by bothscripts/validate-capability-claims.sh(wired intoscripts/pre-push-validate.shTier 1) and the newCapabilitySnapshotTestinmodules/ai-test. The per-runtime contract tests already pin per-runtime drift; this layer pins aggregate count claims inmodules/ai/README.mdagainst the snapshot so prose like "All 9 runtimes…" cannot drift from the running code without breaking the build. Adds a "What capability flags do not claim" disclosure block tomodules/ai/README.md§ Adapter Runtimes covering implementation parity, limit numbers, provider-side guarantees, and production fitness — the four edges callers commonly assume from a capability flag and that the flag does not promise. - drift-log + Stop-hook enforcement (
c685f9588f+4f6a51d3a8) — new.harness/drift-log.mdis the append-only record of every agent claim that diverged from ground truth (code, git history, runtime state). Two enforcement points:scripts/validate-drift-log.shchecks structural hygiene (chronological sections, no future dates, prior-section append-only invariant againstorigin/main) and is wired into pre-push Tier 1;.claude/hooks/check-drift-log.shis a Claude Code Stop hook (registered in.claude/settings.json) that greps the session transcript for high-precision drift-correction patterns and blocks session end if the log was not modified. Together with the capability snapshot, this is the verification rail of the harness pattern documented by Anthropic (Effective harnesses for long-running agents) and OpenAI (Harness engineering), applied to AI prose claims about this repo — measuring change failure rate by agent claim, not utilization. Operator notes live in.harness/README.md.
Fixed
- AiPipeline input-assembly snapshot stale across guardrails+policies (
f16e9da396) — the per-stage telemetry snapshot ofrequest.systemPrompt()was captured before guardrails (AiGuardrail.GuardrailResult.Modify) and governance policies (PolicyDecision.Transform) had a chance to mutate the request. The runtime later executed the post-mutation request, so the system stage was under- or over-reported. Snapshot moved to after both loops have run, before pipeline-driven augmentations (structured-output schema, confidence cue) which are tracked separately. Regression test inAiPipelineInputAssemblyTest. - BudgetCapturingSession wall-clock callback-lazy enforcement (
f16e9da396) — wall-clock cap was sampled only at session-method boundaries, so a provider that hung silently after dispatch never tripped. Now the deadline is scheduled up-front via a daemonScheduledExecutorService; on trip the decorator both routes the typedAiBudgetExceededExceptionthroughsession.errorand fires a pipeline-suppliedonTriphook bound toruntime.executeWithHandle'shandle::cancel, so the in-flight runtime call is cancelled instead of left dangling. The task is cancelled oncomplete()/complete(summary)/error()so the scheduler thread is freed promptly. Existing wall-clock assertion loosened from>to>=(09b2d2b610) because the scheduled task can fire exactly at the deadline. Regression test (wallClockBudgetTripsWhenRuntimeMakesNoSessionCallbacks) covers the no-callback path. - McpToolSource transport leak on initialize/listTools failure (
f16e9da396) —connect(transport, label)constructed anMcpClientand calledinitialize()+listTools()without a failure cleanup path, leaking the underlying transport (subprocess pipes, sockets, HTTP connection pool) for the JVM lifetime if either threw. Wrapped in try/catch withclient.closeGracefully()on failure (Ownership Invariant #1). Regression test stubs anMcpClientTransportwhoseconnect()returnsMono.errorand assertscloseGracefullywas called. - AgentPassivation responseType ignored on resume (
f16e9da396) —AgentSnapshotpersistedresponseTypeNamebutresume()rebuilt the context frombase.responseType(), so a structured-output agent resumed with a base context that lacked the type lost typed parsing despite the snapshot carrying the field. NewresolveResponseTypehelper resolves the snapshot's class name via the thread-context classloader (with fallback tobase.responseType()plus a one-line WARN if the class is not on the resumer's classpath). Regression test inAgentPassivationTest. - off-by-one in
modules/ai/README.md§ ToolLoopPolicy "the other six runtimes" → "the other seven runtimes". With Built-in and Koog handlingCOMPLETE_WITHOUT_TOOLSnatively and 9 runtimes total, the count of "other" runtimes is 7, not 6. Surfaced by the new capability-matrix verification work.
Documentation
atmosphere.github.iocapability claims aligned with the snapshot. Cross-validated against.harness/capabilities.snapshot.json; fixeddocs/.../reference/ai.mdTOOL_APPROVAL list (Embabel and SK were wrongly excluded),docs/.../tutorial/26-foundation-primitives.mdgateway-consumer count ("seven of nine" → all nine — every runtime callsadmitThroughGateway), added 5 missing capability rows (BUDGET_ENFORCEMENT,CONFIDENCE_SCORES,PASSIVATION,MODEL_ENUMERATION,MULTI_AGENT_HANDOFF) totutorial/11-ai-adapters.md, and refreshed four pre-Koog/SK/AgentScope/Alibaba narrative enumerations to the current 9-runtime set. Website main:13fe8c4..harness/README.md— operator manual for the harness directory (canonical files, validators, hooks, regen + append protocols).
Atmosphere 4.0.44
Immutable
release. Only release title and notes can be modified.
Added
- predictable-AI primitives — three framework-level capabilities that close gaps Bonér's "Herding LLMs" deck flagged for distributed-system reliability, all declared on every framework runtime so the matrix closes without
@Betashims:BUDGET_ENFORCEMENT(a4fae39464) — newAiBudgetvalue record (max input / output / total tokens, max steps, max wall clock) installed viapipeline.setDefaultBudget(...)or per-requestai.budgetmetadata.BudgetCapturingSessiondecorator slots into the AiPipeline session-decorator stack between metrics and guardrail layers; on breach it routes a typedAiBudgetExceededException extends AiExceptionthroughsession.error(...)and short-circuits subsequentsend/usage/progress/emit/completecalls so the wire protocol's "one terminal frame" invariant holds. Distinct fromorg.atmosphere.ai.budget.StreamingTextBudgetManager(long-running per-tenant cumulative spend); this capability is the per-call death-spiral guard. 13 new unit tests cover every breach reason, default vs. per-request override, and the post-trip swallow. Wall-clock limits trip universally; token / step limits depend onTOKEN_USAGE(every runtime except Spring AI Alibaba honors both).CONFIDENCE_SCORES(a4fae39464) — newAiConfidencerecord withOptionalDouble aggregate,List<TokenLogprob>tokens, andSourceenum (LOGPROBS_NATIVE/MODEL_REPORTED_FIELD/HEURISTIC).StreamingSession.confidence(AiConfidence)default method auto-emitsai.confidence.aggregate/.source/.tokensmetadata mirroring theusage(TokenUsage)convention;DelegatingStreamingSessiongains the matching forwarding override. Universal model-reported path via the newAiConfidenceElicitationplus theConfidenceCapturingSessiondecorator: pipeline appends an opt-in cue to the system prompt, decorator parses the model-emitted{"confidence": 0.x}field on stream completion (same regex shape as the existingConfidenceThresholdGuardrail) and firessession.confidenceahead of the terminal frame. Decorator self-suppresses when a runtime already invokedconfidence(...)directly withLOGPROBS_NATIVE. Skipped when structured-output mode is in play because the schema parser owns the response shape — callers add aconfidencefield to their record schema in that mode. 14 new unit tests cover record validation, the elicitation cue, parser fallbacks, runtime-explicit override, per-request override of the pipeline default, and the structured-output skip.PASSIVATION(a4fae39464) — newAgentSnapshotrecord inmodules/ai(persistable subset ofAgentExecutionContext— message, system prompt, identity columns, history, JSON-clean metadata, response type name, reason, paused-at). NewAgentPassivationstatic helper inmodules/checkpointwithpassivate(runtime, ctx, store, reason): String,resume(runtime, store, id, externalSignal, base, session), andloadSnapshot(store, id).resumemerges the snapshot onto a caller-supplied base context (which carries the runtime references — tools, memory, listeners, retry policy — that don't survive a JVM restart) and re-runsruntime.execute(...); base wins on metadata-key collision so caller-injected refs (e.g. trace context) are not clobbered by stale snapshot values. Helper lives inmodules/checkpointrather than onAgentRuntimeitself becausemodules/ai → modules/checkpointintroduces aai → checkpoint → coordinator → aicycle; the reverse direction is acyclic. Capability flag declared on every runtime — flag advertises "this runtime cooperates withAgentPassivation," honest because every runtime threadscontext.history()through its dispatch path so a resumed call observes the same conversation the paused call saw. 10 new unit tests cover snapshot round-trip, resume flow with external signal, signal-less replay of pending message, missing-checkpoint errors, metadata filtering (non-String values dropped pre-snapshot), metadata merge precedence, unique IDs across passivations, and null-arg rejection.
Changed
AiCapabilityenum gains 3 entries — total 20 capabilities (was 17).AbstractAgentRuntimeContractTest.expectedCapabilities()pin updated for all 9 framework runtimes: BuiltIn, Spring AI, LangChain4j, ADK, Embabel, Koog, AgentScope, Spring AI Alibaba, Semantic Kernel.BuiltInAgentRuntimecapability count test bumped from 13 to 16. Capability matrix inmodules/ai/README.mdextended withBE/CS/PSVcolumns plus a "Predictable-AI primitives" section documenting each capability's decorator placement, source enum, and runtime-by-runtime caveats (Spring AI Alibaba'sBUDGET_ENFORCEMENTis wall-clock-only because the runtime does not surfaceTOKEN_USAGE).
Tests
- Playwright e2e coverage for the predictable-AI primitives (
4be20c240c) —ai-budget-circuit-breaker.spec.ts,ai-confidence-elicitation.spec.ts,ai-passivation.spec.tsexercise the fullAiPipelinesession-decorator stack through Atmosphere's wire transport. Each spec drives a dedicated test handler (BudgetCircuitBreakerTestHandler/ConfidenceElicitationTestHandler/PassivationTestHandler) registered inAiFeatureTestServerso the harness seesAiBudgetExceededExceptionon the wire's error frame, theai.confidence.aggregate/.source/.tokensmetadata frames theconfidence(...)default sink emits, and the snapshot/resume round-trip across two sequential WebSocket connections.modules/integration-tests/pom.xmlbumpsatmosphere-checkpointfrom test to compile scope soPassivationTestHandlercan callAgentPassivationdirectly.modules/integration-tests/playwright.config.tsregisters the three new spec project entries.
Fixed
- CLI standalone-scaffold compile against the released parent POM (
7383eb0ee2) — twentysamples/spring-boot-*/pom.xmlfiles now declare<netty.version>4.2.13.Final</netty.version>in their own<properties>block so the sample is self-contained: scaffold-then-compile against the releasedorg.atmosphere:atmosphere-project:4.0.43parent (which predates the netty bump and therefore does not declarenetty.version) no longer fails withNon-resolvable import POM: io.netty:netty-bom:pom:${netty.version}.cli/e2e-test-cli-runtime.shalso fixes a long-standing comment-vs-code drift: the script was exportingATMOSPHERE_CLI_VERSIONwhilecli/atmosphereonly ever readATMOSPHERE_VERSION_OVERRIDE, so the SNAPSHOT-against-SNAPSHOT lane silently degraded to release-pin coverage. Renaming the export aligns the script with the CLI's actual contract.
Atmosphere 4.0.43
Immutable
release. Only release title and notes can be modified.
Added
- per-request runtime extension helpers (
f1493c3f9c) — smallattach(context, ...)/from(context)helpers (modeled on the existingCacheHint) that let callers stash framework-native composition objects inAgentExecutionContext.metadata(), so a runtime can apply them per-request without growing the unifiedAgentRuntimeSPI with framework-specific knobs. Runtimes covered:SpringAiAdvisors(Spring AIAdvisorchain — RAG / memory / guardrails / observability),LangChain4jAiServices(LangChain4jAiServices/TokenStream),KoogStrategy(KoogAIAgentGraphStrategyDSL),AdkRootAgent(ADKBaseAgent/SequentialAgent/ParallelAgent/LoopAgenttopology), andToolLoopPolicies(per-requestToolLoopPolicyhonored byBuiltInAgentRuntime's OpenAI-compatible tool loop). The other shipped runtimes (AgentScope,Embabel,SemanticKernel,SpringAiAlibaba) do not yet have a per-request bridge — Embabel got native streaming viaStreamingPromptRunnerBuilder.streaming().generateStream()in the same merge but no sidecar. Also added:AgentLifecycleListener.onModelStart/onModelEnd/onModelErrorhooks withfireXxxfan-out helpers, andAiEventForwardingListeneradapter that translates lifecycle hooks to wire-formatAiEvent.Progressframes (opt-in viacontext.withListeners(...)). Each bridge ships with a unit-level*BridgeTestproving the runtime honors the sidecar.
Fixed
- Quarkus extension closes the
/api/console/infoparity gap — the bundled Atmosphere Console UI gets the samesubtitle / endpoint / runtime / modepayload it gets from the Spring Boot starter, instead of falling through to the Vue defaults on a 404. NewAtmosphereConsoleInfoServlet(HttpServlet, registered at build time via a secondServletBuildItemmapped to/api/console/info) reuses the same package-prefix mode-detection heuristic asAtmosphereConsoleInfoEndpoint(org.atmosphere.{ai,agent,coordinator}.*→"ai", anything else includingManagedAtmosphereHandler→"broadcast"). Endpoint auto-detection prefers the canonical/atmosphere/ai-chatwhen registered (samples likequarkus-ai-chatship multiple@AiEndpoints), then/atmosphere/agent/*, then any other/atmosphere/*. New config keysquarkus.atmosphere.console-subtitleandquarkus.atmosphere.console-endpointmirror the Springatmosphere.console-subtitle/atmosphere.console-endpointproperties. JSON is hand-rolled so the runtime POM stays Jackson-free;AgentRuntimeResolveris reached via reflection so the servlet keeps no compile-time link tomodules/ai. Empirically verified in chrome-devtools againstquarkus-ai-chat—/api/console/infonow returns{"subtitle":"Runtime: langchain4j","endpoint":"/atmosphere/ai-chat","runtime":"langchain4j","mode":"ai"}, the Vue Console shows the runtime label in the header subtitle, and the cross-tab isolation matrix continues to pass on the Quarkus leg. - bundled Atmosphere Console now auto-detects AI vs. broadcast endpoints (
c1e8e36c7b) —/api/console/infoadds amodefield ("ai"for@AiEndpoint/@Agent/@Coordinator,"broadcast"for@ManagedServicechats);AtmosphereConsoleInfoEndpoint#detectModeclassifies via the registered handler's package prefix (org.atmosphere.{ai,agent,coordinator}.*→ ai, everything else includingManagedAtmosphereHandler→ broadcast), so the check stays compile-time independent ofmodules/aiandmodules/agent. The Vue frontend swaps empty-state copy ("Start a conversation" + "AI assistant" → "Start a broadcast" + "every connected client on this endpoint will receive it") and the default subtitle ("Runtime: " → "Multi-client broadcast chat") based on the detected mode. Closes the misleading-UI half of the cross-tab leak follow-up: pre-fix,spring-boot-mcp-serverandspring-boot-otel-chatrendered the AI-assistant copy despite being broadcast-shared by design. Empirically verified in chrome-devtools against both broadcast samples andspring-boot-ai-chat. Per-sampleatmosphere.console-subtitleoverrides still win over the mode-aware default. 5 new contract tests inAtmosphereConsoleInfoEndpointModeTestpin the four classification paths plus the override interaction. - cross-tab isolation matrix extended from 11 → 15 samples (
c1e8e36c7b) — addsquarkus-ai-chat(cross-runtime parity, proves the targeted-dispatch fix from1fbb0958f0survives Quarkus's distinctQuarkusJSR356AsyncSupportpath),spring-boot-checkpoint-agent(@Coordinatorwith analyzer/approver fleet + checkpoint store),spring-boot-ms-governance-chat(@AiEndpointwith@AgentScopeclassification interceptors stacked in front), andspring-boot-channels-chat(omnichannel@AiEndpointwith Telegram/Slack/WhatsApp/Messenger channel-bridge adapters). New fixture entries ine2e/fixtures/sample-server.tsfor the checkpoint and ms-governance samples; quarkus-ai-chat reuses the existing fixture. Out-of-scope docstring corrected to removespring-boot-channels-chat(it's actually an isolated@AiEndpoint, not a broadcast chat) and to explicitly tagspring-boot-a2a-agentas out-of-scope (A2A JSON-RPC has no two-tab Console scenario). All 15 cases pass locally in 3.5m. OpenAiCompatibleClientJavadoc placement broke JDK 26 strict mode (28703ea064) — two stacked Javadoc blocks onforwardResponsesApiUsageraiseddocumentation comment is not attached to any declarationunder-Xlint:all-Werroron JDK 26 (silent on JDK 21). Merged into a single coherent block; CI: Core (JDK 21/26) green.cli/samples.jsonandcli/atmospheretemplate map referenced deletedspring-boot-embabel-chatsample (3a9373e875) —cli/test-cli.shfailed with "samples missing README.md: spring-boot-embabel-chat". Entry removed from samples.json + template-map case statement.
Atmosphere 4.0.42
Immutable
release. Only release title and notes can be modified.
Added
- atmosphere-verifier — plan-and-verify (Meijer "Guardians of the Agents") New module modules/verifier/ + sample samples/spring-boot-guarded-email-agent/ — sealed Workflow AST, ServiceLoader-discovered PlanVerifier chain (Allowlist/WellFormed/Capability/Taint/Automaton/SmtChecker SPI), @sink + @RequiresCapability scanners, PlanAndVerify orchestrator, WorkflowExecutor with partial-env on failure, verify CLI; sample REST + UI exercises the inbox-exfiltration scenario end-to-end (refused before any tool fires) — 74 unit + 4 boot + 6 Playwright tests, all CI green on the feature branch.
Fixed
- fail-closed verifier empty-chain, JSON-escape govern. deny, deflake wasync PlanAndVerify.withDefaults + VerifyCli runChain throw / emit chain-empty violations when ServiceLoader yields no providers (P1: silent fail-open under shading / native-image / fat-jar relocation); governance-deny tool result routes every interpolated field through ToolBridgeUtils.escapeJson via a new buildGovernanceDenyJson helper (P2: backslash/newline/control char break); ChatIntegrationTest.socketStatusTransitions polls for status transition rather than asserting in the same instant the OPEN handler fires (release-pipeline timing flake). 5 new verifier tests + 6 governance-JSON tests.
Changed
- drop org.json:json — Jackson 3 only (CVE hygiene) RoomProtocolCodec + SimpleRestInterceptor migrated to tools.jackson; brace-balanced reader preserves SwaggerSocket header/body chunk semantics; ALLOW_SINGLE_QUOTES kept for wire compatibility; org.json removed from parent + 3 spring-boot samples.
- bump version to 4.0.41
- prepare for next development iteration 4.0.42-SNAPSHOT
Atmosphere 4.0.41
Immutable
release. Only release title and notes can be modified.
Changed — A2A v1.0.0 alignment (wire-breaking)
atmosphere-a2aretracked to A2A v1.0.0 (a2aproject/A2A@v1.0.0,
released 2026-03-12). The pre-1.0 wire surface was the slash-style
method names (message/send,tasks/get, …) and a polymorphic
Partenvelope; both are gone in v1.0.0.- JSON-RPC method names switched to PascalCase per spec §9.4 —
SendMessage,SendStreamingMessage,GetTask,ListTasks,
CancelTask,SubscribeToTask, the four
{Create,Get,List,Delete}TaskPushNotificationConfigoperations, and
GetExtendedAgentCard. The pre-1.0 slash names and the old
tasks/pushNotification/*path are aliased to their v1.0.0
equivalents at handler entry, with a one-time WARN per legacy method
seen — existing Atmosphere clients keep working through the
transition. - HTTP+JSON / REST binding added — colon-verb endpoints
(POST /tasks/{id}:cancel,POST /tasks/{id}:subscribe,
POST /message:send/:stream),pushNotificationConfigsCRUD
URLs, andGET /extendedAgentCardare recognized byA2aHandler.
REST requests are translated to JSON-RPC envelopes and dispatched
through the same handler so the two bindings agree by construction
(Mode Parity invariant #7). - Type schema rewrite under
org.atmosphere.a2a.types:Partcollapses three legacy subtypes (TextPart/FilePart/
DataPart) into a single record carrying atext | raw | url | dataoneof plus sharedmetadata,filename,mediaType. The
deserializer continues to accept the pre-1.0
{"type":"text",…}/{"kind":"text",…}envelopes for
migration.Message.roleis now theRoleenum (ROLE_USER/
ROLE_AGENTper ADR-001 ProtoJSON). Lower-case legacy forms
parse for back-compat.TaskStateaddsSUBMITTED(the v1.0.0 ack-before-work state)
and emits its proto-JSON name on the wire
(TASK_STATE_WORKING, …).Task.messagesis renamed toTask.history;TaskStatusis
promoted to a top-level type and carries atimestamp; both
update events (TaskStatusUpdateEvent,
TaskArtifactUpdateEvent) gaincontextIdandmetadataand
drop the redundantfinalflag.AgentCardgainssupportedInterfaces(so an agent can
advertise JSON-RPC + HTTP+JSON at distinct URLs), structured
AgentProvider,AgentCardSignature,iconUrl, structured
SecurityScheme/SecurityRequirement, andextendedAgentCard
moves intoAgentCapabilities(was
supportsAuthenticatedExtendedCard). The pre-1.0 top-level
guardrailsfield is no longer modeled — guardrails surface as
anAgentExtensiononAgentCapabilities.extensionsunder
https://atmosphere.async-io.org/extensions/guardrails/v1.- New types added for the missing v1.0.0 surface:
AgentInterface,AgentExtension,AgentSkill(replaces
Skill),SecurityRequirement,SecurityScheme+
APIKey/HTTPAuth/OAuth2/OpenIdConnect/MutualTls,
OAuthFlows+ the three non-deprecated flow shapes,
AuthenticationInfo,TaskPushNotificationConfig, and the
response wrappersSendMessageResponse,StreamResponse,
ListTasksResponse,ListTaskPushNotificationConfigsResponse.
- Pagination + history honored:
GetTaskreads
historyLength;ListTasksreadspageSize(clamped 1..100,
default 50),pageToken, optionalstatusfilter; the response
is the v1.0.0ListTasksResponsewithnextPageToken,
pageSize,totalSize.SubscribeToTaskreturns-32004
UnsupportedOperationErroron a terminal task. - Push-notification methods: handlers route the four CRUD names
but return-32003PushNotificationNotSupportedError—
AgentCapabilities.pushNotificationsis advertised asfalse
(Runtime Truth invariant #5; deliveries are not yet wired so the
capability flag stays honest). - SSE chunks emitted by
A2aHandler.handleSseStreamingare now
spec-compliantStreamResponseenvelopes carrying an
artifactUpdateoneof variant (was a custom
{"artifact":{…}}shape pre-1.0). - Coordinator
A2aAgentTransportupdated to send/receive
SendMessage/SendMessageResponseand to accept both the v1.0.0
and pre-1.0 task-status shapes when classifying failure replies. modules/agentAgentProcessorupdated to construct the v1.0.0
AgentCardand surface guardrails via the extension URI above.
Spring BootWellKnownAgentFilterTestfixture rewritten for the
new card constructor.
Atmosphere 4.0.40
Immutable
release. Only release title and notes can be modified.
✨ Added
- policy plane, multi-agent governance, sample retrofit
- render tokens / elapsed / tok/s footer on stream complete
- approve/deny widget for @RequiresApproval tools
- route demo mode through the pipeline via DemoAgentRuntime
🐛 Fixed
- isolate coordinator types from CommitmentRecordView AOT walk
- native-image AOT + CLI E2E SNAPSHOT compat
- survive recycled async request during streaming disconnect
- ship classic chat SPA at / (was hanging silently)
- emit tool-start/tool-result at shared execution seam
- parse nested LLM error envelopes into a compact error card
- ship atmosphere-admin transitively for /atmosphere/admin/
- accept both type and kind as Part discriminator on parse
- redirect / to /atmosphere/console/ when no root UI ships
- rewrite URL so SK 1.4.0 works against non-OpenAI endpoints
- correct README endpoint + broadcaster path
- disable auth by default in sample, document toggle
- always set ToolCallBehavior to avoid SK 1.4.0 NPE
- gate prompt_cache_key by provider hostname for Gemini compat
- return 404 for unmapped /atmosphere/* paths instead of 500
🔧 Changed
- correct AgentWorkspace adapter list — drop fabricated SWE-bench
- drop (v0.5) suffix from Foundation E2E workflow name
- add .mvn/** + workflow_dispatch to all maven-build workflows
- use modern attribute in remaining logback configs
- document LLM provider choices + Gemini free-tier cap
- bind ResourceFactory to server + fix logback config
- re-enable auth in spring-boot-ai-chat fixture for auth specs
- bump version to 4.0.39
- prepare for next development iteration 4.0.40-SNAPSHOT
Full Changelog: atmosphere-4.0.39...atmosphere-4.0.40
Atmosphere 4.0.39
Immutable
release. Only release title and notes can be modified.
✨ Added
- serve /favicon.ico from both starters to kill the default 404 AtmosphereFaviconAutoConfiguration returns the Atmosphere logo PNG on /favicon.ico and /favicon.png for every app using the starter; opt out with atmosphere.favicon.enabled=false.
- reattach e2e — harness sample + direct-writer replay + CI job RunReattachSupport now writes the joined buffer straight to response.getWriter() (U+001E between events); broadcaster routing fed the payload back into the @prompt dispatcher. New spring-boot-reattach-harness plus a SyntheticRunController give Playwright a deterministic HTTP surface — foundation-e2e.yml runs the spec on every push so the reattach wire is proven end-to-end, not just in unit tests.
- TokenUsage → CostCeilingGuardrail.addCost bridge + ownership fix CostAccountingSession wraps every @prompt session when a CostAccountant is installed; built-in CostCeilingAccountant(guardrail, pricing) closes the observability→enforcement loop. Spring Boot auto-configuration installs it and a DisposableBean resets the holder on shutdown, which also fixes broadcaster listener ownership symmetry on the PII installer.
- cpr-core moat — broadcaster PII, tenant drift, cost ceiling, reattach test PiiRedactionFilter auto-installs on every broadcaster (present + future) so response-path PII is rewritten in-flight — framework owns the transport. OutputLengthZScoreGuardrail partitions its rolling window by business.tenant.id MDC so one tenant cannot poison another's baseline. New CostCeilingGuardrail blocks outbound @prompt per tenant once cumulative cost hits budget (observability→enforcement). writeEnabled resolved per-call in both starters for runtime lockdown. RunReattachSupport extracts the replay-on-reconnect path with 5 regression tests. Operator docs split Spring + Quarkus setup with principal-chain paragraphs.
- wire Flow tab into the admin console — SVG graph over /api/admin/flow New tab renders the coordination journal as a circle-layout SVG: nodes = agents, edges = dispatch count + success/failure/avg-duration, red on failure, arrowheads for direction. Optional coordination-id drilldown and lookback-minutes filter. Zero external graph library — plain SVG, adequate for fleet sizes Atmosphere runs. Mirrored across spring-boot-starter and spring-boot3-starter admin assets.
- observability + guardrails + admin auth + flow viewer Observability layer (BusinessMetadata → SLF4J MDC, FactResolver), default guardrails (PII redaction, drift z-score), admin-write auth triple-gate (feature flag → Principal → ControlAuthorizer), agent-to-agent flow viewer (/api/admin/flow), run reattach consumer, gateway admission on handle-based paths, framework-scoped resolution for all v0.8 primitives. Samples boot via spring-boot:run + actuator health; foundation-e2e gates merges including Docker sandbox.
- foundation hardening — primitive wire-in, Sandbox gate, PermissionMode
- AI Agent Foundation — 8 primitives, 2 proof samples, strict OpenAI-compat tool round-trip
🐛 Fixed
- remove orphan javadoc that broke JDK 26 / native-image builds Stray /** ... */ block had no declaration attached; compiler -Xdoclint was fine under -Pfastinstall but strict under Core / Native Image. Reattaches the doc to captureFeedsReattachWithErrorEnvelopeWhenHandlerThrows where it belongs. Also explains why I missed it locally — I was running --fast, which skips the doclint phase; pattern now flagged in my self-review checklist.
- favicon dual-registration + opt-in admin read-auth gate (P1) Drops the @bean method in AtmosphereFaviconAutoConfiguration — the nested @RestController already registers under a stereotype-derived bean name and the @bean factory was producing a second bean mapped to the same /favicon.ico route, triggering "Ambiguous mapping" at startup for any app pulling the starter. Adds atmosphere.admin.http-read-auth-required opt-in flag: when true, Spring's AdminApiAuthFilter and a new Quarkus AdminReadAuthFilter (JAX-RS @Provider) reject anonymous GET/HEAD/OPTIONS on /api/admin with 401 matching the existing write-side chain (X-Atmosphere-Auth + principal attribute sources). Default off so demo consoles keep working; multi-tenant operators flip one flag.
- pin Bouncy Castle >= 1.84 — closes transitive 1.82 advisories docker-java-core 3.7.0 pulls bcpkix/bcprov/bcutil 1.82 (GHSA LDAP injection + risky-crypto). DependencyManagement pin forces 1.84 into the resolved tree so Dependabot alerts 187/188 close on next scan. Provided-scope only (DockerSandboxProvider path); no runtime fat-jar drift.
- malformed journal timestamp returns 400 (Spring parity) Previously returned 200 with an error-item array, masking client errors from caller and breaking Spring/Quarkus API parity. Now returns 400 with the error body, matching AtmosphereAdminEndpoint and Correctness Invariant #4.
- P0 reattach — enforce run ownership + route replay through filter chain Replay now refuses when the reconnecting caller's resolved userId does not match the run's registered userId (bearer-token cross-user leak); anonymous runs keep the open-mode carve-out so demo deployments still work. Every replay frame is routed through the broadcaster's BroadcastFilter chain so PiiRedactionFilter / ContentSafetyFilter apply identically to replay and live frames — a direct writer write previously bypassed them.
- reattach wire fidelity + terminal capture + MDC snapshot Replay now emits AiStreamMessage JSON frames matching the live path (frontend parser can handle replay and live identically); AiEndpointHandler routes timeout/exception terminals through capturingSession so buffered replay ends with an error envelope; CostAccountingSession snapshots tenant MDC at construction so Reactor-thread usage events don't collapse into default. Adds handoff-forwarding regression, strengthens Playwright assertions to pin JSON schema + error envelope.
- RunEventCapturingSession must forward handoff() to delegate The default StreamingSession.handoff throws UnsupportedOperationException, which the reattach capturing wrapper inherited — breaking orchestration-primitives handoff() calls that previously reached AiStreamingSession's agent-backed implementation.
- survive resteasy-reactive UT000048 on servlet proxy resteasy-reactive dispatches on Vert.x, so @context HttpServletRequest throws IllegalStateException: UT000048 on the admin write path. Swallow the exception (attributes cannot fire on Vert.x anyway) and read X-Atmosphere-Auth via @context HttpHeaders, which works on both transports.
- wire reattach producer — capture @prompt events into replay buffer RunEventCapturingSession mirrors every session.send / complete / error into the run's RunEventReplayBuffer; AiEndpointHandler installs it after registering the run so X-Atmosphere-Run-Id reconnects actually have events to replay. Closes the half-shipped reattach primitive — producer was missing even though the consumer (RunReattachSupport) was already wired.
- admin X-Atmosphere-Auth principal path + quarkus-chat fixture Fourth principal source validates the header against atmosphere.admin.auth.token via constant-time compare so Quarkus admin writes work without standing up Jakarta Security; sample fixture sets the env vars and Playwright now authenticates matching the Spring spec pattern.
- review pass 3 — parity delegation, PII hook accuracy, BOM-managed resteasy, ai.userId test Parity test pins delegation shape (doExecute → doExecuteWithHandle for SpringAI/LC4j/ADK) so a refactor to independent dispatch fails without restored admit. PII Javadoc points at the real PiiRedactionFilter / AiStreamBroadcastFilter — previously referenced a fictional per-token hook. resteasy-core at test scope drops its pin to inherit the quarkus-bom version. New ai.userId case rounds AdminResourceAuthzTest to 7 — all three principal sources covered. Non-blocking nits: dropped parity-test change-history Javadoc, explicit stubs instead of RETURNS_DEEP_STUBS, /* package */ marker on writeEnabled.
- v0.9 review second pass — parity-test teeth, quarkus auth chain, PII docs Parity test now scans specific method bodies (doExecute / doExecuteWithHandle / execute / executeWithHandle) with brace-balanced extraction, not file-level grep — dead helper references no longer satisfy. Quarkus guardWrite widened to the 3-source principal chain (SecurityContext → Atmosphere AuthInterceptor attribute → ai.userId). AdminProducer looks up a user-supplied ControlAuthorizer via CDI before falling back to REQUIRE_PRINCIPAL. New AdminResourceAuthzTest (6 cases) pins the gate across starters. PII class Javadoc split into Request (redact via Modify) vs Response (early termination via Block). FactRequest.agentId documents that custom @aiendpoint paths produce null.
- close v0.9-review findings — auth gap, dead SPI, parity test, javadoc drift Quarkus /api/admin/* now enforces the same triple-gate (feature flag → Principal → ControlAuthorizer) as Spring; default DENY_ALL via REQUIRE_PRINCIPAL. FactResolver.cacheHint removed (no consumer). FactRequest.agentId derived from the endpoint path template. RuntimeGatewayAdmissionParityTest verifies all 7 runtimes call admitThroughGateway at source level. FactResolver javadoc corrected (NoopFactResolver → DefaultFactResolver). PII response-path Block documented as early termination, not retroactive redaction.
- register HtmlEncoder as CodeQL XSS sanitizer Resolves 4 false-positive java/xss code-scanning alerts.
- bump Jetty 12.0.33, Tomcat 11.0.21, Kafka 3.9.2 Address 13 Dependabot security alerts (1 critical, 5 high, 3 medium).
🔧 Changed
- fix parallelInterruptsSiblings race on slow CI runners
- trigger on modules/ai + wasync + add workflow_dispatch
- CHANGELOG backfill for post-squash work + fix stale versions + read-auth docs CHANGELOG adds 11 Added and 3 Fixed subsections covering PII filter, cost-ceiling wire, reattach closure, admin read-auth, Quarkus parity, favicon, Flow tab, correctness coverage, e2e ...
Atmosphere 4.0.38
Immutable
release. Only release title and notes can be modified.
✨ Added
- reinstate PromptCacheDemoChat now that 4.0.37 is on Central
🐛 Fixed
- port CoordinationJournal bridge auto-config
- LocalAgentTransport resolves agents lazily to avoid startup race Candidate paths walked on every call; checkpoint-agent sample pulls atmosphere-a2a so @agent handlers land at a resolvable A2A path.
- stop processor-owned journals on framework shutdown
- propagate coordinator name as JournalingAgentFleet.coordinationId Canonical id replaces UUID so REST filter ?coordination=dispatch matches snapshots.
- bridge Spring CoordinationJournal beans into the processor CoordinatorProcessor.resolveJournal now reads framework properties first so spring-boot-starter can wire @bean journals; bridged journals are externally managed (no double start) and a new auto-config closes the durable HITL gap.
🔧 Changed
- coverage sweep round 3 — ~1,650 new unit tests across cpr/ai/a2a/mcp/channels 179 files / 23k lines targeting previously-untested records, interceptors, handlers, protocols, utility classes.
- use hashFiles for Playwright cache key to avoid ordering bug Previous node -p require(...) resolver needed node_modules which only exists after npm ci; every leg failed at Resolve Playwright version.
- cache Playwright browsers + unmap broken specs surfaced by split Cache eliminates Microsoft CDN 403 install flake (~12min on random legs). ai-cancel/semantic-kernel-chat/admin-coverage/orchestration-primitives stay unmapped until their latent bugs are fixed; checkpoint-agent moves under gap-coordinator.
- split slow matrix groups and map unmapped Playwright projects Long pole drops from 15.6min (gap-admin SB3) to ~8min; ai-cancel, checkpoint-agent, semantic-kernel-chat, orchestration-primitives, admin-coverage now run in CI.
- add 15 unit tests for A2A types, Task, AgentCard, listener adapter
- add 36 unit tests for memory strategies, cache, budget, interceptors
- add 65 unit tests for AiEvent, AiCapability, McpMethod, McpMessage, ToolCall
- add 77 unit tests for util, interceptor, websocket, and core adapters
- add 26 unit tests for inject package providers and adapter
- add 66 unit tests for A2A types, WebSocket protocol, and handler
- add 54 unit tests for MCP protocol, registry, handlers, interceptors
- add 118 unit tests for 8 untested core classes
- use forks pool to isolate test file module state Threads pool reuse allowed polyfill singletons to leak across files; forks eliminates the webtransport.test.ts order-dependent flake.
- add tests for StringEscapeUtils, QueryStringDecoder, HeartbeatInterceptor
- add semantic-kernel-chat spec and register projects
Full Changelog: atmosphere-4.0.37...atmosphere-4.0.38
Atmosphere 4.0.37
Immutable
release. Only release title and notes can be modified.
✨ Added
- 4.0.36 e2e coverage sweep + framework fixes from audit Ten gap specs, two samples, five framework fixes (checkpoint/cache/binary/capability/HITL).
- rewrite cloned sample pom.xml for standalone compile Drops relativePath so atmosphere-project parent resolves from Maven Central, pins SNAPSHOT to release, skips repo-local checkstyle/pmd.
- runtime capability honesty pass — 7 runtimes declare honest capabilities
- clone samples for 'atmosphere new' instead of mustache templates Deletes AtmosphereInit.java + handler mustache + bash fallback; compose generator untouched.
🐛 Fixed
- drop PromptCacheDemoChat (requires 4.0.37-SNAPSHOT APIs) Sample demo used AiPipeline.setDefaultCachePolicy which is 4.0.37-only; sparse-clone against 4.0.36 parent broke ai-chat standalone compile. Framework cache-hit signal stays tested in ai-cache.spec.ts.
- await broadcaster subscribers in WAsync long-polling test Replaces brittle 10x5s retry loop with a subscriber-count precondition to eliminate the CI flake on slow runners.
- drop setDefaultCachePolicy from cloned ai-chat sample Method is 4.0.37-SNAPSHOT-only; sparse-clone compile against 4.0.36 parent fails at step 6.
- drop standalone-compile assertions from e2e runtime tests Clone-from-sample pom.xml inherits from the reactor parent; assert structure only. Also fix stale a2a-agent→agent template reference.
- align test-cli.sh + npx wrapper with sample-clone 'atmosphere new' Rewrites sections 12/12b/13 for the sparse-clone path; npx becomes a thin delegating shim.
- LC4j drops post-cancel errors; Settable records first-writer terminal reason RetryPolicy.isInheritSentinel formalises DEFAULT-as-inheritance contract
- use repository-dispatch + SITE_DISPATCH_TOKEN for docs sync Rewrites the atmosphere.github.io sync step to mirror the existing trigger-site-rebuild.yml pattern: fire a repository_dispatch event with the version in client_payload, let the sibling repo's own sync-version.yml workflow run its update script with its own GITHUB_TOKEN. No cross-repo cloning, no new token — reuses SITE_DISPATCH_TOKEN which already has dispatch scope on atmosphere.github.io.
- sync atmosphere.github.io sibling repo after Maven Central push New step in release-maven job clones atmosphere.github.io with DOCS_SITE_TOKEN, runs its own scripts/update-doc-versions.sh, and pushes. The sibling repo shipped 4.0.36 with 23 stale SNAPSHOT references and a 6-runtime Hero stat because the release workflow never touched it — this closes the cross-repo automation gap. When DOCS_SITE_TOKEN is unset the step emits a ::warning:: and exits 0 so missing auth is visible in CI instead of silent.
- catch two stale version patterns the doc-version script missed README.md "Current release: `X.Y.Z`" inline-code pattern and cli/sdkman/SUBMISSION.md "publish.sh X.Y.Z" example command both slipped past the tag-only and json-key regexes — 4.0.36 shipped with 4.0.36-SNAPSHOT and 4.0.35 respectively in these files. Adds two new sections to update-doc-versions.sh so the release-4x.yml workflow catches them next release, and backfills the current state to 4.0.36.
- paid nightly real-LLM workflow must build integration-tests module Same ClassNotFoundException on AiFeatureTestServer as the Ollama workflow had — the -pl target only installed modules/ai and modules/ai-test, but the Playwright fixture spawns exec:java inside modules/integration-tests which needs its own classes compiled. Mirror the Ollama workflow fix: -pl modules/integration-tests with -am pulls all transitive dependencies.
🔧 Changed
- drop hardcoded atmosphere SNAPSHOT version from README Parenthetical auto-rots on every release; update-doc-versions.sh only rewrites JAR-artifact patterns, not prose references.
- update README/CHANGELOG/AGENTS for sample-clone atmosphere new Nine templates, standalone compile from Central parent, npx thin shim, samples/README points at the new flow.
- rewrite 4.0.36 CHANGELOG with verified claims + add hallucination rule
- pin runtime capability declarations to prevent docs drift
- add 4.0.36 CHANGELOG entry covering Waves 1-6 + fixes
- bump svelte from 5.55.0 to 5.55.2 in /atmosphere.js
- bump @vitest/ui from 4.1.2 to 4.1.4 in /atmosphere.js
- bump actions/checkout from 4 to 6
- bump actions/upload-artifact from 4 to 7
- bump org.apache.maven.plugins:maven-jxr-plugin
- bump org.apache.maven.plugins:maven-shade-plugin
- bump kotlinx.coroutines.version from 1.10.1 to 1.10.2
- bump version to 4.0.36
- prepare for next development iteration 4.0.37-SNAPSHOT
Full Changelog: atmosphere-4.0.36...atmosphere-4.0.37