Per mara: configure OTEL in the generated claude settings json (what the
Claude Code docs suggest), not a launch wrapper or /etc shell file.
claude-code auto-discovers /etc/claude-code/managed-settings.json in
every context — the harness turn loop AND hivectl choom — so putting the
OTEL env there gives telemetry parity declaratively, with no wrapper and
no --settings plumbing.
- managed-settings.json: was a static shared .source; now, when OTEL is
enabled, a per-agent build-time jq merge of the base asset + an env
block (jq at build, not eval-time readFile, to avoid IFD). OTEL off =
the static asset verbatim.
- otelSettingsEnv carries the static OTEL knobs + OTEL_RESOURCE_ATTRIBUTES
with the agent name (build-time) and the hive/swarm names forwarded by
meta.rs into environment.variables (mara: forward host config into
agent config where needed).
- removed the hive-serve-otel ExecStart wrapper, the per-unit otelEnv,
and the otel-headers LoadCredential from the harness service — the
harness binary emits no OTEL itself; only claude does, and it now reads
the settings json directly.
Known follow-ups (noted in code): the auth header (otel.headersCredential,
opt-in/default-null) is a secret and can't live in the world-readable
settings file — authenticated collectors need a runtime mechanism; this
PR covers the unauthenticated default.
nix fmt clean.