wrap_up.py reports 'wrapped, ready for reset' and leaves a live ~500MB process with a deleted cwd; worktree remove leaves the directory when gitignored output is present nf-kox ← Beads

open priority 2 task unassigned

Twinned from https://github.com/cfsh/ninefold/issues/769 by tools/beads/import_github.py's reconcile pass.

Found by nf-cto while operating the fleet, and corroborated independently in three reaped session transcripts. Filed unclaimed so it does not die in a transcript; surfaced during the #733 design round (design_docs/006, §2.12.6).

Two halves of one shape: a cleanup that reports done and isn't

1. A session that removes its own worktree does not exit. nf-cto, verbatim:

> "Three separate sessions (reaper, f5-owner, design-tier) removed their own worktree as their last act and then didn't exit. I found live ~500MB processes with /proc/<pid>/cwd reading (deleted) at every single reap tick — a 'wrapped, ready for reset' state that was actually a zombie holding RAM. I had to detect and kill this by hand, every time, because nothing else would."

So the documented terminal state (wrap_up.py --remove → "wrapped, ready for reset") leaves a ~500 MB process per session alive with a deleted cwd, and the only thing that notices is a human operator looking at /proc.

2. git worktree remove silently leaves the directory behind when it holds gitignored output (a session's probe_out/), discovered only by noticing a stray directory during a later reconcile.

Corroboration from the transcripts

The moment wrap_up.py --remove deletes the worktree it is running from, the next Bash call in that session errors at the harness level — Working directory "/root/nf/devs/probe-gate" was deleted; shell cwd recovered to "/root" / pwd: error retrieving current directory: getcwd: cannot access parent directories. Seen in probe-gate and session-state. The tool pulls the rug out from under its own caller's shell as its last act, which is also why nothing downstream of it runs.

Why this is worth a gate rather than a note

Both halves are the same class, and it is the class the fleet reported as its most common real defect (design 006 §2.12.6): a tool that finishes silently without actually finishing. Nothing is claimed until it is true (DEV_PRINCIPLES D2) is the rule being violated, and wrap_up.py is otherwise the best-designed reporter in the tier — it is the one tool that already states the bounds of its own knowledge (*"Not checked here — no tool on this box can see them"*).

Related but distinct: #731 / #736 (Gh.pr_list(head=) makes wrap_up.py exit 1 after a clean removal, so branch cleanup has never run). That is a wrong exit code on a run that worked; this is a right-looking exit on a run that didn't finish.

Unclaimed and unlabelled — backlog.

Dependencies

None.

Comments

No comments.

Add a comment