Skip to content

fix(claude-code-hermit): transcript-digest counts wakes off the wrong turn discriminator #658

Description

@gtapps

scripts/transcript-digest.ts:182 opens turns with isTurnTrigger (isMeta !== true) and classifies wake sources off that entry. Routine wakes ([hermit-routine:<id>] …) and inbound channel envelopes are isMeta: true with string content, so they never open a turn — their tool calls fold into the preceding turn instead.

Content shape, not isMeta, is the discriminator. The cost-attribution path already established this (see the isSkillInjection comment in scripts/lib/cc-compat.ts): measured on live transcripts, 247 routine and 192 channel signals live in isMeta entries.

Effect

  • wakes undercounts.
  • productive_wakes is wrong in both directions — a channel turn's Write/Edit calls currently fold into the preceding routine wake's turn and can mark it productive.

Fix

Promote the predicate turnPromptText already uses into a shared export and use it for segmentation in the digest:

// lib/cc-compat.ts
function isPromptBoundary(entry: Json): boolean {
  return entry.type === 'user' && !isToolResult(entry) && !isSkillInjection(entry);
}

turnPromptText calls it; transcript-digest.ts:182 swaps isTurnTriggerisPromptBoundary. That leaves isTurnTrigger with zero production callers (only transcript-digest.ts and one test comment reference it — cost-tracker.ts uses a deliberately looser inline predicate, see the warning at cost-tracker.ts:156-161), so it should be deleted in the same change with its isMeta rationale folded into a comment on the new predicate.

Gate before merging

This moves an operator-facing counter. The defer-loop rule in skills/reflect/SKILL.md:54 thresholds on wakes >= 20 && productive_wakes / wakes < 0.25, calibrated against the current undercount. Routine wakes are disproportionately unproductive by nature, so the ratio should drop and the rule fire more readily — likely the correct direction, but it needs before/after transcript-digest.ts numbers on live transcripts to confirm 0.25 still separates healthy from pathological.

Wants its own PR rather than riding along with a cost-attribution change.

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