{"_id":"@aashirzayd/sis","name":"@aashirzayd/sis","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@aashirzayd/sis","version":"0.1.0","description":"Autonomous runtime verification for Next.js boundaries","type":"module","publishConfig":{"access":"public"},"bin":{"sis":"dist/cli.js"},"main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./package.json":"./package.json"},"repository":{"type":"git","url":"git+https://github.com/AashirZayd/sis.git"},"homepage":"https://github.com/AashirZayd/sis#readme","bugs":{"url":"https://github.com/AashirZayd/sis/issues"},"engines":{"node":">=24.0.0"},"scripts":{"build":"tsc","dev":"tsc --watch","test":"vitest run","test:watch":"vitest","prepack":"npm run build"},"keywords":["nextjs","react-server-components","runtime-verification","invariant-synthesis","security"],"author":{"name":"Aashir Zayd"},"license":"MIT","dependencies":{"@swc/core":"^1.16.2","chalk":"^6.0.0","commander":"^15.0.0","fast-check":"^4.9.0","isolated-vm":"^7.0.1","ora":"^9.4.1"},"devDependencies":{"@types/node":"^26.4.1","typescript":"^7.0.2","vitest":"^5.0.0"},"gitHead":"71d78a1c26a0a5ded7f61d44d1cadca145fcc65f","_id":"@aashirzayd/sis@0.1.0","_nodeVersion":"24.19.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-e7cFbX300dZGVKEd061Z9MzmEOFRaWe9XLZENJIk6k+hcwTFjsWpvgncomu5SZd3gdhcRd6m6tIXPHhi2aIodw==","shasum":"0fb2b25604469b9f73a111c614b459879202335c","tarball":"https://registry.npmjs.org/@aashirzayd/sis/-/sis-0.1.0.tgz","fileCount":271,"unpackedSize":663834,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCMTa3IQkkEubJdRwPr0tzWDmjYyNomRR2GYLsqK4ifEwIgCGekul+iX07U0EL4mMi5B6xyNkAY+tdMamGuVEYT+I8="}]},"_npmUser":{"name":"aashirzayd","email":"aashirzayd@gmail.com"},"directories":{},"maintainers":[{"name":"aashirzayd","email":"aashirzayd@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sis_0.1.0_1789075352265_0.19790670606829552"},"_hasShrinkwrap":false}},"time":{"created":"2026-09-10T21:22:32.113Z","0.1.0":"2026-09-10T21:22:32.441Z","modified":"2026-09-10T21:22:32.747Z"},"maintainers":[{"name":"aashirzayd","email":"aashirzayd@gmail.com"}],"description":"Autonomous runtime verification for Next.js boundaries","homepage":"https://github.com/AashirZayd/sis#readme","keywords":["nextjs","react-server-components","runtime-verification","invariant-synthesis","security"],"repository":{"type":"git","url":"git+https://github.com/AashirZayd/sis.git"},"author":{"name":"Aashir Zayd"},"bugs":{"url":"https://github.com/AashirZayd/sis/issues"},"license":"MIT","readme":"# SIS\n\n### Speculative Invariant Synthesis\n\n> What if your Next.js app could find the edge cases you forgot to test?\n\nSIS is a zero-configuration analysis and speculative fuzzing tool for modern Next.js App Router and React Server Component boundaries. It discovers Client/Server module boundaries, traces secret data flows, models React Flight serializability contracts, synthesizes targeted adversarial payloads, and dynamically verifies invariants inside an isolated V8 execution sandbox.\n\n[![npm package](https://img.shields.io/badge/npm-%40aashirzayd%2Fsis-blue.svg)](https://github.com/AashirZayd/sis)\n[![node](https://img.shields.io/badge/node-%3E%3D24-brightgreen.svg)](https://nodejs.org)\n[![license](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)\n[![tests](https://img.shields.io/badge/tests-215%20passed-success.svg)](test/)\n\n[Get Started](#installation) · [Architecture](docs/architecture.md) · [CLI Reference](#cli-reference) · [Examples](examples/) · [GitHub](https://github.com/AashirZayd/sis)\n\n---\n\n## The Problem\n\nModern Next.js applications split application logic across Server Components, Client Components, and Server Actions. While happy-path unit and integration tests verify that features work when given expected inputs, production boundaries frequently encounter edge cases developers did not anticipate:\n\n- **Unexpected Argument Shapes**: `null`, `undefined`, sparse arrays, and missing nested keys causing runtime `TypeError: Cannot read properties of undefined`.\n- **Numeric Hazards**: Unchecked `NaN`, `-0`, `Infinity`, and precision loss propagating into downstream business logic or database queries.\n- **Prototype-Sensitive Objects**: Payloads containing `__proto__` or `constructor` causing unexpected object behavior.\n- **Serialization Traps**: Event handlers, custom class instances, and unregistered symbols crossing the Server $\\to$ Client boundary and breaking React Flight wire transfer.\n- **Secret Taint Leaks**: Private server environment variables (`process.env.AUTH_SECRET`) inadvertently forwarded into Client Component props or JSX sinks.\n- **Nested Destructuring Failures**: Complex parameter unpacking failing violently when encountering empty objects or scalar values.\n\nTraditional testing validates developer-written examples. **SIS asks:** *What happens when the boundary receives something you did not think to test?*\n\n---\n\n## What SIS Actually Does\n\nSIS analyzes your Next.js codebase through an integrated static and dynamic verification pipeline:\n\n```mermaid\nflowchart TD\n    Source[\"Source Code (*.ts, *.tsx)\"] --> Scanner[\"Project Discovery & Scanner\"]\n    Scanner --> AST[\"SWC AST & Directive Analysis\"]\n    AST --> Boundary[\"Boundary Model\n(Client / Server / Props / Actions)\"]\n    Boundary --> Dataflow[\"Interprocedural Module Graph\n& Data-Flow Analysis\"]\n    Dataflow --> Taint[\"Static Secret Taint Tracking\n(process.env.* -> Sinks)\"]\n    Boundary --> Shape[\"AST Shape & Signature Inference\"]\n    Shape --> Fuzz[\"Boundary-Directed Speculative Fuzzing\n(fast-check + Specialized Mutations)\"]\n    Fuzz --> Gate{\"Compatibility Gate\"}\n    Gate -->|\"sandbox-compatible\"| Sandbox[\"isolated-vm Zero-Privilege Sandbox\n(Enforced Execution Budget)\"]\n    Gate -->|\"framework-dependent\"| StaticOnly[\"Static-Only Classification\n(Preserves Safety, Bypasses Isolate)\"]\n    Sandbox -->|\"Execution Error\"| Shrinker[\"Delta-Debugging Shrinking Engine\n(Signature Preservation)\"]\n    Shrinker --> Repro[\"Minimal Reproducible Failure\"]\n    Sandbox -->|\"Clean / Handled\"| Findings[\"Finding Synthesis\"]\n    Taint --> Findings\n    StaticOnly --> Findings\n    Repro --> Findings\n    Findings --> Reporter[\"Reporters: Terminal · JSON v1 · SARIF 2.1.0\"]\n```\n\n1. **AST & Boundary Discovery**: Uses `@swc/core` to parse TypeScript and TSX, identifying `\"use client\"` and `\"use server\"` directives, exported Server Actions, and component props.\n2. **Interprocedural Data-Flow & Taint**: Constructs a local module call graph to trace sensitive environment variables across helper functions into Client boundaries.\n3. **React Flight Serializability**: Evaluates props passed to Client Components against React Flight serialization specifications.\n4. **Speculative Shape Inference**: Infers parameter shapes from TypeScript types, destructuring patterns, and property accesses.\n5. **Boundary-Directed Fuzzing**: Synthesizes adversarial payloads targeting boundary hazards using `fast-check` and targeted mutation strategies.\n6. **Isolated Runtime Verification**: Executes sandbox-compatible actions in an `isolated-vm` V8 isolate under an execution budget (default: 20ms).\n7. **Failure-Preserving Shrinking**: Automatically delta-debugs failing payloads to the smallest reproducible input that triggers the identical error signature.\n8. **Deterministic Reporting**: Formats results as actionable terminal output, Version 1 JSON, or OASIS SARIF 2.1.0.\n\n---\n\n## Why SIS Is Different\n\n| Approach | What It Does | SIS Difference |\n| :--- | :--- | :--- |\n| **Unit tests** | Verify developer-written examples | SIS generates boundary-directed adversarial edge cases automatically. |\n| **Generic fuzzing** | Explores arbitrary, untyped inputs | SIS targets discovered Next.js boundary contracts and inferenced shapes. |\n| **Static analysis** | Identifies suspicious syntax patterns | SIS dynamically executes and verifies sandbox-compatible candidates in an isolate. |\n| **Taint analysis** | Traces sensitive values to sinks | SIS combines interprocedural taint with React Server/Client boundary semantics. |\n| **SIS** | Unifies boundary discovery, taint, fuzzing, and shrinking | Delivers verified, minimal reproducers for edge cases developers miss. |\n\n> SIS does not replace your test suite or linter. It complements them by exploring boundary behaviors beyond your happy paths.\n\n---\n\n## See It in Action\n\nConsider a simple Server Action designed to calculate discounts:\n\n```typescript\n\"use server\";\n\nexport async function calculatePrice(value: number) {\n  return value.toFixed(2);\n}\n```\n\nDevelopers expect standard positive numbers. But what happens when unexpected values arrive across the network?\n\nWhen audited, SIS synthesizes numeric edge cases (`0`, `-0`, `NaN`, `Infinity`, `-Infinity`, `null`, `undefined`), executes the candidate inside the V8 isolate, and shrinks the failing payload:\n\n```text\n$ npx @aashirzayd/sis audit app/actions/pricing.ts\n\nSIS  Speculative Invariant Synthesis\nAutonomous runtime verification for Next.js boundaries\n\n◇ DISCOVERY\n  Target: app/actions/pricing.ts (Single File)\n\nScanning 1 source file...\n\n◆ DISCOVERY\n  ✓ 1 server boundary\n  ✓ 1 candidate Server Action\n\n◆ SPECULATIVE FUZZING\n  ◇ 1 boundary target discovered\n  ⟳ 4 fuzz strategies applied\n  ✓ 10 boundary-directed payloads\n\n◆ RUNTIME VERIFICATION\n  ✓ 6 passed\n  ✖ 4 failed\n\n  ✖ calculatePrice\n    Payload #1\n    Input: -Infinity\n    RangeError: toFixed() digits argument must be between 0 and 100\n    app/actions/pricing.ts:4\n\n    Execution: 2ms / 20ms budget\n    Wall time: 6ms\n\n◆ FAILURE SHRINKING\n  ✓ 4 failures reduced\n\n  ✖ calculatePrice\n    Original: -Infinity\n    Minimal reproducer: -Infinity\n    Attempts: 1\n    Reduction: 0%\n    Verification: ✓ failure preserved\n\n────────────────────────────────────────\nAUDIT COMPLETE\n  Files analyzed:        1\n  Server boundaries:     1\n  Candidate actions:     1\n  Runtime failures:      4\n  Taint violations:      0\n\n✖ SIS found 4 verified findings\n────────────────────────────────────────\n```\n\nWhen encountering complex nested inputs, the shrinking engine systematically strips irrelevant properties:\n\n```text\n  ✖ processOrder\n    Original: { user: { profile: { accountId: null, role: \"admin\" } }, tags: [\"urgent\"] }\n    Minimal reproducer: { user: { profile: { accountId: null } } }\n    Attempts: 3\n    Reduction: 73.1%\n    Verification: ✓ failure preserved\n```\n\n---\n\n## Boundary Awareness\n\nSIS models the full spectrum of Next.js App Router boundary semantics:\n\n- **Client Modules**: Files marked with top-level `\"use client\"`.\n- **Server Modules**: Files marked with top-level `\"use server\"`.\n- **Server Components**: Default React components in App Router executed on the server.\n- **Server Actions**: Async functions explicitly callable from the client, designated via module-level or inline `\"use server\"` directive prologues.\n- **Server Functions**: General server-side utility functions. *Not every Server Function is a Server Action.*\n- **Server-to-Client Props**: Prop expressions passed from Server Components into Client Components (`<ClientComponent prop={value} />`).\n\nBoundary semantics determine where adversarial inputs and invariants matter. Server Actions require fuzzing and parameter validation; Client Component boundaries require serializability and secret taint checks.\n\n---\n\n## React Flight Serialization\n\nReact Server Components transfer data over the wire using the React Flight protocol. Props passed from Server Components to Client Components, as well as return values from Server Actions, must be transferable.\n\n```\nJSON.stringify semantics  ≠  React Flight semantics\n```\n\nSIS inspects boundary expressions against React Flight specifications:\n\n- **Supported Built-ins**: Primitives (`string`, `number`, `boolean`, `null`, `undefined`), `Date`, `Map`, `Set`, `ArrayBuffer`, typed arrays (`Uint8Array`, etc.), plain objects, arrays, and functions with `\"use server\"`.\n- **Unsupported Hazards**:\n  - Ordinary functions and closures without `\"use server\"` (e.g. `onClick={() => {}}` passed from a Server Component).\n  - Custom class instances (e.g. `new DatabaseClient()`, `new UserSession()`).\n  - Unregistered `Symbol()` identifiers.\n  - Circular and non-transferable data structures.\n\nWhen non-transferable values cross boundaries, SIS emits `SIS002: serialization-violation`.\n\n---\n\n## Static Taint Analysis\n\nSIS tracks sensitive server environment variables through AST data flows and interprocedural helper chains until they reach a boundary:\n\n```text\nprocess.env.AUTH_SECRET  ──>  getSessionSecret()  ──>  <UserProfile secret={...} />\n```\n\n- **Sensitive Sources**: Automatically matches environment variables matching `*_KEY`, `*_SECRET`, `*_TOKEN`, `*_PASSWORD`, `PRIVATE_*`, and `SECRET_*`.\n- **Safe Variables**: Public environment variables (`NEXT_PUBLIC_*`) are explicitly recognized as safe and excluded from taint tracking.\n- **Sinks**: Direct assignments, object literals, array elements, and template strings reaching `\"use client\"` boundaries or JSX expressions.\n\nIf a sensitive flow is detected, SIS reports a static `SIS001: taint-violation` with source location and trace details.\n\n---\n\n## Isolated Runtime Verification\n\nWhen candidate Server Actions are identified, SIS evaluates their execution compatibility:\n\n- **Sandbox-Compatible**: Self-contained functions without host dependencies or unresolved external imports. These are executed directly inside an `isolated-vm` V8 isolate.\n- **Static-Only**: Functions that depend on external infrastructure (Next.js `cookies()`, `headers()`, `redirect()`, `notFound()`, database connections, ORMs, or network sockets).\n\n```text\nFramework-dependent action\n        ↓\n    cookies()\n        ↓\n   static-only\n        ↓\nStatic analysis continues\nRuntime isolate skipped\n```\n\n> **Why this matters**: `isolated-vm` provides a secure, zero-privilege execution sandbox without access to `process`, `fs`, `fetch`, or host environment variables. SIS does not claim to be a full Next.js runtime. Bypassing isolate execution for framework-dependent functions prevents false-positive crashes while verifying pure logic safely.\n\n---\n\n## Failure Shrinking\n\nWhen a synthesized payload triggers a runtime failure, raw property-based inputs are often noisy and complex. SIS invokes a failure-preserving delta-debugging shrinker:\n\n```text\nComplex failing payload\n        ↓\nCapture failure signature (action + error name + message pattern)\n        ↓\nSystematically strip properties / simplify scalar values\n        ↓\nVerify candidate in sandbox (re-check failure signature)\n        ↓\nSmallest useful failing payload (Minimal Reproducer)\n```\n\nIf a reduced payload fails to reproduce the exact original failure signature, the shrinker discards it and preserves the verified parent state.\n\n---\n\n## Determinism & Reproducibility\n\nSIS guarantees reproducible audits:\n\n```bash\nnpx @aashirzayd/sis audit app/ --seed 42\n```\n\nSpecifying a seed produces deterministic results across runs:\n- **Lexicographical File Ordering**: Directory discovery sorts files consistently across operating systems.\n- **Per-File Seed Derivation**: Each file receives a deterministic seed derived via 32-bit FNV-1a hashing of the base seed and relative file path.\n- **Deterministic Payload Generation**: The underlying `fast-check` PRNG produces identical payloads.\n- **Reproducible Repro Payloads**: Failure signatures and minimal reproducers match across runs.\n\n*(Note: While findings and payloads are deterministic, execution timing measurements naturally vary depending on system hardware).*\n\n---\n\n## Performance & Scaling\n\nSIS enforces a linear budget model:\n\n```text\nTotal Payloads  =  Targets (T)  ×  Runs (N)\n```\n\nThe `--runs` option defines the quota **per candidate target**, rather than a global pool:\n\n- **10 targets** $\\times$ `--runs 10` = 100 synthesized payloads.\n- **100 targets** $\\times$ `--runs 10` = 1,000 synthesized payloads.\n- **100 targets** $\\times$ `--runs 100` = 10,000 synthesized payloads.\n\nThis per-target allocation prevents combinatorial explosion ($O(T \\cdot N)$ rather than $O(T \\cdot N \\cdot S)$), ensuring predictable memory and execution time across large projects.\n\n*(Example benchmark on local developer hardware: 20 targets audit in ~0.8s; 100 targets audit in ~3.5s. Exact timings depend on host machine specifications).*\n\n---\n\n## Installation\n\nRun SIS on-demand using `npx`:\n\n```bash\nnpx @aashirzayd/sis audit .\n```\n\nOr add it to your project's development dependencies:\n\n```bash\nnpm install --save-dev @aashirzayd/sis\n```\n\nOnce installed locally, you can invoke the executable directly:\n\n```bash\nsis audit .\n```\n\n### System Requirements\n\n- **Node.js**: `>= 24.0.0`\n- **Module System**: ESM (ECMAScript Modules)\n- **Target Projects**: Next.js App Router applications (TypeScript or JavaScript)\n\n---\n\n## CLI Reference\n\n```bash\n# Using npx\nnpx @aashirzayd/sis audit [target] [options]\n\n# Or using the locally installed binary\nsis audit [target] [options]\n```\n\n### Common Commands\n\n```bash\n# Audit entire repository\nnpx @aashirzayd/sis audit .\n\n# Audit a specific Server Action or component file\nnpx @aashirzayd/sis audit app/actions/checkout.ts\nnpx @aashirzayd/sis audit app/components/Card.tsx\n\n# Emit machine-readable JSON or SARIF to stdout\nnpx @aashirzayd/sis audit . --json > sis-report.json\nnpx @aashirzayd/sis audit . --sarif > sis-results.sarif\n\n# Run silently in CI scripts (exit code only)\nnpx @aashirzayd/sis audit . --silent\n\n# Configure fuzzing budget and deterministic seed\nnpx @aashirzayd/sis audit . --runs 25 --seed 42 --timeout 50\n```\n\n### Options\n\n| Category | Option | Description | Default |\n| :--- | :--- | :--- | :--- |\n| **Audit** | `<target>` | Path to target project, directory, or individual source file. | *(Required)* |\n| | `--ignore <patterns...>` | Additional directories or file patterns to ignore. | `[]` |\n| | `--max-analysis-depth <n>` | Maximum call-depth for interprocedural analysis. | `8` |\n| **Output** | `-f, --format <format>` | Output format: `terminal`, `json`, or `sarif`. | `\"terminal\"` |\n| | `--json` | Emit output as machine-readable JSON (alias for `--format json`). | `false` |\n| | `--sarif` | Emit output as OASIS SARIF 2.1.0 (alias for `--format sarif`). | `false` |\n| | `--silent` | Suppress human-readable terminal progress and output. | `false` |\n| **Execution** | `-r, --runs <n>` | Number of synthesized payloads allocated per candidate target. | `10` |\n| | `-t, --timeout <ms>` | Candidate JavaScript execution budget inside the isolate in ms. | `20` |\n| | `--no-shrink` | Disable automatic failure shrinking. | `false` |\n| | `--max-shrink-attempts <n>` | Maximum shrinking iterations per failing payload. | `30` |\n| **Reproducibility** | `-s, --seed <n>` | Explicit seed for deterministic synthesis and file ordering. | `Date.now()` |\n| **Global** | `--debug` | Display verbose diagnostics and error stack traces. | `false` |\n| | `-v, --version` | Display current SIS version. | |\n| | `-h, --help` | Display command help. | |\n\n> **Execution Timeout Semantics (`--timeout <ms>`)**:\n> The `--timeout` option configures the **maximum execution budget for candidate JavaScript execution inside the V8 isolate**. It is NOT total audit wall-clock time. Host AST parsing, payload synthesis, isolate spinup, and teardown are not deducted from this budget.\n\n### Exit Code Contract\n\n| Exit Code | Classification | Description |\n| :---: | :--- | :--- |\n| **`0`** | **Clean Audit** | Audit completed successfully with zero actionable findings or invariant violations. |\n| **`1`** | **Violations Detected** | Actionable findings detected (taint leaks, runtime exceptions, timeouts, or serialization errors). |\n| **`2`** | **CLI / Config Error** | Target path not found, invalid numeric option (`--runs <= 0`), conflicting output flags, or malformed arguments. |\n| **`3`** | **Engine Failure** | Unexpected internal executor or isolate failure. |\n| **`130`** | **Interrupted** | Execution canceled by user via `SIGINT` (`Ctrl+C`). |\n| **`143`** | **Terminated** | Execution terminated via `SIGTERM`. |\n\n---\n\n## Findings Catalog\n\nSIS assigns persistent, stable rule identifiers:\n\n| Rule ID | Name | Mode | Severity | Description |\n| :---: | :--- | :---: | :---: | :--- |\n| **`SIS001`** | `taint-violation` | Static | `error` | Sensitive server environment variable flows into a Client boundary. |\n| **`SIS002`** | `serialization-violation` | Static | `error` | Non-transferable value crosses React Flight boundary. |\n| **`SIS003`** | `runtime-exception` | Runtime | `error` | Candidate Server Action threw an unhandled runtime exception. |\n| **`SIS004`** | `timeout` | Runtime | `error` | Candidate Server Action exceeded its allocated execution budget. |\n| **`SIS005`** | `invariant-violation` | Dynamic / Static | `error` | Boundary invariant assertion violated during execution. |\n\n### Rule Details\n\n#### `SIS001`: Taint Violation\n- **Meaning**: Server-side credentials or secrets are accessible in a Client Component or returned to client code.\n- **Example**: `const key = process.env.API_SECRET; return <div>{key}</div>;` inside `\"use client\"`.\n- **Remediation**: Remove secret references from Client Components. Access secrets only inside server-only modules or Server Actions without returning them.\n\n#### `SIS002`: Serialization Violation\n- **Meaning**: A Server Component passes a prop to a Client Component that cannot be serialized over React Flight.\n- **Example**: `<ClientButton onClick={() => doServerWork()} />` where `onClick` is an ordinary server function without `\"use server\"`.\n- **Remediation**: Convert the handler to a Server Action with `\"use server\"`, or pass serializable primitive identifiers.\n\n#### `SIS003`: Runtime Exception\n- **Meaning**: An exported Server Action threw an uncaught error (such as `TypeError` or `RangeError`) when invoked with boundary edge cases.\n- **Example**: `export async function update(data) { return data.user.id; }` fails when `data` is `null`.\n- **Remediation**: Implement defensive parameter validation at the top of the Server Action (e.g. using Zod, ArkType, or explicit guards).\n\n#### `SIS004`: Timeout\n- **Meaning**: An action entered an infinite loop or exceeded its isolate execution budget.\n- **Example**: `while (condition) { ... }` without an exit condition.\n- **Remediation**: Check loop termination conditions and bound recursion depth.\n\n#### `SIS005`: Invariant Violation\n- **Meaning**: A synthesized boundary invariant was breached during analysis or execution.\n- **Remediation**: Review the specific failure diagnostic reported in the audit findings.\n\n---\n\n## Machine-Readable Output & CI\n\n### Stream Discipline\nWhen `--json` or `--sarif` is specified, SIS enforces strict stream separation:\n- **`stdout`**: Reserved strictly for valid JSON or SARIF.\n- **`stderr`**: Receives all diagnostic notices, progress banners, and error boxes.\n\nPiping stdout to a file will never produce corrupted JSON:\n\n```bash\nnpx @aashirzayd/sis audit . --json > sis-report.json\nnpx @aashirzayd/sis audit . --sarif > sis-results.sarif\n```\n\n### GitHub Actions Workflow\n\nIntegrate SIS into GitHub Actions to scan pull requests and publish findings directly to GitHub Security Code Scanning:\n\n```yaml\nname: SIS Security Audit\n\non:\n  push:\n    branches: [main]\n  pull_request:\n    branches: [main]\n\njobs:\n  audit:\n    runs-on: ubuntu-latest\n    permissions:\n      security-events: write\n      contents: read\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v4\n\n      - name: Setup Node.js\n        uses: actions/setup-node@v4\n        with:\n          node-version: 24\n\n      - name: Install dependencies\n        run: npm ci\n\n      - name: Run SIS Audit\n        run: npx @aashirzayd/sis audit . --sarif > sis-results.sarif\n        continue-on-error: true\n\n      - name: Upload SARIF to GitHub Code Scanning\n        uses: github/codeql-action/upload-sarif@v3\n        with:\n          sarif_file: sis-results.sarif\n```\n\n---\n\n## Limitations\n\nTo maintain technical precision and credibility, SIS explicitly identifies its architectural boundaries:\n\n1. **Not a Full Next.js Runtime**: SIS uses `isolated-vm` to execute JavaScript in a clean V8 isolate. It does not run a mock Next.js server, emulate the React reconciler, or provide Next.js routing infrastructure.\n2. **Static-Only for Framework Globals**: Actions requiring live Next.js request context (`cookies()`, `headers()`, `redirect()`, `notFound()`) or external database connections are classified as `static-only` and safely skipped from isolate execution.\n3. **Flight Modeling vs Bundler Emulation**: React Flight serializability is modeled against published protocol specifications; it does not invoke React's internal webpack flight client/server plugin.\n4. **Targeted Fuzzing vs Formal Proof**: Speculative invariant synthesis generates targeted boundary payloads. Passing an audit verifies that tested invariants held against synthesized inputs; it is not a mathematical proof of absolute security.\n5. **Static Taint Reach**: Static analysis operates over discoverable local module graphs. Dynamic evaluation (`eval()`, dynamically constructed `import()`, or obfuscated property access) cannot be tracked.\n\n---\n\n## Roadmap\n\nSIS is developed in rigorous, phased milestones:\n\n- [x] **Phase 1 — Foundation & CLI Shell**: Core contracts, Commander CLI, terminal presenter.\n- [x] **Phase 2 — SWC AST & Boundary Discovery**: Parser, `\"use client\"`/`\"use server\"` discovery, source mapping.\n- [x] **Phase 3 — Static Taint Analysis**: Sensitive environment variable tracking across AST flows.\n- [x] **Phase 4 — Property-Based Payload Synthesis**: Adversarial inputs powered by `fast-check`.\n- [x] **Phase 5 — Isolated Runtime Execution**: Zero-privilege `isolated-vm` sandbox with execution budgets.\n- [x] **Phase 6 — Failure Shrinking & Minimization**: Delta-debugging engine preserving failure signatures.\n- [x] **Phase 7 — Directory Auditing & CLI Experience**: Recursive scanning, FNV-1a seeding, exit code contract.\n- [x] **Phase 8 — Machine-Readable JSON & SARIF**: JSON schema v1, OASIS SARIF 2.1.0, stream separation.\n- [x] **Phase 9 — Interprocedural Data Flow**: Multi-hop module call graphs, cycle-safe analysis depth.\n- [x] **Phase 10 — Next.js Boundary Semantics**: Fine-grained boundary classification, React Flight modeling.\n- [x] **Phase 11 — Boundary-Aware Speculative Fuzzing**: Type-directed shape inference, targeted mutations.\n- [x] **Phase 12 — Real-World Hardening**: Validation against 11 real-world adversarial fixture suites.\n- [x] **Phase 13 — Performance & Determinism**: Linear $O(T \\cdot N)$ scaling, byte-for-byte seed reproducibility.\n- [x] **Phase 14 — CLI/UX & Error Handling Polish**: Input validation, flag aliases, signal handling.\n- [x] **Phase 15 — Documentation & GitHub Excellence**: Authoritative technical documentation, architecture specs, and curated examples.\n- [ ] **Phase 16 — Automated Invariant Remediation**: Automated boundary decorators and patch generation.\n\n---\n\n## Development & Testing\n\n```bash\n# Install dependencies\nnpm install\n\n# Build TypeScript\nnpm run build\n\n# Run test suite (205 tests across 14 suites)\nnpm test\n\n# Run tests in watch mode\nnpm run test:watch\n```\n\n---\n\n## License\n\nMIT © 2026 Aashir Zayd. See [LICENSE](LICENSE) for details.\n","readmeFilename":"README.md","_rev":"1-890126e81211c146151dcd53abf4f968"}