From bcce5315be554f4e0aa830855fd5f7c2fabbfea5 Mon Sep 17 00:00:00 2001 From: Levi Neuwirth Date: Sat, 18 Apr 2026 17:15:24 -0400 Subject: [PATCH] add neuropose reset subcommand for pipeline-wide state wipe Three-layer module: find_neuropose_processes() scans the process table via psutil for running watch/serve instances; terminate_processes() SIGINTs with a configurable grace period before optional SIGKILL escalation; wipe_state() clears $data_dir/in/, out/, failed/, the .neuropose.lock file, and leftover .ingest_/ staging dirs while preserving the container directories themselves. reset_pipeline() composes the three and refuses to wipe while any process survives termination. CLI wraps it with --yes/-y, --keep-failed, --force-kill, --grace-seconds, and --dry-run/-n. Always prints a preview before prompting; returns EXIT_USAGE=2 when survivors block the wipe. Unblocks the Mac benchmark iteration loop where partially-complete runs need to be cleared between experiments. --- CHANGELOG.md | 31 ++- docs/api/reset.md | 3 + mkdocs.yml | 1 + src/neuropose/cli.py | 156 +++++++++++++- src/neuropose/reset.py | 388 +++++++++++++++++++++++++++++++++ tests/unit/test_reset.py | 453 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 1030 insertions(+), 2 deletions(-) create mode 100644 docs/api/reset.md create mode 100644 src/neuropose/reset.py create mode 100644 tests/unit/test_reset.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 83c8802..6cf4d35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -256,6 +256,28 @@ be split into per-release sections once tagging begins. now returns a `LoadedModel` dataclass bundling the TF handle with the pinned SHA and filename so the estimator can build the `Provenance` without re-hashing the tarball. +- **`neuropose.reset`** — pipeline-wide reset utility for the + benchmark / iteration loop. `find_neuropose_processes()` scans the + OS process table (via `psutil`) for running `neuropose watch` and + `neuropose serve` instances and classifies each as `daemon` or + `monitor`. `terminate_processes()` SIGINTs them, polls for graceful + exit up to a configurable grace period, and optionally escalates + to SIGKILL with `force_kill=True`. `wipe_state()` removes the + contents of `$data_dir/in/`, `$data_dir/out/` (including + `status.json`), `$data_dir/failed/` (unless `keep_failed=True`), + the `.neuropose.lock` file, and any leftover `.ingest_/` + staging dirs from interrupted ingests; container directories + themselves are preserved so the daemon does not need to recreate + them on next startup. `reset_pipeline()` composes the three with + one safety guard: if any process survives termination, the wipe + phase is skipped and the returned `ResetReport` flags + `wipe_skipped_due_to_survivors`, because removing `$data_dir` + out from under an active daemon would corrupt its in-flight + writes. Surfaced as `neuropose reset` in the CLI with + `--yes/-y`, `--keep-failed`, `--force-kill`, `--grace-seconds`, + and `--dry-run/-n` flags; the command always prints a preview + before prompting (skipped under `--yes`) and returns + `EXIT_USAGE=2` when survivors block the wipe. - **`neuropose.benchmark`** — multi-pass inference benchmarking for a single video. `run_benchmark()` runs `process_video` N times (default 5), always discards the first pass as warmup (graph @@ -304,7 +326,7 @@ be split into per-release sections once tagging begins. `slow`) loads the real model and asserts the constant still matches, so any upstream skeleton drift fails CI. - **`neuropose.cli`** — Typer-based command-line interface with - seven subcommands: `watch` (run the daemon), `process