MansfieldPlumbing
← mansfieldplumbing.dev
Source Contact
★ FREE-ON-ZERO ⚠ CASCADE-KILL ★ 256-BYTE-ALIGNED REGIONS ⚠ MONOTONIC TIMELINE FENCES ★ ONE OBJECT NAMESPACE ⚠ FAIL-CLOSED RATCHET ★ NOT MONO — NOT AOT ★ FREE-ON-ZERO ⚠ CASCADE-KILL ★ 256-BYTE-ALIGNED REGIONS ⚠ MONOTONIC TIMELINE FENCES ★ ONE OBJECT NAMESPACE ⚠ FAIL-CLOSED RATCHET ★ NOT MONO — NOT AOT
// Specification and Log

Subsystem

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.

01 //

Why

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.

02 //

The One Idea

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.

03 //

Mechanisms

VOM — Virtual Object Manager

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.

Cm — Configuration Manager

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.

DirectPort

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.

DPX — DirectPortX

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.

The Agent

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.

Pwsh — The Runspace

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.

04 //

The Gate

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:

RuleTitle
SS000SystemCatalog.json unavailable — fail-closed when the catalog is missing or unparsable
SS001PowerShell source baked into C#
SS002No such rule. The numbering does not backfill.
SS003Static dictionary as object store
SS004Fabricated namespace path
SS005System-integrity capability carries a script body
SS006Per-call new Random()
SS007Empty catch swallows the error
SS008Cmdlet returns raw memory instead of a VOM handle
SS009Ambient thread outside the kernel
SS010Hardcoded absolute path or URL
SS011Namespace not in the component catalog
SS012Type name violates the closed grammar
SS013Method does not start with a registered verb
SS014Reference violates the component DAG
SS015Static field remembers state in a component
SS016Handle value parsed outside the kernel
SS017Banned word in a name, or casual/inflammatory comment
SS018Async in the core (the core is synchronous)
SS019A comment narrates a removal or rename
SS020Hardcoded model or system prompt
SS021Ambient host path in the portable core
SS022HTTP server for the UI
SS023In Memoriam — the dedication is load-bearing; the build fails if it is altered or removed
SS024Retired word in a string literal
SS025Retired term crossed into a name or path we author
SS026Raw pointer crosses a boundary instead of a VOM handle
SS027Android 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.

05 //

Receipts

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.

06 //

Log

Recent entries, newest first. Compressed from commit subjects; the full history is in git.

2026-07-02a0ca671Deleted the broker layer between the agent and its engines. ss itself is the agent; DPX is a protocol; a foreign engine is a mounted guest.
2026-07-02989cce2gemma4-e2b wired through DPX as a presence-gated capability of the agent.
2026-07-0221ab956DpGang: a synchronous worker-gang execution primitive.
2026-07-02066bd18Per-token KV-cache allocate/copy/close replaced with a persistent VOM ring.
2026-07-02586a04bgemma4-e2b model variants consolidated into a single database; chunked tensor storage restored.
2026-07-02417cd29The resident model exposed over MCP as a query tool.
2026-07-0294c70d3Android Open Accessory USB transport, device and host roles; opt-in BLE discovery relay for MCP.
2026-07-02a7bdaf8Windows and Android GPU paths reconciled; two execution modes: race and deadline-drop.
2026-07-0128b5f9dAn unmeasured latency figure removed from the documentation. No number is cited until a benchmark prints one.
2026-07-019d0b5f9An evolutionary shader tournament for GPU kernel selection.
2026-07-01a8deabbGPU q4 GEMM path landed behind a correctness gate, with a measured receipt.
2026-07-01aaa4c88SIMD MatMulNBits: 16-token decode 88.4 s → 17.1 s (5.2×).
2026-07-015baeafaAgent loops moved under VOM ownership; contract-gate debt cleared to zero.
2026-07-01f50d024An in-process agent peer layer over VOM memory and CPU fences.
2026-07-01e4796b4The build decoupled from any externally installed dotnet SDK.
2026-07-01a427059Packed q4 weight bytes moved into VOM-native memory, off the GC heap.
2026-07-01ac6706bA vom: PowerShell drive provider; the live object table enumerates as a filesystem.
2026-07-014587010DpTensor: tensors backed by VOM memory rather than managed arrays.
2026-06-30f58e39dGraph projection into Qualcomm QNN context binaries.
2026-06-304ec7e2bSTABLEHLO_COMPOSITE ops expanded by executing their decomposition subgraphs.
2026-06-29c9f0e72The inference engine canonized as Subsystem.Dpx (DirectPortX).
2026-06-292e8a126An in-house token decode loop; no external inference runtime in the path.
2026-06-294386a07A TFLite-to-ONNX translator; the Gemma embedder runs on the in-house engine, bundled into ss.exe and the signed Android APK.