Follow-up hardening for the lifecycle features added in #45 (dogfooding-retro fixes). None are regressions — these strengthen the newest, lowest-tier features. Raised by code review.
1. Content-aware review freshness (V-3)
runCloseCommand's freshness guard compares the in-scope file-NAME set, not content. A direct rk close after editing the same files (no add/remove) passes the guard. (rk ship is unaffected — it re-reviews at HEAD before close.)
Fix: stamp the review with the reviewed commit SHA at review-sprint accept time; compare HEAD against it at close. Keep the freshness check independent of --skip-checks.
Files: packages/cli/src/commands/lifecycle.ts (runCloseCommand), packages/cli/src/commands/reviewSprint.ts
2. start-next claim/lock
rk start-next resolves then starts without claim-based double-dispatch protection. runStartCommand re-validates status under lock (a race yields a clean error, not corruption), but parallel invocations can resolve the same sprint from stale snapshots.
Fix: reuse rk next --claim semantics (claim, reload, release on failure); ideally lock the lane across resolve+start.
Files: packages/cli/src/commands/startNext.ts
3. doctor SHA-length gap
doctor only resolves 40-char SHAs (to skip the example scaffold's short placeholders), so a schema-valid short base_sha (ShaSchema allows 7-40 hex) escapes the reachability check.
Fix: make init --example write resolvable (or null) SHAs, then drop the 40-char gate so all schema-valid SHAs are checked.
Files: packages/cli/src/commands/doctor.ts, packages/cli/src/commands/init.ts
4. Dirty denied_paths do not block ship
Uncommitted changes to denied_paths classify as external_dirty, which the ship gate ignores, so forbidden local modifications can be present while checks/review run.
Fix: make dirty denied paths blocking, or require a clean workspace for them.
Files: packages/cli/src/lifecycle/diffClassifier.ts, packages/cli/src/commands/ship.ts
Follow-up hardening for the lifecycle features added in #45 (dogfooding-retro fixes). None are regressions — these strengthen the newest, lowest-tier features. Raised by code review.
1. Content-aware review freshness (V-3)
runCloseCommand's freshness guard compares the in-scope file-NAME set, not content. A direct
rk closeafter editing the same files (no add/remove) passes the guard. (rk shipis unaffected — it re-reviews at HEAD before close.)Fix: stamp the review with the reviewed commit SHA at review-sprint accept time; compare HEAD against it at close. Keep the freshness check independent of --skip-checks.
Files: packages/cli/src/commands/lifecycle.ts (runCloseCommand), packages/cli/src/commands/reviewSprint.ts
2. start-next claim/lock
rk start-next resolves then starts without claim-based double-dispatch protection. runStartCommand re-validates status under lock (a race yields a clean error, not corruption), but parallel invocations can resolve the same sprint from stale snapshots.
Fix: reuse
rk next --claimsemantics (claim, reload, release on failure); ideally lock the lane across resolve+start.Files: packages/cli/src/commands/startNext.ts
3. doctor SHA-length gap
doctor only resolves 40-char SHAs (to skip the example scaffold's short placeholders), so a schema-valid short base_sha (ShaSchema allows 7-40 hex) escapes the reachability check.
Fix: make
init --examplewrite resolvable (or null) SHAs, then drop the 40-char gate so all schema-valid SHAs are checked.Files: packages/cli/src/commands/doctor.ts, packages/cli/src/commands/init.ts
4. Dirty denied_paths do not block ship
Uncommitted changes to denied_paths classify as external_dirty, which the ship gate ignores, so forbidden local modifications can be present while checks/review run.
Fix: make dirty denied paths blocking, or require a clean workspace for them.
Files: packages/cli/src/lifecycle/diffClassifier.ts, packages/cli/src/commands/ship.ts