Skip to content

fix(convo-miner): skip Claude Code subagent transcripts by default (#1217) - #1330

Merged
igorls merged 3 commits into
MemPalace:developfrom
mvalentsev:fix/convo-miner-skip-subagents
Aug 11, 2026
Merged

igorls merged 3 commits into
MemPalace:developfrom
mvalentsev:fix/convo-miner-skip-subagents

Conversation

@mvalentsev

@mvalentsev mvalentsev commented May 3, 2026

Copy link
Copy Markdown
Contributor

Problem

mempalace mine --mode convos walks ~/.claude/projects/<slug>/ recursively
and picks up every .jsonl file, including those inside <session-uuid>/subagents/
where Claude Code records Explore/Plan/Grep subagent transcripts.

Reporter data on issue #1217 (49 projects, 2 months of usage):

  • 57 main session files (1.1%, 288 MB) -- the high-signal content
  • 4,928 subagent files (98.8%, 1.2 GB) -- short ephemeral exchanges already
    summarized in the parent session
  • Mining took 2h30+ at 100% CPU on an Apple M5 Pro

Smoke-tested against a real Claude Code project directory: 21 main + 92
subagent jsonl files (5x ratio), default-skip drops 38% of mined files with
no signal loss.

Fix

scan_convos() now skips any directory named subagents by default. New
--include-subagents flag re-enables them for users who want full history.

The filter is applied inside convo_miner.scan_convos's directory
pruning (the same place SKIP_DIRS is consulted). Pruning governs a
directory walk only, so a transcript named directly -- mine <session>/subagents/agent-x.jsonl -- is still mined without
--include-subagents. That split is deliberate: the flag decides what a
walk sweeps up, while naming a path stays an explicit request.

The shared SKIP_DIRS set in palace.py is left untouched, so project
mining (miner.scan_project) still descends into user-created
subagents/ Python modules in regular code projects.

Files

  • mempalace/convo_miner.py -- scan_convos(include_subagents=False)
    parameter, threaded from mine_convos()
  • mempalace/cli.py -- new --include-subagents flag on mine,
    forwarded through cmd_mine to mine_convos
  • tests/test_convo_miner_unit.py -- 6 new tests (default skip, opt-in,
    any-depth match, suffix-named directories left alone, case-insensitive
    match, and an explicitly named file inside subagents/)
  • tests/test_cli.py -- existing test_cmd_mine_convos_mode updated
    for the new kwarg, new test pinning the flag-threading path

Verification

End-to-end smoke test against a real Claude Code project directory:

$ python3 -m mempalace --palace /tmp/a mine <claude-projects-dir> --mode convos --dry-run
  Files:   150
$ python3 -m mempalace --palace /tmp/b mine <claude-projects-dir> --mode convos --dry-run --include-subagents
  Files:   242

Difference = 92, matches find <claude-projects-dir> -path '*/subagents/*.jsonl' | wc -l.

Out of scope

  • tool-results/ directories -- already covered by the existing
    .meta.json filename filter (no .jsonl files there).
  • A turn-count heuristic (Option B in the issue body) -- more fragile
    and a larger surface; default-skip + opt-in flag is the cleaner UX.
  • .mempalaceignore (feat: default-exclude runtime-state files + per-file drawer cap to prevent ingestion noise #587) -- orthogonal: a future ignore-file
    mechanism would let users override the default if needed, but the
    default-safe path here is additive and doesn't conflict.

@Qodo-Free-For-OSS

Copy link
Copy Markdown

Hi, cmd_mine() directly reads args.include_subagents in convos mode, which raises AttributeError for programmatic callers that construct an argparse.Namespace without that field. This is inconsistent with cmd_mine()'s existing defensive pattern (e.g., getattr(args, "redetect_origin", False)) and can break non-CLI entrypoints/tests that call cmd_mine() directly.

Severity: remediation recommended | Category: reliability

How to fix: Use getattr with default

Agent prompt to fix - you can give this to your LLM of choice:

Issue description

mempalace.cli.cmd_mine() directly accesses args.include_subagents when args.mode == "convos". If cmd_mine() is called programmatically (tests, integrations, or internal code) with an argparse.Namespace that doesn’t include include_subagents, it will raise AttributeError.

Issue Context

cmd_mine() already treats some fields as optional/feature-gated (e.g. redetect_origin) via getattr, so include_subagents should follow the same defensive pattern.

Fix Focus Areas

  • mempalace/cli.py[493-515]
    • Change include_subagents=args.include_subagents to include_subagents=getattr(args, "include_subagents", False) (or ensure the attribute is always present before branching).
    • Consider aligning other new/optional CLI fields to the same pattern to keep cmd_mine() robust for direct callers.

Found by Qodo code review

@igorls igorls added bug Something isn't working area/mining File and conversation mining labels May 6, 2026
@mvalentsev
mvalentsev force-pushed the fix/convo-miner-skip-subagents branch 5 times, most recently from f00d9b9 to 1f4cc8b Compare May 15, 2026 14:03
@mvalentsev
mvalentsev force-pushed the fix/convo-miner-skip-subagents branch 6 times, most recently from 01d5ee3 to f7d3790 Compare May 22, 2026 05:26
@mvalentsev
mvalentsev force-pushed the fix/convo-miner-skip-subagents branch 5 times, most recently from e88126f to df83681 Compare May 24, 2026 23:26
@mvalentsev
mvalentsev force-pushed the fix/convo-miner-skip-subagents branch 2 times, most recently from ea71ca2 to cf652ab Compare June 6, 2026 12:57
@mvalentsev
mvalentsev force-pushed the fix/convo-miner-skip-subagents branch 2 times, most recently from e273d37 to 83a9f86 Compare June 14, 2026 18:36
@mvalentsev
mvalentsev force-pushed the fix/convo-miner-skip-subagents branch 2 times, most recently from 49a7340 to cef1369 Compare June 23, 2026 17:01
@mvalentsev
mvalentsev force-pushed the fix/convo-miner-skip-subagents branch from cef1369 to c7a7787 Compare June 25, 2026 17:23
@mvalentsev
mvalentsev force-pushed the fix/convo-miner-skip-subagents branch from c7a7787 to 6f82262 Compare July 7, 2026 05:39
@mvalentsev
mvalentsev force-pushed the fix/convo-miner-skip-subagents branch 2 times, most recently from ccac056 to c564c59 Compare July 22, 2026 09:36
@mvalentsev
mvalentsev force-pushed the fix/convo-miner-skip-subagents branch from c564c59 to 7e6e8e0 Compare August 2, 2026 21:41
…emPalace#1217)

scan_convos() now prunes any directory named 'subagents' during os.walk.
Claude Code records Explore/Plan/Grep subagent transcripts in
<session-uuid>/subagents/agent-*.jsonl and on a typical workspace these
outweigh main session files ~80:1, dominating mining time and producing
near-zero additional signal (the parent session already summarizes them).

Adds a --include-subagents opt-in flag for users who want full history.
The shared SKIP_DIRS set in palace.py is left untouched, so project
mining (miner.scan_project) still descends into legitimate user-created
subagents/ directories in code projects.
- Case-insensitive directory match (d.lower() == 'subagents') so
  the filter still kicks in if Claude Code or a plugin ever emits
  'Subagents/' on case-preserving filesystems (Windows, macOS APFS).
- Drop defensive getattr in cmd_mine: argparse always defines the
  attribute since --include-subagents is unconditionally registered.
  Direct args.include_subagents access matches every neighbouring
  field and fails loudly if the registration is ever removed.
- Soften CLI help and docstring: drop the 80:1 ratio (reporter-
  specific) and the in-code (MemPalace#1217) reference. Add explicit
  default=False on the argparse flag for symmetry with --extract.
- Add 2 negative tests: 'mysubagents'/'subagentsbackup' must still
  be mined (regression guard against substring-match), and
  'Subagents/' must be skipped (case-insensitive coverage).
@mvalentsev
mvalentsev force-pushed the fix/convo-miner-skip-subagents branch from 7e6e8e0 to a3350ec Compare August 3, 2026 10:42
…gets

The default `subagents/` skip is directory pruning, so it cannot reach a
caller who names one transcript directly: that path feeds a single
synthetic scan entry with no directories to prune. The split is
deliberate -- `--include-subagents` governs what a directory walk sweeps
up, while naming a path stays an explicit request -- but the single-file
scan and this filter were written independently and nothing exercised
them together, so the boundary was unpinned.
@mvalentsev
mvalentsev force-pushed the fix/convo-miner-skip-subagents branch from 49b06fc to 5bc539d Compare August 6, 2026 11:33

@igorls igorls left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wave 1 for 3.7.0: LGTM. Focused fix with tests (or trivial deploy/manifest change). Merging into develop for the release train.

@igorls
igorls merged commit 3161cae into MemPalace:develop Aug 11, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/mining File and conversation mining bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants