github AgentWorkforce/burn analyze-v0.42.0
@relayburn/analyze@0.42.0

latest releases: reader-v0.44.0, relayburn-v0.44.0, mcp-v0.44.0...
5 hours ago

[0.42.0] - 2026-04-28

Added

  • Slash-command-style invocations no longer false-flag as ghosts (#172). The GhostSurfaceAdapter contract gains an optional observedNames(inputs, candidates) hook; the orchestrator unions whatever names that returns into the per-source observed set before deciding which candidates are ghosts. claudeGhostAdapter mines userTurnTextBySession for <command-name>...</command-name> markers (both <command-name>/foo</command-name> and the bare <command-name>foo</command-name> shape are recognised). codexGhostAdapter does a literal /<basename> match, anchored on word boundaries on both sides so https://example.com/foo, /foo-bar, and similar non-invocations don't false-positive. Matching is case-insensitive. Behaviour is opt-in / gated on content-sidecar availability — when userTurnTextBySession is undefined or empty (sidecar pruned, content.store=off), the hook is a no-op and the detector falls back to v1 (tool-call only) behaviour. The inline doc notes on claudeGhostAdapter and codexGhostAdapter document the remaining false-negative for Codex (a prompt invoked entirely without typing /<basename>). New helpers mineClaudeCommandNames and mineCodexSlashInvocations are exported alongside. userTurnTextBySession is now keyed by SourceKind first (Map<SourceKind, Map<string, string[]>>) so the orchestrator passes only the matching source's session texts to each adapter's observedNames hook — preventing Claude <command-name>/foo</command-name> markers from de-ghosting an identically-named Codex prompt and vice versa.
  • Oversized tool output bloat detector (#168). New detectToolOutputBloat that unifies two signal sources under one ToolOutputBloat shape ({ source, kind, toolName, configuredLimit?, evidencedMaxOutput, evidencedP95Output?, occurrenceCount, cost, evidence }). Signal A (Claude-only static config) reads ~/.claude/settings.json and the project's .claude/settings.json and flags any merged env.BASH_MAX_OUTPUT_LENGTH whose token-equivalent (chars ÷ 4) exceeds the 15000-token threshold — i.e. above 60000 characters — project settings override user, last-wins. The shape stores the raw env char value in configuredLimit and the converted token count in evidencedMaxOutput so consumers don't have to branch on kind to know what unit each field is in. Signal B (cross-harness session-data evidence) consumes ToolResultEventRecord.contentLength from the #42 substrate, maps bytes → tokens via the same bytes/4 heuristic (precision deferred to #57), bucketizes by (source, toolName) post-normalizeToolName so Claude Bash, OpenCode bash, and Codex shell aggregate under canonical Bash, and prices the carry cost at the source turn's model input rate. Threshold defaults to max(15000 tokens, p95 across the slice) with a sample-size guard so single-event slices don't self-exclude. New exports: detectToolOutputBloat, detectStaticConfigBloat, detectObservedBloat, loadClaudeSettings, userClaudeSettingsPath, projectClaudeSettingsPath, toolOutputBloatToFinding, BASH_MAX_OUTPUT_ENV_KEY, DEFAULT_BLOAT_TOKEN_THRESHOLD. Findings are emitted as WasteFindings with kind: 'tool-output-bloat' — Signal A pastes the corrected env line (in chars) into settings.json; Signal B pastes a head / tail / grep filtering reminder for the user's CLAUDE.md / AGENTS.md.
  • Cross-harness ghost user-installed surface detector (#166). New detectGhostSurface orchestrator + per-harness GhostSurfaceAdapters (claudeGhostAdapter, codexGhostAdapter, opencodeGhostAdapter) flag user-installed surface files (agents/skills/commands/prompts/rules/memories) that ride in every session's system prompt but were never invoked across the observed window. Claude scans ~/.claude/{agents,skills,commands}/, Codex scans ~/.codex/{prompts,skills,rules,memories}/, and OpenCode walks each project's opencode.json declared skills + custom commands and the project skills folder. Output is a sorted GhostSurfaceFinding[] (source, kind, path, sizeTokens, cost, sessionCount, countedByCatalogBloat?) with cost = sizeTokens × sessionCount × dollarPerToken. Adapters are declarative — adding a new harness is one entry in DEFAULT_GHOST_ADAPTERS. The GhostSurfaceInputs contract reserves a userTurnTextBySession field for the #172 follow-up so slash-command invocation mining can land without a breaking change. OpenCode results dedupe against #54's SystemPromptTax (catalog-bloat) detector by emitting declared catalog skills with cost: 0 and countedByCatalogBloat: true — the entry is still surfaced so the user knows what to remove from opencode.json, but the dollars aren't double-counted. New finding adapter ghostSurfaceToFinding(...) produces a WasteFinding with a mv <path> <archive-dir>/ command-style WasteAction per the #56 envelope.

Don't miss a new burn release

NewReleases is sending notifications on new releases.