Skip to content

Make instance lifecycle no-ops idempotent#205

Merged
sjmiller609 merged 1 commit intomainfrom
codex/idempotent-lifecycle-noops
Apr 30, 2026
Merged

Make instance lifecycle no-ops idempotent#205
sjmiller609 merged 1 commit intomainfrom
codex/idempotent-lifecycle-noops

Conversation

@sjmiller609
Copy link
Copy Markdown
Collaborator

@sjmiller609 sjmiller609 commented Apr 30, 2026

Summary

  • Return success for lifecycle requests that are already in the requested effective state:
    • restore on Running/Initializing
    • start on Running/Initializing when no command overrides are supplied
    • standby on Standby when no standby options are supplied
    • stop on Stopped
  • Preserve existing invalid-state behavior for non-no-op cases like start with command overrides, standby with options, start from Standby, and stop from Standby.
  • Avoid publishing lifecycle events for no-op responses so subscribers only see real transitions.

Why

Clients currently see a 409 for benign races like restore on an already-running instance. Some clients retry 409s, which adds avoidable wake latency. These no-op OK responses make lifecycle calls idempotent where the requested outcome is already true.

Tests

  • go test ./lib/instances -run 'TestLifecycleNoop'\n- go test ./lib/instances\n- go test ./cmd/api/api -run 'Test(Standby|Restore|Stop|Start)Instance'\n\nNote: go test ./cmd/api/api was also attempted but local volume tests require mkfs.ext4, which is not installed in this macOS environment.

Note

Medium Risk
Changes instance lifecycle APIs (StartInstance, StopInstance, RestoreInstance, StandbyInstance) to sometimes return early based on stored state, which could affect client-visible behavior and event-driven consumers if state derivation differs from prior transition logic.

Overview
Makes several instance lifecycle operations idempotent no-ops when the instance is already effectively in the requested state: RestoreInstance returns the current instance for Running/Initializing, StopInstance returns current for Stopped, StartInstance returns current for Running/Initializing when no command overrides are provided, and StandbyInstance returns current for Standby when no standby options are provided.

Adds lightweight state-check helpers (currentInstanceWithoutHydration, startRequestHasOverrides, standbyRequestHasOptions) and ensures no lifecycle events are emitted for these no-op responses. Adds lifecycle_noop_test.go with a fake hypervisor and assertions that no-op calls return success without publishing events, while override/option cases still error as before.

Reviewed by Cursor Bugbot for commit bbc9ae2. Bugbot is set up for automated code reviews on this repo. Configure here.

@sjmiller609 sjmiller609 marked this pull request as ready for review April 30, 2026 15:49
@firetiger-agent
Copy link
Copy Markdown

Firetiger deploy monitoring skipped

This PR didn't match the auto-monitor filter configured on your GitHub connection:

Any PR that changes the kernel API. Monitor changes to API endpoints (packages/api/cmd/api/) and Temporal workflows (packages/api/lib/temporal) in the kernel repo

Reason: PR modifies instance lifecycle logic in packages/api/lib/instances, not the API endpoints (packages/api/cmd/api/) or Temporal workflows (packages/api/lib/temporal) specified in the filter; please opt in manually if deploy monitoring is needed.

To monitor this PR anyway, reply with @firetiger monitor this.

@sjmiller609 sjmiller609 requested a review from hiroTamada April 30, 2026 17:19
@sjmiller609 sjmiller609 merged commit e23740e into main Apr 30, 2026
13 of 14 checks passed
@sjmiller609 sjmiller609 deleted the codex/idempotent-lifecycle-noops branch April 30, 2026 17:24
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