feat: factory session recovery — preserve branches, run index, and session commands#822
Draft
colehurwitz wants to merge 7 commits into
Draft
feat: factory session recovery — preserve branches, run index, and session commands#822colehurwitz wants to merge 7 commits into
colehurwitz wants to merge 7 commits into
Conversation
Stop deleting git branches when removing worktrees (preserve_branch=True by default). Write per-run metadata to .factory/runs/<run_id>.json so past factory sessions can be listed, resumed, and reconstructed. Implements the core infrastructure for issue #698. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Three new commands for managing factory session history: - sessions-list: view past runs with optional status/JSON filtering - sessions-prune: clean up old branches and metadata (with --dry-run) - sessions-resume: reconstruct a worktree from a preserved branch Part of issue #698 session recovery. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…on commands - tests/test_runs.py: 13 tests covering save/load/list/update/delete/prune - tests/test_worktree.py: 4 new branch preservation tests, update existing test to reflect new preserve_branch=True default - tests/test_sessions.py: 7 CLI smoke tests for sessions-list/prune/resume Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sentrux Quality ReportAbsoluteDiff (vs base branch) |
The mock was missing the preserve_branch keyword argument added to remove_worktree, causing TypeError when tests called it with that param. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
User-supplied run_id could contain '../' to read files outside
.factory/runs/. Added regex validation (^[a-f0-9]{8}$) to save_run,
load_run, update_run, and delete_run. Updated test IDs to use valid
hex format and made sessions-resume handle ValueError gracefully.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Collaborator
Author
Factory CEO: KEEP ✓5 commits implementing issue #698:
QA verified:
Issue #698 acceptance criteria — all met:
Ready for human review and merge. |
- prune_runs() now always skips running sessions, even with prune_all=True - save_run() and update_run() use atomic writes (tempfile + os.replace) - delete_run() emits run.deleted event for consistency with save/update - prune_runs() checks git worktree list before deleting branches to avoid removing branches still checked out in active worktrees - sessions-resume accepts --target to override stored worktree path - Added test_prune_all_skips_running to verify critical fix Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Collaborator
Author
Code Review Fixes AppliedAll feedback addressed in commit 6f43882:
New test: |
The run_id validation regex requires 8 hex characters (^[a-f0-9]{8}$).
Test fixtures were using invalid run_ids like "test" and "fake0000"
which fail validation. Changed to valid hex strings "deadbeef" and
"face0000".
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #822 +/- ##
==========================================
- Coverage 87.39% 87.25% -0.14%
==========================================
Files 86 87 +1
Lines 12689 12944 +255
==========================================
+ Hits 11089 11294 +205
- Misses 1600 1650 +50 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Collaborator
|
@colehurwitz Looks like this PR needs to be rebased onto the latest main |
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.
Closes #698
Changes
New module
factory/runs.py:RunMetadataPydantic model and CRUD functions (save_run,load_run,list_runs,update_run,delete_run,prune_runs) for persisting per-run metadata at.factory/runs/<run_id>.json. Emitsrun.createdandrun.updatedevents.factory/worktree.py:remove_worktree()now takespreserve_branch=True(default) — branches are preserved after worktree removal so sessions can be reconstructed.prune_stale()takesdelete_branches=False(default) — orphaned branches are no longer deleted during stale worktree cleanup.factory/cli.py:cmd_ceo()and_run_single_cycle()now callsave_run()after creating a worktree andupdate_run()infinallyblocks to track run lifecycle. Three new CLI commands:factory sessions-list <path>— list past sessions with--statusfilter and--jsonoutputfactory sessions-prune <path>— prune old sessions with--older-than,--dry-run,--allfactory sessions-resume <path> <run-id>— reconstruct worktree from a preserved branchTests: 13 CRUD tests in
test_runs.py, 4 branch preservation tests intest_worktree.py, 7 CLI smoke tests intest_sessions.py(41 total pass).Test plan
pytest tests/test_runs.py -v— all 13 passpytest tests/test_sessions.py -v— all 7 passpytest tests/test_worktree.py -v -k "not Symlink and not Filelock"— all 21 pass (4 pre-existing failures excluded)factory ceo /pathand verify.factory/runs/<id>.jsonis writtengit branch --list factory/run-*)factory sessions-list /pathshows the completed runfactory sessions-resume /path <id>reconstructs the worktree🤖 Generated with Claude Code