Skip to content

fix(resource-monitor): drop subtree when root identity is unverifiable (#543)#572

Merged
mblua merged 1 commit into
mainfrom
fix/543-pid-reuse-unreadable-root
Jun 20, 2026
Merged

fix(resource-monitor): drop subtree when root identity is unverifiable (#543)#572
mblua merged 1 commit into
mainfrom
fix/543-pid-reuse-unreadable-root

Conversation

@mblua

@mblua mblua commented Jun 20, 2026

Copy link
Copy Markdown
Owner

Summary

Closes #543.

Extends the #516 root-PID-reuse guard in build_observed_tree (src-tauri/src/resource_monitor/windows.rs) so a registered root whose live identity is unverifiable (creation_time == 0) also drops its subtree — closing the narrow edge where an unreadable foreign parent (recycled root PID) with a readable child could let that foreign child become kill_allowed = true.

Change

No own-cleanup regression

Our own briefly-unreadable root subtree stays killable: kill_group builds targets from the accumulated observed_processes (add-only), and the reap path stays gated by the #559 observe_identity confirm (alive-but-unopenable root → Err → reap aborts; only genuinely-gone or recycled roots are reaped).

Testing

  • dev-rust: full suite cargo test --lib --bins --tests → 1347 passed / 0 failed; clippy clean; /code-review (high) → 1 candidate refuted, 0 HIGH.
  • grinch (adversarial Step-7): CLEAN — all 5 load-bearing claims verified against code; 41 resource_monitor tests pass incl. the Resource Monitor: agent groups never evicted — ACTIVE GROUPS pins at max (slot leak) #559 reap gates.
  • shipper: built v0.9.14 from the branch, deployed agentscommander_standalone_wg-1.exe to 0_AC.
  • user: manually tested the deployed 0_AC exe (lifecycle regression check) and approved landing.

Single-file backend change in resource_monitor/windows.rs; no schema / IPC / type / dependency changes.

Extend the #516 root-PID-reuse guard in build_observed_tree. The #516 guard
dropped a recycled root's subtree only when the live root process had a
readable creation time that differed from the registered identity. It skipped
the case where the live root is UNREADABLE (identity resolves to None,
creation_time 0): the root itself got kill_allowed = false, but a readable
foreign child hanging off it was still walked and marked kill_allowed = true,
so a later kill could terminate the foreign child.

The guard now drops the whole subtree whenever the live root identity does not
match the registered creation time, covering both the readable-mismatch (#516)
and the unreadable (#543) cases:

  resolved_identity.map(|id| id.creation_time_100ns) != Some(root.creation_time_100ns)

- Resolve the root identity before the placeholder push and run the guard on
  the raw Option, so the unreadable-root drop emits exactly one error (the
  existing "root pid N was not in process snapshot"), matching #516's clean
  single-error contract instead of also emitting "identity unavailable".
- The drop reuses the missing-root error and is re-evaluated every observe
  cycle, so a briefly-unreadable own root is re-adopted in full on the next
  clean read. No cleanup regression: the reap path stays gated by the #559
  observe_identity confirm, which resets strikes for an alive-but-unverifiable
  root, and kill_group still kills already-accumulated descendants.
- Add unit test unreadable_root_drops_subtree_and_protects_readable_child:
  unreadable root + readable child -> child is never observed and never
  kill_allowed. Existing #516 guard tests stay green.

cargo check and cargo clippy --all-targets clean; full suite
cargo test --lib --bins --tests: 1347 passed, 0 failed, 12 ignored.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@mblua mblua merged commit da929a1 into main Jun 20, 2026
9 checks passed
@mblua mblua deleted the fix/543-pid-reuse-unreadable-root branch June 20, 2026 02:41
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.

Resource Monitor: narrow PID-reuse kill-safety edge (unreadable recycled root with readable child)

1 participant