Releases: Atmosphere/atmosphere
Releases · Atmosphere/atmosphere
Release list
Atmosphere 4.0.48
Immutable
release. Only release title and notes can be modified.
Added
- CLI runtime overlays for
anthropicandcohere
(cli/runtime-overlays.json). Both runtimes had been shipped in
modules/and documented in the top-level README —atmosphere-anthropic
since 2026-05-19 (1195845304),atmosphere-coheresince 2026-05-23
(1dfebcb5ff) — but neither had a CLI scaffolding overlay. The
commandatmosphere new my-app --template ai-chat --runtime cohere
(or--runtime anthropic) now works. Same change adds both artifacts
tobom/pom.xmland the parentpom.xml's
<dependencyManagement>so a Maven build resolves their version
without an explicit<version>in the consuming pom. Verified
end-to-end via chrome-devtools against the Atmosphere Console: real
Coherecommand-a-plus-05-2026LLM response over WebSocket with
18.3 tok/s streaming through theCohereChatClient→ real
https://api.cohere.com/v2/chatHTTP call. - Durable hibernating
Workflow<S>primitive in
atmosphere-checkpoint(a0ac15f1e3). OrdersWorkflowStep<S>
instances over an application-owned state type and composes the
existingCheckpointStoreSPI for persistence. Sealed
StepOutcome<S>(Advance/Hibernate/Done/Fail) and
WorkflowResult<S>(Completed/Hibernated/Failed) drive
the runner; per-stepmaxRetries()+retryDelay()cover
transient failures. Hibernation is return-not-park: a step that
returnsStepOutcome.hibernate(state)writes a snapshot and the
call returns to the caller with no platform thread held; a later
run()against the same coordination resumes at the next
un-completed step, including across JVM restarts when the store
is persistent.WorkflowSqliteResumeTestpins the cold-restart
contract — closesSqliteCheckpointStore, opens a fresh handle
on the same file, builds a freshWorkflowinstance, and asserts
only the un-completed step executes. Ten unit tests cover linear
execution, hibernate-and-resume, retry-success, retry-exhaustion,
explicit fail, duplicate-step-name rejection, snapshot-precedence
overinitialState, anddeleteAllSnapshots. SqliteLongTermMemoryandRedisLongTermMemory(835a88d252,
rebased tofbbfa457a2) — persistent backends for the
LongTermMemorySPI inatmosphere-durable-sessions-sqliteand
atmosphere-durable-sessions-redis. Both can share a connection
with their siblingSessionStore/ConversationPersistence
implementations.LongTermMemoryBackendIntegrationTest
parameterizes the fullLongTermMemoryInterceptorround-trip
over all three backends;LongTermMemoryMultiInstanceTest
(d4609cf0fc) proves the pod-A-writes / pod-B-reads scenario the
persistent backends exist for, using two independent
LongTermMemoryhandles against the same shared store.scripts/validate-backend-class-refs.sh(835a88d252) —
structural gate scanning*.javaJavadoc and*.mddocumentation
for(Sqlite|Redis|Postgres|Mongo|Cassandra|Hazelcast|JGroups|Kafka|Nats)<Word>
tokens that don't resolve to a declared class in
modules/**/src/{main,test}/java/..harness/external-class-allowlist.txt
whitelists genuine third-party types (Lettuce, Kafka, Testcontainers,
brand names). Wired intopre-push-validate.shTier-1. Catches
future SPI-backend overclaim drift before it merges (the class of
bug that drift #53 logged on the originalLongTermMemory
Javadoc).- Per-runtime
SKILLCARD.yamlmanifests with OpenSSF Model Signing
(32a8e8b935+ this commit) — capability + provenance documents
signed and verified through the same Sigstore-keyless toolchain
NVIDIA's verified-agent-skills programme uses.
scripts/regen-skillcards.shemits one card per
snapshot-pinned runtime atmodules/<X>/SKILLCARD.yaml, derived
from.harness/capabilities.snapshot.jsonand each module's
pom.xml. The repo-rootSKILLCARDS.mdcatalog (regenerated by
the same script) lists every shipped runtime, its capability
count, and its signature state — that file is the source of
truth for "which runtimes have a card", not this paragraph (a
named list and count would stale every time a new adapter lands).
Each card declaresspec: atmosphere/skillcard/v1with artifact
coordinates, the registeredAgentRuntimeSPI implementation FQN,
the alphabetical+count-pinnedAiCapabilityset, contract-test
path, license (Apache-2.0), and asigningblock referencing
signature_file: SKILLCARD.yaml.sigwithenvelope: openssf-model-signing/v1andbundle_format: sigstore.
.github/workflows/sign-skillcards.ymlsigns every card on tag
push viamodel_signing sign sigstore— short-lived Fulcio cert- Rekor transparency-log entry, OIDC identity bound to the
workflow path — and uploads the.sigfiles as a GitHub release
asset and as a workflow artifact for downstream bundling. Cards
AND signatures are bundled into each runtime jar at
META-INF/atmosphere/via a root-pom<resource>declaration so
consumers can verify integrity without unpacking the source tree;
modules without a SKILLCARD (cpr, mcp, channels…) see the include
filter match nothing and are unaffected.SkillCardSnapshotTest
inatmosphere-ai-testenforces three contracts: (a) capability
set + count drift against the snapshot, (b) every snapshot runtime
has a card on disk, (c) shape conformance with required top-level
keys (schema_version,spec,status,name,language,
description,license,artifact,spi,capabilities,
contract_test,provenance,signing) and required signing
fields (envelope,signature_file). When a.sigis present
beside a card, the test shells out tomodel_signing verify sigstorewith the Atmosphere workflow's identity pin and fails
on any signature mismatch; sigs are skipped silently when absent
(the normal state onmainbetween tagged releases) or when the
model_signingCLI is not installed locally.
scripts/scan-skillcards.shis the SkillSpector-equivalent
pre-publish gate — scans every card for prompt-injection markers
(regex set: "ignore previous instructions",[INST], ChatML role
tags), hidden Unicode (zero-width chars, Bidi overrides),
capability-safety violations (TOOL_CALLING ⇒ TOOL_APPROVAL per OWASP
excessive-agency), missing SPI classes (FQN doesn't resolve to a
source file on disk), and path-shaped-field safety. HIGH-severity
findings fail pre-push and the signing workflow, so a compromised
manifest can never be published as "signed".
scripts/validate-capability-claims.shruns all three of
regen-skillcards.sh --check,scan-skillcards.sh --check, and
the snapshot freshness check;scripts/sign-skillcards.sh+
verify-skillcards.share the local CLI wrappers (key / certificate
/ sigstore modes).regen-skillcards.shadditionally emits
SKILLCARDS.mdat the repo root — the catalog index that lists
every runtime, its signature state, and links to the card +
contract test. Distribution model: git itself is the daily sync,
consistent with the rest of this repository; release-time
signatures are also attached to the GitHub release as workflow
artifacts. Pre-push validator regex coversSKILLCARD.yaml(.sig)?,
(regen|sign|verify|scan)-skillcards.sh, the signing workflow,
andSKILLCARDS.md. Curated runtime-specific risk and mitigation
prose remains in each runtime's module README.
- Rekor transparency-log entry, OIDC identity bound to the
Atmosphere 4.0.47
Immutable
release. Only release title and notes can be modified.
Added
- Native Anthropic Messages API runtime in a new
atmosphere-anthropic
module (1195845304).AnthropicMessagesClientposts directly to
https://api.anthropic.com/v1/messages, parses the SSE stream
(message_start,content_block_start,content_block_deltawith
text_deltaandinput_json_delta,message_deltacarrying
usage.input_tokens/output_tokens,message_stop), and drives the
tool_use→tool_resultloop through the shared
ToolExecutionHelper.executeWithApproval(max five rounds,
cancellation-aware).AnthropicAgentRuntimeis registered via
ServiceLoaderat priority 100 — same posture as every other
framework runtime — and inheritsexecuteWithOuterRetryso it claims
PER_REQUEST_RETRYhonestly alongsideTEXT_STREAMING,
SYSTEM_PROMPT,STRUCTURED_OUTPUT,TOOL_CALLING,TOOL_APPROVAL,
TOKEN_USAGE,CONVERSATION_MEMORY,BUDGET_ENFORCEMENT,
CONFIDENCE_SCORES, andPASSIVATION.isAvailable()returns true
only whenanthropic.api.key(system property orAiConfig.LlmSettings)
is present, satisfying Correctness Invariant #5 (Runtime Truth). The
capability snapshot, capability matrix, andmodules/ai/README.md
prose were regenerated in the same commit; runtime count is now ten. - LangChain4j 1.15.0 parity (
9e72c6c6f7): tool-error fallback in
ToolExecutionHelper.executeWithApprovalwraps null/blank exception
messages with the throwable's simple class name so NPEs surface as
{"error":"NullPointerException"}to the model instead of opaque
{"error":"null"}. Custom HTTP headers onOpenAiCompatibleClient
carry proxy / per-tenant / tracing metadata (Helicone, OpenRouter, …);
reserved names (Authorization,Content-Type,Accept) are
filtered at request-build time.AgentFleet.vote(...)adds consensus
dispatch — fans every call out in parallel and returns the result
whose normalized text (strip().toLowerCase(Locale.ROOT)) is shared
by the most peers, with deterministic insertion-order tie-breaking
and a synthetic"vote"failure when every peer fails. - JFR observability, declarative tool permissions, first-run sub-agent
guard, and episodic memory (63e34f11a4):- JFR events under
org.atmosphere.ai.jfr—AiCallEvent,
AgentTurnEvent,ToolInvocationEvent,SubAgentDispatchEvent,
EpisodicMemoryAccessEvent,SessionLifecycleEvent,
AiErrorEvent— emitted byJfrAiMetrics.CompositeAiMetrics
lets JFR coexist with Micrometer (and any other backend) instead
of one replacing the other. ToolPermissionPolicySPI with thePropertiesToolPermissionPolicy
reference impl: declarative ALLOW/DENY rules layered on top of the
existing@RequiresApprovalannotation gate. Reachable from
ToolExecutionHelperso every runtime inherits it.- First-run sub-agent dispatch guard in
DefaultAgentFleet— the
bootstrap pass sequences the first call through every peer
individually before the parallel fan-out path is unlocked, so a
cold-cache misconfiguration is caught against one peer instead of
fanned out N× simultaneously. EpisodicMemoryStoreSPI withInMemoryEpisodicMemoryStoreand
JsonFileEpisodicMemoryStorebackends, theMemoryEntry/
EpisodicMemoryQuery/EpisodicMemoryTyperecords, and the
EpisodicMemoryAccessEventBridgeJFR fan-out.
- JFR events under
Changed
GrpcWasyncTransportTeststatus-poll widened from 5 s to 20 s and
the@Timeoutfrom 10 s to 30 s for JDK 26 scheduler variance
(df19027ab8). Closes a recurring "Core (JDK 21/26)" flake.
Fixed
samples/spring-boot-coding-agent: case-insensitive README probe
(38565e43ef). Repos likesindresorhus/awesomeshipreadme.md
lowercase, which the oldREADME.md-only lookup missed silently. The
redundantapplication.propertiesand the unused
atmosphere.ai.runtimesetting were also dropped — the sample is
deterministic and never invokes an LLM.
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 ...