feat(updates): restart-safe blocker classification (Step 1 of restart-safe sessions)#658
Open
JKHeadley wants to merge 1 commit into
Open
feat(updates): restart-safe blocker classification (Step 1 of restart-safe sessions)#658JKHeadley wants to merge 1 commit into
JKHeadley wants to merge 1 commit into
Conversation
…hard (Step 1) Codey-scoped Step 1 of restart-safe sessions (#60, mentorship loop): split the sessions blocking a deferred restart into restart-safe (resumable autonomous topics with a per-topic state file) vs hard blockers, surfaced read-only through GET /updates/status. Observability-only — the restart DECISION is unchanged: a restart-safe blocker still defers exactly as today, even when every blocker is restart-safe. Acting on the classification is a deliberately deferred later step. - UpdateGate: optional restartSafetyResolver predicate; classifyRunningSessions splits + stores restartSafeSessions/hardBlockingSessions; GateResult + UpdateGateStatus expose them; reset() clears them. No resolver -> all hard, restart-safe empty (identical to prior behavior); throwing resolver fails safe. - AutoUpdater: wires the resolver to the per-topic autonomous-state-file check; maps the two fields into AutoUpdaterStatus. - routes.ts: GET /updates/status adds both fields to its pick-list. - Tests: +5 UpdateGate unit (split, all-safe-still-defers invariant, no-resolver back-compat, fail-safe, reset) + 2 route integration. Opened for review (forward-looking enhancement, not a regression fix). Spec: docs/specs/restart-safe-blocker-classification-spec.md Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
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.
What
Step 1 of restart-safe sessions — an idea Codey (the codex agent) proposed and scoped during the 2026-06-01 mentorship loop (drive-Codey-as-Justin). Codey independently identified that restart-deferral behind active sessions is the root reason updates lag (a published+installed update sits unapplied while any healthy session blocks the restart), and scoped this exact first slice.
This PR adds observability-only classification of the restart-deferral blocker set into
restartSafeSessions(topics that resume cleanly across a restart — resumable autonomous topics with a per-topic state file) vshardBlockingSessions, surfaced read-only throughGET /updates/status.The restart decision is unchanged
A restart-safe blocker still defers exactly as today — even when every blocker is restart-safe, the gate still defers. This PR only establishes the classification primitive; acting on it (restarting through the safe ones, carrying their state across) is a deliberately deferred later step.
Changes
UpdateGate(pure logic): optionalrestartSafetyResolver?(session)predicate;classifyRunningSessionssplits + storesrestartSafeSessions/hardBlockingSessions;GateResult+UpdateGateStatusexpose them;reset()clears them. No resolver → all blockers hard, restart-safe empty (byte-for-byte prior behavior); a throwing resolver fails safe to "hard".AutoUpdater: wires the resolver to the per-topic autonomous-state-file check (.instar/autonomous/<topicId>.local.md); maps the two fields intoAutoUpdaterStatus. Fails safe on missing topic id / fs error.routes.ts:GET /updates/statusadds both fields to its pick-list (same pattern as fix(updates): surface restartImmediately in GET /updates/status (#59 — close #641 obs gap) #652/feat(parallel-dev): composition-root wiring for WorktreeManager #59).Tests
tests/unit/UpdateGate.test.ts): mixed blockers still defer + split correctly; all-restart-safe still defers (the no-behavior-change invariant); no-resolver back-compat; throwing-resolver fail-safe; reset clears.tests/integration/updates-status-restart-safe-sessions-route.test.ts): route surfaces both fields (populated + empty).Review status
Spec:
docs/specs/restart-safe-blocker-classification-spec.md· ELI16:…spec.eli16.md🤖 Generated with Claude Code