mirror of
https://github.com/kvcache-ai/AgentENV.git
synced 2026-11-05 01:17:36 +00:00
[PR #403] refactor(orchestrator): typed lifecycle claims #406
Labels
No labels
bug
documentation
enhancement
enhancement
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
kvcache-ai/AgentENV#406
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/kvcache-ai/AgentENV/pull/403
Author: @yingdi-shan
Created: 10/20/2026
Status: 🔄 Open
Base:
main← Head:refactor/orchestrator-lifecycle-claims📝 Commits (3)
2ecb7fcrefactor(orchestrator): hold transitional lifecycle states through typed claims1d92ff2fix(orchestrator): keep pause artifacts when persisting the paused record fails00f22c7refactor(orchestrator): split lifecycle operations out of service.rs📊 Changes
17 files changed (+2911 additions, -1982 deletions)
View changed files
📝
CLAUDE.md(+6 -3)➕
src/orchestrator/claim.rs(+327 -0)📝
src/orchestrator/launch_plan.rs(+37 -21)📝
src/orchestrator/mod.rs(+1 -0)📝
src/orchestrator/persistence/file_backed.rs(+10 -15)📝
src/orchestrator/persistence/mod.rs(+5 -0)📝
src/orchestrator/service.rs(+97 -1841)➕
src/orchestrator/service/create.rs(+257 -0)➕
src/orchestrator/service/delete.rs(+305 -0)➕
src/orchestrator/service/evict.rs(+174 -0)➕
src/orchestrator/service/fork.rs(+238 -0)➕
src/orchestrator/service/launch.rs(+272 -0)➕
src/orchestrator/service/pause.rs(+274 -0)➕
src/orchestrator/service/resume.rs(+185 -0)➕
src/orchestrator/service/snapshot.rs(+158 -0)📝
src/orchestrator/tests.rs(+407 -98)📝
tests/integration/orchestrator.rs(+158 -4)📄 Description
What
Makes orchestrator lifecycle state handling type-checked, fixes two lifecycle bugs, and splits
service.rsper lifecycle. Three commits, meant to be reviewed one at a time:refactor(orchestrator): hold transitional lifecycle states through typed claims(fixes #372)Claim<K>insrc/orchestrator/claim.rs. Acquiring one is the only way intoCreating,Resuming,Pausing,ForkingorSnapshotting.commit,rollbackorteardown.#[must_use]warns when one is ignored. A claim dropped unresolved logs a warning and rolls back in the background, so an early return or?can no longer strand a sandbox.Claim<PendingResume>::mark_resuming()returnsClaim<Resume>, and a resumeLaunchPlancan only be built from aClaim<Resume>. The persistedResumingmark is therefore undone exactly when it was made.launch_sandboxnow starts the runtime, waits until it is ready, then commits once. This replacesFailedLaunchStageand the rollback helpers that were written separately for each failure stage.Killingstays forward-only throughDeleteProgress.fix(orchestrator): keep pause artifacts when persisting the paused record fails(fixes #391)persist_pausedno longer removes the artifact root when encoding or writing the record fails. That root can hold the sealed live rootfs layer that the running VM still reads.refactor(orchestrator): split lifecycle operations out of service.rssrc/orchestrator/service/:create,launch,resume,pause,fork,snapshot,deleteandevict.pub(super)on the methods called across files, and rustfmt re-wrapping those signatures.git diff --color-movedshows it.Why
Every lifecycle operation moved a sandbox into a transitional state and relied on each error branch to write its own way back. #372 is what happens when a branch forgets: the launch shutdown gate and the missing-paused-state check skipped the rollback and left sandboxes in
Resuming, and their paused artifacts were then destroyed on the next startup. With claims, leaving a transitional state is enforced by types and checked by tests, instead of depending on review discipline.In #391, a failed pause persist deleted a layer the live VM still reads. The VM was then resumed on a missing lower layer, so its next pause or resume failed.
At about 3,000 lines,
service.rswas hard to navigate, which is why commit 3 splits it.Related issue
Closes #372
Closes #391
Scope and non-goals
Killing) keeps its existing forward-onlyDeleteProgressand does not use claims. No changes to the public API, configuration or persistence format.Design and behavior changes
TRANSITIONAL,COMMITTEDandROLLBACK; stable-state kinds also declareFROM. The rollback is one of:Restore(state)RestorePausedRecord:Paused, plus undoing the persisted resuming markRemove: for createteardown, which detaches and stops the runtime, finalizes volumes, deletes persisted state and removes the sandbox.Running.Paused.Compatibility and operations
Validation
make fmtmake clippymake test-unitmake -C services test(required whenservices/changes)maketargetCommands and results:
New tests:
resume_racing_shutdown_rolls_back_to_pausedandresume_without_paused_state_leaves_sandbox_paused.lifecycle_failures_never_leave_transitional_states: injects faults into create, resume, pause, fork and snapshot. It asserts that no transitional state remains and that no claim was dropped without being resolved.pause_persistence_and_resume_failure_removes_sandbox_and_artifacts(unit) andfailed_pause_persistence_keeps_live_rootfs_layer(real VM).Resuming, and the #391 test fails with "failed to open lower layer".Skipped checks and reasons:
make test-unitas an aggregate target: I ran theagentenvlib suite and the targeted real-VM orchestrator suite instead.make -C services test:services/is unchanged.Risks and reviewer notes
git show --color-moved=dimmed-zebra <sha>is the easiest way to read it.src/orchestrator/claim.rslaunch_sandboxand its helpers (service/launch.rsafter commit 3)pause_claimedandrecover_failed_pause(service/pause.rs)ClaimHostimpl inservice.rsChecklist
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.