Share private owner protection and delete the Pi platform copy
Problem
Pi owns a separate OS credential-protection implementation, while LocalHarness persists its owner independently. This prevents deleting the duplicated bootstrap boundary.
Design
Share bounded current-user payload protection in acyclic-native-runtime. Both Pi and LocalHarness use the same functions. DPAPI output stays foreign-owned and is cleared/freed after the caller's callback, including callback errors and unwinding; only successful API output is adopted. The caller still funds its original payload copy. Pi key generation now uses getrandom.
Deletions
Delete plugin/src/pi_owner_protection.rs and its BCrypt/DPAPI implementation; repoint production and test callers. The change relative to #495 is +239 / -158, net +81, including five focused protection tests. Remaining GraphCoder and Pi owner/root-provider bootstrap deletion work is still required.
Decisions
-
Substrate decision 10: all harness communication uses stream transactions and follows. Agent-to-agent handoffs use atomic appends plus filesystem publication; clients submit appends/request files and follow the multiplexed Streams session. No actor WebSockets or virtual channels are used.
-
Substrate decision 6 replaces the former service plan. No harness service, gateway, daemon or transport is added.
-
pi_owner*maps to the existing LocalHarness owner bootstrap; credentials are per-user state, and policy is authenticated task admission rather than a second Pi owner file. -
pi_root_provider*maps to LocalHarness workspace/volume composition and the shared filesystem resource-creation path. Retain its source-identity, original-work and admission checks in the harness while removing the Pi allocator. -
pi_native_host/authoritymaps to harness admission, result-writer and journal binding. Pi must not issue a second signing authority. -
GraphCoder
native/{mod,config}maps to LocalHarness configuration and the shared actor client. Wrapper rendering remains client-side; task/effect execution belongs to the actor package. -
The gc-service lane owns actor entry/manifest and the in-process runtime; gc-client owns the one client trait to platform APIs/local runtime. Existing socket/wire code maps there only where needed as local runtime/client implementation, otherwise it is deleted. Stream multiplexing belongs to Streams.
-
Finish #535 and #495 first, then bind bash/fs to the checkout together with #503, then perform these consumer deletions. Keep this PR draft until the bootstrap paths are actually removed and the startup regressions pass.
-
Stack on #495; merge it first. This is the first consumer follow-up and does not rewrite pushed history.
-
Keep the original Pi byte bounds and native-work copy callback. LocalHarness uses the same bounded path and writes protected bytes directly, without an extra SDK-owned ciphertext copy.
-
Use Windows current-user DPAPI and Unix private file permissions.
-
Keep all README changes in #509.
Tests run
- Windows at 8e4a4907a: all five protection cases passed in 0.01 s (0.293 s process time), after building. Covers round trip, corrupt ciphertext, input/output bounds before copying, and callback failure propagation.
- git diff --check passed.
- Windows: cargo check --locked -p acyclic-plugin --tests passed.
- macOS: all three portable protection cases passed at 8e4a4907a in under 0.01 s (0.45 s process); cargo check --locked -p acyclic-plugin --tests passed.
- WSL: all three portable protection cases passed at 8e4a4907a in under 0.01 s; cargo check --locked -p acyclic-plugin --tests passed.
- LocalHarness is merged through #495. The native recovery matrix and private-summary follow-up are green in #681 and #711; those results do not establish Pi startup parity.
Draft: review P1 remains open until the remaining Pi/GraphCoder bootstrap copies are deleted and repointed.
Live steps
Verify hosted Actors effect bindings for outbound HTTPS, bash compute and credential secrets. Continue with the in-process local runtime while those platform capabilities are established.
Current deletion ownership
2026-10-17 dependency audit: #626 is merged and GraphCoder native/ is absent from origin/main at 1b26e4a7770895b7afb5b967e359a59788e4ccdc. Pi pi_owner*, pi_root_provider* and pi_native_host/authority still exist on main; their replacement belongs to open #515 at 52f7252ae469dfb9501c70b106da3851f18874d6. #515 remains draft with its own blocking review findings. This PR remains draft until that migration lands; do not duplicate its bootstrap implementation here. The shared native-runtime protection implementation in this branch is still absent from main. The coordinator must decide whether that surviving protection delta is retained after the Pi migration.