Repository navigation
Agent-safe dev/spin lifecycle manager - #59
Merged
Merged
Conversation
Adds simpleaudit_studio/lifecycle.py so agents can safely start, reuse, stop, restart, reset and uninstall a local stack without killing unrelated processes or resetting real data. - Instance identity: sha256 of canonical checkout path (dev) or data dir (spin); file locks (owner.lock non-blocking, ports.lock blocking). - Port allocation before Django starts; worktree baseline 8100. - _live() validates PID running + create_time + UID to reject PID reuse. - Destructive boundaries: refuses custom SIMPLEAUDIT_DATA_DIR / SIMPLEAUDIT_SQLITE_PATH on reset/uninstall; uv cache cleanup is package-scoped only (never global `uv cache clean`). - manage.py `dev` and spin CLI dispatch subcommands before django.setup(). - devctl.sh rewritten as a thin compatibility wrapper; all legacy kill -9 / pgrep / lsof port-based cleanup removed. Fix orphaned runserver on shutdown: _stop_web now SIGTERMs the reloader subtree by PID (psutil), never by process group, because the reloader tree shares the owner's group with Caddy/Open WebUI which must keep running. Verified live: healthz 200, Django template autoreload works without restart, desktop + mobile render correctly, spin agent-info/status are read-only, and `dev down` leaves no orphaned processes. Docs: docs/development-lifecycle.md, AGENTS.md, README.md. Tests: tests/test_lifecycle.py (10 network-free tests). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an ownership-safe lifecycle manager so agents can start, reuse, stop, restart, reset and uninstall a local stack without killing unrelated processes or resetting real data. Previously there was no safe way for an agent to manage a running
dev/spininstance — repeated starts could double-bind ports, anddevctl.shused destructivekill -9/pgrepport-based cleanup.What changed
simpleaudit_studio/lifecycle.py(new) — single lifecycle manager shared bydevandspin:dev) or data dir (spin).owner.lock(non-blocking, prevents double-start),ports.lock(blocking, serializes port allocation)._live()validates PID running +create_time+ UID to reject PID-reuse false positives.SIMPLEAUDIT_DATA_DIR/SIMPLEAUDIT_SQLITE_PATHon reset/uninstall; uv cache cleanup is package-scoped only (never globaluv cache clean).manage.py—devdispatches subcommands beforedjango.setup().simpleaudit_studio/cli.py—spingains anactionpositional; lifecycle dispatch after arg parse.infra/management/commands/dev_server.py— bug fix:_stop_webnow SIGTERMs the runserver reloader subtree by PID (psutil), never by process group. The reloader tree shares the owner's process group with Caddy/Open WebUI, so a group kill would nuke the whole stack, and terminating only the guard left an orphaned runserver holding the internal port.devctl.sh— rewritten as a thin compatibility wrapper; all legacykill -9/pgrep/lsofport-cleanup removed.docs/development-lifecycle.md,AGENTS.md,README.md.tests/test_lifecycle.py(10 network-free tests).Verified by actual execution
dev/spin agent-info,status_live()checksdevstartdev downorphansuvx --from git+...@feat/agent-safe-dev-lifecycle spin …Test results
All checks passed!pytest -m "not embedded_hatchet"): 1283 passed, 4 failed — all 4 pre-existing (fail on base too: catalog metadata drift, retrieval-source INCONCLUSIVE, 2× verify_agentic_audit SystemExit). This branch introduces zero new failures.Known limitations (documented in
docs/development-lifecycle.md)restart. Not implementable without a separate worker-process phase.uvxmay retain shared cached environments that can't be safely identified by package on uninstall.spin uninstall/resetThe genuine data-deletion code path (uninstall/reset against the default spin data dir) was not exercised end-to-end because this machine's
~/.simpleaudit-studioholds ~2.5GB of real user data and the safety boundary forbids resetting it. The refusal path (custom data dir → refused) was verified through a real git-based uvx install. This PR should stay unmerged untilspin uninstall/resetcleanup is validated from a genuineuvxinstallation on a machine where the default data dir is disposable.Notes
main; does not merge the earlier agentic-demo work.