MEM-031: WOOFApiOpen leaks dogs/buffers on later open failure (woof/CONN.c)

WOOFApiOpen acquires keeper/graf/spot/sniff and three cli buffers, then sets woof_api_ready=YES only at :581. If a later alloc (:565-567), PATHu8bFeed, or memfd_create (:578-579 fail(WOOFFAIL)) fails, it returns with ready still NO and no cleanup, since call()/fail() do bare returns with no finalizer. WOOFApiClose is gated on woof_api_ready (:586) so it early-returns, and woof_serve only flips WOOF.api=NO; the open keeper object-store mmap plus graf/spot/sniff singletons and cli buffers leak for the process lifetime. The goal is to release every partially-acquired resource on the error path.

Issues

Partial open survives because the close path is gated on the never-set ready flag.

Blockers

None.

WIP

Re-verified 2026-07-07: flaw intact, sites shifted — keeper/graf/spot/sniff acquired at woof/CONN.c:586-602, then fallible call(PATHu8bAlloc/u8csbAlloc/PATHu8bFeed,…) (:604-606,614) and memfd_create<0 fail(WOOFFAIL) (:627) bare-return; woof_api_ready=YES only at :629; WOOFApiClose still gates if (!woof_api_ready) return; at :634 before its per-resource frees (:637-648).

TODOs

- Drop the woof_api_ready gate in WOOFApiClose (:634) and rely on its existing have_*/keep_owned/memfd>=0 checks; call it on WOOFApiOpen's error path. - Or restructure WOOFApiOpen to acquire only past a single ready point, or add a cleanup arm per acquiring step; re-run woof --api tests. - Repro FIRST (§17): force a late alloc/memfd failure in WOOFApiOpen; assert keeper/graf/spot/sniff + cli buffers are released.

Blockers and bummers

None.