
An in-process CoreCLR / .NET 11 runtime — JIT, full reflection, runtime self-compile via Roslyn — hosting PowerShell 7.7, with the garbage collector removed from the data plane. Memory is owned by the Virtual Object Manager, not a tracing GC. Not Mono. Not AOT. The same binary logic runs on Windows x64 and Android ARM64.
As far as the record shows, this is the first native in-process CoreCLR + PowerShell runspace on Android. No Termux, no Linux layer, no chroot, no root. It is microkernel-shaped, not a microkernel in the strict sense: owners share one address space and isolate cooperatively.
The project is six weeks old. It is developed solo, at high velocity, pairing with AI coding agents — and the compiler gate below exists partly for that reason: code is held to the same structural law regardless of whether a human or a model wrote it.
The Windows NT Object Manager got the important things right: one namespace, the handle as the sole form of authority, mechanism over policy. It also had structural faults it could never shed — a closed ring-0 type taxonomy that cannot be extended from outside the kernel, a registry bolted on as a second store of truth beside the namespace instead of a projection of it, and a kernel that cannot host or rebuild itself.
Subsystem keeps the discipline and removes the faults with one move: recursion. There is one self-similar node type — a child object manager is the same type as its parent. The registry projects the namespace rather than duplicating it. And the image builds itself from source it carries. Terminating an owner cancels its token and cascades depth-first, revoking every child handle; a wedged thread is left resourceless while the rest of the system keeps running.
A unit of work is a 256-byte-aligned shared memory region, a monotonic timeline fence, and free-on-zero refcounting. You push it across a boundary. The boundary is the only thing that changes: inside the process, the handle is a pointer. Between processes, it is an NT shared handle. Across a die, a language, or a machine, it is the same contract over a C ABI.
This is one primitive applied at every scale, on purpose. Threads inside the process trade work the same way processes do — a handle and a fence, never a shared mutable object. In-process handoff is IPC-shaped deliberately: the determinism comes from the contract, not from proximity. And because the data plane is native memory behind a C ABI, a C++ module and a C# module share one heap: sharing a base pointer and a layout is sharing the heap. Delivery is push-based and latest-wins — a stale frame drops. That is the correct semantic for streaming inference and the wrong one for transactions; the system is built for the former.
A path-named, generational handle table over native-allocated, 256-byte-aligned memory. Handles are refcounted and freed at zero. Owners are hierarchical and carry byte and element quotas; exceeding one throws. Terminate cancels the owner's token and cascades depth-first, revoking every child handle and reclaiming native memory in one pass. Stale handle IDs are rejected in O(1) by generation check.
The registry projects the namespace; it is not a second store beside it. Capabilities, prompts, tools, and UI directives are rows: a volatile in-memory plane for reads, a durable SQLite WAL plane for restarts. Nothing downstream holds its own truth. The shell reads its front door from a record and can be swapped without recompiling.
The transport. A producer writes a shared 256-byte-aligned region, signals a value-based fence; consumers wait on the value. Zero-copy on the same adapter. The UI is a consumer like any other: shared float regions and fence ticks, no HTTP server, no loopback port, no JSON envelope on the hot path.
The inference protocol. model.db is the truth; ONNX, LiteRT, QNN, and GGUF files are treated as lossy projections of it. Tensors live in VOM memory, off the GC heap. The decode loop is a citizen of the object model (DpxDecoder : ITurnSource); a foreign engine is a mounted guest behind one narrow contract, brought up and torn down like any other device.
ss itself is the agent; there is no middle layer. An on-device model (Gemma, via DPX or a mounted guest) drives the OS through the same object model the human uses. Its tool surface is projected from registry records; hardware tools check a consent record before dispatch, default-deny. Work arrives through a request queue shaped like Remedy ITSM — symptom, root cause, resolution, verification — a shape chosen because models carry decades of ITSM convention in their training data: an agent handed a request already knows the discipline. The model chooses; the deterministic harness does the work.
PowerShell 7.7 is mounted as a device under the VOM: owned, refcounted, enumerable, torn down by the same cascade as everything else. Remoting is in-process PSRP; results cross the boundary as serialized objects with type fidelity, never as text to be parsed. Cmdlet arguments bind structurally — prose stays data.
The binary carries its own source and compiles itself in-process with Roslyn (ss build self) — no external SDK, no MSBuild — running 26 analyzers over its own tree on every build. The gate is fail-closed: 573 standing findings are held under a ratchet, and a single new finding fails the build. The baseline shrinks only by fixing.
The loop composes. The binary rebuilds itself, the gate rides every rebuild, and the ratchet only tightens — so each pass leaves the system structurally stronger, not more fragile. That is what makes a one-person project at this velocity hold: the rules are not written down for contributors to remember, they are compiled into the thing itself, and they bind human and model authors identically. Exact rule titles, from the code:
| Rule | Title |
|---|---|
| SS000 | SystemCatalog.json unavailable — fail-closed when the catalog is missing or unparsable |
| SS001 | PowerShell source baked into C# |
| SS002 | No such rule. The numbering does not backfill. |
| SS003 | Static dictionary as object store |
| SS004 | Fabricated namespace path |
| SS005 | System-integrity capability carries a script body |
| SS006 | Per-call new Random() |
| SS007 | Empty catch swallows the error |
| SS008 | Cmdlet returns raw memory instead of a VOM handle |
| SS009 | Ambient thread outside the kernel |
| SS010 | Hardcoded absolute path or URL |
| SS011 | Namespace not in the component catalog |
| SS012 | Type name violates the closed grammar |
| SS013 | Method does not start with a registered verb |
| SS014 | Reference violates the component DAG |
| SS015 | Static field remembers state in a component |
| SS016 | Handle value parsed outside the kernel |
| SS017 | Banned word in a name, or casual/inflammatory comment |
| SS018 | Async in the core (the core is synchronous) |
| SS019 | A comment narrates a removal or rename |
| SS020 | Hardcoded model or system prompt |
| SS021 | Ambient host path in the portable core |
| SS022 | HTTP server for the UI |
| SS023 | In Memoriam — the dedication is load-bearing; the build fails if it is altered or removed |
| SS024 | Retired word in a string literal |
| SS025 | Retired term crossed into a name or path we author |
| SS026 | Raw pointer crosses a boundary instead of a VOM handle |
| SS027 | Android API floor below 36 (Android 16) |
The type grammar is closed: names are mechanism nouns, methods begin with approved verbs, and suffixes like Manager, Helper, Factory, and Orchestrator do not compile.
| Test | What it proves | Result |
|---|---|---|
| check --gate | 26 analyzers over the full tree; baseline 573, new findings 0 | GREEN 2026-07-01 |
| selftest | 4 MiB allocated and reclaimed; stale handles rejected; 3-deep owner cascade to zero; quorum wait parks then wakes (~128 ms laggard, by design) | GREEN 2026-07-01 |
| kokoro parity | Kokoro-82M end-to-end on the in-house ONNX interpreter: 49/49 op-types, all 2,463 nodes; RMSE vs the onnxruntime oracle | 2.516e-2 (floor 3.0e-2) |
| matmulnbits | SIMD q4 kernel; 16-token decode 88.4 s → 17.1 s; parity vs the scalar oracle is the binding receipt | 5.2× |
| q4 GEMM on D3D12 | MLP up-projection, decode shape M=1 K=2048 N=8192: CPU 24.9 ms → GPU 1.1 ms, parity-exact vs the scalar oracle (max|diff| ≤ 1.4e-4); kernel per shape-class selected by measured tournament. Timings provisional — shared box. | 21.9× |
| full suite | 24 pass / 2 fail / 2 skip. The failures are named: test.gpu.dpgpu-gemm-csharp (regression; was green 2026-06-29) and test.staging.ai-transport-assets (has not yet passed) | RED 2026-07-01 |
Every test prints a receipt: the command, the verdict, and the measured numbers, appended to a ledger the binary writes itself. A number appears here only after a benchmark prints it. The suite state above is reported as-is, including the failures.
Recent entries, newest first. Compressed from commit subjects; the full history is in git.