Stability checkpoint — MCP server claude-compatible (streamable-http) + Javadoc fix

- feat(mcp): switch Spring AI MCP server to streamable-http protocol
  - File : src/main/resources/application.yml (+12 LOC)
  - One config knob : `spring.ai.mcp.server.protocol: STREAMABLE` (was
    default `SSE`). Switches the exposed transport from legacy
    /sse + /mcp/message (with session IDs) to the MCP 2025-03-26
    single-endpoint streamable-http at /mcp.
- docs(mcp): correct ActuatorService Javadoc — "Both" → "the two optional" beans
  - File : src/main/java/com/mirador/mcp/actuator/ActuatorService.java
    (+2 / -2 LOC)
  - Caught by the 2026-04-27 MCP foundation code review pass
    (a2717cf9 background agent report). The constructor wires THREE
    providers (health, info, env) but the Javadoc said "Both" — now
    accurately "the two optional" (health, info ; env is mandatory).

CI :
- ✅ Main pipeline #921 — https://gitlab.com/mirador1/mirador-service-java/-/pipelines/2481724902
  - 19 required jobs all green :
    - lint   : ✅ openapi-lint | ✅ hadolint
    - test   : ✅ unit-test | ✅ secret-scan | ✅ secret_detection | ✅ semgrep-sast | ✅ owasp-dependency-check
    - integration : ✅ integration-test
    - sonar  : ✅ sonar-analysis | ✅ code-quality
    - package : ✅ docker-build | ✅ build-jar | ✅ cosign:verify | ✅ cosign:sign | ✅ dockle | ✅ grype:scan | ✅ sbom:syft | ✅ trivy:scan
    - infra  : ✅ terraform-plan
  - manual-only (not triggered) : compat-sb3/sb4 × java17/21, build-native, mutation-test, semgrep, deploy:*, smoke-test, terraform-apply
- ✅ MR pipeline (refs/merge-requests/229/head) green before auto-merge

Local test pass :
- ⏭ ./mvnw verify -q — N/A : CI's main pipeline #921 ran the full
  unit + integration + JaCoCo gate. Re-running locally would be
  redundant for a 12-line YAML config change + 4-line Javadoc edit.
- ⏭ ./mvnw verify -Dcompat -Djava21 -q — N/A : compat matrix is
  manual-only on this repo, not triggered by routine merges.
- ⏭ bin/dev/stability-check.sh — N/A : the script exists in this
  repo (bin/dev/stability-check.sh) but is not part of the post-merge
  default flow ; would warrant its own dedicated audit cycle, not
  this incremental tag.
- ⏭ bin/dev/api-smoke.sh — N/A on this rev : no REST surface change.
  Order/Product/Customer flows are unchanged from stable-v1.2.9.

Manual probe :
- ✅ Direct curl `POST http://localhost:8080/mcp -H 'X-API-Key:
  demo-api-key-2026' -H 'Accept: application/json, text/event-stream'`
  with a JSON-RPC `initialize` body returned the full server
  capabilities block (`protocolVersion: 2025-06-18`, prompts /
  resources / tools listChanged true, server name = mcp-server).
  This was the SMOKING-GUN evidence that streamable-http is
  exposed correctly.
- ✅ `claude mcp list` (in /Users/benoitbesson/dev/mirador) reports :
    `mirador-java: http://localhost:8080/mcp (HTTP) - ✓ Connected`
  Where prior to this rev the same entry showed ✗ Failed to connect
  even with `--transport sse` against /sse — claude's SSE client did
  not complete the legacy SSE handshake against Spring AI's session-
  ID-based transport.

Regression check vs previous tag (stable-v1.2.9) :
- ✅ SLO dashboards (slo-overview, apdex, latency-heatmap,
  slo-breakdown-by-endpoint) still load — no observability change.
- ✅ Chaos demo annotations still render (no change to slo-overview
  config in this rev).
- ✅ JaCoCo coverage gates : 70 % global, per-package gates
  (com.mirador.order ≥ 30 %, com.mirador.product disabled) — all
  preserved per the build artefact in pipeline #921.
- ✅ grype suppressions in `.grype.yaml` for mcp-core 0.17.0 GHSAs
  still in force ; the dated TODO 2026-05-26 still binds (scheduled
  task `mirador-grype-mcp-core-cve-revisit` will re-evaluate).
- 🆕 ActuatorService Javadoc accuracy improved (`Both` was
  off-by-one ; fixed).

- MCP server now claude-compatible via streamable-http (the MCP
  2025-03-26 single-endpoint transport). The 14 in-process @Tool
  methods (`com.mirador.mcp.{domain,actuator,logs,metrics,openapi}`)
  are now reachable from `claude` without protocol gymnastics —
  `claude mcp add --transport http mirador-java
  http://localhost:8080/mcp --header "X-API-Key: <key>"` works on
  the first try.
- Spring AI version unchanged at 1.1.4 ; the protocol switch is a
  pure server-config move (no library bump).
- AI Observability spans (gen_ai.* via Spring AI's Micrometer
  observation) remain emitted to Tempo unchanged.

- Auth surface unchanged : JWT (15-min) via /auth/login + X-API-Key
  static via the `app.api-key` filter (`demo-api-key-2026` default).
  /mcp inherits the same SecurityConfig path matchers
  (`/sse, /sse/**, /mcp/**` authenticated).
- CVE posture unchanged : grype:scan ✅ (mcp-core 0.17.0 GHSAs
  remain suppressed via .grype.yaml dated-TODO 2026-05-26 ; no new
  HIGH found by trivy:scan or owasp-dependency-check).
- Headers + filters unchanged : SecurityHeadersFilter,
  RateLimitingFilter, IdempotencyFilter, RequestIdFilter all in the
  same chain order.

- ⏭ N/A — no REST endpoint or domain logic change. Customer /
  Order / Product / OrderLine surface and 6 invariants from
  shared ADR-0059 are untouched.

- ⏭ N/A — no IaC or cluster change. The Java jar runs identically
  ; only the in-process MCP transport contract changes.
- terraform-plan ✅ (no drift introduced).

- ⏭ N/A — no SLO / dashboard / alert / runbook change in this rev.
  All 4 dashboards from stable-v1.2.9 still served by the LGTM
  container at localhost:3000.

- Javadoc accuracy improvement on ActuatorService (caught by the
  2026-04-27 MCP foundation code review — agent a2717cf9). The
  constructor's 3-providers wiring is now correctly described.
- All static-analysis gates green : sonar-analysis ✅, code-quality
  ✅, hadolint ✅, openapi-lint ✅, semgrep-sast ✅,
  owasp-dependency-check ✅.
- Coverage / mutation / pitest unchanged — config-only rev.

- 19 required jobs green on main pipeline #921 (~25 min total).
- Conventional Commits respected : `feat(mcp): …` triggers a minor
  bump → stable-v1.2.10.
- Post-merge main pipeline ran the full default-branch ruleset
  (security stage included grype, dockle, cosign verify+sign — all
  green).

- MCP transport architecture now aligned with MCP spec 2025-03-26
  (streamable-http) — leaves the legacy SSE transport in the past
  rather than cargo-culting it. Spring AI 1.1.4 supports both ; the
  server-side knob (`spring.ai.mcp.server.protocol=STREAMABLE`)
  picks the simpler one.
- ADR-0062 invariants still hold : per-method @Tool, in-process
  only (no Loki/Mimir/Grafana/GitLab/k8s clients in the jar), DTOs
  returned (no entities), audit log per call, idempotency on writes,
  role-based authz, env redaction.
- File length / root hygiene / subdirectory hygiene : no drift.

- ⏭ N/A — backend repo (Java).

- mirador-java MCP wiring works on first try with `claude mcp add
  --transport http`. The pre-fix experience was : connect → ✗
  Failed → debug for 30 min → realize it's Spring AI's legacy SSE
  handshake conflict with claude's SSE transport. Saved hours for
  every dev who'll wire mirador-java going forward.
- Streamable-http is one HTTP POST per JSON-RPC call — far easier
  to reason about / curl-debug than the SSE + session-ID protocol.

- mcp-core 0.17.0 GHSAs (HIGH GHSA-8jxr-pr72-r468 + MEDIUM
  GHSA-hv2w-8mjj-jw22) suppressed in .grype.yaml — dated
  exit-ticket 2026-05-26 ; scheduled task
  `mirador-grype-mcp-core-cve-revisit` will check Spring AI 1.1.5+
  on Maven Central that day and drop the suppression if the
  upstream bumps mcp-core ≥ 1.0.1 natively.
- Compat matrix (SB3/SB4 × Java17/21/25) only triggered manually
  on this repo — pre-existing, not introduced here.
- mirador-python MCP wiring done in a sibling tag (stable-py-v0.6.9
  on the Python repo) ; running both backends simultaneously
  requires `MIRADOR_SERVER_PORT=8000` override on Python because of
  the shared :8080 default contract.

- Run mirador-python and wire its MCP via X-API-Key (the just-
  shipped Python ApiKeyMiddleware in stable-py-v0.6.9 unblocks this).
- Update the README of this repo with the new top "What this
  project demonstrates mastery of" 10-axis block (per the new
  global rule landed 2026-04-27).
- Consider lowering grype suppression dated-TODO once Spring AI
  ships 1.1.5+ with mcp-core ≥ 1.0.1.