Move docs/ package mirror into document-navigator plugin

Relocate the ~6k-file docs tree from the repo root into
plugins/document-navigator/docs/ so the plugin is self-contained and
portable. docs/superpowers/ (specs and plans) stays at the repo root.

Moved via cp+rm rather than git mv because directory rename() fails with
EPERM on this WSL /mnt DrvFs mount; git rename-detection pairs the
identical-content files at commit time.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-30 01:10:00 +01:00
parent fe3fedf42e
commit 9bf56a806b
6022 changed files with 12437 additions and 0 deletions

View File

@@ -0,0 +1,100 @@
# Vm sandbox conformance harness
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
`runVmSandboxConformance(label, makeSandbox)` is the public conformance
suite every `vm.Context`-based sandbox host must pass. The suite
encodes the package's spec ADDED requirements as runnable assertions
so any future host implementation (an alternative isolate library, a
hardened wrapper, a worker-thread variant) plugs in against the same
contract by exporting a single factory function.
This module is the reusable bridge between the OpenSpec capability
spec and the implementation; checking that a sandbox passes the
harness is sufficient to verify it satisfies the public requirements.
## Features
- Six assertions covering: `process` global absence, frozen
`globalThis`, direct dynamic-code rejection, indirect dynamic-code
rejection, node-built-in import refusal, dispose idempotency.
- Adapter-driven: the harness calls `makeSandbox(source)` to obtain a
fresh handle for every assertion so adapters with non-trivial setup
cost can amortise it through closure capture.
- Permissive eval-code expectation: the indirect-dynamic case accepts
either `EVAL_REJECTED` or `INDIRECT_EVAL_REJECTED` so adapters that
implement only the broad trap still pass.
## Usage: Basic
```ts
import { runVmSandboxConformance } from "@suaveplan/api-sandbox-vm/testing";
import { createVmSandbox } from "@suaveplan/api-sandbox-vm/sandbox/sandbox";
import { createPermissionChecker } from "@suaveplan/api-sandbox-vm/permissions/checker";
runVmSandboxConformance("self", async (source) =>
createVmSandbox({
pluginId: "self",
logger: console as never,
checker: createPermissionChecker({ policy: {} }),
pluginModule: { kind: "source", identifier: "x", source },
proxies: {
fs: { readFile: async () => "", writeFile: async () => undefined },
fetch: {
request: async () => ({ status: 204, headers: {}, body: "" }),
},
capabilities: {},
},
})
);
```
## Usage: Advanced
Compose with a stricter checker and a pre-baked capability bag so the
harness also exercises the host's `__suaveplan` receiver:
```ts
import { runVmSandboxConformance } from "@suaveplan/api-sandbox-vm/testing";
import { createVmSandbox } from "@suaveplan/api-sandbox-vm/sandbox/sandbox";
runVmSandboxConformance("strict", async (source) =>
createVmSandbox({
pluginId: "strict",
logger,
checker: strictChecker,
pluginModule: { kind: "source", identifier: "strict.mjs", source },
proxies: {
fs: realFs,
fetch: realFetch,
capabilities: {
db: { query: async (sql) => realQuery(String(sql)) },
},
},
})
);
```
## API Reference
- `runVmSandboxConformance(label, makeSandbox)` — register the suite
under `runVmSandboxConformance — ${label}`.
- `type MakeVmSandbox` — factory accepting plugin source text and
returning a `VmSandboxHandle` (synchronously or via Promise).
## Implementation Notes
The harness uses `@suaveplan/testing/runner` so it remains runner-
agnostic — Bun-mode and Vitest-mode test runs see identical
descriptions and assertion semantics. Sandbox source strings are
constructed by concatenation rather than tagged templates so the
emitted code never references a host-side binding. The
`EVAL_TOK` token-split is a defence against static analysers that
would otherwise flag the harness as containing direct `eval` usage —
the harness exercises the trap, not the function. Disposal happens
inside every assertion so the harness never leaks contexts; the
adapter is responsible for tearing the handle down promptly.