feat: add pt handoff command for unfinished/non-PR records#125
Merged
Conversation
Introduces `pt handoff create/list/show/resolve` backed by a new `handoffs` table (migration 010). Records capture intent, current status, next command, file classifications, and optional pr_exempt metadata. All subcommands emit `pt.handoff.v1` JSON envelopes using the canonical `_emit_json` / `_emit_json_error` / `PtJsonError` pattern from PR #124. 18 tests green. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- MEDIUM #1: _auto_classify_files() now surfaces git failures via stderr warnings (FileNotFoundError, TimeoutExpired, non-zero exit). Callers using --auto-files can no longer mistake "no dirty files" for "git unavailable". Two new tests cover FileNotFoundError + non-zero exit. - MEDIUM #2: Removed _ensure_handoffs_table() entirely. Tests now apply the real migration 010 via the migration_runner — eliminates the schema-drift risk where DDL in code could lag the migration. - LOW #3: --files now validates each element is a {path, classification} dict with classification in the allowed set. Three new tests. - LOW #4: pt handoff resolve refuses to overwrite an already-resolved record (preserves the original timestamp + note as historical state). New test asserts both the validation error and that show still shows the first resolution. - LOCAL_ONLY classification: docstring on migration 010 + new entry in DECISIONS.md ("Handoffs are LOCAL_ONLY by design") explaining why cross-machine replication of dirty-tree pointers would be misleading. Test count: 18 -> 24, all green. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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
pt handoffcommand group for recording structured "unfinished work" or "non-PR exempt" records:create,list,show,resolve. Required as the escape hatch for Phase C's session-end gate.handoffstable via additive migration010_add_handoffs_table.py. Indexed oncard_id,project,unresolved_at. Classified asLOCAL_ONLYin the CR-SQLite manifest (see DECISIONS.md addition for rationale).pt.handoff.v1matching the schema-versioning pattern from PR feat: add read-only JSON memory CLI for SSH/cron automation #124.Phase context
Phase D of the Locked Project Hygiene Workflow (umbrella card #6118).
Notable design choice
handoffsisLOCAL_ONLY_TABLES(not replicated cross-machine via CR-SQLite). New entry inDECISIONS.mdexplains: a handoff exists because there's uncommitted local work in a dirty tree. That dirty tree is, by definition, machine-local — it hasn't been pushed. Replicating the pointer cross-machine would be a tease, not a resume point. Same rationale lives in the migration's docstring.Test plan
pytest tests/test_handoff_cli.py -v)db.migration_runner.apply_migration) — no parallel runtime DDL to drift from the migration file.pt db migrateapplies migration 010 cleanly on a fresh DB.pt handoff create CARD_ID --intent ... --status ... --next ... --guidance ... --jsonproduces apt.handoff.v1payload, persists to the new table.pt handoff list --unresolved-only --jsonreturns only unresolved records.pt handoff resolve <id>on an already-resolved handoff fails with validation error and preserves the original timestamp/note (regression test for the double-resolve idempotency fix).pt handoff create --auto-fileswarns to stderr ifgitis unavailable or returns non-zero, while still creating the handoff with emptyfile_list.Code review history
1e1d168: FAIL — 2 MEDIUM (silent git failure in_auto_classify_files, schema drift via parallel runtime DDL), 1 design question (LOCAL_ONLY classification — resolved with Erik), 2 LOW.2d0f206: PASS — distinct stderr warnings on each git-failure path;_ensure_handoffs_table()removed entirely (tests now drive the real migration runner so schema drift is structurally impossible);--fileselement-shape validation; double-resolve refused with validation error; LOCAL_ONLY rationale in migration docstring + DECISIONS.md.Known follow-ups (filed)
Related