agent-platform release v4.15.6

Fixed

  • Every agent turn ended 3 s late: the actors could not reach the OTLP gateway, and the Go ADK’s pre-response trace flush spent its full deadline on every turn (giantswarm/agent-platform#456; gazelle, 2026-09-14, nine of nine turns). The kagent controller sets KAGENT_PRE_RESPONSE_TRACE_FLUSH=true on Substrate actors (a checkpoint runtime has no later export window), so the Go ADK force-flushes a turn’s spans before the A2A response closes, with a detached deadline of KAGENT_TRACE_FLUSH_TIMEOUT_MS (3 s by default). The actors’ exporters point at the OTLP gateway kagent.otel names (http://otlp-gateway.kube-system.svc:4317), but the connectivity chart’s substrate-atenet-egress policy — the actors’ egress allow-list, since every connection an actor opens leaves through Substrate’s egress gateway — opened nothing towards it: every flush ran into traces export: context deadline exceeded at exactly +3.000 s, then the checkpoint, then the controller’s SendStreamingMessage closed; the caller (Swarmgeist’s ✅, the portal’s receipt) saw a one-word answer “done” 3.3–3.6 s after the text. The actors’ log exporter was broken twice over: the controller forwards only its tracing variables to the actors, so the Go ADK’s built-in log exporter (HTTP, /v1/logs) posted to the gRPC port and every batch ended in EOF. Three changes, one path: (1) the connectivity chart opens the OTLP gateway on the egress gateway and — through the same helper, agent-platform.kagent.otlpEgress — on the kagent controller’s egress policy, one rule per distinct destination of the kagent.otel signals that are on, selecting the pods of the endpoint’s namespace (<svc>.<ns>.svc[.cluster.local]) on the endpoint’s port (kube-system on 4317 by default, once for both signals; a second endpoint a second rule; an endpoint that is not a Service address the cluster entity on its port, as the controller’s rule was for every endpoint before); nothing when both signals resolve off. (2) The platform Harness’s env (kagent.harness.env) gains OTEL_LOGGING_ENABLED=true — the Go ADK exports the actors’ logs over gRPC to the tracing endpoint instead of the HTTP fallback — and OTEL_EXPORTER_OTLP_HEADERS=X-Scope-OrgID=giantswarm, the tenant header the controller sends and deliberately keeps from the actors; the meta chart drops the former when kagent.otel.logging resolves off and the latter when both exporters do (agent-platform.shape.dropEnv, the rule the controller’s header already followed). (3) KAGENT_TRACE_FLUSH_TIMEOUT_MS=500 on the Harness caps the flush: an in-cluster export takes tens of milliseconds, and a slow or unreachable collector can now cost a turn half a second, not three. make verify-actor-telemetry-egress asserts the rules (both policies, the default, a second endpoint, the port following the protocol, both signals off, auto off without the monitoring API, one signal on, the kubernetes flavour rendering no Substrate egress policy); tests/verify-kagent-harness.py the env in every exporter state. The lab renders no network policies (kind runs no Cilium): the policy is render-verified and live-verified on gazelle (hubble observe --verdict DROPPED on the egress gateway stays empty during a turn); the flush cap is lab-verified against an unreachable collector. Substrate’s own telemetry (the ateom worker’s periodic failed to upload metrics: … dial tcp [::1]:4317, substrate.otel.endpoint unset in the meta chart, the atelet OTLP relay socket absent on a worker that started before its atelet) is a separate finding, not on a turn’s path — a follow-up issue.