Skip to content

chore(claude-code-hermit): turnPromptText walks back with no compact-boundary stop #659

Description

@gtapps

turnPromptText (scripts/lib/cc-compat.ts:251) has exactly one terminating condition that isn't "ran off the start of the buffer": finding a qualifying user entry. Anything the predicate skips (isSkillInjection) is structurally invisible, so if a turn's real opening prompt were isMeta + array content, the walk would sail past it into the previous turn's prompt — cross-turn source bleed, which the old type === 'user' && !isToolResult boundary could not produce (every skip was a tool_result, which belongs to the turn you're already in). boundaryFound would not flag it.

Measurement

Scanned 333 local transcripts / 68k entries:

compact_boundaries:                12
mid_turn_boundaries:                0
next user entry after a boundary:  12x  user/isMeta=false/content=string
skipped_by_walk:                    0

Both concerns came back clean:

  • No compaction sits mid-turn (between a turn's opening prompt and a later billed assistant entry), so an isCompactBoundary stop could not regress a single real turn — it would only fire where the walk would otherwise cross a context epoch, which is always wrong.
  • Every post-compaction continuation is a plain string-content, non-meta user entry — exactly what the walk already stops on. The "continuation summary gets skipped" premise does not reproduce.

Status

Not a live bug on this evidence. The proposed isCompactBoundary stop (return { text: '', boundaryFound: false, index: -1 }, which callers already downgrade to other) remains defensible as cheap structural insurance, since it is provably a no-op on every turn whose walk already terminates before a boundary.

Caveats on the sample: 12 boundaries is thin, and these are dev sessions rather than always-on hermits, which compact far more often. Re-run the measurement against live fleet transcripts before deciding. If mid-turn boundaries turn out to be nonzero there, the stop needs to be asymmetric (carry the pre-boundary source forward but flag it) rather than a blanket downgrade.

Low priority.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions