Merge nucleic/olive-jade-civet-rznt into dev

This commit is contained in:
2026-07-29 00:05:26 -07:00
parent 5af84b8edc
commit b342860779
4 changed files with 529 additions and 0 deletions
+77
View File
@@ -0,0 +1,77 @@
# M1 spikes (docs/WINDOWS_PORT.md §13)
Programs that answer questions the port is currently *guessing* at. They are checked in and
runnable on purpose: a spike whose answer nobody can reproduce six months later is a rumour.
They are deliberately **not** in `windows/Nucleic.sln`. The solution's broker contract tests must
keep running on any machine against `FakeWslc`; these need the `Microsoft.WSL.Containers` preview
NuGet and a real WSL stack, so they are built by path.
---
## `WslcApiDump` — what does the wslc API actually look like?
**The problem it solves.** Items 5, 6 and 7 — the C# broker, the Swift wslc client, and the
control plane — were all built against Microsoft's *documentation*, on machines with no WSL.
`NucleicBroker/Wslc/WslcFacade.cs` is therefore a careful transcription that has never been
compiled against the real assembly, and `-p:UseWslc=true` is the only thing standing between it
and the build. Every line in it might be right. We have no idea which.
A typed spike cannot tell us: if `Session.CreateOrOpen` is really `Session.Open`, the spike fails
to **compile**, which teaches us one name and stops. So this tool is written entirely in
reflection. It cannot fail to build, and a single run prints the complete list of what is wrong.
```powershell
cd windows/spikes/WslcApiDump
dotnet run # dump the API + check every facade assumption
dotnet run -- --probe # + call the two read-only statics (service version, missing components)
dotnet run -- --session # + create a real session and print its live property VALUES
```
It writes the full public object model to `wslc-api-dump.txt` (`--out` to relocate) and prints an
`ok` / `MISSING` line per assumption, each with *why that member matters* and a nearest-name hint.
It exits 0 even when assumptions fail — a mismatch is the product, not an error. Only a genuinely
broken run (the assembly won't load) exits non-zero.
**What to send back:** the console output, and `wslc-api-dump.txt` if anything is MISSING.
### Why `--session` earns its risk
`--session` creates a real wslc session named `nucleic-spike` under
`%LOCALAPPDATA%\Nucleic\spike\wslc` and leaves it running. It exists for one question that type
metadata cannot answer: **where does the WSL-facing host gateway address come from?** §5 makes
gateway TCP the primary control-plane transport, `WslcContainerEngine.ensureRunning` returns that
address to the Swift side, and `control-bridge.js` dials it. The facade guesses
`Session.HostGatewayAddress`. Dumping the live *values* of every session property lets us
recognise a gateway IP whatever it is called — and if nothing on the session looks like one,
that is itself the finding, and §5's hvsocket fallback gets promoted from upside to dependency.
Leaving the session running is also the cheap version of a §2.3 question: broker supervision
assumes wslc state is **service-backed**, so that a crashed `nucleic-brokerd` can reattach and
re-enumerate rather than orphaning containers. If `wslc session ls` still shows `nucleic-spike`
after this process exits, that assumption holds. Tear it down with `wslc` when you're done.
### The three answers that change the design
Most mismatches are a one-line edit in `WslcFacade.cs` — that is exactly what the `IWslc` seam is
for, and nothing above it should move. These three are different:
| Finding | Consequence |
| --- | --- |
| No create-or-attach on `Session` | Broker-crash reattach (§2.3) has no mechanism; supervision needs redesigning before item 11. |
| No gateway address on a live `Session` | §5's primary transport loses its source; promote the AF_HYPERV/AF_VSOCK fallback and spike that instead. |
| No uid on `ProcessSettings` | Recoverable, and already planned for: exec wraps argv in `setpriv`/`su agent -c`. Interceptors and nash don't care about the numeric uid (§3.2). |
---
## Not yet written
- **`WslcSpike`** — the typed happy path: session → GHCR pull of `naros-agent` → container with an
NTFS `ContainerVolume` → `exec git status` in the bind-mounted worktree → stdio round-trip →
SIGTERM, plus the 9P latency numbers §15 wants (`git status` and `npm install` on a real repo,
mounted vs. in-VM). Deliberately held back until `WslcApiDump` has run: written now, against
guessed names, it would not compile, and fixing it blind is the mistake this whole approach
exists to avoid.
- **`HvSocketSpike`** — M1 (b): AF_HYPERV host listener ↔ AF_VSOCK dial from inside a wslc
container, plus gateway-TCP reachability and default-firewall behaviour in NAT and mirrored
modes. Only worth building once a container can be started at all.