Skip to content

fix(sleep): reject unknown transcript source names in harvest_for_config - #354

Merged
Yifan Yang (Yif-Yang) merged 1 commit into
microsoft:mainfrom
Hrushikesh-ramilla:fix/harvest-source-unknown-validation
Nov 4, 2026
Merged

Yifan Yang (Yif-Yang) merged 1 commit into
microsoft:mainfrom
Hrushikesh-ramilla:fix/harvest-source-unknown-validation

Conversation

@Hrushikesh-ramilla

@Hrushikesh-ramilla Hrushikesh Ramilla (Hrushikesh-ramilla) commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Currently, harvest_for_config() falls through to harvest(cfg.transcripts_dir) (the Claude harvester) when an unrecognized transcript source name or typo is configured. This causes misconfigurations in config files or programmatic runs to silently harvest Claude transcripts rather than notifying the user of the invalid source.

This change explicitly validates rtranscript_source against SUPPORTED_SOURCES in harvest_for_config(), raising a descriptive ValueError on unknown sources, while preserving the default fallback for empty/None inputs and case-insensitivity.

Changes

  • In skillopt_sleep/harvest_sources.py: define SUPPORTED_SOURCES, validate source, and raise ValueError listing valid sources when unrecognized.

  • In tests/test_sleep_engine.py: add test_harvest_for_config_rejects_unknown_source and test_harvest_for_config_accepts_empty_and_case_insensitive_source.

@Yif-Yang
Yifan Yang (Yif-Yang) merged commit 51ae501 into microsoft:main Nov 4, 2026
7 checks passed
@Yif-Yang

Copy link
Copy Markdown
Contributor

Merged — thank you. A misspelled or unknown transcript_source in a config file or programmatic call now raises a clear error instead of silently harvesting Claude transcripts. Empty values still default to claude, and matching is case-insensitive. The CLI already restricted --source via choices, so this closes the config/programmatic path.

Verified: your rejection test fails on the previous main code, both new tests pass here, and the full suite and CI on the resulting main pass. Non-blocking note: SUPPORTED_SOURCES duplicates the CLI choices list; if #314's registry lands, both should come from one place.

One more non-blocking follow-up: the lower-casing happens only inside harvest_for_config(). The per-source harvest checkpoint is still keyed by the raw transcript_source string, so "Codex" and "codex" keep separate cursors, and a non-string value now raises AttributeError rather than this ValueError. Normalising and validating the value once when the config is loaded would keep the two in step; I'll handle it in a small follow-up.

Verified integration main: 51ae50161aa6.

Yifan Yang (Yif-Yang) added a commit that referenced this pull request Nov 4, 2026
… harvested source (#363)

#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>
@Yif-Yang

Copy link
Copy Markdown
Contributor

Follow-up: #363 (now merged) normalizes transcript_source once, so the harvest, its per-source checkpoint and the tasks document all use the same canonical name, and a non-string value gets a clear ValueError. Thanks again for #354.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants