Skip to content

Conversation

@frontegg-david
Copy link
Contributor

@frontegg-david frontegg-david commented Jan 9, 2026

Summary by CodeRabbit

  • New Features

    • Configurable tool-bridge modes (string/direct) with payload-size limits, host-side bridge, safer sandbox-host calls, runtime memory guards for allocations, and return-value serialization-size checks.
    • Centralized safe-error handling and serialization-size utilities; improved handling for large/complex values and bigint serialization.
  • Documentation

    • Major README restructure (Install, Why Enclave?, Quick Start), streamlined navigation, theme/metadata updates, and removal of several in-repo doc pages.
  • Tests

    • Expanded tests for resource exhaustion, serialization limits, tool-bridge behavior, and memory-attack scenarios.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 9, 2026

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Removes many in-repo docs and README content; adds centralized safe-error utilities, a versioned string/direct tool-bridge with payload limits/sidecar support, return-value serialization-size checks, Array.fill memory guards, AST opt-in for dynamic fills, and expanded enclave-vm tests.

Changes

Cohort / File(s) Summary
Docs & README
README.md, docs/docs.json, docs/draft/docs.json, docs/draft/docs/..., docs/live/docs/libraries/vectoriadb.mdx
README reorganized; docs site manifest updated; many draft/live MDX pages removed.
UI Snippets
docs/live/snippets/card.jsx
Removed BlogCard component.
AST Guard: Resource Exhaustion
libs/ast-guard/src/presets/agentscript.preset.ts, libs/ast-guard/src/rules/resource-exhaustion.rule.ts
Added allowDynamicArrayFill?: boolean option and propagated into ResourceExhaustionRule; default false; enclave enables when memoryLimit set.
Safe Error Utilities
libs/enclave-vm/src/safe-error.ts, libs/enclave-vm/src/safe-runtime.ts, libs/enclave-vm/src/secure-proxy.ts
New centralized createSafeError / createSafeTypeError; replaced local implementations; standardized SecurityError throws.
Tool Bridge & Types
libs/enclave-vm/src/tool-bridge.ts, libs/enclave-vm/src/types.ts, libs/enclave-vm/src/enclave.ts
New host-side createHostToolBridge (JSON protocol, versioned), ToolBridgeMode/ToolBridgeConfig types, Enclave config normalization/validation and defaults for toolBridge.
VM Adapter & Double-VM
libs/enclave-vm/src/adapters/vm-adapter.ts, libs/enclave-vm/src/double-vm/double-vm-wrapper.ts, libs/enclave-vm/src/double-vm/parent-vm-bootstrap.ts
Added string-mode host bridge (__host_callToolBridge__), bridged tool call wiring, size checks, patched Array.prototype.fill memory estimation/tracking, hardened error objects, and removed leaked host globals; passed toolBridgeMode/maxPayload through bootstrap.
Serialization Size Protection
libs/enclave-vm/src/value-sanitizer.ts, libs/enclave-vm/src/adapters/vm-adapter.ts, libs/enclave-vm/src/double-vm/double-vm-wrapper.ts
Added estimateSerializedSize / checkSerializedSize; VM adapter and double-VM now check return-value serialized size and return MemoryLimitError-like payload when oversized.
Tests: coverage & behavior
libs/enclave-vm/src/__tests__/*
Added tool-bridge.spec.ts; expanded resource-exhaustion tests (dynamic Array.fill, rope/string exhaustion); updated constructor-obfuscation tests to use env secrets; adjusted test configs for toolBridge.
Minor docs/README adjustments
libs/enclave-vm/README.md
Tweaked security header wording and test counts.

Sequence Diagram(s)

sequenceDiagram
    participant Sandbox as Sandbox VM
    participant HostBridge as Host Tool Bridge
    participant ToolHandler as Tool Handler
    participant Sidecar as Sidecar (optional)

    Sandbox->>HostBridge: __host_callToolBridge__(JSON request)
    HostBridge->>HostBridge: Validate size & protocol version
    HostBridge->>HostBridge: Parse & validate tool call
    HostBridge->>ToolHandler: Execute tool handler
    alt Tool execution succeeds
        ToolHandler-->>HostBridge: Tool result
        HostBridge->>HostBridge: Sanitize & check size
        alt Result too large
            HostBridge->>Sidecar: Store large payload → ref
            HostBridge-->>Sandbox: JSON response with reference ID
        else Result fits
            HostBridge-->>Sandbox: JSON response with result
        end
    else Tool execution fails
        ToolHandler-->>HostBridge: Error thrown
        HostBridge->>HostBridge: Package error payload (truncated if needed)
        HostBridge-->>Sandbox: JSON error response
    end
Loading
sequenceDiagram
    participant Inner as Inner VM / Sandbox
    participant Adapter as VM Adapter
    participant SerCheck as Serialization Checker
    participant Host as Host

    Inner->>Adapter: execute() -> value
    Adapter->>SerCheck: checkSerializedSize(value, maxBytes)
    alt within limit
        SerCheck-->>Adapter: { ok: true, estimatedBytes }
        Adapter->>Host: return value
    else exceeds limit
        SerCheck-->>Adapter: { ok: false, error }
        Adapter->>Host: return MemoryLimitError-like result
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 I stitched a JSON bridge so neat,
I counted bytes before they meet,
Errors now wear null-proto hats,
Arrays ask first: "Will I fit that?"
Hop, clip, secure — I guard the beats.

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 61.54% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the main security enhancement focus across multiple files: safe error handling via new utilities and standardized error creation throughout the codebase.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 60870da and 24e2d85.

📒 Files selected for processing (3)
  • README.md
  • libs/enclave-vm/README.md
  • libs/enclave-vm/src/value-sanitizer.ts

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
libs/enclave-vm/src/__tests__/constructor-obfuscation-attacks.spec.ts (1)

611-703: Make env restoration + enclave.dispose() robust to unexpected throws / assertion failures.

Right now process.env is restored in finally, but await enclave.run(code) and enclave.dispose() sit outside that guard. If enclave.run throws unexpectedly or an assertion throws, you can leak env state and/or not dispose the enclave. Wrap both in the same try/finally.

Proposed fix
       const envKey = 'ENCLAVE_TEST_SECRET_35';
       const secretValue = 'FAKE_SECRET_FOR_SECURITY_CHALLENGE';
       const prevEnv = process.env[envKey];
       process.env[envKey] = secretValue;

       const code = `
@@
       `;

-      const result = await enclave.run(code);
-
-      try {
+      let result;
+      try {
+        result = await enclave.run(code);
         // The attack should be blocked - it should NOT return the secret from host process.env
         // If the attack succeeds, it returns the env var string.
         // If blocked, it returns a "blocked:" message, undefined, or throws an error.
         if (result.success) {
@@
         } else {
           // Execution failed with error - this is also acceptable as long as it's not the secret
           expect(result.error?.message).not.toContain(secretValue);
         }
       } finally {
         // Restore env for other tests
         if (prevEnv === undefined) {
           delete process.env[envKey];
         } else {
           process.env[envKey] = prevEnv;
         }
+        enclave.dispose();
       }
-
-      enclave.dispose();

Also applies to: 627-631, 677-699

🤖 Fix all issues with AI agents
In @docs/docs.json:
- Around line 81-83: Update the three navigation path entries so they point to
the actual documentation locations: replace "docs/libraries/enclave" with
"docs/docs/libraries/enclave", "docs/libraries/ast-guard" with
"docs/docs/libraries/ast-guard", and "docs/libraries/vectoriadb" with
"docs/docs/libraries/vectoriadb" in the docs.json navigation array so they match
the real files (enclave.mdx, ast-guard.mdx, vectoriadb.mdx).

In @README.md:
- Line 16: README contains inconsistent documentation URLs: replace the
alternate doc link (https://agentfront.dev/docs/guides/enclave) with the
canonical URL (https://enclave.agentfront.dev) so all documentation links in
README point to the same canonical URL, and verify docs.json/any other config
uses https://enclave.agentfront.dev as the canonical docs URL.
- Line 3: The README references a missing image asset via the <img> tag src
"assets/logo.dark.svg" which causes a broken image; either add the missing file
named "logo.dark.svg" under the assets directory (so the existing <img> tag in
README.md resolves) or update the <img src="assets/logo.dark.svg"> entry in
README.md to point to an existing asset file/path or replace it with an
available logo filename.
🧹 Nitpick comments (3)
libs/enclave-vm/src/__tests__/safe-runtime-reference.spec.ts (1)

15-45: Keep test toolBridge defaults aligned with runtime normalization (avoid drift).

The added toolBridge block is sensible, but since it’s essentially “defaults”, consider referencing a shared default (if available) or add a short comment that this must track Enclave’s default normalization to prevent future divergence.

Also applies to: 29-33

libs/enclave-vm/src/__tests__/tool-bridge.spec.ts (1)

25-56: Payload size enforcement tests are well-structured.

Both request and response payload size tests verify the expected error messages. Consider also asserting on result.error?.code for more precise validation (e.g., TOOL_BRIDGE_RESPONSE_TOO_LARGE / TOOL_BRIDGE_REQUEST_TOO_LARGE).

💡 Optional: Add error code assertions for precision
     expect(result.success).toBe(false);
     expect(result.error?.message).toMatch(/Tool response exceeds maximum size/i);
+    expect(result.error?.code).toBe('TOOL_BRIDGE_RESPONSE_TOO_LARGE');
     expect(result.success).toBe(false);
     expect(result.error?.message).toMatch(/Tool request exceeds maximum size/i);
+    expect(result.error?.code).toBe('TOOL_BRIDGE_REQUEST_TOO_LARGE');
libs/enclave-vm/src/value-sanitizer.ts (1)

326-349: UTF-8 estimation doesn't handle 4-byte sequences (surrogate pairs).

The UTF-8 byte estimation handles 1-3 byte sequences but misses 4-byte sequences for code points >= U+10000 (encoded as surrogate pairs in JavaScript strings). While rare in typical data, this could underestimate sizes for strings containing emoji or other supplementary characters.

🔧 Optional fix for surrogate pair handling
       } else if (code < 2048) {
         bytes += 2; // 2-byte UTF-8
+      } else if (code >= 0xd800 && code <= 0xdbff) {
+        // High surrogate - next char is low surrogate, together they form a 4-byte UTF-8 sequence
+        bytes += 4;
+        i++; // Skip the low surrogate
       } else {
         bytes += 3; // 3-byte UTF-8
       }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f753d30 and c4122cc.

⛔ Files ignored due to path filters (27)
  • assets/logo.dark.svg is excluded by !**/*.svg, !**/*.svg
  • assets/logo.light.svg is excluded by !**/*.svg, !**/*.svg
  • docs/draft/assets/banners/codecall-plugin/code-call-example.png is excluded by !**/*.png
  • docs/draft/assets/banners/codecall-plugin/code-call-options.dark.png is excluded by !**/*.png
  • docs/draft/assets/banners/codecall-plugin/code-call-options.light.png is excluded by !**/*.png
  • docs/draft/assets/banners/codecall-plugin/code-call-plugin.png is excluded by !**/*.png
  • docs/draft/assets/banners/codecall-plugin/codecall-overview-dark.png is excluded by !**/*.png
  • docs/draft/assets/banners/codecall-plugin/codecall-overview-light.png is excluded by !**/*.png
  • docs/draft/assets/banners/codecall-plugin/early-day-vs-today.dark.png is excluded by !**/*.png
  • docs/draft/assets/banners/codecall-plugin/early-day-vs-today.light.png is excluded by !**/*.png
  • docs/draft/assets/banners/codecall-plugin/security-layers.dark.png is excluded by !**/*.png
  • docs/draft/assets/banners/codecall-plugin/security-layers.light.png is excluded by !**/*.png
  • docs/draft/assets/logo/banner.dark.png is excluded by !**/*.png
  • docs/draft/assets/logo/banner.light.png is excluded by !**/*.png
  • docs/draft/assets/logo/favicon-32x32.png is excluded by !**/*.png
  • docs/draft/assets/logo/favicon.dark.ico is excluded by !**/*.ico
  • docs/draft/assets/logo/favicon.svg is excluded by !**/*.svg, !**/*.svg
  • docs/draft/assets/logo/frontmcp.dark.png is excluded by !**/*.png
  • docs/draft/assets/logo/frontmcp.dark.svg is excluded by !**/*.svg, !**/*.svg
  • docs/draft/assets/logo/frontmcp.light.png is excluded by !**/*.png
  • docs/draft/assets/logo/frontmcp.light.svg is excluded by !**/*.svg, !**/*.svg
  • docs/draft/assets/logo/logo.dark.png is excluded by !**/*.png
  • docs/draft/assets/logo/logo.dark.svg is excluded by !**/*.svg, !**/*.svg
  • docs/draft/assets/logo/logo.light.png is excluded by !**/*.png
  • docs/draft/assets/logo/logo.light.svg is excluded by !**/*.svg, !**/*.svg
  • docs/favicon.ico is excluded by !**/*.ico
  • docs/live/favicon.ico is excluded by !**/*.ico
📒 Files selected for processing (35)
  • README.md
  • docs/docs.json
  • docs/docs/getting-started/installation.mdx
  • docs/docs/getting-started/welcome.mdx
  • docs/docs/libraries/ast-guard.mdx
  • docs/docs/libraries/enclave.mdx
  • docs/docs/libraries/vectoriadb.mdx
  • docs/draft/docs.json
  • docs/draft/docs/getting-started/installation.mdx
  • docs/draft/docs/getting-started/welcome.mdx
  • docs/draft/docs/libraries/ast-guard.mdx
  • docs/draft/docs/libraries/enclave.mdx
  • docs/draft/updates.mdx
  • docs/live/docs/libraries/vectoriadb.mdx
  • docs/live/snippets/card.jsx
  • docs/snippets/card.jsx
  • docs/style.css
  • docs/updates.mdx
  • libs/ast-guard/src/presets/agentscript.preset.ts
  • libs/ast-guard/src/rules/resource-exhaustion.rule.ts
  • libs/enclave-vm/src/__tests__/constructor-obfuscation-attacks.spec.ts
  • libs/enclave-vm/src/__tests__/enclave.spec.ts
  • libs/enclave-vm/src/__tests__/resource-exhaustion.spec.ts
  • libs/enclave-vm/src/__tests__/safe-runtime-reference.spec.ts
  • libs/enclave-vm/src/__tests__/tool-bridge.spec.ts
  • libs/enclave-vm/src/adapters/vm-adapter.ts
  • libs/enclave-vm/src/double-vm/double-vm-wrapper.ts
  • libs/enclave-vm/src/double-vm/parent-vm-bootstrap.ts
  • libs/enclave-vm/src/enclave.ts
  • libs/enclave-vm/src/safe-error.ts
  • libs/enclave-vm/src/safe-runtime.ts
  • libs/enclave-vm/src/secure-proxy.ts
  • libs/enclave-vm/src/tool-bridge.ts
  • libs/enclave-vm/src/types.ts
  • libs/enclave-vm/src/value-sanitizer.ts
💤 Files with no reviewable changes (8)
  • docs/draft/docs/getting-started/installation.mdx
  • docs/draft/docs.json
  • docs/draft/docs/getting-started/welcome.mdx
  • docs/live/docs/libraries/vectoriadb.mdx
  • docs/draft/docs/libraries/ast-guard.mdx
  • docs/draft/docs/libraries/enclave.mdx
  • docs/draft/updates.mdx
  • docs/live/snippets/card.jsx
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Use ESLint flat config with unused parameters and variables prefixed with underscore _
Prefer workspace import paths (e.g., import { validate } from 'ast-guard') over deep cross-library relative imports

Files:

  • libs/ast-guard/src/rules/resource-exhaustion.rule.ts
  • libs/enclave-vm/src/safe-error.ts
  • libs/enclave-vm/src/tool-bridge.ts
  • libs/enclave-vm/src/__tests__/tool-bridge.spec.ts
  • libs/enclave-vm/src/__tests__/resource-exhaustion.spec.ts
  • libs/enclave-vm/src/__tests__/safe-runtime-reference.spec.ts
  • libs/enclave-vm/src/__tests__/enclave.spec.ts
  • libs/enclave-vm/src/types.ts
  • libs/enclave-vm/src/adapters/vm-adapter.ts
  • libs/enclave-vm/src/value-sanitizer.ts
  • libs/enclave-vm/src/double-vm/double-vm-wrapper.ts
  • libs/enclave-vm/src/safe-runtime.ts
  • libs/enclave-vm/src/enclave.ts
  • libs/enclave-vm/src/secure-proxy.ts
  • libs/ast-guard/src/presets/agentscript.preset.ts
  • libs/enclave-vm/src/double-vm/parent-vm-bootstrap.ts
  • libs/enclave-vm/src/__tests__/constructor-obfuscation-attacks.spec.ts
libs/**

⚙️ CodeRabbit configuration file

libs/**: Contains publishable SDK libraries. Review for API correctness, breaking changes, and consistency with docs. When public APIs change, ensure there is a matching docs/draft/docs/** update (not direct edits under docs/docs/**).

Files:

  • libs/ast-guard/src/rules/resource-exhaustion.rule.ts
  • libs/enclave-vm/src/safe-error.ts
  • libs/enclave-vm/src/tool-bridge.ts
  • libs/enclave-vm/src/__tests__/tool-bridge.spec.ts
  • libs/enclave-vm/src/__tests__/resource-exhaustion.spec.ts
  • libs/enclave-vm/src/__tests__/safe-runtime-reference.spec.ts
  • libs/enclave-vm/src/__tests__/enclave.spec.ts
  • libs/enclave-vm/src/types.ts
  • libs/enclave-vm/src/adapters/vm-adapter.ts
  • libs/enclave-vm/src/value-sanitizer.ts
  • libs/enclave-vm/src/double-vm/double-vm-wrapper.ts
  • libs/enclave-vm/src/safe-runtime.ts
  • libs/enclave-vm/src/enclave.ts
  • libs/enclave-vm/src/secure-proxy.ts
  • libs/ast-guard/src/presets/agentscript.preset.ts
  • libs/enclave-vm/src/double-vm/parent-vm-bootstrap.ts
  • libs/enclave-vm/src/__tests__/constructor-obfuscation-attacks.spec.ts
docs/docs.json

⚙️ CodeRabbit configuration file

docs/docs.json: Mintlify navigation configuration. Important structure: - dropdowns[].dropdown == "Documentation":

  • Contains a "versions" array.
  • Latest version entry: "version": "vX.Y (latest)", "default": true, with
    paths like "docs/getting-started/welcome" and "updates" (NO "v/X.Y" prefix).
  • Older versions: "version": "v0.2", "version": "v0.1", etc., with paths
    like "docs/v/0.2/getting-started/welcome".
  • dropdowns[].dropdown == "Blog":
    • Contains blog groups (e.g. "blog/november-2025/introducing-frontmcp").
      Review guidelines: - Do NOT suggest editing the Blog dropdown unless the PR explicitly adds/changes blogs. - Ensure latest version uses non-versioned "docs/..." paths, and older versions
      use "docs/v/{minor}/..." paths.
  • If you see changes that try to route archived versions away from docs/v/**,
    flag that as incorrect.

Files:

  • docs/docs.json
docs/**

⚙️ CodeRabbit configuration file

docs/**: Repository documentation for the SDK, using MDX and hosted by Mintlify. See more specific rules for: - docs/docs/** (latest rendered docs, automation-only) - docs/v/** (archived versions, read-only) - docs/draft/docs/** (human-editable drafts) - docs/blogs/** (blogs, human edited) - docs/docs.json (Mintlify navigation)

Files:

  • docs/docs.json
**/src/__tests__/**/*.spec.ts

📄 CodeRabbit inference engine (AGENTS.md)

Place test files under src/__tests__/**/*.spec.ts with performance tests under libs/enclave-vm/src/__tests__/perf/**/*.perf.spec.ts

Files:

  • libs/enclave-vm/src/__tests__/tool-bridge.spec.ts
  • libs/enclave-vm/src/__tests__/resource-exhaustion.spec.ts
  • libs/enclave-vm/src/__tests__/safe-runtime-reference.spec.ts
  • libs/enclave-vm/src/__tests__/enclave.spec.ts
  • libs/enclave-vm/src/__tests__/constructor-obfuscation-attacks.spec.ts
🧠 Learnings (4)
📚 Learning: 2026-01-08T18:40:23.667Z
Learnt from: CR
Repo: agentfront/enclave PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T18:40:23.667Z
Learning: Enforce global coverage threshold for `enclave-vm` as configured in `libs/enclave-vm/jest.config.ts`

Applied to files:

  • README.md
  • libs/enclave-vm/src/__tests__/tool-bridge.spec.ts
  • libs/enclave-vm/src/__tests__/resource-exhaustion.spec.ts
  • libs/enclave-vm/src/__tests__/safe-runtime-reference.spec.ts
  • libs/enclave-vm/src/__tests__/enclave.spec.ts
  • libs/enclave-vm/src/types.ts
  • libs/enclave-vm/src/enclave.ts
  • libs/enclave-vm/src/__tests__/constructor-obfuscation-attacks.spec.ts
📚 Learning: 2026-01-08T18:40:23.667Z
Learnt from: CR
Repo: agentfront/enclave PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T18:40:23.667Z
Learning: Applies to libs/enclave-vm/src/__tests__/perf/**/*.perf.spec.ts : Performance tests for enclave-vm should be placed under `libs/enclave-vm/src/__tests__/perf/**/*.perf.spec.ts`

Applied to files:

  • README.md
  • libs/enclave-vm/src/__tests__/tool-bridge.spec.ts
  • libs/enclave-vm/src/__tests__/resource-exhaustion.spec.ts
  • libs/enclave-vm/src/__tests__/safe-runtime-reference.spec.ts
  • libs/enclave-vm/src/__tests__/enclave.spec.ts
  • libs/enclave-vm/src/__tests__/constructor-obfuscation-attacks.spec.ts
📚 Learning: 2026-01-08T18:40:23.667Z
Learnt from: CR
Repo: agentfront/enclave PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T18:40:23.667Z
Learning: Applies to **/src/__tests__/**/*.spec.ts : Place test files under `src/__tests__/**/*.spec.ts` with performance tests under `libs/enclave-vm/src/__tests__/perf/**/*.perf.spec.ts`

Applied to files:

  • libs/enclave-vm/src/__tests__/tool-bridge.spec.ts
  • libs/enclave-vm/src/__tests__/resource-exhaustion.spec.ts
  • libs/enclave-vm/src/__tests__/safe-runtime-reference.spec.ts
  • libs/enclave-vm/src/__tests__/enclave.spec.ts
  • libs/enclave-vm/src/__tests__/constructor-obfuscation-attacks.spec.ts
📚 Learning: 2026-01-08T18:40:23.667Z
Learnt from: CR
Repo: agentfront/enclave PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T18:40:23.667Z
Learning: PRs must include problem/solution description, test evidence (`yarn test` or `nx test <project>`), and security-impact notes for sandbox/VM changes

Applied to files:

  • libs/enclave-vm/src/__tests__/resource-exhaustion.spec.ts
🧬 Code graph analysis (5)
libs/enclave-vm/src/tool-bridge.ts (2)
libs/enclave-vm/src/types.ts (1)
  • ExecutionContext (636-682)
libs/enclave-vm/src/value-sanitizer.ts (1)
  • sanitizeValue (89-246)
libs/enclave-vm/src/__tests__/tool-bridge.spec.ts (1)
libs/enclave-vm/src/enclave.ts (1)
  • Enclave (163-756)
libs/enclave-vm/src/__tests__/resource-exhaustion.spec.ts (1)
libs/enclave-vm/src/enclave.ts (1)
  • Enclave (163-756)
libs/enclave-vm/src/double-vm/double-vm-wrapper.ts (2)
libs/enclave-vm/src/value-sanitizer.ts (1)
  • checkSerializedSize (476-486)
libs/enclave-vm/src/tool-bridge.ts (1)
  • createHostToolBridge (146-427)
libs/enclave-vm/src/secure-proxy.ts (1)
libs/enclave-vm/src/safe-error.ts (1)
  • createSafeError (18-75)
🪛 markdownlint-cli2 (0.18.1)
README.md

7-7: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

🔇 Additional comments (46)
docs/docs.json (5)

4-4: LGTM! Clear security messaging.

The updated description effectively communicates the security focus of the project and aligns well with the PR's security hardening objectives.


6-9: Theme updates look good.

The appearance and theme changes provide a consistent dark aesthetic for the documentation site.


48-53: Footer social links enhance discoverability.

Good addition for community engagement.


33-36: No issues found. The Playground URL at https://enclave.agentfront.dev is live and properly accessible (HTTP 200), confirming the navigation link is correctly configured.


23-30: Metadata is correctly configured. The og:image URL at https://enclave.agentfront.dev/og-image.png is accessible and returns a valid PNG image, and the Twitter handle @agentfront is correct.

README.md (2)

22-35: Clear installation instructions and compelling benefits.

The Install and Why Enclave sections effectively communicate the value proposition. The security claims (1000+ tests, 100% CVE coverage) are strong selling points.

Consider verifying that the security claims can be substantiated with test coverage reports or security audit documentation.


7-7: Static analysis hint can be ignored.

The markdownlint tool flagged this line for using emphasis instead of a heading. However, this bold text is intentionally part of the centered header design, not a standalone heading. The current structure is appropriate for the visual layout.

libs/enclave-vm/src/__tests__/enclave.spec.ts (1)

429-447: LGTM: assertion now matches bridged tool error message.

Also applies to: 443-445

libs/ast-guard/src/rules/resource-exhaustion.rule.ts (1)

7-31: The allowDynamicArrayFill option is correctly gated to runtime memory enforcement.

The code properly couples the option to runtime protection: in libs/enclave-vm/src/enclave.ts line 683, the agentscript preset enables it only when this.config.memoryLimit > 0. Since the default memoryLimit is 1MB, runtime Array.prototype.fill patching is active by default, preventing memory exhaustion attacks. The static rule defaults to blocking dynamic fill (safe), but allows it when memoryLimit is configured, achieving the desired defense-in-depth.

libs/enclave-vm/src/types.ts (1)

445-477: Enforcement is correctly implemented: mode: 'direct' is properly gated by acknowledgeInsecureDirect === true at the Enclave constructor.

The normalization and validation at Enclave constructor (lines 202-217 in enclave.ts) throws immediately if mode='direct' without explicit acknowledgement. The enforced config then flows to all downstream consumers (double-vm-wrapper, vm-adapter) which receive the pre-validated configuration. Tests confirm the gate works correctly.

libs/ast-guard/src/presets/agentscript.preset.ts (2)

220-233: Well-documented security option with safe default.

The new allowDynamicArrayFill option is properly documented with clear guidance on when to enable it (only when memoryLimit is configured). The default of false ensures a secure-by-default posture for environments without runtime protection.


568-569: Correctly wired to ResourceExhaustionRule.

The option is properly passed through with a safe default via nullish coalescing (?? false).

libs/enclave-vm/src/secure-proxy.ts (3)

19-19: Good: Centralized safe error import.

Importing createSafeError from the dedicated module ensures consistent, secure error handling across the codebase.


220-220: Security hardening: Safe error for Reflect.construct blocking.

Using createSafeError with 'SecurityError' name prevents prototype chain escape attacks that could occur if a regular Error instance crossed the sandbox boundary.


503-507: Consistent security error handling across all proxy traps.

All blocked property access paths (get, set, defineProperty, getOwnPropertyDescriptor) now use createSafeError with 'SecurityError' name. This ensures that even if an attacker triggers these security violations, the thrown error cannot be used as an escape vector.

Also applies to: 524-528, 568-572, 589-593, 638-642

libs/enclave-vm/src/__tests__/tool-bridge.spec.ts (2)

1-6: Good test coverage for tool bridge security requirements.

The test correctly verifies that toolBridge.mode='direct' requires explicit acknowledgement, enforcing the security-by-default principle.


58-73: Defense-in-depth test for single-VM mode.

Good verification that the host bridge global is not exposed when doubleVm is disabled, preventing potential attack vectors.

libs/enclave-vm/src/enclave.ts (3)

55-58: Reasonable default payload limit.

5MB is a sensible default that balances usability with protection against oversized payloads.


200-219: Robust tool bridge configuration validation.

The validation logic properly:

  1. Validates mode is one of the allowed values
  2. Ensures maxPayloadBytes is a positive finite number (handles NaN, Infinity, negatives)
  3. Enforces explicit acknowledgement for insecure direct mode

The security gate on direct mode is critical for preventing accidental exposure of the insecure path.


677-683: Correct integration of allowDynamicArrayFill with memoryLimit.

Enabling allowDynamicArrayFill only when memoryLimit > 0 ensures runtime protection is in place before allowing dynamic array sizes. This aligns with the documentation in the preset options.

libs/enclave-vm/src/safe-error.ts (3)

1-12: Excellent threat model documentation.

The header clearly explains the security rationale: preventing sandbox escape via prototype chain walks from host errors that cross the boundary. This documentation helps future maintainers understand why this module exists.


18-75: Robust safe error implementation.

The implementation correctly addresses all escape vectors:

  1. Line 48: Object.setPrototypeOf(error, null) - Critical for severing the actual [[Prototype]] chain
  2. Lines 23-44: Null-prototype SafeConstructor breaks err.constructor.constructor chains
  3. Lines 51-56, 58-63: Shadow properties for defense-in-depth
  4. Lines 66-71: Stack trace hidden to prevent host path leakage
  5. Line 73: Object.freeze(error) prevents any modification

This is a well-designed security primitive.


77-79: Convenient helper for TypeError.

Simple delegation to createSafeError maintains consistency.

libs/enclave-vm/src/__tests__/resource-exhaustion.spec.ts (2)

272-320: Comprehensive dynamic Array.fill test coverage.

The tests correctly verify:

  1. Dynamic sizes allowed when memoryLimit enables runtime protection
  2. Large allocations blocked at runtime
  3. Computed sizes within limits work correctly

Good coverage of the allowDynamicArrayFill feature interaction with memoryLimit.


1658-1753: Thorough ATK-RSRC-340 rope string exhaustion tests.

These tests effectively cover the serialization bomb attack vector where in-memory structures with shared string references explode during JSON serialization. Key test scenarios:

  1. Lines 1666-1697: Reference multiplication attack (500 refs × 5 copies)
  2. Lines 1699-1715: Baseline - reasonable repetition allowed
  3. Lines 1717-1733: Nested repetition attack
  4. Lines 1735-1752: Object-based variant

The assertions on error.code === 'SERIALIZATION_LIMIT_EXCEEDED' provide precise validation.

libs/enclave-vm/src/double-vm/double-vm-wrapper.ts (4)

13-18: Clean import organization for new dependencies.

Imports for checkSerializedSize, createSafeError, and createHostToolBridge are properly grouped with related functionality.


141-163: Critical security fix for Vector 340 (rope string exhaustion).

This check prevents attacks where structures with many references to the same string appear small in memory but explode during serialization. The implementation:

  1. Line 149: Uses Math.min(config.memoryLimit, 50MB) as a reasonable cap
  2. Line 150: Leverages checkSerializedSize for estimation
  3. Lines 153-162: Returns structured error with SERIALIZATION_LIMIT_EXCEEDED code

This is a well-placed defense that catches serialization bombs before they can cause resource exhaustion.


275-284: Defense-in-depth: Configurable host properties allow cleanup.

Changing host-injected properties to configurable: true enables the parent VM bootstrap to delete these references after capturing them. This prevents access if child VM code escapes to the parent context.

The inline comments clearly document this security rationale.

Also applies to: 290-291, 297-298, 304-305, 316-317


504-521: Tool bridge configuration propagated to bootstrap.

The toolBridgeMode and toolBridgeMaxPayloadBytes are correctly extracted from config with appropriate defaults and passed to the bootstrap generator.

libs/enclave-vm/src/safe-runtime.ts (2)

12-12: LGTM: Centralized safe error imports.

Good refactor to centralize error creation utilities. This improves consistency and maintainability across the codebase.


478-486: Robust error message extraction.

The defensive approach handles non-Error objects well. The fallback chain (checking for .message string → Object.prototype.toString.call()String()) covers edge cases where errors might be plain objects, null prototypes, or primitives.

libs/enclave-vm/src/value-sanitizer.ts (2)

476-486: LGTM: Clean wrapper for size checking.

The checkSerializedSize function provides a clean API that catches exceptions and returns a discriminated union result. This is a good pattern for callers who want to check without handling exceptions.


363-366: Remove concern about misleading estimates—the function correctly assumes BigInt becomes a string.

While JSON.stringify does throw on BigInt, estimateSerializedSize doesn't claim to estimate raw JSON serialization. It correctly predicts what safeJsonStringify (in tool-bridge.ts) will produce, which converts BigInt to string via the jsonReplacer replacer function. The estimate of String(value).length + 2 for a quoted string is accurate for this code path.

Note: sanitizeValue passes BigInt through unchanged as a primitive; the actual conversion to string happens in the jsonReplacer at serialization time, not upstream.

Likely an incorrect or invalid review comment.

libs/enclave-vm/src/adapters/vm-adapter.ts (3)

832-859: Good addition: Array.fill memory protection.

The patch correctly implements the ECMA-262 fill range calculation algorithm and tracks memory before allocation. This closes Vector 1110/1170 where Array(largeSize).fill() could exhaust memory by converting sparse arrays to dense.

The 8 bytes per element estimate is reasonable for object pointers in V8's tagged pointer representation.


900-1019: Comprehensive tool bridge implementation.

The string-mode tool bridge provides good security boundaries:

  • Captures and deletes host bridge reference (defense-in-depth)
  • Conservative UTF-8 byte estimation (length * 4)
  • Protocol version validation
  • Input sanitization via JSON round-trip
  • Proper error propagation with safe error types

One minor observation: the estimateBytes function uses length * 4 which is very conservative (UTF-8 max is 4 bytes per code point, but JavaScript strings are UTF-16 where most characters are 2 bytes max in UTF-8).


1136-1158: LGTM: Serialization size check prevents Vector 340.

Good security fix. The check before returning prevents memory exhaustion from structures that appear small in-memory (due to string reference sharing) but explode during JSON serialization.

The cap at 50MB (Math.min(config.memoryLimit, 50 * 1024 * 1024)) provides a sensible upper bound even for generous memory limits.

libs/enclave-vm/src/tool-bridge.ts (4)

1-46: Well-structured utility functions.

Good defensive utilities:

  • utf8ByteLength uses Node's Buffer for accurate byte counts
  • jsonReplacer handles BigInt and non-finite numbers that would otherwise throw or produce invalid JSON
  • safeJsonStringify wraps with the replacer
  • truncateForErrorMessage prevents oversized error messages

Clean separation of concerns.


196-215: Potential off-by-one in tool call limit check.

The stats increment happens at line 199 before the limit check at line 202. However, when updateStats is true, this increments stats.toolCallCount and then checks if it exceeds config.maxToolCalls.

If maxToolCalls is 10 and this is the 11th call, toolCallCount becomes 11, and 11 > 10 correctly fails. This looks correct.

However, note that in safe-runtime.ts line 84-87, the increment happens first and then checks > (not >=). This means the check allows exactly maxToolCalls calls, which is the expected behavior.


246-263: Good defensive sanitization of tool arguments.

Sanitizing tool args with allowDates: false and allowErrors: false is appropriate for the bridge since these types don't round-trip through JSON cleanly. The subsequent type check ensures the result is a plain object.


361-372: LGTM: Sidecar lift for large string results.

Good optimization to store large string results in sidecar and return a reference ID. The silent fallback on storage failure is appropriate since the original value is still valid.

libs/enclave-vm/src/double-vm/parent-vm-bootstrap.ts (6)

33-43: Good API addition for tool bridge configuration.

The new toolBridgeMode and toolBridgeMaxPayloadBytes options provide necessary configurability for the tool bridge feature. Default values (5MB payload, 'string' mode) are reasonable.


454-463: Correct fix: Use defineProperty for error.name.

In strict mode, directly assigning to error.name can fail if Error.prototype.name is frozen or non-writable. Using Object.defineProperty with a try-catch is the correct defensive approach.


664-671: Good defense-in-depth: Delete host references after capture.

Deleting __host_* globals after capturing them prevents inner VM escape attempts from discovering these references. The try-catch handles cases where deletion might fail.


710-721: Critical security improvement: Proper prototype chain severance.

Using Object.setPrototypeOf(error, null) properly severs the prototype chain at the native level, not just shadowing __proto__. This is more robust than the previous approach and blocks Object.getPrototypeOf(error).constructor.constructor attacks.


1079-1135: Comprehensive tool bridge mode handling.

The string mode implementation:

  • Validates JSON serialization
  • Checks payload size with conservative estimate (length * 4)
  • Parses and validates response structure
  • Properly handles success and error cases
  • Uses createSafeError for all error paths

The fallback to direct mode (hostCallTool(toolName, sanitizedArgs)) maintains backward compatibility.


1506-1524: Consistent Array.fill patch with vm-adapter.

The Array.fill memory patch mirrors the implementation in vm-adapter.ts, which is good for consistency. Both implementations:

  • Calculate fill range per ECMA-262 spec
  • Estimate 8 bytes per element
  • Check against memory limit
  • Track cumulative memory before allocation

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Fix all issues with AI agents
In @libs/enclave-vm/src/value-sanitizer.ts:
- Around line 426-433: The RegExp branch in value size estimation is wrong:
instead of returning String(value).length + 2 it should mirror JSON.stringify
behavior (RegExp -> "{}"), so call currentPath.delete(value as object) and
return 2; update the RegExp handling in the same block as the Date check (the
instance check for RegExp) to delete the object from currentPath and return 2.
- Around line 372-375: The BigInt branch in sanitizeValue incorrectly returns a
quoted-string length instead of matching JSON.stringify behavior; update the
bigint handling in sanitizeValue (value-sanitizer.ts) to fail-fast by throwing a
TypeError (or a descriptive custom error) when type === 'bigint' so BigInt
values are rejected rather than treated as strings, and ensure any callers of
sanitizeValue catch or propagate that error appropriately.
- Around line 439-468: The code under the object iteration in
estimateSerializedSize incorrectly assumes key length as key.length + 3 and
ignores JSON string escaping; replace that naive calculation by estimating the
serialized size of the key as a JSON string (accounting for quotes and necessary
escape sequences) using the same string estimation logic used for values (or a
small helper like estimateSerializedKey) and add the resulting size (including
the surrounding quotes and colon) instead of key.length + 3; keep the existing
maxBytes check and currentPath cleanup behavior unchanged and reuse the existing
helper/logic so keys with quotes, backslashes or control characters are
correctly sized.
- Around line 324-358: The string-size estimator currently treats all control
chars (code < 32) as 2-byte escapes, undercounting JSON serialized size; update
the string branch that computes bytes for ASCII to treat only quote (code 34)
and backslash (code 92) as 2-byte escapes and treat other control characters
(code < 32) as 6 bytes (the "\uXXXX" form) so bytes += 6 for those codes; keep
the existing logic for multibyte UTF-8 and surrogate pairs, and ensure the check
that throws the Error using maxBytes still uses the corrected bytes value.

In @README.md:
- Line 7: The document uses bold markup "**Secure sandbox runtime for AI
agents**" instead of a proper Markdown heading; replace that bolded text with
the appropriate heading syntax (e.g., prepend one or more '#' characters such as
"## Secure sandbox runtime for AI agents") so it follows markdownlint MD036 and
proper heading hierarchy, ensuring the exact phrase "Secure sandbox runtime for
AI agents" becomes a heading rather than bold inline text.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c4122cc and c866abb.

📒 Files selected for processing (9)
  • README.md
  • docs/getting-started/installation.mdx
  • docs/getting-started/welcome.mdx
  • docs/libraries/ast-guard.mdx
  • docs/libraries/enclave.mdx
  • docs/libraries/vectoriadb.mdx
  • libs/enclave-vm/src/__tests__/constructor-obfuscation-attacks.spec.ts
  • libs/enclave-vm/src/__tests__/tool-bridge.spec.ts
  • libs/enclave-vm/src/value-sanitizer.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • libs/enclave-vm/src/tests/constructor-obfuscation-attacks.spec.ts
  • libs/enclave-vm/src/tests/tool-bridge.spec.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Use ESLint flat config with unused parameters and variables prefixed with underscore _
Prefer workspace import paths (e.g., import { validate } from 'ast-guard') over deep cross-library relative imports

Files:

  • libs/enclave-vm/src/value-sanitizer.ts
libs/**

⚙️ CodeRabbit configuration file

libs/**: Contains publishable SDK libraries. Review for API correctness, breaking changes, and consistency with docs. When public APIs change, ensure there is a matching docs/draft/docs/** update (not direct edits under docs/docs/**).

Files:

  • libs/enclave-vm/src/value-sanitizer.ts
🧠 Learnings (3)
📓 Common learnings
Learnt from: CR
Repo: agentfront/enclave PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T18:40:23.667Z
Learning: PRs must include problem/solution description, test evidence (`yarn test` or `nx test <project>`), and security-impact notes for sandbox/VM changes
Learnt from: CR
Repo: agentfront/enclave PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T18:40:23.667Z
Learning: Enforce global coverage threshold for `enclave-vm` as configured in `libs/enclave-vm/jest.config.ts`
📚 Learning: 2026-01-08T18:40:23.667Z
Learnt from: CR
Repo: agentfront/enclave PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T18:40:23.667Z
Learning: Enforce global coverage threshold for `enclave-vm` as configured in `libs/enclave-vm/jest.config.ts`

Applied to files:

  • README.md
📚 Learning: 2026-01-08T18:40:23.667Z
Learnt from: CR
Repo: agentfront/enclave PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T18:40:23.667Z
Learning: Applies to libs/enclave-vm/src/__tests__/perf/**/*.perf.spec.ts : Performance tests for enclave-vm should be placed under `libs/enclave-vm/src/__tests__/perf/**/*.perf.spec.ts`

Applied to files:

  • README.md
🪛 markdownlint-cli2 (0.18.1)
README.md

7-7: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Test
🔇 Additional comments (8)
README.md (1)

1-50: Verify that PR description includes security-impact documentation and test coverage evidence.

The README has been simplified appropriately for a quick-start guide. However, this PR implements significant security enhancements (centralized safe error handling, tool-bridge versioning, memory guards, serialization checks) that warrant security-impact notes in the PR description.

Based on learnings from prior reviews, sandbox/VM security changes must include:

  1. Problem statement and solution description
  2. Test evidence (e.g., yarn test output for enclave-vm)
  3. Security-impact notes for the sandbox changes

Ensure these are documented in the pull request description on GitHub, as they're essential for reviewers to assess the security implications of the changes.

libs/enclave-vm/src/value-sanitizer.ts (7)

280-304: LGTM - Excellent security documentation.

The documentation clearly explains the attack vector (Vector 340) and the distinction between circular and repeated references, which is critical for understanding the function's behavior.


318-320: LGTM - Correct JSON semantics.

Properly handles null as 4 bytes and undefined as omitted (0 bytes).


377-380: LGTM - Correct JSON behavior.

Functions and symbols are properly handled as omitted (0 bytes), matching JSON.stringify behavior.


383-412: LGTM - Solid circular reference handling.

The array handling correctly uses currentPath to detect circular references and performs incremental size checks with fast-fail behavior. The cleanup pattern (removing from currentPath before throwing) prevents memory leaks.


478-495: LGTM - Clean error handling wrapper.

The wrapper provides a safe, non-throwing API for size checking. Good pattern for library consumers.


305-476: These are internal utility functions, not public APIs; documentation updates are not required.

The estimateSerializedSize and checkSerializedSize functions are internal implementation details used within the enclave-vm library (referenced in vm-adapter.ts and double-vm-wrapper.ts) and are not exported from the public API in index.ts. Test coverage is already comprehensive—resource-exhaustion.spec.ts includes multiple test cases covering ATK-RSRC-340 scenarios (rope string exhaustion, nested repetition, object structures). The global coverage thresholds are configured in jest.config.ts (40-45% for functions/lines/statements/branches). No public documentation updates are needed since these are internal utilities, not public API exports.

Likely an incorrect or invalid review comment.


313-316: Clarify JSDoc and reconsider severity of depth limit behavior.

The depth limit check returns a fixed estimate (20 bytes) rather than throwing, as stated in the JSDoc ("@throws Error if... depth limit"). While this creates potential for underestimation in extremely deep structures (depth > 2000), the actual attack vector (Vector 340) is caught by the maxBytes check that runs at each recursion level. The depth limit of 2000 is intentionally lenient to prevent stack overflow while still supporting legitimate deep structures.

However, the JSDoc is inaccurate: it claims the function throws on depth limit violations, but it returns an estimate instead. Update the JSDoc to reflect this behavior or reconsider whether throwing would be more appropriate for consistency with sanitizeValue() (which does throw at its depth limit on line 102).

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In @libs/enclave-vm/src/value-sanitizer.ts:
- Around line 353-356: The current size-estimation logic returns a fixed 20 when
depth > maxDepth, which allows nested attackers to bypass protections; instead,
change the behavior in the size-estimation routine (the function that checks
`depth` against `maxDepth` in libs/enclave-vm/src/value-sanitizer.ts) to
raise/throw an error (or otherwise abort processing) when the depth limit is
exceeded, so deeply nested structures are rejected rather than conservatively
underestimated; update any callers of this function to handle the thrown error
(or propagate it) and ensure tests cover the new behavior.
- Around line 123-126: sanitizeValue currently returns BigInt primitives as-is
which will cause JSON.stringify to throw; update the primitive branch in
sanitizeValue to detect type === 'bigint' and return value.toString() (or
String(value)) instead of the raw BigInt, and adjust the comment to note BigInt
is converted to a string for JSON-safety; also add a brief guard or comment in
checkSerializedSize noting BigInt strings are used so size checks remain
accurate.

In @README.md:
- Around line 32-35: Update the "Why Enclave?" / README copy to either
substantiate the security metrics by linking to the supporting artifacts (e.g.,
SECURITY-AUDIT report, test-suite dashboard, CHANGELOG security section, or a
security whitepaper) or tone down the absolute claims to verifiable language;
specifically replace "1000+ security tests" and "100% CVE coverage" with either
a parenthetical link to the test/audit resources or a milder phrasing such as
"extensive security testing" and "broad CVE mitigations" so the README no longer
makes unreferenced quantitative claims.
🧹 Nitpick comments (1)
README.md (1)

39-46: Quick Start example doesn't demonstrate new security capabilities.

The example shows basic arithmetic (1 + 2) without exercising any of the security features being added in this PR (safe error handling, memory guards, serialization checks, etc.). Consider including a slightly more realistic example that:

  • Demonstrates error handling behavior (how errors are safely surfaced), or
  • Shows a pattern that would trigger memory guards or serialization checks, enabling users to validate the new protections.

This would help users immediately understand the value of the enhancements.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c866abb and 2de0ec4.

📒 Files selected for processing (2)
  • README.md
  • libs/enclave-vm/src/value-sanitizer.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Use ESLint flat config with unused parameters and variables prefixed with underscore _
Prefer workspace import paths (e.g., import { validate } from 'ast-guard') over deep cross-library relative imports

Files:

  • libs/enclave-vm/src/value-sanitizer.ts
libs/**

⚙️ CodeRabbit configuration file

libs/**: Contains publishable SDK libraries. Review for API correctness, breaking changes, and consistency with docs. When public APIs change, ensure there is a matching docs/draft/docs/** update (not direct edits under docs/docs/**).

Files:

  • libs/enclave-vm/src/value-sanitizer.ts
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
Repo: agentfront/enclave PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T18:40:23.667Z
Learning: PRs must include problem/solution description, test evidence (`yarn test` or `nx test <project>`), and security-impact notes for sandbox/VM changes
📚 Learning: 2026-01-08T18:40:23.667Z
Learnt from: CR
Repo: agentfront/enclave PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T18:40:23.667Z
Learning: Enforce global coverage threshold for `enclave-vm` as configured in `libs/enclave-vm/jest.config.ts`

Applied to files:

  • README.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Test
  • GitHub Check: Performance
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (5)
libs/enclave-vm/src/value-sanitizer.ts (5)

280-318: LGTM! String size estimation is thorough and correct.

The function properly accounts for JSON escaping, UTF-8 encoding, and surrogate pairs. The handling of unpaired surrogates is correct (3 bytes each), and the logic for control character escapes (\uXXXX) is accurate.


399-425: LGTM! Array handling with circular reference detection is correct.

The use of currentPath Set to track ancestors correctly detects circular references without conflating repeated (non-circular) object references. The incremental size checking with fast-fail optimization is efficient, and cleanup before throwing is proper.


429-487: LGTM! Object handling with special type support is well-designed.

The function correctly handles:

  • Circular reference detection using the ancestor path pattern
  • Special objects (Date → 26-byte ISO string, RegExp → "{}" = 2 bytes)
  • Key serialization accounting for JSON escaping
  • Getter trap protection with try-catch
  • Incremental size validation with proper cleanup

493-510: LGTM! Wrapper function provides ergonomic error handling.

The discriminated union return type allows callers to easily check success/failure and handle errors gracefully without exception handling.


320-491: Verify test coverage for security-critical size estimation.

Given the security-critical nature of these functions (preventing memory exhaustion attacks), ensure comprehensive test coverage exists for:

  • Deep nesting beyond maxDepth
  • Circular reference detection
  • Repeated references to large strings (Vector 340 mentioned in comments)
  • Edge cases: surrogate pairs, control characters, special objects
  • Fast-fail behavior when size limits exceeded

As per the repository learnings, please confirm test evidence (yarn test or nx test) and security-impact notes are included in the PR description.

Based on learnings, security/sandbox changes require test evidence and impact documentation.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In @libs/enclave-vm/README.md:
- Line 15: The README row currently reads "Security Tests | 1100+ tests, 100%
pass rate"; update that table cell to reflect the actual test coverage (e.g.,
"Security Tests | 1921 tests, 100% pass rate" or "Security Tests | 1900+ tests,
100% pass rate") to accurately reflect the added safe-error and tool-bridge
tests; edit the string "Security Tests | 1100+ tests, 100% pass rate" in
libs/enclave-vm/README.md to the new value.

In @libs/enclave-vm/src/value-sanitizer.ts:
- Around line 403-433: The array handling in estimateSerializedSize
underestimates sizes because array elements that are undefined, functions, or
symbols are treated via primitive branches as 0 bytes whereas JSON.stringify
coerces them to null (4 bytes); when iterating elements inside the Array.isArray
branch (and before calling estimateSerializedSize recursively), coerce any
element where value[i] === undefined || typeof value[i] === 'function' || typeof
value[i] === 'symbol' to null (or call estimateSerializedSize with null) so
those entries contribute the correct 4 bytes, keep the existing
circular-check/currentPath.add/currentPath.delete logic and the incremental
maxBytes check intact.

In @README.md:
- Line 3: The README image tag references "./assets/logo.dark.svg" which is
missing, causing a broken image; either add the missing SVG file at that path
and commit the assets directory (ensure the filename exactly matches
"logo.dark.svg"), or update the <img> src in README.md to point to an existing
logo asset (or a CDN) and commit that change so the reference resolves.
🧹 Nitpick comments (1)
libs/enclave-vm/src/value-sanitizer.ts (1)

371-490: maxBytes isn’t propagated into recursion; huge strings still fully scanned before failing.
You’re already doing incremental container checks, but passing maxBytes=0 into recursive calls prevents “fail-fast” for obviously-too-large leaves (e.g., a single giant string). Propagating maxBytes enables earlier aborts without changing correctness.

Proposed refactor (pass maxBytes through)
-      const elementSize = estimateSerializedSize(value[i], 0, depth + 1, maxDepth, currentPath);
+      const elementSize = estimateSerializedSize(value[i], maxBytes, depth + 1, maxDepth, currentPath);
...
-      const valueSize = estimateSerializedSize(propValue, 0, depth + 1, maxDepth, currentPath);
+      const valueSize = estimateSerializedSize(propValue, maxBytes, depth + 1, maxDepth, currentPath);
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2de0ec4 and 60870da.

📒 Files selected for processing (3)
  • README.md
  • libs/enclave-vm/README.md
  • libs/enclave-vm/src/value-sanitizer.ts
🧰 Additional context used
📓 Path-based instructions (2)
libs/**

⚙️ CodeRabbit configuration file

libs/**: Contains publishable SDK libraries. Review for API correctness, breaking changes, and consistency with docs. When public APIs change, ensure there is a matching docs/draft/docs/** update (not direct edits under docs/docs/**).

Files:

  • libs/enclave-vm/README.md
  • libs/enclave-vm/src/value-sanitizer.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Use ESLint flat config with unused parameters and variables prefixed with underscore _
Prefer workspace import paths (e.g., import { validate } from 'ast-guard') over deep cross-library relative imports

Files:

  • libs/enclave-vm/src/value-sanitizer.ts
🧠 Learnings (5)
📓 Common learnings
Learnt from: CR
Repo: agentfront/enclave PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T18:40:23.667Z
Learning: PRs must include problem/solution description, test evidence (`yarn test` or `nx test <project>`), and security-impact notes for sandbox/VM changes
📚 Learning: 2026-01-08T18:40:23.667Z
Learnt from: CR
Repo: agentfront/enclave PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T18:40:23.667Z
Learning: PRs must include problem/solution description, test evidence (`yarn test` or `nx test <project>`), and security-impact notes for sandbox/VM changes

Applied to files:

  • README.md
  • libs/enclave-vm/README.md
📚 Learning: 2026-01-08T18:40:23.667Z
Learnt from: CR
Repo: agentfront/enclave PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T18:40:23.667Z
Learning: Follow `SECURITY.md` for responsible disclosure when vulnerabilities are found

Applied to files:

  • README.md
📚 Learning: 2026-01-08T18:40:23.667Z
Learnt from: CR
Repo: agentfront/enclave PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T18:40:23.667Z
Learning: Enforce global coverage threshold for `enclave-vm` as configured in `libs/enclave-vm/jest.config.ts`

Applied to files:

  • README.md
  • libs/enclave-vm/README.md
📚 Learning: 2026-01-08T18:40:23.667Z
Learnt from: CR
Repo: agentfront/enclave PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-08T18:40:23.667Z
Learning: Applies to libs/enclave-vm/src/__tests__/perf/**/*.perf.spec.ts : Performance tests for enclave-vm should be placed under `libs/enclave-vm/src/__tests__/perf/**/*.perf.spec.ts`

Applied to files:

  • README.md
🧬 Code graph analysis (1)
libs/enclave-vm/src/value-sanitizer.ts (1)
libs/enclave-vm/src/index.ts (1)
  • estimateStringSize (112-112)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Test
  • GitHub Check: Performance
🔇 Additional comments (7)
libs/enclave-vm/README.md (1)

17-17: CVE language change is more accurate.

The shift from a categorical claim to "Covers known vm2, isolated-vm, node-vm exploits" is more defensible and aligns with responsible security disclosures. This improves the README without overstating protections.

README.md (3)

42-48: Quick Start code example aligns with Enclave API.

The TypeScript example correctly demonstrates:

  • Enclave constructor with securityLevel and toolHandler
  • toolHandler as async function with tool name and args
  • Error handling for unknown tools

The code structure matches the library's documented API.


1-62: PR lacks explicit problem/solution description and security-impact notes.

Per learnings, sandbox/VM security changes should include a clear problem statement, solution description, test evidence, and security-impact analysis. This root README now serves as the project entry point but omits these critical details.

While the library-specific README (libs/enclave-vm/README.md) documents features, the PR itself should clarify:

  • What security vulnerabilities or gaps this PR addresses
  • How the new safe-error handling, tool-bridge, and serialization checks mitigate them
  • Test coverage for the new security features

These details may be documented in the PR description. Please confirm that the PR description on GitHub includes problem/solution context and security-impact notes.


16-16: Documentation link is accessible and current.

The documentation URL https://enclave.agentfront.dev is confirmed to be accessible and actively serves the EnclaveVM Playground documentation. No action needed.

libs/enclave-vm/src/value-sanitizer.ts (3)

123-131: BigInt handling in sanitizeValue is a good hardening step.
Converting bigint to string before it can reach JSON serialization avoids JSON.stringify throwing.


507-517: These are internal VM utilities, not public API—but PR should document the security implications.

The functions checkSerializedSize and estimateSerializedSize are not part of the public barrel export (not re-exported in libs/enclave-vm/src/index.ts), so they are internal utilities rather than public API. They are actively used within the VM adapter for security purposes (detecting serialization-based memory exhaustion attacks per the JSDoc).

Per AGENTS.md guidelines, PRs with sandbox/VM changes should include a security-impact note in the problem/solution description and test evidence (nx test enclave-vm). Ensure your PR description covers why these serialization size checks are necessary for resource isolation.


292-323: The export claim is incorrect—this function should remain private, and there is no build break.

The function at line 292 in value-sanitizer.ts is a private helper for estimating JSON serialized size. The exported estimateStringSize is in memory-tracker.ts (line 70) and serves a different purpose (V8 heap memory estimation, not JSON size). Adding export would be wrong.

However, the escaping accuracy issue is valid: the function treats all control characters as \uXXXX (6 bytes), but JSON.stringify uses short escapes for common controls (\n, \r, \t, \b, \f—each 2 bytes). This causes overestimation in JSON size validation.

To fix only the escaping accuracy (without the incorrect export):

Accurate escaping fix (without export)
  function estimateStringSize(str: string): number {
    let bytes = 2; // quotes
    for (let i = 0; i < str.length; i++) {
      const code = str.charCodeAt(i);
      if (code < 128) {
        // ASCII: check if needs escaping
        if (code === 34 || code === 92) {
          // Quote and backslash: 2-byte escape (\" or \\)
          bytes += 2;
+       } else if (
+         code === 0x08 || // \b
+         code === 0x09 || // \t
+         code === 0x0a || // \n
+         code === 0x0c || // \f
+         code === 0x0d    // \r
+       ) {
+         // Common JSON short escapes
+         bytes += 2;
        } else if (code < 32) {
          // Control characters: 6-byte \uXXXX escape
          bytes += 6;

Likely an incorrect or invalid review comment.

@frontegg-david frontegg-david merged commit ed8bc43 into main Jan 9, 2026
3 of 4 checks passed
@frontegg-david frontegg-david deleted the fix-security-issue branch January 9, 2026 02:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants