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

policystrata

v0.1.3

Published

TypeScript/Node trace recorder and runtime authorizer for PolicyStrata

Readme

PolicyStrata Node SDK

This package records sanitized agent, tool, SQL, and mutation traces from TypeScript/Node applications. Read-tool SQL records are compatible with policystrata scan JSONL imports. The scanner/CLI distribution remains the PolicyStrata PyPI package; this directory is the TypeScript SDK source and packaging surface.

It also exposes a deterministic runtime authorizer at policystrata/runtime. The scanner remains a release gate, not a live service dependency; the runtime authorizer is the small in-process helper applications can put on their own request path.

Install the Node runtime from npm:

npm install policystrata

pip install policystrata installs the Python CLI and scanner. It does not make policystrata/runtime importable to Node applications.

import { createPolicyStrataRecorder } from "policystrata/node";

const recorder = createPolicyStrataRecorder({
  service: "demo-data-agent",
  environment: process.env.NODE_ENV,
  out: ".policystrata/traces.jsonl",
  tenancy: {
    tenantColumns: ["transactions.household_id", "accounts.household_id"],
  },
});

const searchTransactions = recorder.wrapTool("searchTransactions", {
  kind: "read",
  scope: "household",
  handler: async (args, ctx) => {
    const query = db
      .select()
      .from(transactions)
      .where(eq(transactions.householdId, ctx.householdId));

    recorder.captureQuery(query);
    return await query;
  },
});

By default the recorder hashes ID fields with a per-recorder HMAC key, drops prompt text, redacts raw error messages and SQL literal values, records sanitized argument shape instead of argument values, and summarizes result rows as sanitized field names plus row count. Pass a deployment-specific redaction.hashSalt when traces need stable pseudonymous IDs across recorder instances. With default ID hashing, scanner-contract tenant_ids are omitted rather than HMACed; use redaction.hashIds: false only for trusted fixture traces that need explicit tenant IDs for real database comparison. Structured payloads such as semantic_ir, expected_policy, mutation, and audit metadata are recursively redacted; semantic_ir.filters.tenant_id is HMACed under default ID hashing and preserved raw only when trusted fixtures set redaction.hashIds: false.

Drizzle

Use captureQuery(query) on Drizzle query builders that expose .toSQL(), or wrap a client:

const tracedDb = recorder.wrapDrizzleClient(db);

The proxy captures common execution methods (execute, all, get, values, run) and query builders with .toSQL() before they execute. For explicit control, prefer captureQuery() at the tool boundary where request context and release decisions are available.

Record Types

  • sql_trace: read-tool SQL records with top-level sql and principal; trusted fixture traces may also include raw tenant_ids for policystrata scan.
  • agent_session: session metadata such as model, prompt class, available tools, approval policy, and write-tool enablement. Prompt text is omitted unless explicitly enabled.
  • mutation: write-tool metadata such as touched table, ownership predicates, written columns, and audit event state. These records intentionally omit top-level read SQL.
  • tool_execution: a tool call that did not execute SQL.

The Python scanner ignores non-SQL SDK records when they appear in the same JSONL file.

Runtime Authorizer

import { createPolicyStrataAuthorizer } from "policystrata/runtime";

const authorizer = createPolicyStrataAuthorizer(runtimeManifest);
const decision = authorizer.authorize({
  subject: { id: "user-1", role: "owner" },
  action: "read",
  resource: "searchTransactions",
  context: {
    semanticIr: { metric: "transaction_spend", dimensions: ["merchant_name"] },
  },
  mode: "shadow",
});

authorizeTool() remains as a compatibility wrapper over the generic API:

const toolDecision = authorizer.authorizeTool({
  toolName: "searchTransactions",
  userId: "user-1",
  householdId: "household-1",
  role: "owner",
  toolKind: "read",
  allowWriteTools: false,
  writeState: "disabled",
  approvalRequiredSatisfied: true,
  approvalState: "satisfied",
  decisionPoint: "execution",
  semanticIr: { metric: "transaction_spend", dimensions: ["merchant_name"] },
  mode: "shadow",
});

authorizeTool() decisions include operational metadata for application logs and metrics: toolKind, decisionPoint, writeState, approvalState, userId, and householdId. Approval-required tools may be visible at decisionPoint: "pre_model" with approvalState: "pending"; the same pending approval is denied at decisionPoint: "execution".

authorizeRelease() wraps the same API for the paper's release-conformance boundary: a result and its lineage may leave only approved boundaries.

const releaseDecision = authorizer.authorizeRelease({
  subject: { id: "user-1", role: "owner" },
  resource: "searchTransactions",
  boundary: "user",
  result: { kind: "aggregate", rowCount: 12, containsSensitiveValues: false },
  lineage: { sources: ["transactions"], containsRawRows: false },
  mode: "enforce",
});

Runtime manifests must default to deny. Unknown tools/resources/actions, unknown roles, missing approval, write tools without an application write-tool grant, undeclared semantic metrics or dimensions, and release attempts that violate result/lineage/boundary constraints are denied. allowed is always the deterministic policy decision. mode is reported as rollout metadata: applications usually log or sample denied shadow decisions, then block the same denied decision only after switching that call site to mode: "enforce".

if (!decision.allowed && decision.enforcementMode === "enforce") {
  throw new Error(decision.reasons.join("; "));
}

The same runtime module evaluates v0.2 gateway events across auth context, retrieval, memory, tool, browser/code, SQL, schema binding, output, egress, and trace layers:

import { evaluateRuntimeEvent, sqlRuntimeEvent } from "policystrata/runtime";

const runtimeDecision = evaluateRuntimeEvent(runtimeManifest, sqlRuntimeEvent({
  eventId: "evt_1",
  project: "support-bi",
  agent: { key: "support-bi-copilot" },
  summary: "Tenant-scoped support ticket query",
  actor: { userId: "user-1", tenantId: "tenant-a", role: "support", purpose: "support" },
  resource: { kind: "table", name: "support_tickets" },
  sql: "select count(*) from support_tickets where tenant_id = $1",
}));

Runtime event builders are available for common layers:

  • buildRuntimeEvent() for explicit low-level events.
  • sqlRuntimeEvent() for SQL statement metadata.
  • toolRuntimeEvent() for MCP/tool calls and schema refs.
  • retrievalRuntimeEvent() for vector/search retrieval evidence.
  • egressRuntimeEvent() for outbound webhook/API destinations.
  • clearanceEvidencePackRuntimeEvent() for referencing a local .clearance/evidence-pack.json artifact in runtime evidence without calling hosted Clearance APIs.

Next.js Route Handler

Use the runtime helpers in the application request path, not as a hosted dependency:

import { NextResponse } from "next/server";
import { evaluateRuntimeEvent, sqlRuntimeEvent } from "policystrata/runtime";
import runtimeManifest from "@/policystrata.runtime.json";

export async function POST(request: Request) {
  const body = await request.json();
  const sql = compileTenantScopedSql(body);
  const decision = evaluateRuntimeEvent(runtimeManifest, sqlRuntimeEvent({
    eventId: crypto.randomUUID(),
    project: "support-bi",
    agent: { key: "support-bi-copilot" },
    summary: "Support ticket query",
    actor: {
      userId: body.userId,
      tenantId: body.tenantId,
      role: body.role,
      purpose: "support",
    },
    resource: { kind: "table", name: "support_tickets", tenantId: body.tenantId },
    sql,
  }));

  if (!decision.allowed) {
    return NextResponse.json({ error: decision.reason }, { status: 403 });
  }

  return NextResponse.json(await runQuery(sql));
}

For a customer-hosted sidecar, install @policystrata/agent-trust-gateway; it wraps this evaluator in an HTTP gateway and strips runtime-event payload and fixture-only expectedDecision metadata before control-plane upload by default. The gateway is an application-side enforcement and telemetry helper; it does not replace policystrata scan, policystrata doctor, application authorization, or database controls.

The runtime manifest schema is available at policystrata/runtime-manifest.schema.json and in this source tree at schema/runtime-manifest.schema.json. The runtime authorizer is for in-process app checks on tool and release boundaries in the request path. policystrata scan remains the CI/release evidence gate over exported traces and should not be treated as a live authorization service.