npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@sanoy24/jevpolicy

v0.2.0

Published

Policy-as-code for probabilistic software decisions.

Readme

JevPolicy

Code calculates. Jev judges. Policy decides.

JevPolicy is an open-source TypeScript decision runtime that turns probabilistic judgments from Jev, accessed through Vercel AI Gateway, into versioned, deterministic, replayable, observable application decisions.

What it does

JevPolicy separates probabilistic judgment from deterministic application policy. An application supplies state and facts, Jev answers typed questions with probabilities, and ordered YAML rules turn those signals into a decision.

This is useful for workflows such as support routing, moderation, approval gates, risk review, and escalation. JevPolicy returns the decision and its audit trace; the host application remains responsible for carrying out any action.

state + facts
     |
     v
deterministic preconditions
     |
     v
Jev typed questions -> normalized probabilistic signals
     |
     v
ordered policy rules -> decision + trace + optional record

Installation

Requires Node.js 22.18 or later.

npm install @sanoy24/jevpolicy

The package includes the jevpolicy CLI:

npx jevpolicy validate ./policy.yaml

Live evaluation requires a Vercel AI Gateway key:

export AI_GATEWAY_API_KEY="your-api-key"

In PowerShell:

$env:AI_GATEWAY_API_KEY = "your-api-key"

Run the example from source

Clone the repository, install its dependencies, and validate the included policy:

git clone https://github.com/Sanoy24/jevpolicy.git
cd jevpolicy
npm install
npm run cli -- validate examples/support-routing.policy.yaml

Compare the released policy with a candidate entirely offline:

npm run cli -- diff \
  examples/support-routing.policy.yaml \
  examples/support-routing.candidate.policy.yaml \
  --json

The diff reports stable paths for added, removed, changed, and reordered policy elements. Rules and preconditions are matched by ID because their order affects which decision wins.

The included example asks Jev to classify a support request, then applies deterministic routing rules. Its essential policy is:

schema: jevpolicy/v1
name: support-routing
version: 1

decisions: [billing, technical, account, human_review]

questions:
  category:
    type: choice
    instructions: Which support category best matches this ticket?
    criteria:
      billing: Payment, refund, or charge problems
      technical: Product or application problems
      account: Login or account-management problems

rules:
  - id: billing-route
    when:
      signal: category
      op: eq
      value: billing
    decision: billing

fallback:
  provider_error: human_review
  provider_timeout: human_review
  invalid_provider_response: human_review
  no_match: human_review

See the complete support-routing.policy.yaml for its fact declaration, precondition, additional questions, and remaining routes.

The example state is ordinary JSON:

{
  "subject": "Refund missing",
  "body": "I was charged twice and need help resolving it.",
  "authenticated": true
}

Evaluate it and record the decision:

npm run cli -- evaluate examples/support-routing.policy.yaml \
  --state examples/support-routing.state.json \
  --record decisions.jsonl \
  --json

Evaluate a compatible candidate policy in shadow mode with the same provider request:

npm run cli -- evaluate examples/support-routing.policy.yaml \
  --state examples/support-routing.state.json \
  --shadow-policy examples/support-routing.candidate.policy.yaml \
  --record decisions.jsonl \
  --json

Abridged result:

{
  "mode": "live",
  "decision": "billing",
  "matched": { "ruleId": "billing-route" },
  "signals": {
    "category": { "type": "choice", "value": "billing" }
  },
  "provider": {
    "adapter": "vercel-jev",
    "model": "typesafe-ai/jev",
    "invoked": true
  },
  "fallback": { "used": false }
}

Jev supplied the probabilistic category signal; the billing-route policy rule made the final decision. Replay reuses the recorded signals without another provider call:

npm run cli -- replay decisions.jsonl \
  --policy examples/support-routing.policy.yaml \
  --json

The CLI derives declared facts from same-named top-level properties in the state object. Use --facts facts.json to supply them separately. It records to decisions.jsonl by default; use --no-record to disable recording. --json is available for validate, diff, evaluate, and replay.

Library usage

The same runtime can be embedded directly in a TypeScript application:

import {
  JsonlRecorder,
  createJevPolicyRuntime,
  loadPolicyFile,
} from '@sanoy24/jevpolicy';

const policy = await loadPolicyFile('./policy.yaml');
const runtime = createJevPolicyRuntime({
  policy,
  provider: {
    type: 'vercel-jev',
    model: 'typesafe-ai/jev',
    timeoutMs: 10_000,
  },
  recorder: new JsonlRecorder('./decisions.jsonl'),
});

const result = await runtime.evaluate({
  state: {
    subject: 'Refund missing',
    body: 'I was charged twice',
  },
  facts: { authenticated: true },
});

console.log(result.decision, result.trace, result.fallback);

Deterministic preconditions run before any provider call. Provider timeouts, invalid responses, and other provider failures map only to explicit policy fallbacks; they never silently become an allow decision.

Policy comparison

diffPolicies exposes the same semantic comparison used by the CLI:

import { diffPolicies, loadPolicyFile } from '@sanoy24/jevpolicy';

const base = await loadPolicyFile('./policy.yaml');
const candidate = await loadPolicyFile('./policy.candidate.yaml');
const diff = diffPolicies(base, candidate);

console.log(diff.changed, diff.summary, diff.changes);

The comparison is deterministic and does not call a provider. Decision names are treated as a set; named facts and questions are compared by key; and preconditions and rules are matched by ID with order changes reported separately.

Shadow evaluation

Use a shadow policy to test rule and threshold changes against live traffic without letting the candidate decision control application behavior:

const shadowPolicy = await loadPolicyFile('./policy.candidate.yaml');
const result = await runtime.evaluateWithShadow({
  shadowPolicy,
  state: {
    subject: 'Refund missing',
    body: 'I was charged twice',
  },
  facts: { authenticated: true },
});

applyDecision(result.active.decision);
console.log(result.shadow.decision, result.comparison);

The active and shadow envelopes have live and shadow modes respectively. Both are recorded when a recorder is attached, but only active should drive host side effects. A compatible pair must have the same policy name, fact contract, question names, and question fingerprints. JevPolicy rejects an incompatible pair before invoking the provider. Compatible policies share one provider request, so shadow evaluation is intended for comparing policy logic over the same signal contract.

OpenTelemetry

Applications with an OpenTelemetry SDK can attach the optional observer:

import { createJevPolicyRuntime } from '@sanoy24/jevpolicy';
import { OpenTelemetryDecisionObserver } from '@sanoy24/jevpolicy/opentelemetry';

const runtime = createJevPolicyRuntime({
  policy,
  provider: {
    type: 'vercel-jev',
    model: 'typesafe-ai/jev',
  },
  observer: new OpenTelemetryDecisionObserver(),
});

Install @opentelemetry/api alongside JevPolicy when using this entry point. The application remains responsible for configuring its OpenTelemetry SDK and exporters; without a registered SDK, the API uses its standard no-op providers.

The observer emits jevpolicy.decision.evaluate spans, evaluation and fallback counters, and decision/provider duration histograms. Attributes cover policy identity, mode, decision, provider, match, and fallback metadata. State, facts, signals, prompts, and provider responses are deliberately excluded. Observer failures are isolated and never change or reject a completed policy decision.

Recording and replay

Raw state recording defaults to none. Policies may opt into full state recording, or redacted recording when the programmatic runtime supplies a redaction hook. Records contain declared deterministic facts. Successful provider evaluations also contain question-fingerprinted normalized signals so replay can reproduce policy logic without calling the provider. Records created by a terminating precondition or provider fallback may not contain the complete signal set and cannot be replayed against policies that require those signals.

Do not place credentials or secrets in declared facts. Decision logs may contain sensitive facts, signals, or state, so keep them out of version control.

If persistence fails, evaluation throws RecorderError; its envelope property contains the decision that was already computed.

Responsibility boundary

Vercel AI Gateway owns

  • inference authentication,
  • access to Jev,
  • model/provider routing capabilities,
  • provider-level request infrastructure,
  • gateway usage/spend visibility.

JevPolicy owns

  • policy-as-code,
  • deterministic preconditions,
  • Jev question definitions,
  • signal normalization,
  • ordered decision rules,
  • explicit probability thresholds without implicit Boolean coercion,
  • typed fallbacks,
  • decision envelopes,
  • audit traces,
  • record/replay,
  • signal replay with question compatibility fingerprints.

Host application owns

  • actual side effects,
  • authorization,
  • financial execution,
  • filesystem mutation,
  • tool execution,
  • user notifications,
  • business transactions.

JevPolicy never executes the business action itself.

License

Apache-2.0.