You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
refactor(supervisor): make managed child ownership structural #3154
Make Linux managed-child ownership structural so callers cannot accidentally separate spawning, PID registration, waiting, unregistering, and lost-child diagnostics.
Context
The child reaper race fixed by PR #3142 required every Linux child path to use the correct registration protocol. The current registry helper closes the immediate spawn-to-registration window, but ownership remains a convention across canonical and SSH process paths. The diagnostics and wait-handling follow-ups explored during that review belong with the ownership cleanup.
Definition of Done
Introduce a managed-child abstraction that owns Linux child registration and cleanup.
Route canonical and SSH child paths through the abstraction.
Centralize explicit-wait handling, unregistering, and ECHILD diagnostics.
Add deterministic tests for ownership and reaper interleavings.
Preserve non-Linux behavior without introducing Linux-only reaper machinery there.
Issue type:refactor Complexity: Medium Confidence: High — the RFC 0012 ownership boundary is now established and the remaining manual child lifecycle paths are identifiable.
Summary
Replace the managed-child convention with a generic, cross-platform ManagedChild<C> owner at the post-RFC 0012 sandbox boundary. Linux orphan-reaper registration remains internal to the wrapper, while canonical-process and boundary-exec callers use the same managed Tokio/std child lifecycle API on every platform.
Scope
crates/openshell-sandbox/src/managed_children.rs: provide the cross-platform wrapper while preserving the generation-safe Linux registry and orphan-reaper mechanics.
crates/openshell-sandbox/src/process.rs: migrate the canonical Tokio child path to the wrapper on every platform.
crates/openshell-sandbox/src/boundary_exec.rs: migrate piped and PTY boundary-exec child paths, which now serve SSH execution after RFC 0012, to the standard-child wrapper.
Implementation Steps
Keep ManagedChild<C> as the single owner of child PID registration, wait cleanup, drop cleanup, and lost-child diagnostics.
Preserve the separate generation-bearing registration token for boundary operations that do not own a child handle.
Route canonical process spawning, stdio extraction, waiting, and try_wait through ManagedChild<tokio::process::Child>.
Route both piped and PTY BoundaryExec spawning, stdio extraction, failure cleanup, and waiter ownership through ManagedChild<std::process::Child>.
Remove manual registration and unregistering from child-owning call sites while retaining the existing terminal-observation and signal-ordering guarantees.
Unit tests: cross-platform Tokio/std lifecycle behavior; Linux registration before return, successful and failed wait cleanup, try_wait(None) retention, and existing boundary-exec coverage.
Integration tests: run the full openshell-sandbox test suite to exercise canonical and boundary execution composition.
Do not expose unrestricted raw-child access or into_inner, which would let callers bypass lifecycle cleanup.
Preserve BoundaryExec's terminal observation before final reap and its signal lock ordering.
Keep Linux-only reaper behavior internal rather than leaking platform-specific child types into callers.
Tests that fork or execute system binaries may behave differently under SELinux enforcement, but this refactor does not add new /proc/<pid>/exe inspection or cross-label behavior.
Documentation Impact
None expected — no user-facing behavior, configuration, or workflow changes.
Revision 3 — adapt ownership scope to the RFC 0012 sandbox and BoundaryExec architecture Revision 2 — cross-platform ownership model
Implementation is available in stacked PR #3156 (base: #3142).
It applies the cross-platform ManagedChild<C> ownership model from the plan: Linux reaper registration stays internal, while canonical-process and SSH callers use the same managed Tokio/std child lifecycle API on every platform. The PR includes cross-platform std/Tokio lifecycle tests and retains Linux-only reaper-race coverage.
The implementation is now aligned with RFC 0012. Both the canonical sandbox process and the BoundaryExec path used by SSH own their children through the cross-platform ManagedChild<C> abstraction. Raw Linux registry mutation is private, while terminal observation, signal ordering, process-group tracking, and cancellation behavior remain intact.
This issue has had no activity for 14 days and is now marked stale. It may be closed in 7 days if there is no further activity. Comment or remove the state:stale label to keep it open.
Activity
elezar commentedon Sep 3, 2026
Implementation Plan
Issue type:
refactorComplexity: Medium
Confidence: High — the RFC 0012 ownership boundary is now established and the remaining manual child lifecycle paths are identifiable.
Summary
Replace the managed-child convention with a generic, cross-platform
ManagedChild<C>owner at the post-RFC 0012 sandbox boundary. Linux orphan-reaper registration remains internal to the wrapper, while canonical-process and boundary-exec callers use the same managed Tokio/std child lifecycle API on every platform.Scope
crates/openshell-sandbox/src/managed_children.rs: provide the cross-platform wrapper while preserving the generation-safe Linux registry and orphan-reaper mechanics.crates/openshell-sandbox/src/process.rs: migrate the canonical Tokio child path to the wrapper on every platform.crates/openshell-sandbox/src/boundary_exec.rs: migrate piped and PTY boundary-exec child paths, which now serve SSH execution after RFC 0012, to the standard-child wrapper.Implementation Steps
ManagedChild<C>as the single owner of child PID registration, wait cleanup, drop cleanup, and lost-child diagnostics.try_waitthroughManagedChild<tokio::process::Child>.BoundaryExecspawning, stdio extraction, failure cleanup, and waiter ownership throughManagedChild<std::process::Child>.Test Plan
try_wait(None)retention, and existing boundary-exec coverage.openshell-sandboxtest suite to exercise canonical and boundary execution composition.Risks & Open Questions
into_inner, which would let callers bypass lifecycle cleanup.BoundaryExec's terminal observation before final reap and its signal lock ordering./proc/<pid>/exeinspection or cross-label behavior.Documentation Impact
None expected — no user-facing behavior, configuration, or workflow changes.
Revision 3 — adapt ownership scope to the RFC 0012 sandbox and BoundaryExec architecture
Revision 2 — cross-platform ownership model
elezar commentedon Sep 3, 2026
Implementation is available in stacked PR #3156 (base: #3142).
It applies the cross-platform
ManagedChild<C>ownership model from the plan: Linux reaper registration stays internal, while canonical-process and SSH callers use the same managed Tokio/std child lifecycle API on every platform. The PR includes cross-platform std/Tokio lifecycle tests and retains Linux-only reaper-race coverage.refactor(supervisor): make managed child ownership structural
refactor(sandbox): manage boundary exec child ownership
elezar commentedon Sep 18, 2026
Implementation Updated
PR: #3156
What changed
The implementation is now aligned with RFC 0012. Both the canonical sandbox process and the
BoundaryExecpath used by SSH own their children through the cross-platformManagedChild<C>abstraction. Raw Linux registry mutation is private, while terminal observation, signal ordering, process-group tracking, and cancellation behavior remain intact.Tests
cargo test -p openshell-sandbox— 83 passed, 1 expected ignoredmise run pre-commit— passedmainDocs updated
The issue will auto-close when the PR is merged.
github-actions commentedon Oct 2, 2026
This issue has had no activity for 14 days and is now marked stale. It may be closed in 7 days if there is no further activity. Comment or remove the state:stale label to keep it open.