Skip to content
purwar21darsh-codePublic

About

Deterministic fault-injection and counterfactual scenario matrix for TypeScript workflows

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

FAULTLINE

A small, deterministic counterfactual scenario matrix for testing proposed workflows against controlled failures in isolated state.

FAULTLINE is an open-source TypeScript library. It does not contain a scheduler, a household model or a UI. A caller supplies:

  • an initial state,
  • a plan,
  • a state-cloning function,
  • a simulation callback,
  • an outcome evaluator,
  • and a list of typed fault scenarios.

FAULTLINE runs the baseline once and then runs every scenario against its own clone. It returns a structured report with pass/fail/error/invalid statuses, violations, metrics and isolation disclosures.

Status: version 0.1.0. Public repository: https://github.com/purwar21darsh-code/faultline. It is not published to npm. It has been tested on Node.js 24 / Windows with 13 passing unit tests. It is not a production or security sandbox.

Why this exists

Agent and workflow authors often test the happy path. A plan may work until a delivery is late, an ingredient disappears, a step overruns or a resource goes offline. FAULTLINE makes those experiments repeatable and keeps each fault from contaminating the baseline or another scenario.

The important design rule is simple: the outcome is calculated by your simulator and evaluator, not by FAULTLINE and not by an LLM.

Install

From this repository:

npm install
npm run build
npm test
npm run example

Use it from another project through the published v0.1.0 release artifact:

npm install https://github.com/purwar21darsh-code/faultline/releases/download/v0.1.0/faultline-sim-0.1.0.tgz

Or pin a dependency explicitly:

{
  "dependencies": {
    "faultline-sim": "https://github.com/purwar21darsh-code/faultline/releases/download/v0.1.0/faultline-sim-0.1.0.tgz"
  }
}

For simultaneous local development, a file:../faultline dependency is also supported.

Then import the built package:

import { runScenarioMatrix } from "faultline-sim";

The package is ESM-only and its development/test toolchain requires Node.js 20.19 or newer.

Quick start

import {
  runScenarioMatrix,
  type FaultScenario
} from "faultline-sim";

interface State {
  stock: number;
  delay: number;
}

interface Plan {
  orders: number;
}

const initialState: State = { stock: 2, delay: 0 };
const plan: Plan = { orders: 2 };

const scenarios: FaultScenario<State, { increase: number }>[] = [
  {
    id: "stock-shortage",
    name: "One unit missing",
    faultType: "INVENTORY_LOSS",
    fault: { increase: 1 },
    applyFault(draft) {
      draft.stock -= 1;
    }
  }
];

const report = runScenarioMatrix<State, Plan, State, { increase: number }>({
  initialState,
  plan,
  scenarios,
  cloneState: (state) => structuredClone(state),
  simulateInSandbox: (state, currentPlan) => {
    state.stock -= currentPlan.orders;
    return state;
  },
  evaluateOutcome: (result) => ({
    passed: result.stock >= 0,
    summary: result.stock >= 0 ? "Enough stock" : "Short by " + Math.abs(result.stock),
    violations: result.stock >= 0 ? [] : ["stock is negative"],
    metrics: { finalStock: result.stock }
  })
});

console.log(report.baseline.status);
console.log(report.scenarios[0]?.status);
console.log(report.summary.overallStatus);

API

runScenarioMatrix(options)

Synchronous. Returns a SimulationReport.

Input Required Meaning
initialState yes State that must never be passed directly to user callbacks.
plan yes Plan supplied to every simulation. Treat it as read-only.
scenarios yes Array of FaultScenario.
cloneState yes Returns an independent state value.
simulateInSandbox yes Simulates a private clone; may be deterministic or use scenario context.
evaluateOutcome yes Returns { passed, summary?, violations?, metrics? }.

The baseline is simulated first in its own clone. Each scenario then receives a fresh clone of the original state, not the post-baseline state. This prevents one scenario's mutation from leaking into another.

Scenario-level exceptions become status: "error" entries. Invalid scenario definitions become status: "invalid" entries and are not simulated. A broken baseline rejects with SimulationExecutionError, because there is no trustworthy baseline against which to compare.

Types

  • FaultScenario<TState, TFault> — id, name, fault type, fault payload, validation hook and applyFault.
  • ScenarioOutcome — normalized pass flag, summary, violations and metrics.
  • ScenarioResult<TState, TPlan, TResult> — status, isolated state/result, outcome, error or validation issues.
  • SimulationReport<TState, TPlan, TResult> — baseline, scenario results, summary and isolation disclosure.
  • SimulationAdapter<TState, TPlan, TResult, TFault> — clone, simulate and evaluate function shapes.
  • ScenarioStatus — "passed" | "failed" | "error" | "invalid".
  • SimulationSummary — counts and "passed" | "failed" | "incomplete".

See docs/API.md for the full reference and examples/task-inventory.ts for a runnable example.

State support and isolation boundaries

FAULTLINE is an isolation coordinator, not a security sandbox.

  • The exported structuredCloneState supports structured-cloneable data: plain objects, arrays, Map, Set, Date, typed arrays and cycles. It does not support functions, promises, DOM nodes, database handles, sockets or class instances with private state.
  • For other state, pass a domain-specific cloneState. It must return a new object/array, not the original reference. FAULTLINE rejects reference reuse for object state.
  • Simulation callbacks execute in the same Node.js process. They can still perform side effects if you write them to. FAULTLINE does not intercept network, filesystem or child-process calls.
  • Do not run untrusted generated code in a simulation callback. This library is not a VM, container or permission system.
  • The library never passes initialState to applyFault or simulateInSandbox. It does pass the caller's plan by reference; treat plans as immutable.
  • isolation.originalStatePassedToCallbacks is always false, reflecting the call graph. It is not a cryptographic proof against a callback that closes over the original variable.

Validation rules

Root configuration issues throw FaultlineInputError.

A scenario is marked invalid when:

  • its id is missing or does not match [A-Za-z0-9][A-Za-z0-9._:-]{0,127},
  • its id duplicates an earlier scenario,
  • its name or fault type is empty,
  • fault is absent,
  • applyFault is not a function,
  • its validate hook returns issues or throws.

Duplicate ids are reported on the later entry; the earlier entry remains authoritative.

Determinism

FAULTLINE does not use timestamps, randomness or wall-clock time. If your clone, fault application, simulator and evaluator are deterministic, the returned report is reproducible. Scenario order is preserved in the output.

Example

npm run example

The example models a tiny kitchen plan and runs:

  • missing chicken,
  • a 30-minute delivery delay,
  • a 50% roast overrun.

It prints the baseline, each isolated result, the summary and checks that the original state did not change and that a repeated run serializes identically.

Tests

npm test
npm run typecheck
npm run build
npm run example

The unit suite covers state cloning, baseline execution, scenario isolation, fault injection, deterministic replay, invalid input, scenario exceptions, evaluator exceptions, multiple scenarios, original-state preservation, summary status and export shape.

Design limitations

  • Synchronous only. Async simulators need to be adapted or run through a wrapper.
  • One plan per matrix. Run multiple matrices for multiple plans.
  • No automatic repair or search; that belongs in a domain toolkit such as FORKCAST.
  • No deep-equality mutation detector for arbitrary state. Isolation relies on correct cloning and non-mutating callbacks.
  • No bandwidth, capacity or resource scheduling semantics. Those belong to the caller's simulator.
  • The example and tests are demonstration software, not production scheduling advice.

License

MIT. See LICENSE.

About

Deterministic fault-injection and counterfactual scenario matrix for TypeScript workflows

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages