Skip to content

[Rust port] relayburn-analyze: tool-output-bloat detector #271

Description

@willwashburn

Parent: #244
Depends on: #242, #266 (foundation), #268 (findings)

Context

Detects tool calls whose output exceeded a token threshold (default 15k) and surfaces them as bloat findings. Includes the Claude Code settings.json loader (~/.claude/settings.json + <project>/.claude/settings.json) used to read the per-tool BASH_MAX_OUTPUT_LENGTH envelope and merge static-config bloat (bash_max_output_length set too high) with observed bloat.

Scope

tool_output_bloat.rs (port of tool-output-bloat.ts, ~597 LoC)

  • Port BASH_MAX_OUTPUT_ENV_KEY = "BASH_MAX_OUTPUT_LENGTH" and DEFAULT_BLOAT_TOKEN_THRESHOLD = 15000.
  • Port ToolOutputBloat, ClaudeSettings, LoadedClaudeSettings types.
  • Port userClaudeSettingsPath(), projectClaudeSettingsPath(cwd), loadClaudeSettings(cwd).
  • Port detectStaticConfigBloat(options), detectObservedBloat(options), detectToolOutputBloat(options) — the merged entry point.
  • Port toolOutputBloatToFinding(bloat) adapter.
  • File loading is async in TS; in Rust use tokio::fs::read_to_string if loadClaudeSettings is the only async surface, otherwise sync std::fs is fine — match whatever convention the foundation crate established.

Conformance gate

  • packages/analyze/src/tool-output-bloat.test.ts (764 lines — the largest single test file in the package).

The settings-loader path needs both happy-path and missing-file fixtures. Use tempfile::TempDir for synthetic settings dirs.

Acceptance

  • cargo test -p relayburn-analyze green for tool-output-bloat.
  • Public surface: BASH_MAX_OUTPUT_ENV_KEY, DEFAULT_BLOAT_TOKEN_THRESHOLD, detectObservedBloat, detectStaticConfigBloat, detectToolOutputBloat, loadClaudeSettings, projectClaudeSettingsPath, userClaudeSettingsPath, toolOutputBloatToFinding, plus all listed types.
  • Static-config + observed-bloat merging produces findings in the same canonical order as TS.
  • Missing user / project settings is non-fatal (returns LoadedClaudeSettings { settings: ClaudeSettings::default(), .. }); test covers both files-present and files-absent.

Files

  • packages/analyze/src/tool-output-bloat.ts + tool-output-bloat.test.ts

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions