Skip to content

fix(agentic): leak-check cannot see orphaned Aspire process descendants, so it reports clean through a real leak #1429

Description

@rickylabs

Recorded as C-D86 (plus two addenda) in the 0.0.5 orchestration drift log. Demonstrated twice, not inferred.

Evidence

  • Row 70 (scaffold.runtime RED): an aspire-managed nuget search survived with PPID 1 for 1h53m, working-dir inside that run's own workspace plugin-smoke-20260809-204236. That run's receipt had recorded a secondary TypeError: Child process has already terminated during teardown, which was read at the time as cosmetic noise. It was not — the teardown had lost track of a live child.
  • Row 74 (scaffold.runtime GREEN): six helpers from that run's own workspace plugin-smoke-20260809-224559 were still running 17 minutes after it finished, while the same receipt recorded cleanup.aspire-stop passing in 1.003s and run-owned survivors: 0.
  • Census at that moment across sibling worktrees: 16 in ns005-w2c, 5 in ns005-w3a, 3 in ns005-w3b2, all ~20-21h old. This is systemic, not a one-off.

The defect

agentic:leak-check measures containers and AppHosts. Detached process descendants are outside what it can observe, so "zero run-owned survivors" is true about containers and simultaneously compatible with several run-owned processes still executing. A check that cannot observe the failure it is trusted to rule out is worse than no check, because it is quoted as proof.

Concretely: every scaffold.runtime execution appears to leak these helpers, and no gate reports it.

Important caveat for whoever implements this

Do not reclaim on PPID 1 plus path containment alone. Aspire spawns these helpers detached by design, so PPID 1 is normal operation — during the row-74 run itself, 40 such processes belonged to the live gate. A tool that reclaimed on containment alone would have killed an authorized run mid-flight.

Reclaim only when all three hold:

  1. path containment in the slice worktree (proves ownership),
  2. the workspace directory is not the active run's (proves the owning run ended),
  3. age far exceeds the operation's normal duration (a nuget search is sub-second).

That is the rule used to clean these safely by targeted PID; foreign helpers in sibling worktrees were left untouched.

Wording correction owed to existing evidence

Expensive-gate ledger rows 67, 69, 73 and 75 each state "zero run-owned survivors" on the strength of this blind check. They should be read as zero run-owned containers and AppHosts. No gate verdict changes — the leaked helpers are idle nuget search calls, not resource holders — but the claims are narrower than their wording implies.

Refs #1333.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions