Plan: POSIX Adapter
Overview
Implementation track for the POSIX adapter sketched in
docs/proposals/posix-adapter-proposal.md. The proposal’s Phase P1.1
through P1.3 decomposition is the source of truth; each task below maps to
one phase. This plan is ad-hoc until selected.
The v0 phases are parallel-safe with the kernel-core selected milestone in
the directories they own (new libcapos/, new libcapos-posix/, new
vendor/dns-c-wahern/, new vendor/dash/, new demos/c-hello/,
demos/posix-dns-resolver/, demos/posix-pipe-shim/, repo-root
system-c-hello.cue, system-posix-dns.cue, system-posix-pipe.cue,
matching Makefile targets, and proposal/plan docs). P1.2 and P1.3 add
new interfaces under schema/capos.capnp and must serialise on the shared
schema serial surface per docs/plans/README.md Concurrency Notes.
P1.1 is the strict prerequisite for P1.2 and P1.3 and is being landed under a separate libcapos C-substrate v0 task; this plan’s Task 1 tracks closeout coordination rather than re-doing the implementation.
Conflict Surface
Owned by this plan:
libcapos/(NEW Rust crate,crate-type = ["staticlib"], standalone likecapos-rt/).libcapos-posix/(NEW Rust crate, same staticlib pattern, links abovelibcapos).include/capos/andinclude/capos/posix/(NEW C header trees).vendor/dns-c-wahern/andvendor/dash/(NEW vendored upstream sources at pinned tags).demos/c-hello/,demos/posix-dns-resolver/,demos/posix-pipe-shim/(NEW per-phase smoke binaries; demos workspace addition).Makefile(newlibcapos-build,libcapos-posix-build,c-build,run-c-hello,run-posix-dns-smoke,run-posix-pipe-smoke, and the successorrun-posix-shell-smoketarget).- Repo-root
system-c-hello.cue,system-posix-dns.cue,system-posix-pipe.cue, and the successorsystem-posix-shell.cuefocused-proof manifests. docs/proposals/posix-adapter-proposal.md(status updates, closeout stamps, phase progress).docs/plans/posix-adapter.md(this file).docs/plans/README.mdTrack Map row only.docs/SUMMARY.mdPlans + Proposal Index entries for the new files.book.toml(new proposal entry,enable = falseuntil implementation lands).
Coordinated overlap with sibling tracks:
Cargo.tomlworkspace member entries (or standalone-crate handling) – the newlibcapos/andlibcapos-posix/crates are coordinated with the libcapos C-substrate v0 task that introduceslibcapos/. Treatlibcapos/itself as owned by P1.1 until that task closes; this plan ownslibcapos-posix/from P1.2 onwards.schema/capos.capnp(P1.2 addsUdpSocket+NetworkManager.createUdpSocket; P1.3 addsPipe). Both phases queue on the sharedschema/capos.capnpserial surface perdocs/plans/README.mdConcurrency Notes; do not run concurrently with other schema-touching plans, and do not run P1.2 and P1.3 concurrently against each other.kernel/src/cap/network.rsandkernel/src/virtio.rs(P1.2 UDP path). Coordinate with Device Driver Foundation if that work also touches these files.kernel/src/cap/process_spawner.rs(P1.3 fd-action grant path). Coordinate with anything mutating spawn grants.capos-rt/src/client.rs(P1.2UdpSocketClient, P1.3PipeClient).tools/(newc-buildhelper if it lands as a standalone tool).
Do not touch from this plan:
- Kernel-core cap tables, scheduler, device manager, or other userspace
runtime files outside
capos-rt/src/client.rsextensions described above. tools/remote-session-client/(owned by remote-session plan).docs/topics.md(auto-regenerated; never edit manually).docs/proposals/userspace-binaries-proposal.mdanddocs/programming-languages.md(owned by the libcapos C-substrate v0 task that introduces the C library row). Cross-link from this plan only after that task closes, to avoid duplicating the row update.WORKPLAN.md(track-add row update is owned by the planning audit refresh, not by this docs-only lift).
Validation Commands
make fmt-checkmake generated-code-checkcargo build --features qemucargo test-configcargo test-libcargo build-demos-caposmake capos-rt-checkmake run-smoke- Per-phase smoke targets (added as the matching task lands):
- P1.1:
make run-c-hello - P1.2:
make run-posix-dns-smoke - P1.3:
make run-posix-pipe-smoke - Successor (after Namespace + File caps land):
make run-posix-shell-smoke
- P1.1:
Treat the matching make run-* target for the most recent phase as
required for any iteration that touches this plan’s owned files.
Success Criteria
Each landed phase must keep its make run-* target green, leave unrelated
make run-* targets unaffected, and stamp the phase closeout in
docs/proposals/posix-adapter-proposal.md with commit hash and minute-
precision timestamp. The track is recorded done when the dash port lands
green against make run-posix-shell-smoke. P1.2 (DNS resolver smoke) and
P1.3 (pipe primitive smoke) close independently as their dependencies land.
Task 1: Phase P1.1 – libcapos C-substrate v0 + C hello-world smoke
- Owned by the separate libcapos C-substrate v0 task: thin Rust
staticlib mirror of
capos-rtfor C consumers. That task ownslibcapos/,include/capos/, thec-buildMake helper,demos/c-hello/, andsystem-c-hello.cue. Tracked here for closeout only – do not duplicate the implementation work in this plan. - On merge of the libcapos C-substrate v0 task, stamp the phase
closeout in
docs/proposals/posix-adapter-proposal.mdwith commit hash and minute-precision timestamp. - On merge of the libcapos C-substrate v0 task, refresh the Track
Map row in
docs/plans/README.mdto reflect that P1.1 is closed and the next schema-touching iteration (P1.2 or P1.3) is the current owner of this plan’s queue position.
Task 2: Phase P1.2 – UDP cap surface + dns.c stub resolver smoke
- Resolve open question §2 (DNS resolver candidate, recommended dns.c) before vendoring; promote to a final decision in the proposal.
- Resolve open question §8 (UDP cap surface scope: shape of
createUdpSocket,sendTo,recvFrom,close; readiness vs blocking-with-timeoutrecvFrom) before adding the schema additions; promote to a final decision in the proposal. - Resolve open questions §4 (errno representation) and §5 (fd table location) before writing the wrappers; promote each to a final decision in the proposal.
- Add
UdpSocketinterface andNetworkManager.createUdpSocketmethod toschema/capos.capnp. Queue on the shared schema serial surface; do not run concurrently with another schema-touching plan. Runmake generated-code-checkbefore downstream Cargo builds. - Extend
kernel/src/cap/network.rswith the UDP path mirroring the existing TCP path; add UDP RX demux on the existing scheduler-polled smoltcp runtime inkernel/src/virtio.rs. - Add typed
UdpSocketClientincapos-rt/src/client.rs. - Create
libcapos-posix/crate with the minimalsocket/sendto/recvfrom/pollsurface for one UDP fd at a time, plusmalloc/freere-export, errno cell, fd 2 stdio wrapper,clock_gettime/gettimeofday. - Vendor dns.c by William Ahern under
vendor/dns-c-wahern/at a pinned tag (single.cplus header). - Add
demos/posix-dns-resolver/(new C demo binary). - Add
system-posix-dns.cue(its own distinct CUE package; imports the sharedcapos.local/cue/defaultspackage per the slice-3 defaults pattern). - Add
make run-posix-dns-smoketarget. Smoke must printresolved <name> -> <addr>for a known A record (e.g. against QEMU slirp’s 10.0.2.3) and exit cleanly under QEMU. - Stamp the phase closeout in
docs/proposals/posix-adapter-proposal.mdwith commit hash and minute-precision timestamp.
Task 3: Phase P1.3 – Pipe capability + libcapos-posix pipe / fork-for-exec scaffolding
- Resolve open question §6 (fork policy: whether the shim records
inter-call
dup2/closeasposix_spawnfile actions or requires the port to callposix_spawnwith explicit file actions) before writing the wrappers; promote to a final decision in the proposal. - Resolve open question §9 (pipe cap design: kernel-allocated bounded SPSC ring with EOF on close vs shared MemoryObject + userspace ring) before adding the schema additions; promote to a final decision in the proposal.
- Add
Pipeinterface toschema/capos.capnp(small additive change, distinct from UDP andLaunchParameterssurfaces). Queue on the shared schema serial surface; do not run concurrently with P1.2 or another schema-touching plan. Runmake generated-code-checkbefore downstream Cargo builds. - Add
kernel/src/cap/pipe.rs: bounded SPSC byte ring backed by a kernel-allocated MemoryObject page, with EOF semantics on close. - Extend
kernel/src/cap/process_spawner.rsso spawn grants can mintPipehalves and bind them to the child’s standard fds. - Add typed
PipeClientincapos-rt/src/client.rs. - Extend
libcapos-posix/withpipe/dup2/closeover the new cap. - Extend
libcapos-posix/withfork/execve/waitpid/posix_spawnover ProcessSpawner (TLS “next exec is the real spawn” state machine, with the §6-confirmed handling of inter-call file actions). - Add
demos/posix-pipe-shim/: minimal C program thatpipe()s,posix_spawn()s a child whose stdout is the write end, parent reads from the read end and prints. This covers theposix_spawn-direct path. - Add a second smoke that exercises the §6-selected fork-for-exec
path: if §6 chooses the inter-call recording shim, the smoke must
pipe()thenfork()thendup2(fd, STDOUT_FILENO)thenexecve()and prove the recorded file actions are applied to the spawn; if §6 chooses the patched-port variant, the smoke must drive the patched call sequence end-to-end. Either path must fail closed when the recorded action allowlist is violated. - Add
system-posix-pipe.cue(its own distinct CUE package; imports the sharedcapos.local/cue/defaultspackage). - Add
make run-posix-pipe-smoketarget. Smoke must drive both theposix_spawn-direct path and the §6-selected fork-for-exec path, print the child’s emitted line through the parent for each path, and exit cleanly under QEMU. - Stamp the phase closeout in the proposal.
Task 4: Successor – vendor dash + ship make run-posix-shell-smoke
- Blocked on Namespace + File cap surface (Phase 2 of
docs/proposals/storage-and-naming-proposal.md). Note the block in the proposal status header until storage proposals land. - Vendor dash 0.5.13.x under
vendor/dash/at a pinned tag. - Extend
libcapos-posix/with file I/O wrappers over Namespace + File caps (open/read/write/stat/access/unlink, directory iteration via Directory cap), plusgetenv/setenv/putenvover the per-process env vector (populated fromLaunchParametersif available, else manifest rodata). - Add
system-posix-shell.cueandmake run-posix-shell-smoketarget. Smoke must runls; echo donefrom a heredoc and printdonecleanly under QEMU. - Stretch goal: extend the smoke to
cat foo | grep barend-to-end, exercising the P1.3 pipe primitive in a shell pipeline. - Resolve open questions §1 (shell candidate, confirm dash) and §7 (fd 0 backing) before vendoring; promote each to a final decision in the proposal.
- Stamp the phase closeout in the proposal.