# Changelog

## Baseline

- First survey — no prior run to compare against. CAI 62.

## Lenses

- Code Health 87
- Architecture 100
- Maturity 66
- Readiness 68
- Security 76
- Accessibility 52

## Changes since last survey

- 300 commits — 220 feature/other, 80 fixes

## By area

- modules/ai — 51 commits
- .github/workflows — 35 commits
- (root) — 27 commits
- modules/integration-tests — 21 commits
- .harness/drift-log.md — 17 commits
- modules/spring-boot-starter — 16 commits
- modules/quarkus-admin-extension — 15 commits
- (repo) — 10 commits
- cli/atmosphere — 8 commits
- atmosphere.js/package-lock.json — 6 commits
- modules/agent — 6 commits
- modules/embabel — 5 commits
- modules/quarkus-extension — 4 commits
- .harness/phantom-javadoc-allowlist.txt — 3 commits
- atmosphere.js/src — 3 commits
- modules/a2a — 3 commits
- modules/adk — 3 commits
- modules/cpr — 3 commits
- samples/spring-boot-ai-chat — 3 commits
- samples/spring-boot-ai-classroom — 3 commits

## Notable commits

- fix: chore(ci): hold mcp-core to 1.0.x in dependabot (block minor, not just major) Keeps it on the CVE-fixed 1.0.1 force-pin; stops the recurring 1.1.x bump PRs.
- fix: ci(gates): wire phantom-Javadoc validator into pre-push and index Kotlin declarations Fixes the real phantoms it caught: Javadoc misnamed GuardrailAsPolicy/PolicyAsGuardrail and GovernanceFleetInterceptor; SdkTracerProvider allowlisted as OpenTelemetry SDK.
- fix: feat(ai): deep-agent harness on @Agent(deepAgent) + wired @SandboxTool @Agent(deepAgent=true) — or atmosphere.ai.deep-agent.enabled app-wide — attaches long-term memory, a prompt-cache default, selectable compaction and fleet delegation with per-primitive runtime-truth at /api/console/info; @SandboxTool routes a tool method through a framework-owned Sandbox; fixed the built-in runtime model fallback so LTM fact extraction works (browser-proven cross-session recall); Spring/Quarkus/servlet parity; personal-assistant + coding-agent samples converted.
- fix: feat(ai): 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
- fix: feat(ai): planning + virtual-filesystem harness primitives; console broadcast fix write_todos and bounded ls/read/write/edit/glob/grep tools attach by default on every tool-calling runtime (Harness PLANNING/FILESYSTEM); AgentScope PlanNotebook, Embabel GOAP and Alibaba todos delegate via AiCapability.PLANNING while ADK artifacts and the Anthropic memory tool expose the store via VIRTUAL_FILESYSTEM; console gains a Workspace tab plus a broadcast-mode fix from a 29-sample browser sweep (outbound {author,message} envelope, event-less inbound frames render, cross-client Playwright regression); browser-proven with a real model.
- fix: fix(a2a): reject SSRF to internal targets in push-notification webhooks Deny loopback/private/link-local/metadata by default (delivery-time re-check for DNS rebinding); opt in via org.atmosphere.a2a.pushAllowPrivateTargets on trusted networks
- fix: fix(admin): require auth for recorded-content admin reads by default governance/decisions, audit, journal expose prompt/response + coordination content — default-deny, Spring+Quarkus parity, opt-out content-read-auth-required
- fix: fix(agent): guard eager runtime configure() so @Agent registers on Quarkus AgentProcessor.resolveRuntime now swallows a backend's configure() failure like AiEndpointProcessor already does, so an unready Quarkus TLS bean no longer aborts the annotation scan and drops every endpoint.
- fix: fix(agui): 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)
- fix: fix(ai): append grounded facts after the system prompt so provider prefix caches keep hitting time.now renders at minute granularity; schema/confidence appends splice in before the trailing fact block so volatile facts stay the suffix.
- fix: fix(ai): 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)
- fix: fix(ai): don't let an OTel GenAI meter conflict crash the request path MicrometerAiMetrics dual-emits gen_ai.client.operation.duration and token.usage; when a co-resident instrumentation (quarkus-langchain4j) already owns those OTel names with different tag keys, Micrometer/Prometheus rejects the registration and the exception surfaced as an in-stream error frame (paid-nightly Gemini disconnect-recovery). Back off the dual-emit once on conflict, keeping the atmosphere.ai.* series; regression test drives a registry that rejects the registration.
- fix: fix(ai): embedding scope guardrail degrades to rule-based when embeddings fail A failed embed call (e.g. the provider has no matching embedding model — Gemini 404s on text-embedding-3-small) previously errored and blocked every request, bricking any @Agent with a restrictive EMBEDDING_SIMILARITY scope; it now falls back to keyword rule-based enforcement so the agent stays usable and forbidden topics are still blocked.
- fix: fix(ai): env/sysprop LLM knobs win over RUNTIME.md pins A workspace RUNTIME.md model/mode/base-url/api-key pin was overriding an operator's explicit LLM_MODEL/LLM_MODE/... env (or system property), so pointing the personal-assistant sample at Ollama 404'd on the pinned gemini model; pins are now defaults an env override beats. Regression + env-lookup seam keep the test hermetic against ambient .envrc vars.
- fix: fix(ai): explicit client bindings beat the demo runtime and survive auto-configuration setChatClient/setModel now mark an explicit binding (demo fallback yields keyless) and autoconfig offers instead of clobbering, so a caller-built ChatClient keeps its defaultAdvisors; new keyless foundation-e2e spec pins the advisors sample contract.
- fix: fix(ai): forward stream(String,List) on DelegatingStreamingSession; scope advisors endpoint
- fix: fix(ai): guardrail scope no longer self-blocks an agent's own domain
- fix: fix(ai): harden planning + virtual-filesystem harness — bounds, scoping, runtime truth, auth
- fix: fix(ai): harness review — attach-time runtime truth, delegate_task user guard, mode parity
- fix: fix(ai): 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)
- …and 280 more
