ce-compound session-history: extract-metadata.py drops every resumed session at MAX_LINES = 25 and counts the misses as parse_errors (recurrence of #923 in the sibling script)

Author: therealDimitriCreated Sep 16, 2026Updated Sep 16, 2026

Summary

skills/ce-compound/scripts/session-history/extract-metadata.py reads only the first 25 lines of each session file, and try_claude yields metadata only from a record that is both type == "user" and carries gitBranch. In a resumed Claude Code session that record sits past line 25, so the file is skipped. The skip is then counted as parse_errors, which is a mislabel: every line the extractor read parses cleanly as JSON, and several of them carry cwd and gitBranch on other record types.

The visible effect is ce-compound reporting "no relevant prior sessions" with a large parse_errors count beside it, which reads as a corrupt-file problem rather than a coverage one.

This is the same defect class as #923, which fixed the 10-line detection cap in ce-sessions/scripts/extract-skeleton.py by dropping the cap. The sibling script was not covered by that change.

Measurement

81 session files in one ~/.claude/projects/<encoded-cwd>/ directory, run through the shipped script and again with only MAX_LINES raised:

MAX_LINES = 25  (as shipped)   {"files_processed": 81, "parse_errors": 38}
MAX_LINES = 400                {"files_processed": 81, "parse_errors": 1}

37 of the 38 reported parse errors were not parse errors. Locating the first type == "user" record carrying gitBranch in each file:

record found                         80 of 81
  within the 25-line cap             43
  past the cap, silently dropped     37   (lines 26, 27, 31, 32, 34, 35, 36, 38, 39, 40, 41, 42)
  deepest                            line 42
no such record anywhere               1   (the one genuine miss)

Why the dropped set is the worst possible one

File size only correlates. Long sessions are the ones that get resumed, and a resumed session opens with a preamble of queue-operation, system and hook records before the first user turn, which is what pushes that turn past the cap. So the blind spot lands on the longest and most-resumed sessions, which are exactly the ones most likely to hold the prior work a history scan is looking for. In two consecutive ce-compound runs here the zero was reported and believed both times.

Source

skills/ce-compound/scripts/session-history/extract-metadata.py at 082c83e:

  • line 19: MAX_LINES = 25 # Only need first ~25 lines for metadata
  • lines 21 to 43: try_claude returns a result only on obj.get("type") == "user" and "gitBranch" in obj
  • line 382: if i >= MAX_LINES: break
  • lines 509 and 511: the "no metadata found" branch increments parse_errors, and the meta record reports it under that name

Suggested fix

Two independent one-line changes, either of which restores coverage:

diff
-MAX_LINES = 25  # Only need first ~25 lines for metadata
+MAX_LINES = 200  # Resumed sessions front-load a preamble before the first user turn

Scanning until the metadata is found, as #923 did, is the more robust version, since any cap is a guess about a preamble length nobody controls. The cost is bounded either way because try_claude breaks as soon as it has both fields.

Separately, the counter deserves splitting, because the two conditions have different remedies and only one of them is a parse problem:

diff
-        elif error:
-            parse_errors += 1
+        elif error:
+            no_metadata += 1

reported as files_without_metadata alongside a real parse_errors. As it stands the number sends an investigation to the JSON parser, where there is nothing wrong.

Environment

Claude Code on macOS, plugin version 3.26.3, marketplace clone at 082c83e.

Source: EveryInc/compound-engineering-plugin