Skip to content

Commit a2cd01a

Browse files
committed
fix: generate valid MDX in conformance reports (remove icon, use Accordion, escape braces)
1 parent 5c2e0f4 commit a2cd01a

10 files changed

+52
-42
lines changed

docs/docs.json

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,20 +60,24 @@
6060
"features/typescript",
6161
"features/permissions",
6262
"features/filesystem",
63-
"features/virtual-filesystem",
6463
"features/networking",
6564
"features/module-loading",
6665
"features/output-capture",
6766
"features/resource-limits",
6867
"features/child-processes",
69-
"process-isolation"
68+
"features/virtual-filesystem",
69+
{
70+
"group": "Advanced",
71+
"pages": [
72+
"features/process-isolation"
73+
]
74+
}
7075
]
7176
},
7277
{
7378
"group": "Reference",
7479
"pages": [
7580
"api-reference",
76-
"nodejs-compatibility",
7781
"benchmarks",
7882
{
7983
"group": "Comparison",
@@ -85,6 +89,10 @@
8589
{
8690
"group": "Advanced",
8791
"pages": [
92+
"nodejs-compatibility",
93+
"nodejs-conformance-report",
94+
"posix-compatibility",
95+
"posix-conformance-report",
8896
"cost-evaluation",
8997
"architecture",
9098
"security-model"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
---
22
title: Process Isolation
33
description: Configure V8 process topology to control crash blast radius and resource partitioning.
4+
icon: castle
45
---
56

67
<Warning>Process isolation depends on `@secure-exec/v8`, which is experimental. APIs and behavior may change without notice.</Warning>

docs/features/virtual-filesystem.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: Custom Virtual Filesystem
2+
title: Virtual Filesystem
33
description: Implement your own VirtualFileSystem to control how sandboxed code reads and writes files.
44
icon: "hard-drive"
55
---

docs/nodejs-compatibility.mdx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
---
22
title: Node.js Compatibility
33
description: Target Node.js version and standard-library compatibility matrix for secure-exec.
4-
icon: "list-check"
54
---
65

76
## Target Node Version

docs/nodejs-conformance-report.mdx

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
---
22
title: Node.js Conformance Report
33
description: Node.js v22 test/parallel/ conformance results for the secure-exec sandbox.
4-
icon: "chart-bar"
54
---
65

76
{/* AUTO-GENERATED — do not edit. Run: pnpm tsx scripts/generate-node-conformance-report.ts */}
@@ -279,7 +278,7 @@ icon: "chart-bar"
279278
- `test-debugger-*.js` — debugger protocol requires inspector which is Tier 5 (Unsupported)
280279
- `test-quic-*.js` — QUIC protocol depends on tls which is Tier 4 (Deferred)
281280

282-
<details><summary>179 individual tests</summary>
281+
<Accordion title="179 individual tests">
283282

284283
| Test | Reason |
285284
| --- | --- |
@@ -463,7 +462,7 @@ icon: "chart-bar"
463462
| `test-buffer-resizable.js` | requires 'test' module (node:test) which is not available in sandbox |
464463
| `test-stream-consumers.js` | stream/consumers submodule not available in stream polyfill |
465464

466-
</details>
465+
</Accordion>
467466

468467
### unsupported-api (79 entries)
469468

@@ -473,7 +472,7 @@ icon: "chart-bar"
473472
- `test-shadow-*.js` — ShadowRealm is experimental and not supported in sandbox
474473
- `test-compile-*.js` — V8 compile cache/code cache features not available in sandbox
475474

476-
<details><summary>76 individual tests</summary>
475+
<Accordion title="76 individual tests">
477476

478477
| Test | Reason |
479478
| --- | --- |
@@ -489,14 +488,14 @@ icon: "chart-bar"
489488
| `test-fs-options-immutable.js` | hangs — fs.watch() with frozen options waits for events that never arrive (VFS has no inotify) |
490489
| `test-fs-promises-watch.js` | hangs — fs.promises.watch() waits forever for filesystem events (VFS has no watcher) |
491490
| `test-fs-watch-file-enoent-after-deletion.js` | hangs — fs.watchFile() waits for stat changes that never arrive (VFS has no inotify) |
492-
| `test-fs-watch-recursive-add-file-to-existing-subfolder.js` | hangs — fs.watch({recursive}) waits for filesystem events that never arrive (VFS has no inotify) |
493-
| `test-fs-watch-recursive-add-file-to-new-folder.js` | hangs — fs.watch({recursive}) waits for filesystem events that never arrive (VFS has no inotify) |
494-
| `test-fs-watch-recursive-add-file.js` | hangs — fs.watch({recursive}) waits for filesystem events that never arrive (VFS has no inotify) |
495-
| `test-fs-watch-recursive-assert-leaks.js` | hangs — fs.watch({recursive}) waits for filesystem events that never arrive (VFS has no inotify) |
496-
| `test-fs-watch-recursive-delete.js` | hangs — fs.watch({recursive}) waits for filesystem events that never arrive (VFS has no inotify) |
497-
| `test-fs-watch-recursive-linux-parallel-remove.js` | hangs — fs.watch({recursive}) waits for filesystem events that never arrive (VFS has no inotify) |
491+
| `test-fs-watch-recursive-add-file-to-existing-subfolder.js` | hangs — fs.watch(\{recursive\}) waits for filesystem events that never arrive (VFS has no inotify) |
492+
| `test-fs-watch-recursive-add-file-to-new-folder.js` | hangs — fs.watch(\{recursive\}) waits for filesystem events that never arrive (VFS has no inotify) |
493+
| `test-fs-watch-recursive-add-file.js` | hangs — fs.watch(\{recursive\}) waits for filesystem events that never arrive (VFS has no inotify) |
494+
| `test-fs-watch-recursive-assert-leaks.js` | hangs — fs.watch(\{recursive\}) waits for filesystem events that never arrive (VFS has no inotify) |
495+
| `test-fs-watch-recursive-delete.js` | hangs — fs.watch(\{recursive\}) waits for filesystem events that never arrive (VFS has no inotify) |
496+
| `test-fs-watch-recursive-linux-parallel-remove.js` | hangs — fs.watch(\{recursive\}) waits for filesystem events that never arrive (VFS has no inotify) |
498497
| `test-fs-watch-recursive-sync-write.js` | hangs — fs.watch() with recursive option waits forever for events |
499-
| `test-fs-watch-recursive-update-file.js` | hangs — fs.watch({recursive}) waits for filesystem events that never arrive (VFS has no inotify) |
498+
| `test-fs-watch-recursive-update-file.js` | hangs — fs.watch(\{recursive\}) waits for filesystem events that never arrive (VFS has no inotify) |
500499
| `test-fs-watch-stop-async.js` | uses fs.watch/watchFile — inotify not available in VFS |
501500
| `test-fs-watch-stop-sync.js` | uses fs.watch/watchFile — inotify not available in VFS |
502501
| `test-fs-watch.js` | hangs — fs.watch() waits for filesystem events that never arrive (VFS has no inotify) |
@@ -544,7 +543,7 @@ icon: "chart-bar"
544543
| `test-util-types-exists.js` | require('util/types') subpath import not supported by sandbox module system |
545544
| `test-websocket.js` | WebSocket global is not defined in sandbox — Node.js 22 added WebSocket as a global but the sandbox does not expose it |
546545
| `test-webstream-readable-from.js` | ReadableStream.from() static method not implemented in sandbox WebStreams polyfill — added in Node.js 20 and not available globally in sandbox |
547-
| `test-webstreams-clone-unref.js` | structuredClone({ transfer: [stream] }) for ReadableStream/WritableStream not supported in sandbox — transferable stream structured clone not implemented |
546+
| `test-webstreams-clone-unref.js` | structuredClone(\{ transfer: [stream] \}) for ReadableStream/WritableStream not supported in sandbox — transferable stream structured clone not implemented |
548547
| `test-zlib-brotli-16GB.js` | getDefaultHighWaterMark() not exported from readable-stream v3 polyfill — test also relies on native zlib BrotliDecompress buffering behavior with _readableState internals |
549548
| `test-buffer-constructor-outside-node-modules.js` | ReferenceError: document is not defined — test uses browser DOM API not available in sandbox |
550549
| `test-child-process-fork.js` | child_process.fork is not supported in sandbox |
@@ -554,7 +553,7 @@ icon: "chart-bar"
554553
| `test-fs-watchfile-ref-unref.js` | fs.watchFile not supported in sandbox |
555554
| `test-fs-write-stream-file-handle-2.js` | fs.promises.open (FileHandle API) not implemented |
556555

557-
</details>
556+
</Accordion>
558557

559558
### requires-v8-flags (239 entries)
560559

@@ -566,7 +565,7 @@ icon: "chart-bar"
566565

567566
- `test-permission-*.js` — spawns child Node.js process via process.execPath — sandbox does not provide a real node binary
568567

569-
<details><summary>172 individual tests</summary>
568+
<Accordion title="172 individual tests">
570569

571570
| Test | Reason |
572571
| --- | --- |
@@ -743,17 +742,17 @@ icon: "chart-bar"
743742
| `test-webstorage.js` | spawns child Node.js process via process.execPath — sandbox does not provide a real node binary |
744743
| `test-windows-failed-heap-allocation.js` | spawns child Node.js process via process.execPath — sandbox does not provide a real node binary |
745744

746-
</details>
745+
</Accordion>
747746

748747
### security-constraint (1 entries)
749748

750-
<details><summary>1 individual test</summary>
749+
<Accordion title="1 individual test">
751750

752751
| Test | Reason |
753752
| --- | --- |
754753
| `test-process-binding-internalbinding-allowlist.js` | process.binding is not supported in sandbox (security constraint) |
755754

756-
</details>
755+
</Accordion>
757756

758757
### test-infra (22 entries)
759758

@@ -762,7 +761,7 @@ icon: "chart-bar"
762761
- `test-runner-*.js` — Node.js test runner infrastructure — not runtime behavior
763762
- `test-eslint-*.js` — ESLint integration tests — Node.js CI tooling, not runtime
764763

765-
<details><summary>20 individual tests</summary>
764+
<Accordion title="20 individual tests">
766765

767766
| Test | Reason |
768767
| --- | --- |
@@ -787,23 +786,23 @@ icon: "chart-bar"
787786
| `test-worker-messaging-errors-handler.js` | passes in sandbox — overrides glob pattern |
788787
| `test-worker-messaging-errors-invalid.js` | passes in sandbox — overrides glob pattern |
789788

790-
</details>
789+
</Accordion>
791790

792791
### native-addon (3 entries)
793792

794-
<details><summary>3 individual tests</summary>
793+
<Accordion title="3 individual tests">
795794

796795
| Test | Reason |
797796
| --- | --- |
798797
| `test-http-parser-timeout-reset.js` | uses process.binding() or native addons — not available in sandbox |
799798
| `test-internal-process-binding.js` | uses process.binding() or native addons — not available in sandbox |
800799
| `test-process-binding-util.js` | uses process.binding() or native addons — not available in sandbox |
801800

802-
</details>
801+
</Accordion>
803802

804803
### vacuous-skip (34 entries)
805804

806-
<details><summary>34 individual tests</summary>
805+
<Accordion title="34 individual tests">
807806

808807
| Test | Reason |
809808
| --- | --- |
@@ -842,4 +841,4 @@ icon: "chart-bar"
842841
| `test-fs-utimes-y2K38.js` | vacuous pass — test self-skips because child_process.spawnSync(touch) fails in sandbox |
843842
| `test-tick-processor-arguments.js` | vacuous pass — test self-skips because common.enoughTestMem is undefined in sandbox shim |
844843

845-
</details>
844+
</Accordion>

docs/posix-compatibility.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
# POSIX Compatibility
1+
---
2+
title: POSIX Compatibility
3+
---
24

35
> **This is a living document.** Update it when kernel, WasmVM, Node bridge, or Python bridge behavior changes for any POSIX-relevant feature.
46
5-
> **Looking for automated test results?** See the [POSIX Conformance Report](posix-conformance-report.mdx) for os-test suite results with per-suite pass rates and exclusion details.
7+
> **Looking for automated test results?** See the [POSIX Conformance Report](posix-conformance-report) for os-test suite results with per-suite pass rates and exclusion details.
68
79
This document tracks how closely the secure-exec kernel, runtimes, and bridges conform to POSIX and Linux behavior. The goal is full POSIX compliance 1:1 — every syscall, signal, and shell behavior should match a real Linux system unless an architectural constraint makes it impossible.
810

9-
For command-level support (ls, grep, awk, etc.), see [WasmVM Supported Commands](wasmvm/supported-commands.md). For Node.js API compatibility (fs, http, crypto modules), see [Node.js Compatibility](nodejs-compatibility.mdx). For Python API compatibility, see [Python Compatibility](python-compatibility.mdx).
11+
For command-level support (ls, grep, awk, etc.), see [WasmVM Supported Commands](wasmvm/supported-commands.md). For Node.js API compatibility (fs, http, crypto modules), see [Node.js Compatibility](nodejs-compatibility). For Python API compatibility, see [Python Compatibility](python-compatibility).
1012

1113
---
1214

docs/posix-conformance-report.mdx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
---
22
title: POSIX Conformance Report
33
description: os-test POSIX.1-2024 conformance results for WasmVM.
4-
icon: "chart-bar"
54
---
65

76
{/* AUTO-GENERATED — do not edit. Run scripts/generate-posix-report.ts */}
@@ -15,7 +14,7 @@ icon: "chart-bar"
1514
| Passing | 3347 (99.9%) |
1615
| Expected fail | 3 |
1716
| Skip | 0 |
18-
| Native parity | 98.4% |
17+
| Native verified | undefined of 3347 passing tests verified against native output (NaN%) |
1918
| Last updated | 2026-03-23 |
2019

2120
## Per-Suite Results
@@ -47,5 +46,5 @@ WASI Preview 1 lacks the required syscall.
4746

4847
| Test | Reason | Issue |
4948
| --- | --- | --- |
50-
| `basic/sys_statvfs/fstatvfs` | fstatvfs() not part of WASI — no filesystem statistics interface | [#34](https://github.com/rivet-dev/secure-exec/issues/34) |
51-
| `basic/sys_statvfs/statvfs` | statvfs() not part of WASI — no filesystem statistics interface | [#34](https://github.com/rivet-dev/secure-exec/issues/34) |
49+
| `basic/sys_statvfs/fstatvfs` | fstatvfs() not part of WASI — no filesystem statistics interface | [#48](https://github.com/rivet-dev/secure-exec/issues/48) |
50+
| `basic/sys_statvfs/statvfs` | statvfs() not part of WASI — no filesystem statistics interface | [#48](https://github.com/rivet-dev/secure-exec/issues/48) |

docs/runtimes/node.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ const runtime = new NodeRuntime({
6363
These exports are also available from `@secure-exec/nodejs`.
6464
</Note>
6565

66-
By default, all runtimes share a single V8 child process. You can pass a dedicated `V8Runtime` handle via `createNodeRuntimeDriverFactory({ v8Runtime })` to control crash blast radius and resource partitioning. See [Process Isolation](/process-isolation) for topology options and trade-offs.
66+
By default, all runtimes share a single V8 child process. You can pass a dedicated `V8Runtime` handle via `createNodeRuntimeDriverFactory({ v8Runtime })` to control crash blast radius and resource partitioning. See [Process Isolation](/features/process-isolation) for topology options and trade-offs.
6767

6868
## exec vs run
6969

scripts/generate-node-conformance-report.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -233,14 +233,17 @@ const lines: string[] = [];
233233
function line(s = "") {
234234
lines.push(s);
235235
}
236+
/** Escape curly braces for MDX (they're interpreted as JSX expressions). */
237+
function esc(s: string): string {
238+
return s.replace(/\{/g, "\\{").replace(/\}/g, "\\}");
239+
}
236240

237241
// Frontmatter
238242
line("---");
239243
line("title: Node.js Conformance Report");
240244
line(
241245
"description: Node.js v22 test/parallel/ conformance results for the secure-exec sandbox.",
242246
);
243-
line('icon: "chart-bar"');
244247
line("---");
245248
line();
246249
line(
@@ -348,23 +351,23 @@ for (const cat of categoryOrder) {
348351
line("**Glob patterns:**");
349352
line();
350353
for (const { key, entry } of globs) {
351-
line(`- \`${key}\` — ${entry.reason}`);
354+
line(`- \`${key}\` — ${esc(entry.reason)}`);
352355
}
353356
line();
354357
}
355358

356359
if (individual.length > 0 && individual.length <= 200) {
357360
line(
358-
`<details><summary>${individual.length} individual test${individual.length === 1 ? "" : "s"}</summary>`,
361+
`<Accordion title="${individual.length} individual test${individual.length === 1 ? "" : "s"}">`,
359362
);
360363
line();
361364
line("| Test | Reason |");
362365
line("| --- | --- |");
363366
for (const { key, entry } of individual) {
364-
line(`| \`${key}\` | ${entry.reason} |`);
367+
line(`| \`${key}\` | ${esc(entry.reason)} |`);
365368
}
366369
line();
367-
line("</details>");
370+
line("</Accordion>");
368371
line();
369372
} else if (individual.length > 200) {
370373
line(

scripts/generate-posix-report.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ function line(s = '') {
9090
line('---');
9191
line('title: POSIX Conformance Report');
9292
line('description: os-test POSIX.1-2024 conformance results for WasmVM.');
93-
line('icon: "chart-bar"');
9493
line('---');
9594
line();
9695
line('{/* AUTO-GENERATED — do not edit. Run scripts/generate-posix-report.ts */}');

0 commit comments

Comments
 (0)