Skip to content

feat: trustworthy tool summaries, semantic audit, and repetition collapsing#7

Merged
Mapleeeeeeeeeee merged 16 commits into
mainfrom
feat/trustworthy-summaries-and-collapse
Jul 16, 2026
Merged

feat: trustworthy tool summaries, semantic audit, and repetition collapsing#7
Mapleeeeeeeeeee merged 16 commits into
mainfrom
feat/trustworthy-summaries-and-collapse

Conversation

@Mapleeeeeeeeeee

Copy link
Copy Markdown
Owner

Summary

Two-day overhaul of what an inheriting Claude session actually sees, driven by real-transcript evidence: the compressed output previously lied (failures rendered as -> ok, edits invisible), and the tool's own metrics couldn't be trusted to tune it.

Injected-context correctness

  • Status determination ladder (ADR-003): toolUseResult.successis_error → conservative failure sniffing. Real Bash/Read results carry no success field and were blindly defaulted to ok — -> ok: Exit code 1 contradictions are gone.
  • Error excerpts: skip noise lines (line-number prefixes, hook boilerplate, bare Exit code N), 200-rune budget for failures.
  • Edit/Write diff summaries: -> ok (+15, -3 @ L42) / (new file, N lines) from structuredPatch — plus a fix for a pre-existing bug where RawName never resolved on real transcripts, so ADR-002's per-tool suppression had never actually fired.
  • Unknown-tool fallback: first input key-values instead of a bare [ToolName].
  • Repetition collapsing (ADR-005): retry loops (FAILED ×3: <error>, only when commands share a token-boundary prefix and errors are identical) and consecutive same-file Reads ([Read#id ×N] path). Invariants adversarially verified; two violations found and fixed pre-release.

Discoverability & metrics

  • list: durations no longer all 0m (tail-read timestamp fallback); previews survive command-first sessions.
  • context: minimal header when session metadata is missing.
  • stats: KEPT breakdown now measured from the real render pipeline — reconciles with Filtered to the character.
  • audit: semantic histogram of CUT content (risk-descending) + failed-result length distribution.
  • Telemetry: command outcomes (result/error), inject→inherit alias normalization, version fallback via BuildInfo, and expand now logs requested tool ids.

Decision records

  • ADR-003 (status ladder & summaries), ADR-004 (failure retention strategy — fully investigated with fleet-level stats across 379 sessions and two adversarial review rounds, implementation deliberately deferred until the feedback loop matures), ADR-005 (collapse rules incl. negative knowledge).

Tests

  • Every fix ships a red-first regression test; pipeline-level fixtures go through real JSONL parsing (no hand-filled fields).
  • New boundary suites: malformed JSONL (truncated/garbage/1MB single line) and UTF-8 truncation (CJK, emoji ZWJ, combining chars).

Benchmark

Compression holds at ~80% saved (baseline 81.9%), break-even still turn 1 — the added diff/error detail is paid for by collapsing and boilerplate suppression.

🤖 Generated with Claude Code

https://claude.ai/code/session_01SaBPDHw1cZDxhehYrqFgGe

Mapleeeeeeeeeee and others added 16 commits July 15, 2026 15:46
Bash/Read results carry no toolUseResult.success field, so every failed
command was rendered as "-> ok: Exit code 1" — misleading LLMs consuming
injected context. Status now follows ADR-003's ladder: explicit success
field, then is_error:true on the tool_result block (previously unparsed),
then a conservative sniff list (non-zero "Exit code N", hook error), else
ok. Failure excerpts skip noise lines (line-number prefixes, bare exit
code lines, hook boilerplate) and widen to 200 runes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013UQYeDtvg1CQYvirZ4jWC5
Successful Edit results now render "-> ok (+A, -D @ L<n>)" computed from
toolUseResult.structuredPatch hunks; Write renders "-> ok (new file, N
lines)"; missing patch data falls back to the bare status (ADR-003
decisions 3-4). Unknown tools show their first input key/values instead
of a bare tag, so new Claude Code tools degrade gracefully.

Also fixes the pre-existing root cause that defeated ADR-002's per-tool
suppression on real transcripts: tool names live on the assistant
tool_use block, not on toolUseResult (commandName/agentType are absent
for Bash/Read/Write/Edit), so RawName was always empty. ReadFile now
correlates tool_use id -> name and resolves result names through it,
covered by pipeline-level regression tests that parse realistic
two-entry fixtures instead of hand-filled RawName values.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013UQYeDtvg1CQYvirZ4jWC5
writeContextHeader silently skipped the header whenever the session-meta
JSON was absent — and upstream stopped producing those files, so every
recent session's context output started mid-dialogue with no hint of
which project or conversation it was. The fallback header now derives
session id, project (from event cwd, else transcript directory), and
date (first non-empty event timestamp) from the transcript itself.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013UQYeDtvg1CQYvirZ4jWC5
Session-meta JSON files stopped being produced upstream, so every recent
session fell back to the header scan, which showed 0m durations and
blank previews for inherit-style sessions. Duration now derives from
the transcript's first/last timestamps (last one found via a bounded
16KB tail read, never a whole-file load). The preview scan no longer
lets noise lines (command tags, skill injections, tool results,
interrupt sentinels) consume the candidate budget, and falls back to a
[/command args] preview when no genuine prompt exists.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013UQYeDtvg1CQYvirZ4jWC5
Usage entries now carry result (ok/error) and a one-line error message,
written after the command finishes via a begin/finalize split around the
existing exitOnError choke point — failures before target resolution are
captured too. Legacy entries without the field read back as unknown,
never as errors. The usage query normalizes the pre-rename "inject"
command to "inherit" in both filter and display, and local builds
resolve their version from runtime/debug.ReadBuildInfo instead of "dev".

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013UQYeDtvg1CQYvirZ4jWC5
ComputeStats kept its own copy of the compaction logic, so the KEPT
category sum drifted from the Filtered total (some categories counted
pre-compression text, join newlines went unaccounted, and formatter-side
cc-session collapsing was invisible). Filtered is now measured from the
actual read-render output via a content sink threaded through the
formatter, categories derive from that same pass, and the residual
template bytes (timestamps, role labels, indentation) surface as an
explicit "render overhead" row — the breakdown now reconciles to the
character. System-reminder/context-usage blocks that the renderer drops
are no longer miscounted as kept user text.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013UQYeDtvg1CQYvirZ4jWC5
- analyzer references formatter.Category* constants instead of re-typed
  string literals, so the category-name invariant is compiler-enforced
- render pipeline params (agentIDs/opts/out/sink) bundled into a
  renderContext struct; output verified byte-identical before/after
- mutation-guard tests: countContentLines' documented no-trailing-newline
  and empty-content contract, and the (?m)^Exit code N$ anchor that keeps
  mid-sentence mentions from sniffing as FAILED
- stats test expectation hardcodes "??-?? ??:??" instead of borrowing
  parser.FormatTimestamp into the expected value

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013UQYeDtvg1CQYvirZ4jWC5
Bucket CUT content by semantic risk (failure_output first, harness_noise
last), report failed-result length stats (count/median/p90/max) to inform
the upcoming head+tail error retention threshold, and annotate audit
samples with their bucket.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SaBPDHw1cZDxhehYrqFgGe
Records the fleet length distribution (379 sessions), the adversarially
reviewed two-tier design (threshold ~1,500, global-ranking head+tail+signal
truncation, self-describing omission markers, re-derivability budgets),
and the measured rejection of project-path rescue (<1% net coverage, half
noise). Implementation deferred until the expand-telemetry feedback loop
exists; revisit triggers listed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SaBPDHw1cZDxhehYrqFgGe
Truncated/garbage/null-byte lines error explicitly without panic or silent
loss; a 1MB single line guards against a future bufio.Scanner 64KB-token
regression; Truncate stays valid UTF-8 at emoji-ZWJ and combining-char
boundaries (grapheme-cluster integrity documented as a known limitation).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SaBPDHw1cZDxhehYrqFgGe
Prerequisite for ADR-004's feedback loop: expand entries now carry
tool_ids (all requested short IDs, including unresolved ones — the goal
is what the caller wanted to inspect). Legacy entries without the field
read back empty; display appends tools: only for expand rows.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SaBPDHw1cZDxhehYrqFgGe
Consecutive failed calls of the same tool whose command shares a prefix
collapse to one line with a xN count and the last error (last tool id
kept so expand reaches the final state); consecutive successful Reads of
the same file collapse to a single xN line. Collapsing never crosses an
interleaved event, never hides a distinct failure, and -verbose-bash
exempts retry collapsing per the ADR-001 precedent.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SaBPDHw1cZDxhehYrqFgGe
…token prefix

Adversarial verification (Codex) found two violations of ADR-005's
invariants: distinct errors under a prefix-matched command merged into
one line hiding the earlier error, and bare HasPrefix let 'git add'
absorb 'git add-on-something' (and a bare 'git' absorb everything).
Collapsing now additionally requires identical failure excerpts, and a
prefix match needs a whitespace token boundary plus a multi-token
shorter command. ADR-005 revised to match, including the rendered-event
boundary semantics and expanded negative knowledge.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SaBPDHw1cZDxhehYrqFgGe
…g in tests

ProjectDirName (single source of truth, was duplicated across production
caller detection and two test helpers) now also normalizes backslashes
and drive colons — a no-op on unix paths; the SKILL.md frontmatter test
helper trims CR before quote stripping. Both regressions are pinned by
OS-independent tests that inject windows-style inputs directly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SaBPDHw1cZDxhehYrqFgGe
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SaBPDHw1cZDxhehYrqFgGe
@Mapleeeeeeeeeee
Mapleeeeeeeeeee merged commit 8b3bdf7 into main Jul 16, 2026
3 checks passed
@Mapleeeeeeeeeee
Mapleeeeeeeeeee deleted the feat/trustworthy-summaries-and-collapse branch July 16, 2026 06:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant