Repository navigation
fix(sleep): normalize transcript_source once so checkpoints match the harvested source - #363
Merged
Yifan Yang (Yif-Yang) merged 1 commit intoNov 4, 2026
Conversation
… harvested source #354 normalized transcript_source only inside harvest_for_config, while the per-(project, source) harvest checkpoint and the tasks document still used the raw config value. "Codex" therefore harvested Codex but read and advanced a "<project>::Codex" cursor, which may hold a time written while that spelling silently harvested Claude, so older Codex sessions could be skipped (#312). A non-string value raised AttributeError. Add normalize_transcript_source() and use it for the harvest, for the cursor in run_sleep_cycle and the handoff pin, and for the tasks document. The cycle now validates the source before it creates the night's staging dir. Canonical names keep byte-identical cursor keys, and the legacy bare-project cursor is still read as the fallback. Also note the #350/#354 fail-loudly change in CHANGELOG. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Author
|
Merging this maintainer follow-up to #354. Background: an independent re-check of #354 (Claude Code, cross-checked here) found that
The CHANGELOG entry credits Hrushikesh Ramilla (@Hrushikesh-ramilla) for #350/#354. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Follow-up to #354. That PR normalized
transcript_source(case, surrounding whitespace) only insideharvest_for_config(). The per-(project, source) harvest checkpoint from #322/#312 and the tasks document still used the raw config value. As a result:"Codex"harvested Codex but read and advanced a<project>::Codexcursor. That cursor may hold a time written while the misspelling was silently harvesting Claude, so older Codex sessions could be skipped (the skillopt-sleep: harvest checkpoint is keyed by project, so a second --source in the same project skips its unseen sessions #312 class of bug).AttributeErrorinstead of a clear error.This adds
normalize_transcript_source()inskillopt_sleep/harvest_sources.pyand uses that one canonical value everywhere:run_sleep_cycleand in the handoff pin path;cmd_harvest.run_sleep_cyclenow validates the source before it creates the night's staging directory, so an invalid value no longer leaves an orphan staging dir. Canonical names keep byte-identical cursor keys, and the legacy bare-<project>cursor is still read as the fallback forclaude.get_backend()andstate.pyare unchanged.CHANGELOG.md[Unreleased] → Changednow also tells users that a misspelledbackendortranscript_sourcestops the run instead of silently using the mock backend or Claude transcripts (#350, #354, thanks Hrushikesh Ramilla (@Hrushikesh-ramilla)).Verification
tests/test_harvest_checkpoint_source.py. 12 fail on currentmainfor the intended reasons: the stale::Codexcursor is read, the tasks document records" Codex ", a list value raisesAttributeError, and an orphan staging dir is left behind. All 13 pass here. Canonical keys and the legacy bare-project cursor are pinned unchanged.mkdocs build --strictpasses. New code is ruff-clean; the one remaining finding is an existingI001incycle.py's import block, also onmain.Compatibility notes:
lookback_hourswindow. The stale::Codexentry is left instate.jsonbut is no longer used.seed_tasksor pinned digests now also reject an invalidtranscript_source.