Skip to content

KEP-0022: accept as implemented; settle all four unresolved questions - #57

Merged
baijum merged 1 commit into
mainfrom
claude/kep-0022-as-implemented
Sep 1, 2026
Merged

KEP-0022: accept as implemented; settle all four unresolved questions#57
baijum merged 1 commit into
mainfrom
claude/kep-0022-as-implemented

Conversation

@baijum

@baijum baijum commented Sep 1, 2026

Copy link
Copy Markdown
Member

The KEP-hygiene half of kaappi/kaappi#2417. Core PR: kaappi/kaappi#2455. Docs PR: kaappi/kaappi.github.io#41.

All four phases of (kaappi process) landed on kaappi main between 2026-08-31 and 2026-09-01 (#2442, #2445, #2450, #2455), ahead of ratification. This accepts them retroactively and reconciles the document with what shipped.

Status goes to Accepted, not Final. Nothing here is in a release — v0.25.0 predates Phase 1 — and the process reserves Final for a released, reconciled design. The remaining step is the next release plus the two follow-ups flagged below.

The four unresolved questions, settled in place

  1. Pseudo-terminals stay deferred, now with four phases of evidence behind it — and explicitly not as an open follow-up. Adding one later is another redirection spec in parseRedir, not a redesign; keeping a speculative feature open forever is how a subsystem grows a surface nobody asked for.
  2. Cross-thread process-wait raises, as proposed — and the owner check is on every entry point except the predicate, not just the wait, so the whole class is unreachable rather than patched procedure by procedure.
  3. Zombie discipline got the sweep and the GC finalizer. The KEP's "reap-on-GC-finalize considered only if a concrete program escapes the sweep" was settled in Phase 1 instead: a Process collected while its child still runs is not hypothetical, it is what a program that spawns and drops the handle does every time.
  4. Status encoding is the flat integer plus (signaled . n). No decoder procedures.

Ten divergences recorded

The two worth reading:

  • pass-fds: was never implemented, and is withdrawn. What replaced it is narrower and sufficient — a redirection spec may be an fd-backed port. A general allowlist for arbitrary extra descriptors has no consumer, and every case it would serve needs the child to know the number anyway, which its command line has to carry regardless. The option name is reserved.
  • run-process is Scheme over a bootstrap stub, not a primitive. Spawning and joining fibers is dispatch-loop work a native frame cannot do — which is exactly what %process-spawn was added in Phase 1 to support. Two consequences the KEP did not anticipate are recorded with it.

The rest: a third process-wait tier (the polled park, for kernels where pidfd_open is ENOSYS — Rosetta included, which CI actually runs), run-process's output: option and its three unstated defaults, the Windows 128 + n signal folding, two redirection-port rejections, the explicit SIGPIPE handling on both sides, process-environment as a procedure in its own right, the process-timeout condition taking no new KP code, and the implementation plan's stale "cond-expand feature" line contradicting the section above it.

Open follow-ups

The release itself, and the two pre-existing fd-inheritance leaks this KEP's own CLOEXEC audit surfaced — kaappi/kaappi#2422 and kaappi/kaappi#2424. Neither is reachable through (kaappi process)'s own spawn path, which closes by default.

🤖 Generated with Claude Code

All four phases of (kaappi process) landed on kaappi main between
2026-08-31 and 2026-09-01 (kaappi/kaappi#2442, #2445, #2450, #2455), ahead
of ratification. This accepts them retroactively and reconciles the
document with what shipped.

Status goes to Accepted, not Final: nothing here is in a release --
v0.25.0 predates Phase 1 -- and the process reserves Final for a released,
reconciled design.

The four unresolved questions are all settled, each annotated in place:

1. Pseudo-terminals stay deferred, now with four phases of evidence
   behind it, and explicitly not as an open follow-up -- adding one later
   is another redirection spec, not a redesign.
2. Cross-thread process-wait raises, as proposed, and the check is on
   every entry point rather than just the wait: one owner check makes the
   whole class unreachable.
3. Zombie discipline got the sweep *and* the GC finalizer. The KEP's
   "considered only if a concrete program escapes the sweep" was settled
   in Phase 1 instead, because a Process collected while its child runs is
   what a program that spawns and drops the handle does every time.
4. Status encoding is the flat integer plus (signaled . n).

Ten divergences recorded. The two worth reading:

- pass-fds: was never implemented and is withdrawn. A redirection spec may
  *be* an fd-backed port, which covers the cases that have names; a
  general allowlist has no consumer and needs the child to know the
  descriptor number anyway.
- run-process is Scheme over a bootstrap stub, not a primitive. Spawning
  and joining fibers is dispatch-loop work a native frame cannot do --
  which is what %process-spawn was added in Phase 1 to support.

Also: a third process-wait tier (the polled park, for kernels where
pidfd_open is ENOSYS, Rosetta included), the Windows 128+n signal folding,
two redirection-port rejections, the explicit SIGPIPE handling on both
sides, process-environment as a procedure in its own right, and the
implementation plan's stale "cond-expand feature" line.

Open follow-ups: the release itself, and the two pre-existing
fd-inheritance leaks this KEP's own CLOEXEC audit found
(kaappi/kaappi#2422, #2424).

Signed-off-by: Baiju Muthukadan <baiju.m.mail@gmail.com>
@baijum
baijum merged commit a495455 into main Sep 1, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant