Part of an ActiveAgent + actionagent dashboard functional review (multi-agent, adversarially verified). Severity: 🟠 Major.
ActiveAgent::Telemetry::Instrumentation unconditionally records full message bodies (rendered system prompt, user/history messages, assistant response, tool I/O) onto spans, ignoring the capture_bodies setting it documents and contradicting the shared telemetry gem's contract. Apps that disable body capture for privacy still ship every body.
Findings
Framework instrumentation ignores capture_bodies and always ships prompt, response, and tool bodies, contradicting its own docs and the shared gem's contract
- Where:
lib/active_agent/telemetry/instrumentation.rb:119 · severity: major · kind: security · repo: activeagent
- What breaks: ActiveAgent::Telemetry::Instrumentation unconditionally records full message bodies onto spans: prompt.input.instructions (rendered system prompt, line 77), prompt.input.messages (full user/history content, line 119), llm.output.message (assistant response, line 178), tool.input.args (line 223) and tool.output.result (line 227). Nothing in lib/active_agent reads configuration.capture_bodies (grep finds only a comment mention in configuration.rb:14), yet capture_bodies defaults to false (activeagents-telemetry configuration.rb:50) and the docs promise the opposite: docs/framework/telemetry.md:124 lists capture_bodies default false 'Include message bodies' and lines 351-359 state 'Message bodies are not captured by default. Enable with caution'. The activeagents-telemetry README:53-55 makes the same promise, and the ruby_llm adapter actually honors it (adapters/ruby_llm/lib/.../ruby_llm.rb:147,181 gate content on configuration.capture_bodies?). Result: an app that enables telemetry against the hosted DEFAULT_ENDPOINT (api.activeagents.ai) with the documented default of capture_bodies:false still ships every prompt, completion, and tool argument/result off-box — a privacy contract break, only partially mitigated by key-name redaction. Note the dashboard's Interactions/Evaluations views rely on these attributes for locally-stored traces, so the fix should gate HTTP-bound content on capture_bodies? (or default it true only for local_storage) rather than delete the attributes.
- Evidence: Code path read end-to-end: instrumentation.rb:77,94,119,178,223,227 set body attributes with no capture_bodies check;
grep -rn capture_bodies /home/user/activeagent/lib returns only the configuration.rb:14 comment; shared default false at activeagents-telemetry/lib/activeagents/telemetry/configuration.rb:50; contradicted docs at /home/user/activeagent/docs/framework/telemetry.md:124,353-359 and /home/user/activeagents-telemetry/README.md:53-55; adapter honoring the flag at adapters/ruby_llm/lib/activeagents/telemetry/ruby_llm.rb:147,181.
- Suggested fix: In ActiveAgent::Telemetry::Instrumentation (lib/active_agent/telemetry/instrumentation.rb), gate the five body attributes — prompt.input.instructions, prompt.input.messages, llm.output.message, tool.input.args, tool.output.result — on Telemetry.configuration.capture_bodies? (a single private helper, e.g.
capture_bodies? = Telemetry.configuration.capture_bodies?, checked at :77, :107-120, :177-179, :222-224, :227). Keep non-body attributes (counts, tool roster names, tokens, finish_reason) unconditional. To preserve the dashboard's Interactions/Evaluations content views, have Configuration#local_storage= (lib/active_agent/telemetry/configuration.rb) default capture_bodies to true when local_storage is enabled and the user has not set it explicitly (bodies never leave the process in that mode), or have the actionagent install generator emit capture_bodies: true. Update docs/framework/telemetry.md and v2-extraction-roadmap.md:122 to describe the actual behavior, and add a regression test asserting no body attributes appear on spans when capture_bodies is false and the reporter is HTTP-bound.
Verification
Each finding above was produced by a dedicated per-feature review agent, then confirmed by an independent adversarial verifier (all rated high-confidence; zero rejected in this set). File:line citations are against the current main/HEAD of each repo; many were reproduced live against a booted dashboard.
ActiveAgent::Telemetry::Instrumentationunconditionally records full message bodies (rendered system prompt, user/history messages, assistant response, tool I/O) onto spans, ignoring thecapture_bodiessetting it documents and contradicting the shared telemetry gem's contract. Apps that disable body capture for privacy still ship every body.Findings
Framework instrumentation ignores capture_bodies and always ships prompt, response, and tool bodies, contradicting its own docs and the shared gem's contract
lib/active_agent/telemetry/instrumentation.rb:119· severity: major · kind: security · repo:activeagentgrep -rn capture_bodies /home/user/activeagent/libreturns only the configuration.rb:14 comment; shared default false at activeagents-telemetry/lib/activeagents/telemetry/configuration.rb:50; contradicted docs at /home/user/activeagent/docs/framework/telemetry.md:124,353-359 and /home/user/activeagents-telemetry/README.md:53-55; adapter honoring the flag at adapters/ruby_llm/lib/activeagents/telemetry/ruby_llm.rb:147,181.capture_bodies? = Telemetry.configuration.capture_bodies?, checked at :77, :107-120, :177-179, :222-224, :227). Keep non-body attributes (counts, tool roster names, tokens, finish_reason) unconditional. To preserve the dashboard's Interactions/Evaluations content views, have Configuration#local_storage= (lib/active_agent/telemetry/configuration.rb) default capture_bodies to true when local_storage is enabled and the user has not set it explicitly (bodies never leave the process in that mode), or have the actionagent install generator emit capture_bodies: true. Update docs/framework/telemetry.md and v2-extraction-roadmap.md:122 to describe the actual behavior, and add a regression test asserting no body attributes appear on spans when capture_bodies is false and the reporter is HTTP-bound.Verification
Each finding above was produced by a dedicated per-feature review agent, then confirmed by an independent adversarial verifier (all rated high-confidence; zero rejected in this set). File:line citations are against the current
main/HEAD of each repo; many were reproduced live against a booted dashboard.