Skip to content

fix(claude-code): redact home paths and raw content in episodic logging - #67

Open
diazMelgarejo wants to merge 1 commit into
codejunkie99:masterfrom
diazMelgarejo:fix/claude-code-hook-privacy-leak
Open

fix(claude-code): redact home paths and raw content in episodic logging#67
diazMelgarejo wants to merge 1 commit into
codejunkie99:masterfrom
diazMelgarejo:fix/claude-code-hook-privacy-leak

Conversation

@diazMelgarejo

@diazMelgarejo diazMelgarejo commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Fixes #66.

What

claude_code_post_tool.py persisted raw absolute paths and raw file
content/edit diffs into AGENT_LEARNINGS.jsonl — a durable, cross-session
log meant to be shared, diffed, and eventually exported via the data
flywheel. Two leak sites:

  1. file_path values went into action/reflection unnormalized —
    /Users/<name>/... baked into every entry touching a file.
  2. Edit/MultiEdit reflection used repr(old[:30])/repr(new[:30])
    (literal content), and the generic _reflection() fallback for
    unhandled tool types (Read, Grep, Glob, WebFetch, ...) embedded raw
    json.dumps(tool_input) whenever the result was under 80 chars — which
    is backwards, since a short absolute path is exactly the case most
    likely to leak in full.

Fix

  • New _normalize_path() helper, pure stdlib, reuses the hook's own
    existing AGENT_ROOT resolution (no new dependency, no new config) —
    normalizes to project-relative or ~-relative form.
  • Content/diff previews replaced with char counts ("Edited {path}: N chars -> M chars" instead of literal excerpts).
  • _reflection()'s fallback branch now normalizes file_path/path/
    new_path before the length check, instead of dumping raw JSON.
  • _detail()'s raw json.dumps(tool_input)[:300] fallback replaced with
    a small normalized-metadata dict (tool name, normalized path, content
    size / edit char counts) — same shape as the existing Bash-specific
    branch already used.

Testing

Extended tests/test_claude_code_hook.py with a new section (10b) — 8
checks across an Edit and a Write case, asserting no raw home path or
file content survives into a persisted entry. Full suite: 62/62 passing
(up from 54/54, all pre-existing checks still green).

python3 tests/test_claude_code_hook.py
  62/62 passed — all good

Note

Redact home-directory paths and raw content from episodic log entries in claude-code hook

  • Adds _normalize_path in claude_code_post_tool.py to convert absolute paths to project-relative or ~-prefixed forms before persisting them.
  • Updates _action_label, _reflection, and _detail to use normalized paths and character counts instead of raw file content or absolute paths.
  • Adds a test in test_claude_code_hook.py asserting that episodic entries contain no raw home-directory paths or secret content.
  • Behavioral Change: Edit reflections now report old/new character counts instead of string snippets; detail fields no longer contain raw tool input.

Macroscope summarized 81e0f1e.

claude_code_post_tool.py persisted raw absolute paths and raw edit/write
content into AGENT_LEARNINGS.jsonl -- a log meant to be shared, diffed,
and exported via the data flywheel:

- file_path values went into action/reflection unnormalized, baking the
  operator's home directory into every entry that touched a file.
- Edit/MultiEdit reflection used repr(old[:30])/repr(new[:30]) -- literal
  content excerpts, not just that an edit happened.
- The generic _reflection() fallback (for tool types not explicitly
  handled -- Read, Grep, Glob, WebFetch, etc.) embedded raw
  json.dumps(tool_input) whenever it was under 80 chars, which is
  backwards: a short absolute path is exactly the case most likely to
  leak in full.

Adds _normalize_path(), reusing the hook's own existing AGENT_ROOT
resolution (no new dependency, no new config) to normalize to
project-relative or ~-relative form. Replaces content/diff previews with
char counts. Fixes the _reflection() fallback to normalize paths before
its length check instead of dumping raw JSON.

tests/test_claude_code_hook.py: new TestNoRawContentOrPathsPersisted-style
coverage (8 new checks, section 10b) asserting no raw home path or file
content survives into a persisted entry, for both Edit and Write --
62/62 passing, up from 54/54.

Fixes codejunkie99#66
@diazMelgarejo

Copy link
Copy Markdown
Contributor Author

Cross-ref: sibling fix in everything-claude-code for the same-shaped bug (raw tool-call payload into a durable, shareable artifact): affaan-m/ECC#2731

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.

Privacy: claude_code_post_tool.py persists raw absolute paths and file content/diffs into AGENT_LEARNINGS.jsonl

1 participant