Skip to content

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

  1. Define a small SpawnSpec/runner interface only for current needs.
  2. Implement direct exec.CommandContext-style launching with argv.
  3. Capture output with explicit size/stream behavior.
  4. Propagate cancellation and test a long-running helper process.
  5. Decide how environment variables are inherited/overridden; keep secrets out of debug logs.
  6. 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.

Forge is local-first. The docs are part of the product engineering system.