Repository navigation
feat: add NVX phase 2 filesystem and one-shot foundations - #8779
Conversation
Build deterministic EROFS layers and private ext4 scratch images. Add a fail-closed adapter for one-shot NVX execution. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6b7bb21d-a74b-4061-b1d0-ae2a18df7a8c
Documentation PreviewDocumentation has been built for this PR. To view locally:
Built from commit 52c8d9a |
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Filesystem staging has credential and race vulnerabilities, identity configuration can diverge, and process-group termination can leave descendants running.
Get a fresh assessment by requesting another Copilot review.
Review effort: Balanced
Findings: 2
Open (4)
What changed in this PR
Adds Phase 2 NVX filesystem and one-shot execution foundations without enabling NVX as a runtime.
Changes:
- Builds deterministic EROFS layers and private ext4 scratch images.
- Adds one-shot execution, output filtering, timeout handling, and outcome validation.
- Documents the Phase 2 security boundary.
| File | Description |
|---|---|
src/nvx/filesystem-builder.ts |
Builds filesystem artifacts and manifests. |
src/nvx/filesystem-builder.test.ts |
Tests filesystem preparation and exclusions. |
src/nvx/one-shot-adapter.ts |
Implements one-shot NVX execution. |
src/nvx/one-shot-adapter.test.ts |
Tests execution outcomes and filtering. |
src/nvx/outcome.ts |
Parses strict outcome reports. |
src/nvx/outcome.test.ts |
Tests outcome validation. |
src/nvx/index.ts |
Exports NVX APIs. |
docs/nvx-security-design.md |
Documents Phase 2 boundaries. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| const DEFAULT_EXCLUDED_PATHS = CREDENTIAL_ENTRIES.map(({ path: entryPath }) => | ||
| normalizeRelative(entryPath) | ||
| ); |
| } else { | ||
| await fs.mkdir(path.dirname(destination), { recursive: true, mode: 0o700 }); | ||
| await fs.copyFile(current, destination); |
| readonly scratchUid?: number; | ||
| readonly scratchGid?: number; |
| child.once('exit', (exitCode, signal) => { | ||
| clearTimeout(timeout); | ||
| clearTimeout(forceKillTimer); |
Read NVX outcomes through a no-follow file descriptor. Update the vulnerable adm-zip override and correct the runner-doctor assertion. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6b7bb21d-a74b-4061-b1d0-ae2a18df7a8c
|
✅ Copilot review passed with no inline comments. @lpcox Add the |
|
| Metric | Base | PR | Delta |
|---|---|---|---|
| Lines | 94.26% | 93.54% | 📉 -0.72% |
| Statements | 92.96% | 92.23% | 📉 -0.73% |
| Functions | 93.56% | 92.64% | 📉 -0.92% |
| Branches | 86.92% | 86.19% | 📉 -0.73% |
📁 Per-file Coverage Changes (1 files)
| File | Lines (Before → After) | Statements (Before → After) |
|---|---|---|
src/log-directory-setup.ts |
96.2% → 100.0% (+3.78%) | 96.3% → 100.0% (+3.71%) |
✨ New Files (4 files)
src/nvx/filesystem-builder.ts: 89.1% linessrc/nvx/index.ts: 0.0% linessrc/nvx/one-shot-adapter.ts: 67.3% linessrc/nvx/outcome.ts: 84.0% lines
Coverage comparison generated by scripts/ci/compare-coverage.ts
|
@copilot address review feedback |
|
| Metric | Base | PR | Delta |
|---|---|---|---|
| Lines | 94.26% | 93.75% | 📉 -0.51% |
| Statements | 92.96% | 92.43% | 📉 -0.53% |
| Functions | 93.56% | 92.99% | 📉 -0.57% |
| Branches | 86.92% | 86.22% | 📉 -0.70% |
📁 Per-file Coverage Changes (1 files)
| File | Lines (Before → After) | Statements (Before → After) |
|---|---|---|
src/log-directory-setup.ts |
96.2% → 100.0% (+3.78%) | 96.3% → 100.0% (+3.71%) |
✨ New Files (4 files)
src/nvx/filesystem-builder.ts: 88.4% linessrc/nvx/index.ts: 0.0% linessrc/nvx/one-shot-adapter.ts: 79.8% linessrc/nvx/outcome.ts: 84.0% lines
Coverage comparison generated by scripts/ci/compare-coverage.ts
|
✅ Security Guard completed successfully! PR #8779 passes security review: adm-zip version bump (0.6.0→0.6.1) is a routine dependency update with no firewall rule changes, capability additions, egress expansion, or other security-weakening modifications.
|
|
✅ Smoke Copilot BYOK completed. Copilot BYOK mode operational. 🔓
|
|
Chroot tests passed! Smoke Chroot - All security and functionality tests succeeded.
|
|
📡 Smoke OTel Tracing completed. All tracing scenarios validated. ✅
|
|
❌ Smoke Copilot BYOK AOAI (Entra) reports failed. AOAI BYOK (Entra) mode investigation needed...
|
|
✅ Build Test Suite completed successfully!
|
|
🛡️ Smoke Copilot Network Isolation confirmed the egress allowlist is enforced. ✅ Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
To allow these domains, add them to the network:
allowed:
- defaults
- "example.com"See Network Configuration for more information.
|
|
✨ The prophecy is fulfilled... Smoke Codex has completed its mystical journey. The stars align. 🌟 Warning Firewall blocked 7 domainsThe following domains were blocked by the firewall during workflow execution:
To allow these domains, add them to the network:
allowed:
- defaults
- "accounts.google.com"
- "clients2.google.com"
- "contentautofill.googleapis.com"
- "msfeed25.pkgs.visualstudio.com"
- "update.googleapis.com"
- "www.google.com"
- "www.gstatic.com"See Network Configuration for more information.
|
|
❌ Smoke Copilot BYOK AOAI (api-key) reports failed. AOAI BYOK (api-key) mode investigation needed...
|
|
✅ Smoke Claude passed Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
To allow these domains, add them to the network:
allowed:
- defaults
- "api.anthropic.com"See Network Configuration for more information.
|
|
📰 DEVELOPING STORY: Smoke Docker Sbx reports failed. Our correspondents are investigating the incident...
|
|
🔌 Smoke Services — All services reachable! ✅
|
|
📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤
|
|
❌ Smoke Gemini reports failed. Facets need polishing...
|
|
EGRESS_RESULT allow=pass deny=pass ✅ Allowed domain (github.com) reachable: Overall: PASS Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
To allow these domains, add them to the network:
allowed:
- defaults
- "example.com"See Network Configuration for more information.
|
Smoke Test: Copilot BYOK (Direct Mode) ✅ PASS
Running in direct BYOK mode via
|
Smoke Test: Claude Engine Validation
Overall result: PASS Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
To allow these domains, add them to the network:
allowed:
- defaults
- "api.anthropic.com"See Network Configuration for more information.
|
|
Smoke Test: Copilot Engine — cc @lpcox
Overall: PASS
|
|
AWF Sandbox Connectivity Smoke Test
Overall: PASS
|
🏗️ Build Test Suite Results
Overall: 8/8 ecosystems passed — PASS Notes:
|
Chroot Version Comparison Results
Overall: FAILED — Node.js version mismatch between host and chroot environment.
|
|
Smoke test
Warning Firewall blocked 7 domainsThe following domains were blocked by the firewall during workflow execution:
To allow these domains, add them to the network:
allowed:
- defaults
- "accounts.google.com"
- "clients2.google.com"
- "contentautofill.googleapis.com"
- "msfeed25.pkgs.visualstudio.com"
- "update.googleapis.com"
- "www.google.com"
- "www.gstatic.com"See Network Configuration for more information.
|
📡 OTel Tracing Smoke Test Results
Summary: All 5 scenarios pass. No regressions detected in OTel tracing integration.
|


Summary
nvx.py sandbox runadapter with process-group timeout/cancellation, minimal host environment, streaming workflow-command filtering, and bounded raw diagnostic tails125, and verify the reported network policy matches the requested fail-closed policyValidation
npm run buildnpm run lintnpm run type-checknpm test -- --runInBand src/nvx/filesystem-builder.test.ts src/nvx/outcome.test.ts src/nvx/one-shot-adapter.test.tsnpx markdownlint-cli2 docs/nvx-security-design.mdThe full test suite reports 6002 passing tests and one unrelated existing failure in
scripts/ci/self-hosted-runner-doctor-workflow.test.ts; both the test and portable-agent input are byte-identical toorigin/main.