# Fix daemon process management — prevent duplicate processes

Fix the daemon process management in qc-trace so only ONE daemon process runs at a time. Currently multiple processes accumulate from launchd restarts, manual `quickcall start`, and version upgrades — they compete and cause slow push rates.

Reference: https://github.com/quickcall-dev/trace/issues/65

## Key files

- `scripts/install.sh` — daemon wrapper script (`quickcall-daemon`) at line 202
- `qc_trace/cli/traced.py` — `cmd_start()` at line 129, `_read_pid()` at line 50
- `qc_trace/daemon/main.py` — `_write_pid()` at line 224

## Problems to fix

1. The daemon wrapper (`quickcall-daemon`) starts `uvx quickcall run &` in background but doesn't kill existing processes first. On launchd `KeepAlive` restart, a new wrapper spawns alongside the old one.
2. `quickcall start` only checks PID file — doesn't detect launchd-managed daemons.
3. PID file points to the `quickcall run` child process, but the wrapper parent process (`sh`) also stays alive. Killing the child doesn't kill the parent, and launchd restarts the parent.
4. `_write_pid()` in `main.py` warns about stale PIDs but doesn't kill them.

## Expected behavior

- Only one daemon process runs at any time
- Wrapper script should `pkill -f "quickcall run"` before starting a new one
- `quickcall start` should refuse if launchd/systemd service is active
- `quickcall stop` should stop both manual and service-managed daemons
- PID file should be cleaned up reliably on exit

## Git workflow

You are on branch `bugs-and-perf`. Commit and push as you go:

```bash
git add -A && git commit -m "fix: <description>" && git push origin bugs-and-perf
```

After each meaningful change, update the tracking issue with a comment:

```bash
gh issue comment 65 --repo quickcall-dev/trace --body "**Process management update**: <what was done>"
```

## Verification

Run `uv run pytest tests/` after changes. Bump version and publish to PyPI using `.prod.env` for the token.
