ProcessManager: spawn / stdin / kill / captured / event bus (#2) #34

Merged
gronod merged 1 commits from feat/2-process-manager into milestone/m1-foundation 2026-09-08 18:52:17 +01:00
Owner

Implements issue #2 (M1).

  • actor ProcessManager in ICCeryCore: runStreaming / runCaptured / sendStdin / kill / killAll / multicast events() bus.
  • runCaptured drains stdout+stderr concurrently — verified with a 5000-line-per-stream test exceeding the 64 KiB pipe buffer.
  • stdin handle in its own slot, independent of wait (#84); kill drops stdin so writers fail fast; duplicate id rejected (#116).
  • exit emitted exactly once per child, gated on EOF of both pipes so buffered output survives fast exits.
  • ROW_COLORS_JSON: jsonRow (prefix stripped); ARGYLL_NOT_INTERACTIVE=1 on every child; spawn argv logged with ~ sanitization.
  • ProcessLineDecoder (UTF-8-safe \n split, CRLF, unterminated tail), JSONAccumulator (multiline JSON for instlist/profcheck/manifest), ProcessID conventions (instlist, chartread_<basename>, profcheck_<ti3_path>, iccgamut_<stem>, …).
  • Fixups from #1 AC: com.apple.security.device.usb entitlement; preset select + Calibrate Printer disabled; only Stage 1 enabled until #4 gating.

Verified: 23/23 tests pass under xcodebuild build test -scheme ICCery.

Closes #2

Implements issue #2 (M1). - `actor ProcessManager` in ICCeryCore: `runStreaming` / `runCaptured` / `sendStdin` / `kill` / `killAll` / multicast `events()` bus. - `runCaptured` drains stdout+stderr concurrently — verified with a 5000-line-per-stream test exceeding the 64 KiB pipe buffer. - stdin handle in its own slot, independent of wait (#84); `kill` drops stdin so writers fail fast; duplicate id rejected (#116). - `exit` emitted exactly once per child, gated on EOF of both pipes so buffered output survives fast exits. - `ROW_COLORS_JSON: ` → `jsonRow` (prefix stripped); `ARGYLL_NOT_INTERACTIVE=1` on every child; spawn argv logged with `~` sanitization. - `ProcessLineDecoder` (UTF-8-safe \n split, CRLF, unterminated tail), `JSONAccumulator` (multiline JSON for instlist/profcheck/manifest), `ProcessID` conventions (`instlist`, `chartread_<basename>`, `profcheck_<ti3_path>`, `iccgamut_<stem>`, …). - Fixups from #1 AC: `com.apple.security.device.usb` entitlement; preset select + Calibrate Printer disabled; only Stage 1 enabled until #4 gating. Verified: 23/23 tests pass under `xcodebuild build test -scheme ICCery`. Closes #2
gronod added the
Priority
Critical
1
Project/ICCery-v2Feature/Architecture
labels 2026-09-08 18:52:10 +01:00
gronod added 1 commit 2026-09-08 18:52:10 +01:00
- actor ProcessManager: runStreaming + runCaptured (concurrent pipe
  drain — no 64 KiB deadlock), sendStdin with independent stdin map
  (#84), kill/killAll, duplicate-id rejection (#116)
- Multicast AsyncStream<ProcessEvent> bus: stdout/stderr/exit/error/
  jsonRow (ROW_COLORS_JSON: prefix stripped)
- exit emitted exactly once, gated on both pipes reaching EOF so
  buffered output is never lost on fast exits or kills
- ARGYLL_NOT_INTERACTIVE=1 on every child; argv logged with ~ home
  sanitization; subprocess stdout→info, stderr→warn
- ProcessLineDecoder (byte-split at \n, UTF-8 safe, CRLF, unterminated
  tail flush), JSONAccumulator (multiline JSON for instlist/profcheck/
  manifest), ProcessID conventions
- 19 new tests incl. large-output captured run and stdin round-trip
- Fixup: entitlements gain com.apple.security.device.usb; sidebar
  preset/Calibrate disabled and only Stage 1 enabled per #1 AC

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
gronod merged commit 20d6bf7fdc into milestone/m1-foundation 2026-09-08 18:52:17 +01:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: gronod/iccery-v2-mac#34