Releases: Atmosphere/atmosphere
Release list
Atmosphere 4.0.59
Added
- screen long-term-memory writes for injection by default harden coverage evidence gate; relabel opt-in OWASP/compliance rows honestly
Changed
- bump Spring Boot, LangChain4j, Embabel, ADK, Spring AI Alibaba Embabel 0.5.0 adds EmbeddingService.pricingModel; test stub reports ALL_YOU_CAN_EAT.
- record coverage-overstatement drift + self-referential-gate rule
- add obsidian skills + atmosphere-vault docs routing
- align capability comment, sample runtime defaults, and XSS skip note with reality
- add workflow_dispatch to Core and Doc Version Guard
- bump version to 4.0.58
- prepare for next development iteration 4.0.59-SNAPSHOT
Atmosphere 4.0.58
Added
- default-on RAG injection-safety wiring across runtimes Screens retrieved RAG documents for indirect prompt injection before the LLM (fail-closed RULE_BASED/DROP); wired for @aiendpoint, Spring Boot 3/4, and Quarkus with console runtime-truth and a poisoned-doc sample.
Fixed
- pin rag-chat getting-started to released 4.0.57
Changed
- stage doc sweep and fail-fast on doc-version drift before publish
- bump version to 4.0.57
- prepare next development version 5.0.35
- prepare for next development iteration 4.0.58-SNAPSHOT
Atmosphere 4.0.57
Added
- provider-native structured output across 9 runtimes
Fixed
- guard expo stats render against undefined token metrics
- unblock MCP Apps sandbox CSP and stop optional-tab 404 probes
- expose analyzer as @AgentSkill so approve happy path works
Changed
- expect analyzer's headless A2A registration
- note path-scoped native structured output for Spring AI, Koog, ADK
- enforce Atmosphere doc matches the released version
- retry fetch+rebase+push so a lost race can't red a green release
- apt-get update before installing libxml2-utils so the delisted stale version isn't fetched
- rebase before pushing JS dev-bump so it can't lose the race to the Maven job
- prepare next development version 5.0.34
- bump version to 4.0.56
- prepare for next development iteration 4.0.57-SNAPSHOT
Atmosphere 4.0.56
Added
- guardrails + OBO + cost + run-registry AI bean parity with SB4
- config-driven AI routing parity with the SB4 starter
- install governance decision log out-of-box for the queryable audit trail
- warn on unauthenticated A2A endpoint + advertise declared security scheme
- make spring-boot-agui-chat a real AG-UI agent via the native bridge @agent + @prompt + real @aitool through session.stream() (demo fallback when no key); AiEvent->AgUiEvent over /atmosphere/agent/{name}/agui; replaces the scripted controller
- config-driven cost/latency/model routing rules in atmosphere.ai.routing extends F3a (content-only); compose order content->model->cost->latency; off-by-default + content behavior byte-identical
- emit experimental OTel GenAI semconv span attributes via GenAiTracer gen_ai.usage./request+response.model/operation/provider on the live span; fixes provider Runtime-Truth bug (real runtime name, not hardcoded atmosphere); legacy ai.tokens. byte-identical
- add --routing flag to 'atmosphere new' for routing config scaffolding injects a commented atmosphere.ai.routing.* block into AI-template application.yml; off by default, rejected for non-AI templates
- wire real LongTermMemory cross-session recall into personal-assistant InMemoryLongTermMemory + LongTermMemoryInterceptor on the UpstreamMcpAgent @aiendpoint (no-arg interceptor + static holder pattern); makes the memory-bearing claim true
- opt-in RoutingLlmClient via atmosphere.ai.routing.enabled autoconfig wraps the resolved client with content-based routing rules; adds AiConfig.installClient seam; default-off byte-identical
- wire ApiKeyResolver into anthropic/cohere with provider env-var support renamed from CredentialResolver (clashed with AiGateway.CredentialResolver); per-provider precedence reads ANTHROPIC_API_KEY/COHERE_API_KEY, no cross-provider key leak
- add generation params (temperature/maxTokens/topP/stop) to LlmSettings wired to the wire for built-in/anthropic/spring-ai/langchain4j; honest per-runtime matrix in README; empty=byte-identical
- explicit prompt-cache-key tri-state replaces base-URL sniffing PromptCacheKeyMode AUTO/ENABLED/DISABLED on LlmSettings; AUTO preserves current per-path heuristics byte-for-byte
- store resolved apiKey on LlmSettings so apiKey() works for any client removes the OpenAiCompatibleClient-only instanceof; 4-arg constructor preserves old behavior; adds CredentialResolver precedence primitive
- provider-neutral model tier aliases (fast/frontier/reasoning) ModelTier resolves tier tokens to a concrete model by active provider; raw model strings pass through unchanged
- add provider-neutral configureNativeClient(Object) to AbstractAgentRuntime type-checked against nativeClientClassName(); provider-typed static setters remain the primary wiring path
Fixed
- reachable agent bridge + keep response open during AG-UI streaming AgUiAgentBridge made public (cross-module reflective invoke from agui handler); handlePost joins the run thread so virtual-thread SSE writes don't hit a recycled response — fixes the agui-chat demo+UI e2e (only RUN_STARTED was reaching the wire)
- converge AUTO prompt-cache-key to one default-deny allow-list built-in and framework runtimes share CacheHint.endpointAcceptsPromptCacheKey; framework no longer emits on unknown hosts under AUTO (force via PromptCacheKeyMode.ENABLED)
- honor per-request ToolLoopPolicy in anthropic/cohere/langchain4j tool loops they hardcoded a 5-round cap and ignored maxIterations/onMaxIterations; now route through the shared ToolLoopGuard like the built-in (default behavior unchanged)
- make default model configurable, default claude-sonnet-4-6 adds anthropic.model system property; per-request and AiConfig models still win over the fallback
- version-bump touches only Atmosphere deps; regen SKILLCARDs
- repair rag-chat/mcp-server/browser-agent + SB3 Tomcat + stream errors
- restore real third-party dep versions clobbered by 4.0.x bump
Changed
- pin deny-policy refusal on A2A and AG-UI bridges
- fail-closed Maven Central pre-check guards against version burn
- e2e proving config-driven routing is consumed on the wire
- attribute GenAI "experimental" to the OpenTelemetry spec, not the emitter GenAiTracer/MetricsCapturingSession Javadoc + README make clear the implementation is production code; only the upstream OTel GenAI convention is experimental
- document atmosphere new --routing flag and correct agui-chat sample row agui-chat is now a real @agent (LLM + @aitool over the AG-UI native bridge), not scripted
- consolidate per-model-call observability into ModelCallScope replaces duplicated fireModelStart/End/Error + timing across 9 adapters and 2 Kotlin runtimes; event count/ordering unchanged (ADK start-time aligned to dispatch)
- unify tool-call accumulator across built-in, anthropic, cohere shared ToolCallAccumulator gains argumentsAsMap(); deletes the two private copies; built-in parse path unchanged
- extract AbstractSseLlmClient shared by Anthropic and Cohere clients collapses ~268 lines of duplicated HTTP/SSE plumbing (header filter, snippet read, data: loop, tool-schema) into one base; wire behavior byte-identical (black-box suites unchanged)
- add TokenUsage.fromCounts and migrate adapter usage translation collapses 11 hand-rolled null-guard/total-fallback sites; 2 sites now compute total=input+output instead of 0 when the provider omits total (regression-tested)
- hoist models() default into AbstractAgentRuntime removes 9 byte-identical adapter overrides; koog (distinct logic) and the interface default unchanged
- fix cancel-test race by awaiting worker interrupt observation worker records the interrupt asynchronously; wait on a latch instead of reading the flag right after whenDone()
- correct AI doc/sample drift vs verified runtime capabilities embeddings 5->7 runtimes, TOOL_CALL_DELTA Built-in+Cohere, ai.md classpath table, agui relabel, samples.json reattach
- bound playwright install with timeout to prevent multi-hour hangs
- both-layer regressions for the sweep failures (JUnit + Playwright)
- sync version stamp to 4.0.56-SNAPSHOT
- deep-link concept tables to docs site; fix verifier count
- bump version to 4.0.55
- prepare next development version 5.0.33
- prepare for next development iteration 4.0.56-SNAPSHOT
Atmosphere 4.0.55
Added
- Static verifier over MCP. The plan-and-verify ("Guardians") stack is
reachable as read-only MCP tools whenatmosphere-verifieris on the
classpath:atmosphere_verifier_summary,atmosphere_verifier_examples, and
atmosphere_verifier_check. The check tool plans a goal and runs every
verifier over the resulting plan without executing it (status
verified/refusedwith the per-verifier violations); the mutating
verify-then-execute path stays behind the admin write gate.
Fixed
- wasync: a user
close()is no longer resurrected by a late OPEN event —
a close requested before the transport finished opening is now honored when
the OPEN arrives, instead of reviving the connection. - Documentation accuracy sweep — corrected the Z3 binding version (4.14.0)
andSmtCheckerpriority (200); aligned ADK / Semantic Kernel / Alibaba
versions, crewai test counts, and the ms-governance policy name; fixed the
embedded-jetty client type, the admin-bundle default authorizer, and
runtime-truth claims in the embabel / agentscope / coding-agent docs;
corrected third-party dependency versions and citations.
Changed
- CI doc-drift gates — fact/enumeration checks, link-rot detection, and
sibling-site (atmosphere.github.io) verification, plus anatmosphere-skills
link-checker allowlist.
Atmosphere 4.0.54
Added
- Rich human-in-the-loop approval payloads. A reviewer can now resolve a tool
approval with more than approve/deny: approve-with-edited-arguments (the
tool runs with the reviewer's arguments) or respond (the reviewer answers on
the tool's behalf — structured JSON or free-form text — and the tool does not
run). Wire protocol:/__approval/<id>/approve {"arguments":{…}}and
/__approval/<id>/respond {…}. Fail-safe: a malformed edited-args payload denies.
Session-scoped in-memory (not crash-durable). The legacy boolean resolution path
is unchanged. - Eval flywheel.
JournalDatasetPromoterturns a recordedCoordinationJournal
interaction into anEvalCasedataset row (trace→dataset), andSampledLiveScorer
grades a configurable fraction of live turns intoEvalRunverdicts (online
scoring). Both are wired intoEvalControllerwith admin REST routes
(/api/admin/evals/dataset,/dataset/promote,/score). - OAuth on-behalf-of credential vault.
OAuthOnBehalfOfCredentialStoreis a
concreteCredentialStorethat performs an RFC 8693 token exchange — swapping a
user's stored subject token for a short-lived access token scoped to a downstream
tool, so an agent calls external APIs as the user. Fail-closed (no token →
no fallback credential), token-cached until expiry. Opt in with
atmosphere.ai.identity.oauth-obo.enabled=true. - Realtime voice bridge.
VoiceBridge+ theRealtimeVoiceProviderSPI bridge
client audio frames over the existing WebSocket broadcaster to a speech-to-speech
provider, fanning synthesized audio (Content.Audio) and transcripts back to the
client. A dependency-freeLoopbackVoiceProviderships as the runnable reference
(echoes audio); OpenAI Realtime / Gemini Live providers implement the same SPI. - Content-safety moderation guardrail.
ModerationGuardrailblocks turns
whose request and/or response is flagged for hate / harassment / self-harm /
sexual / violence / illicit content, on the existing fail-closed guardrail
pipeline. Pluggable detector: zero-depRuleBasedModerationDetector(default)
or cross-runtimeLlmModerationDetector. Fail-closed by default (a detector
outage blocks the turn;.failOpen()is the explicit opt-out). Opt in with
atmosphere.ai.guardrails.moderation.enabled=true
(...detector=llmfor the model tier). - Self-healing structured output.
@AiEndpoint(structuredOutputRetries = N)
(or theai.structured.retryrequest-metadata key on theAiPipelinepath)
re-prompts the model with the schema-validation error as feedback when a typed
response fails to parse, up toNextra attempts, then fails closed. Works
identically on the websocket and channel-bridge paths. - OpenAPI → governed tools.
OpenApiToolImporterturns an OpenAPI 3.x spec
(JSON or YAML, with local$refresolution) intoToolDefinitions whose
executor performs the HTTP call. The imported operations ride the same
policy-admission and plan-and-verify path as hand-written@AiToolmethods;
approvalForWritesroutes mutating verbs through the HITL gate. - MCP client depth.
McpClientOptionsadds per-server tool filtering and
display-only renaming (the executor still calls the server's original tool
name), plus elicitation/sampling callback handlers advertised during
initialize.McpServerRegistryaggregates several servers into one
collision-free tool list (first-wins) and owns their lifecycle.
Atmosphere 4.0.52
Added
- MCP authorization now validates bearer tokens end-to-end. A request is authenticated
when either a servlet resource-server filter set the request principal (e.g. Spring
Securityoauth2ResourceServer) or a configuredTokenValidatoraccepts the
Authorization: Bearertoken (loaded fromorg.atmosphere.auth.tokenValidator, validated
byatmosphere-mcpitself — no framework-specific wiring). The RFC 9728 metadata is now
served on the agent registration path too. Proven end-to-end on the embedded server,
Spring Boot, and Quarkus (JVM). Thespring-boot-mcp-serversample gains an opt-inauth
profile (default off) demonstrating it. - MCP runs on Quarkus.
@Agent-based MCP endpoints now register under the Quarkus
extension (the build scan recognizes@Agentand indexes the optional
atmosphere-agent/atmosphere-mcpjars when an@Agentclass is present). JVM mode;
native image is not yet supported for@Agent-based MCP.
Tested
- Added a stateless
2026-07-28round-robin end-to-end test (twotools/callwith no
session header both succeed, plusserver/discoverandMcp-Methodmismatch) in
modules/integration-tests, proving the no-session-affinity claim over live HTTP.
Atmosphere 4.0.51
Added
- MCP
2026-07-28release candidate — the largest MCP revision since launch,
implemented as a stateless dialect that coexists with the session-based protocol
(2024-11-05through2025-11-25). The dialect is selected per request (the client
carries the protocol version inparams._metaor callsserver/discover), so existing
clients are unaffected. Stateless core has noMcp-Session-Idand noinitialize
handshake, so the server runs behind a plain round-robin load balancer with no session
affinity. - MCP operability —
Mcp-Method/Mcp-Namerouting headers (validated against the
body),ttlMs+cacheScopecache metadata ontools/list/resources/list/
resources/read, and W3C Trace Context (traceparent/tracestate/baggage) read
from_metaand bridged into the OpenTelemetry span. - MCP Tasks extension (
io.modelcontextprotocol/tasks) and multi-round-trip input —
@McpTool(longRunning = true)returns a task handle polled viatasks/get, and the
stateless dialect can returnInputRequiredResultwith a base64requestStateto
request more input mid-call and resume on any instance. - JSON Schema 2020-12 dialect (
$schema) on generated tool input schemas, and a
standardized resource-not-found error (-32602) on the stateless dialect. - MCP Apps (SEP-1865) —
@McpTool(uiResource = "ui://…")plus a
text/html;profile=mcp-appresource makes a tool an MCP App. The Atmosphere console is a
working host: it renders the app in a sandboxed iframe, runs a bidirectional App
Bridge (apps call server tools through the host under the policy gateway; the host
lists and calls the app's ownappCapabilities.tools), and uses a separate-origin
sandbox proxy for isolation (atmosphere.mcp-sandbox-origin, with alocalhost↔
127.0.0.1dev fallback, otherwise an opaque-origin direct sandbox). - MCP authorization — the server acts as an OAuth 2.0 Resource Server: RFC 9728
protected-resource metadata at/.well-known/oauth-protected-resourceand a401+
WWW-Authenticatechallenge for unauthenticated requests. Token validation is delegated
to the host framework (Spring Security resource server /quarkus-oidc); opt in via the
org.atmosphere.mcp.auth.*init parameters.
Atmosphere 4.0.50
Removed
- Pruned dead/unwired internal classes found during a release-readiness audit —
none was documented, advertised, or reachable from a user code path:
McpWebSocketHandler(superseded byMcpHandler's direct WebSocket-frame
handling),AgUiSession(superseded byResourceAgUiStreamingSession),
AiCoalescingBroadcasterCache(a delegate-onlyBroadcasterCachethat the
no-arg reflective cache-wiring path cannot instantiate),AdkArtifactBridge,
AdkCompactionBridge,AtmosphereRequestBridge,AtmosphereResponseBridge,
the channelsAuditLoggingFilter(never registered as a bean, so it never
reached the filter chain), the unwiredGrpcProtocolBridge, and the A2A
ListTaskPushNotificationConfigsResponseDTO (the
ListTaskPushNotificationConfigsmethod returnsERROR_PUSH_NOT_SUPPORTED,
so the response type was never constructed).
Fixed
ToolBridgeUtils.findUnescapedQuoteno longer advances the scan index past
the end of the string when malformed tool-call JSON ends in a lone backslash
— the escaped-character skip is now bounds-checked (boundary safety,
Correctness Invariant #4). Regression test added.
Added
-
Interactions API (
org.atmosphere.interactions, artifactatmosphere-interactions)
— a stateful agent-turn resource layered above theAgentRuntimeSPI, so it
works for every adapter with no per-runtime code. AnInteractioncarries a
stable id, a durablesteps[]event log, and chains turns via
previousInteractionId(the server holds history; the client does not resend
it). Turns run synchronously or in the background (background=true
returns aRUNNINGrecord immediately and is retrievable after a disconnect),
andstore=falsestreams without persisting. The starter exposes the resource
overPOST /api/interactions,POST /api/interactions/{id}/continue,
GET /api/interactions/{id},GET /api/interactions,
POST /api/interactions/{id}/cancel, andDELETE /api/interactions/{id}—
every mutating route is default-deny behindatmosphere.interactions.http-write-enabled
plus an authenticated principal (Correctness Invariant #6). TwoInteractionStore
backends ship:InMemoryInteractionStore(default) andSqliteInteractionStore;
the SPI is pluggable for others.atmosphere.jsgains a typedInteractionsClient
(atmosphere.js/interactions) covering the REST surface pluspollUntilTerminal
/watchhelpers. -
Interactions live streaming — a background interaction now streams its
durablesteps[]to a subscribed browser as they are produced, over the
Atmosphere transport (/atmosphere/interactions-stream?id=<id>, WebSocket/SSE).
On connect the handler replays the steps captured so far (late-joiner catch-up,
deduped client-side by sequence), then pushes each new step live and a terminal
frame on completion; ownership is enforced per-interaction, same scope as the
REST read.InteractionsClient.subscribe(id, handlers)bridges it on the client
and the Atmosphere Console's Interactions tab renders the live step timeline.
AnAtmosphereInterceptorresolves the principal for the stream socket so
ownership holds across all transports (a servlet filter's request attribute does
not survive the WebSocket upgrade). Demonstrated inspring-boot-coding-agent
andspring-boot-multi-agent-startup-team. -
ToolKind+@AiTool(kind = …)— tools declare a behavioural category
(EDIT,READ,EXECUTE,NETWORK,DELETE,OTHER; defaultOTHER).
This makesPermissionMode.ACCEPT_EDITSa real behaviour instead of a
DEFAULTalias: it now auto-approves a tool's own@RequiresApproval
prompt whenkind == EDIT, while every other tool still routes through the
per-tool approval gate. The classification is compile-time author metadata
(not runtime caller-asserted intent), the defaultOTHERkeeps the approval
posture exactly as restrictive as before, and the relaxation never overrides
an operator-configuredToolPermissionPolicyDENY/CONFIRMor aDenyAll
policy.ToolExecutionHelperAcceptEditsTestpins all four cases. -
Code-as-action sandbox (
org.atmosphere.ai.code) — acode_exectool that
lets a model accomplish tasks by writing a block of code (bash / JavaScript /
Python) instead of negotiating many fine-grained tool calls. Each session gets
an isolated, ephemeral container (CodeSandboxSPI,ContainerCodeSandboxover
Docker/Podman) with hardening applied —--network noneby default, non-root,
--cap-drop ALL,--security-opt no-new-privileges, read-only rootfs + a bounded
writable workspace, and memory/cpu/pid caps — provisioned lazily on first use and
torn down on every terminal path via the newStreamingSession.onTerminate(AutoCloseable)
primitive. Default-deny: code execution is off unless
org.atmosphere.ai.code.enabled=trueand a container engine is confirmed present
at runtime (Correctness Invariant #5); the tool is registered into@AiEndpoint
dispatch only then, with the tool-loop ceiling lifted to 25 write→run→observe
rounds. Each round streams anAiEvent.AgentStepplus any screenshots the code
produced, rendered inline in the Console as markdown data-URI images. New
samples/spring-boot-browser-agentdemonstrates it (Cohere-backed, requires
Docker): the agent drives a headless browser with Playwright and you watch the
screenshots arrive live.
Changed
ai-policy-regoandai-policy-cedarnow ship a
META-INF/services/org.atmosphere.ai.governance.PolicyParserregistration,
so Rego and Cedar policy artifacts are auto-discovered byServiceLoader
the same way YAML always has been — no programmatic parser wiring required.
Safe because both parsers have lazy no-arg constructors (theopa/cedar
binary is only touched at evaluation, and parse failure is already
fail-closed). The Kafka/Postgres audit sinks are deliberately left on
programmaticGovernanceDecisionLog.addSink()wiring: they need a live
broker / JDBC connection, so auto-activating them on classpath presence
would advertise capability that cannot run (Runtime-Truth, Correctness
Invariant #5).RegoPolicyParserTest/CedarPolicyParserTestpin the
discovery.- Four new pre-push drift-prevention gates, each closing a class the
.harness/drift-log.mdhad recorded but left un-automated, wired into
scripts/pre-push-validate.shTier-1:
validate-runtime-overlay-coverage.sh(every snapshot runtime must have a
CLI overlay and abom/pom.xmlartifact — drift #59);
validate-dangling-doc-comments.sh(parse-onlyjavac -Xlint:dangling-doc-comments
under a JDK ≥ 23 to catch detached Javadoc locally, not only on the Native
Image lane — drift #80);
validate-doc-version-alignment.sh(third-party dependency versions in
Markdown must match the pinnedpom.xml/package.json— drift #12/#18/#75);
andvalidate-doc-symbols.sh(annotation references in Markdown must resolve
to an in-tree declaration or a curated external allowlist — drift #72). Two of the
gates caught a pre-existing drift on first run:atmosphere-semantic-kernel
was missing frombom/pom.xml(now added), andmodules/langchain4j/README.md
named LangChain4j 1.12.2 while the pom pins 1.15.0 (now corrected). CLI overlay
coverage was also extended to the three native runtimes (anthropic,cohere,
crewai) incli-e2e.ymlpath filters and thetest-cli.shscaffold+compile
matrix.
Atmosphere 4.0.49
Added
-
atmosphere-crewai—AgentRuntimefor the
CrewAI multi-agent framework via an
out-of-process Python sidecar. First non-Java runtime adapter in the
project; the boundary isHTTP + SSEfor the request stream plus a
loopbackToolCallbackServerfor Java→Python tool RPC. Pins 9
capabilities (TEXT_STREAMING,TOKEN_USAGE,AGENT_ORCHESTRATION,
CANCELLATION,TOOL_CALLING,SYSTEM_PROMPT,
STRUCTURED_OUTPUT,TOOL_APPROVAL,PER_REQUEST_RETRY) via
CrewAiRuntimeContractTest+ the capability snapshot (which now
enumerates 12 runtimes). Like every other runtime,isAvailable()
is config-gated — requiresATMOSPHERE_CREWAI_SIDECAR_URLpointing
at a running sidecar that responds OK toGET /health. -
modules/crewai/sidecar/— companion Python package
atmosphere-crewai-bridge(FastAPI + uvicorn + crewai 1.14)
speaking the documented wire protocol. Materialises Java
ToolDefinitions ascrewai.tools.BaseToolsubclasses via
pydantic.create_model, injects them into agents, and threads
context.systemPrompt()into each agent'sbackstoryinside a
delimited block. Ships with a workingexamples/ollama_crew.py
factory that targetsqwen2.5:0.5b(no API key required). -
CLI runtime overlay (
cli/runtime-overlays.json) forcrewai, so
atmosphere new my-app --template ai-chat --runtime crewai
scaffolds with the dependency wired and the sidecar setup
documented inline. -
End-to-end validation captured at
.harness/crewai-e2e-success.png: chrome-devtools drove
/atmosphere/console/against a real Ollama-backed crew; the
browser rendered 25 tokens at 46.8 tok/s through the full chain
WebSocket → @AiEndpoint(runtime=crewai) → HttpSseSidecarClient → atmosphere-crewai-bridge → crewai 1.14 → litellm → Ollama. Console
zero errors, sidecar log confirmsPOST /v1/chat/completions HTTP/1.1 200 OKagainst the local Ollama instance. -
modules/coordinator/journal— event-sourced execution log for
the coordinator. Layers four additive pieces onto the existing
CoordinationJournalSPI without breaking any of the 94 existing
new CoordinationEvent.*call sites across coordinator / admin /
checkpoint / integration-tests / samples:EventEnvelope(eventId, parentEventId, event)+ default-method
recordEnveloped/retrieveEnvelopedonCoordinationJournal.
JournalingAgentFleetthreads parent IDs through every dispatch
path (parallel/pipeline/route/proxy.call/
callAsync/stream):CoordinationStarted→AgentDispatched
→AgentCompleted/AgentFailed→AgentEvaluated. Legacy
record(event)callers continue working — events are wrapped as
root envelopes with no parent.CoordinationProjection.from(journal, coordinationId)— pure
read-only causal DAG built fromretrieveEnveloped. Exposes
roots(),children(eventId),walk(visitor),agents(),
failedDispatches(),evaluations(). No execution, no LLM, no
side effects.FileCoordinationJournal(Path)— append-only NDJSON file backend,
one JSON object per line. Replays onstart()into an in-memory
index for queries; tolerates a truncated final line from a JVM
kill mid-append (logs and skips). Single-writer locked appends;
polymorphic ser/deser of the sealedCoordinationEventhierarchy
via a Jackson 3 mix-in so the event records stay annotation-free.CoordinationFork+ newForkCreatedevent variant — what-if
branching primitive.fork.from(coordId, eventId).reason(...).with(altCall).execute(fleet)
creates a new coordination id (or accepts an explicit one),
records aForkCreatedenvelope linking back to the parent event,
and runs the alternate dispatch via
JournalingAgentFleet.withCoordinationId(...). The parent
coordination is immutable; the fork is a peer with its own future.
Pre-flight check rejects unknownparentEventIdwith a fast
IllegalArgumentException.
Backed by 38 tests in
modules/coordinator/src/test/java/.../journal/
including a three-process integration test that runs a parallel
coordination, restart-replays from disk, projects the DAG, forks an
alternate, restart-replays again, and verifies both the original and
the forked branch survive across two simulated JVM kills.
modules/coordinator/README.mddocuments the new surface. -
Cohere
TOOL_CALL_DELTAstreaming capability (3327425d50).
CohereChatClient.handleToolCallDeltasurfaces incremental tool-call
argument fragments as they arrive, andCohereAgentRuntime
(line 269) now declaresTOOL_CALL_DELTA. The same honesty pass
removedPROMPT_CACHINGfrom Cohere — the v2 API exposes no
prompt-cache control, so advertising it was Runtime-Truth drift; the
capability snapshot was re-pinned accordingly. -
Quarkus extension integration parity: five optional surfaces, each
gated on classpath presence and covered by a dedicated build-step
test (3327425d50).AtmosphereProcessorregisters Cache, Health
(HealthBuildItem), Micrometer metrics
(AtmosphereMetricsProducer), OpenTelemetry tracing
(AtmosphereTracingProducer), and governance metrics
(AtmosphereGovernanceMetricsProducer) producers — see
AtmosphereProcessor.java:432-510and the
Atmosphere{Cache,Health,Metrics,Tracing,GovernanceMetrics}BuildStepTest
suite. -
modules/quarkus-grpc— Quarkus gRPC bridge extension (runtime+
deploymentsubmodules) (3327425d50). -
scripts/validate-no-beta-on-main.sh— push-time gate enforcing the
release-frequency rule: pre-GA escape-hatch framing (beta annotations,
hourglass deferral markers, phased planning labels, or roadmap-deferral
prose) introduced relative toorigin/mainfails the build, somain
stays release-ready (3327425d50).
Changed
- Bumped JetBrains Koog
0.8.0 → 1.0.0(4685a844bb, root pom
koog.version) — Koog's first GA. The adapter configures via
Koog 1.0's stableOpenAILLMClient/MultiLLMPromptExecutor
(AtmosphereKoogAutoConfiguration.kt); the full Koog capability set
(VISION,AUDIO,MULTI_MODAL,PROMPT_CACHING,TOOL_CALLING,
TOOL_APPROVAL, …) is unchanged and re-pinned by
KoogRuntimeContractTest+ the capability snapshot. - Bumped
langchain4j.version1.14.0 → 1.15.0(abd774f68d),
logback-version1.5.25 → 1.5.32(58f2e6d373), and
commons-lang33.18.0 → 3.20.0(8dea5788ac).
Fixed
HttpSseSidecarClientnow pinsHttpClient.Version.HTTP_1_1. The
JDK'sjava.net.http.HttpClientdefaults to HTTP/2 for plain HTTP
and attempts anUpgrade: h2cnegotiation; uvicorn (the FastAPI
host for the CrewAI sidecar) does not implement the h2c upgrade and
the resulting request lands with an empty body, which FastAPI
rejects as422 Field required, loc=["body"], input=null. The
bridge-testFakeSidecar(a
com.sun.net.httpserver.HttpServer) tolerated the upgrade preamble
and parsed the body anyway, so the bug only surfaced under real
uvicorn — exactly the gapfeedback_chrome_devtools_only.mdwarns
about. Added a regression test
(CrewAiAgentRuntimeBridgeTest.httpClient_pinnedToHttp11) that
reflects into the client and asserts the version, so a future "just
use the defaultHttpClient" refactor breaks the build before it
breaks production. Drift recorded as.harness/drift-log.md#64.- Koog runtime reaches Gemini via Google's OpenAI-compatible base
URL (87aa2cc824). Koog 1.0's native Google client ships only on a
JVM-incompatible path, soAtmosphereKoogAutoConfigurationpoints the
stableOpenAILLMClientat any OpenAI-compatible endpoint when
atmosphere.koog.base-url/LLM_BASE_URLis set (e.g.
https://generativelanguage.googleapis.com/v1beta/openaifor
gemini-2.5-flash). Regression-gated by
AtmosphereKoogAutoConfigurationTest. Drift recorded as
.harness/drift-log.md#77 — the0.8.0 → 1.0.0bump had been
reported done on CI alone, which hid the dropped-Gemini regression. - Spring Boot JDK 26 long-term-memory disconnect hang resolved via
an idle-reaper fallback (b2e9e09e71).
LongTermMemoryHttpE2eTest's disconnect path intermittently hung on
the JDK 26 lane because the WebSocket-close →onDisconnectlifecycle
could be dropped under fork contention; an
IdleResourceInterceptor-based reaper (platform-thread scheduler,
maxInactiveActivity=5000) now fires the disconnect lifecycle
independently, so suspended resources are reaped and facts persisted
even when the close frame is lost. Drift recorded as
.harness/drift-log.md#78–#79 — an earlier 60s → 120s await bump was
ineffective (a timeout cannot fix a hang).
Security
- Bumped
tomcat-embed-core11.0.21 → 11.0.22(root pom
tomcat-versionproperty) to close 7 Dependabot advisories — 3
critical (security-constraint bypassGHSA-5m62-pw8w-7w9f,
digest-auth bypassGHSA-h6fc-48rj-7qqh, HTTP/2 header validation
GHSA-r29c-68gh-xp6x), 3 high (LockOutRealm case-sensitivity
GHSA-5mp6-jrq3-r938, WebSocket auth-header exposure
GHSA-fv25-8xcx-gqjc, WebDAVLOCK/PROPFINDunbounded read
GHSA-gx5v-xp9w-j4cg), and 1 low (AJP secret non-constant-time
compareGHSA-9m89-8frq-c98c). The pin stays scoped to
tomcat-embed-core;tomcat-embed-elandtomcat-embed-websocket
continue to follow each Spring Boot BOM (3.5.x keeps the 10.1.x
line, 4.0.x stays on 11.0.x). - Bumped
protobufjs7.5.6 → 7.5.8in
modules/integration-tests/package.json+ lockfile to close
GHSA-jggg-4jg4-v7c6. - Dismissed 3 remaining open Dependabot alerts that have no in-tree
fix path. Twoorg.json:jsonalerts (GHSA-3vqj-43w4-2q58,
GHSA-4jq9-2xhw-jpx7) citedmodules/runtime/pom.xml— a manifest
that no longer exists;org.json:jsonwas removed reactor-wide in
commit `...