Theme
Lesson 08 — One safe process-launch boundary
Outcome
Create one controlled process-launch API used by Git and later agent adapters.
Why this comes now
Git, setup scripts, verification, and some agent strategies all spawn processes. If each package invents its own environment/signals/quoting behavior, bugs multiply.
Understand
Prefer executable + argv to shell strings. A ProcessRunner centralizes cwd, environment, stdout/stderr handling, cancellation, deadlines, process groups, and future redaction/logging rules.
This boundary is infrastructure, not the Agent Run model. A managed OS process is an implementation detail.
Build the real project
- Define a small
SpawnSpec/runner interface only for current needs. - Implement direct
exec.CommandContext-style launching with argv. - Capture output with explicit size/stream behavior.
- Propagate cancellation and test a long-running helper process.
- Decide how environment variables are inherited/overridden; keep secrets out of debug logs.
- Make GitService depend on this runner in the next lesson.
Completion gate
Tests prove arguments containing spaces/special characters remain single argv entries, cancellation terminates the child, and cwd/environment work as expected.
Pitfalls to avoid
Do not call bash -c merely for convenience. Do not expose this runner to the Electron renderer. Do not make PID a domain identity.
References
os/exec, Emdash contributor guidance: https://github.com/generalaction/emdash/blob/main/CONTRIBUTING.md
Checkpoint
Add any platform-specific process behavior you encounter to RISK_REGISTER.md only if it could affect product safety/reliability.