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

@blocksifr/pctr

v0.1.0

Published

See what your AI agents can cause, route them safely, and prove what happened. Consequence preview, trust routing and signed execution receipts for AI agents.

Readme

PCTR — Protected Consequence Trust Routing

See what your agents can cause. Route them safely. Prove what happened.

Your agent can have valid credentials and still be about to do the wrong thing.

Objective  ->  Trust Route  ->  Consequence Preview  ->  Execution Authority  ->  Protected Action  ->  Receipt

60 seconds

Not on npm yet — from a clone of this repo:

npm link ./packages/pctr    # then the bare `pctr` command works anywhere
pctr init                   # discover agents and tools, write pctr.json
pctr scan                   # what consequences can they reach?

No account. No network. Everything stays in ./pctr.json and ./.pctr.

Share what you find

pctr scan --share           # writes pctr-report.md

Drops straight into a pull request or an issue: a severity table, the highest-priority consequence with the route that reaches it, and what to do about it. Add packages/pctr/examples/pctr-scan.yml to .github/workflows/ and every PR gets the same report as a comment, with fail-on: critical to block a merge when an agent can reach an irreversible consequence.

## 🛑 PCTR consequence scan

**5 agents · 3 tools · 4 actions.** 3 of them can cause a protected consequence, and 2 cannot be undone.

| Severity | Consequences |
| --- | --- |
| 🔴 CRITICAL | 1 |
| 🟠 HIGH | 1 |

### Highest priority: `customers.delete`

Causes **data deleted** · **irreversible** · 1,842 records · blast radius WIDE

The three questions

| Question | Command | Answers | | --- | --- | --- | | Consequence — what can this action cause? | pctr preview <action> | records, money, reversibility, blast radius | | Route — which trustworthy agent path may get there? | pctr route <action> | the selected path, and why every other one was rejected | | Authority — is this exact execution allowed right now? | pctr protect <action> | an allow/deny decision plus a verifiable receipt |

Consequence Twin

See what your AI is about to change before it changes it — git diff for autonomous agents. It reasons over the graph and the parameters you declare; it does not query your live systems (see Honest limits).

pctr preview customers.delete --records 1842
CONSEQUENCE PREVIEW

Action                customers.delete
Causes                data deleted
Records affected      1842
Reversible            NO
Connected workflows   4
Blast radius          WIDE (100/100)
Routes that reach it  1
Risk                  CRITICAL

Recommended

- Require TTP execution authority bound to these exact parameters
- Limit batch to 25 records (currently 1842) + require approval
- Notify 4 connected workflows before executing
- Verify authority at the effect boundary, not in the calling agent

TrustRoute Autopilot

The right trustworthy agent gets the job automatically. Admissibility is decided first; only routes that survive are optimized for latency and cost. A security constraint is never traded away for a faster or cheaper route.

pctr route payments.transfer --amount 18000
ROUTE SELECTED

user:local
  |
  v
planner
  |
  v
finance-agent-d
  |
  v
payments
  |
  v
payments.transfer

Effective trust       0.9178 (0.9 required for CRITICAL)
Hops                  5
Human approval        REQUIRED

Rejected routes

user:local -> planner -> finance-agent-a -> payments -> payments.transfer
  x finance-agent-a evidence is 4200s old; CRITICAL actions require evidence under 300s
  x effective trust 0.6579 is below the 0.9 required for CRITICAL consequences

At $1,800 the same action is HIGH and needs no approval; the amount is what moves it to CRITICAL. Material parameters change the consequence, and the consequence sets the bar.

finance-agent-a was the faster route. It was still rejected.

Agent Time Machine

Replay exactly why your AI did what it did.

pctr protect payments.transfer --amount 18000
pctr replay
pctr explain EXECUTION_DENIED
WHY WAS THIS EXECUTION DENIED?

policy requires human approval for CRITICAL consequences

Because

- Objective received: protect payments.transfer
- Action proposed: payments.transfer ($18000)
- Consequence detected: MONEY_MOVED (CRITICAL)
- Route selected: user:local -> planner -> finance-agent-d -> payments -> payments.transfer

Every answer is derived from the recorded causal chain, not re-narrated by a model. Runs can also be forked and compared:

pctr replay <run> --fork e3
pctr replay <run> --compare <other-run>

Execution authority

A valid identity is not enough. A valid credential is not enough. A valid route is not enough. Authority binds principal, delegator, session, action, target, material parameters, constraints, policy, consequence, validity window and nonce — and the effect boundary verifies it independently of the agent that asked.

import { issueAuthority, verifyAuthority } from '@blocksifr/pctr';

const authority = issueAuthority({
  principal: 'user:ops', action: 'payments.transfer', target: 'acct:9931',
  params: { amount: 1800 }, consequence: 'MONEY_MOVED', route
});

// Same authority, changed amount — possession is not authority.
verifyAuthority(authority, { action: 'payments.transfer', target: 'acct:9931', params: { amount: 18000 } });
// -> { allowed: false, failures: [{ code: 'PARAMETER_MISMATCH', ... }] }

Authority also expires and can only be spent once (REPLAYED_AUTHORITY).

Receipts

Every protected execution produces verifiable evidence of what was requested, who delegated it, which route was selected, what consequence was identified, what parameters were bound, which verifier checked it, and what actually executed.

pctr receipt         # show the last one
pctr verify          # verify all of them, including the chain

A receipt that records an execution which was never allowed fails verification (EXECUTED_WITHOUT_AUTHORITY), and a removed or reordered receipt breaks the chain.

Receipts and authority are signed with Ed25519. Verification takes the public key, so someone who can check your receipts cannot mint one:

pctr keys --export public-key.pem   # share this; never share .pctr/keys/signing-key.pem
pctr verify --key public-key.pem
RECEIPT VERIFICATION

Receipts checked      3
Valid                 2 of 3
Chain                 BROKEN
Signer                verified against a pinned key
  x rcpt-3d80fffd-b45a-405f-8a70-007b5ce7bfde
      receipt signature does not verify

Verifying without a pinned key still works, but reports itself as signerVerified: false with an UNPINNED_KEY warning — internal consistency is not proof of who signed. Pin signers permanently with "trustedSigners": ["ed25519:…"] in pctr.json.

Commands

pctr init                 Discover agents and tools, write pctr.json
pctr scan                 What consequences can your agents reach?
pctr graph                Show the trust graph
pctr preview <action>     Consequence Twin
pctr route <action>       TrustRoute Autopilot
pctr protect <action>     Run the full loop and issue a receipt
pctr simulate <action>    Same, without executing any effect
pctr replay [run]         Agent Time Machine
pctr explain <event>      Why was this allowed, denied, or rerouted?
pctr receipt [id]         Show an execution receipt
pctr verify [id]          Verify receipt signatures and the receipt chain
pctr keys                 Show your signing key id and public key
pctr serve                Run the effect boundary as its own process
pctr doctor               Check your setup

Every command prints plain English first. Add --json for machine-readable output.

pctr.json

{
  "principal": "user:ops",
  "agents": [
    { "id": "planner", "framework": "openai-agents", "trust": 0.98, "evidenceAgeSeconds": 20,
      "authority": ["*"], "jurisdiction": "eu", "tools": [], "delegatesTo": ["finance-agent-d"] },
    { "id": "finance-agent-d", "framework": "claude-agents", "trust": 0.97, "evidenceAgeSeconds": 30,
      "authority": ["payments.*"], "jurisdiction": "eu", "latencyMs": 140, "tools": ["payments"] }
  ],
  "tools": [{ "id": "payments", "protocol": "mcp", "actions": ["payments.transfer"] }],
  "actions": [{ "id": "payments.transfer", "amount": 1800, "connectedWorkflows": 2 }],
  "policy": {
    "requireApprovalAtOrAbove": "CRITICAL",
    "approvalThresholds": { "amount": 5000 },
    "jurisdictions": { "MONEY_MOVED": ["eu"] },
    "maxHops": 6,
    "decayPerHop": 0.05
  }
}

Agents are participants, not platforms. A new framework needs an adapter that maps its runtime events onto the canonical PCTR events — not a redesign of PCTR.

Universal agent fabric

Adapters ship for openai-agents, claude-agents, langgraph, crewai, autogen, semantic-kernel, mcp, a2a, microsoft-agt (see below), and a generic envelope for everything else. Each one maps a framework's own events onto the 16 canonical security events and drops the rest:

import { ingest, createTimeline } from '@blocksifr/pctr';

const timeline = createTimeline({ objective: 'Settle invoice INV-4471' });
ingest('crewai', crewEvents, timeline);
ingest('langgraph', graphEvents, timeline);   // one timeline, one security meaning

A tool call in any of them becomes ACTION_PROPOSED plus the CONSEQUENCE_DETECTED it implies — the part every framework leaves out. Token usage, streamed text and other framework internals are dropped rather than invented into events.

See node examples/pctr-universal-fabric-demo.mjs for four frameworks feeding one protected execution through a remote effect boundary.

Microsoft AGT (Agent Governance Toolkit)

microsoft/agent-governance-toolkit is a first-class target, not an afterthought. Types here follow the toolkit's own agent-governance-typescript/src/types.ts — PolicyAction, PolicyDecisionResult, AuditEntry, TrustScore, ExecutionRing, CascadeEvent, RingViolation — and the loop is the one in docs/integration-guide.md Part 6:

1. AGT enforces pre-execution policy
2. PCTR observes the consequence, the route and the signed receipt
3. Trust is recomputed from that behavioural evidence
4. AGT consumes it and adjusts the next decision

AGT stays authoritative for allow/deny. PCTR supplies the evidence it decides on and never builds a parallel privilege model.

import { ingest, agtClaims, toTrustEvidence, toMeshAttestation, toAgtScore } from '@blocksifr/pctr';

ingest('agt', agtRuntimeEvents, timeline);          // AGT's shapes -> canonical events
const claims = agtClaims({ route, preview, issuerCount: 2 });   // -> input.ttp for Rego
const evidence = toTrustEvidence(receipt);          // -> behavioural evidence, back to AGT
const attestation = toMeshAttestation(receipt);     // -> AgentMesh peer attestation

| Integration surface | Guide | What PCTR provides | | --- | --- | --- | | OPA/Rego bridge | 6.2 | agtClaims() returns input.ttp with ttp_domain, ttp_score, issuer_count — plus the consequence, severity, reversibility, route and receipt hash | | SPIFFE/SVID identity | 6.3 | SVID URIs work directly as agent ids; parseSpiffeId() exposes the trust domain, and claims surface spiffe_ids | | Trust score | 6.4 | toAgtTrustScore() produces AGT's TrustScore { overall, dimensions, tier }. AGT scores 0-1, banded untrusted 0.0 / provisional 0.3 / trusted 0.6 / verified 0.85 — PCTR is already 0-1, so it maps across unscaled. toAgtScore() (×1000) remains for the downstream consumers the guide mentions, but it is not the AGT-native path | | Execution rings | — | ringForSeverity() proposes a ExecutionRing from what the action can cause (CRITICAL → Ring0); AGT's own actionRings config stays authoritative | | AgentMesh bridge | 6.5 | toMeshAttestation() maps a receipt to a peer attestation carrying receiptId, receiptHash and signing key |

The event normalizer reads the toolkit's real shapes: every PolicyAction (allow/log/warn → allowed, deny → denied, require_approval → not executable yet, with the approvers carried), AuditEntry including its hash/previousHash chain, CascadeEvent containment actions (a quarantined or killed agent has no trust left, while health_propagated is telemetry and is dropped), RingViolation, kill-switch results and TrustVerificationResult with its tier. Anything it can't read returns null — PCTR never invents a security event from a shape it doesn't recognise, and there's a test for that.

Worth noting: AGT hash-chains its audit log exactly as PCTR chains receipts, so the two evidence trails line up.

A denial at a high-consequence action is the strongest behavioural signal there is, so toTrustEvidence() weights by what the action could have caused, not merely whether it ran.

Worked end to end: npm run demo:pctr-agt.

Python. AGT is Python-first, so the bridge exists there too — sdk/python/agt.py, same functions, same behaviour. scripts/check-agt-parity.mjs runs both implementations over one corpus in CI and fails the build on any divergence, so the bindings cannot drift apart.

Relationship to TTP

PCTR answers which path through multiple agents is trustworthy enough to reach this consequence. TTP answers is this exact execution authority valid for this principal, action, target, parameters, delegation and moment.

TLS protects the channel. TTP protects the authority transferred through the channel.

Probes: measure the consequence, don't declare it

A number typed into pctr.json is a guess. A probe measures. Probes must be read-only — a COUNT, a dry run, a terraform plan — because PCTR runs them before anything is authorized.

// probes/count-customers.mjs
export default async function probe({ action, params }) {
  const { rows } = await db.query('select count(*) as rows from customers where inactive_days > $1', [params.olderThanDays]);
  return { recordsAffected: Number(rows), connectedWorkflows: 4, reversible: false };
}
{ "probes": { "customers.delete": "./probes/count-customers.mjs" } }
Records affected      1842 (measured)

A shell probe works too ({ "command": "./plan.sh" }, JSON on stdout, with PCTR_ACTION, PCTR_TARGET and PCTR_PARAMS in the environment). If a probe fails, the preview falls back to declared values and says so — it never silently becomes "no consequence".

The effect boundary

The requesting agent must not enforce its own authority, so run the boundary somewhere the agent does not control:

pctr serve --port 8787                      # holds the replay state and the trusted signers
pctr protect payments.transfer --boundary http://127.0.0.1:8787

Spent nonces persist to .pctr/spent-nonces.json, so an authority cannot be replayed across a restart. If the boundary is unreachable, execution is denied — it never fails open.

Honest limits

  • Blast radius is a heuristic, not a measurement: severity, record count, connected workflows and route count folded into a 0-100 score. The inputs are measurable; the weighting is a judgement call.
  • Trust scores come from your manifest. PCTR decays them, tests them against the bar the consequence sets, and refuses stale evidence — but it does not attest agents itself. Wire trust and evidenceAgeSeconds to a real attestation source.
  • Discovery reads source, not running systems. It parses MCP/LangChain/CrewAI tool and agent declarations statically, and does not connect to a live MCP server to list its tools. Anything it cannot see, you declare — and declared entries always win.
  • Keys live on disk. .pctr/keys/signing-key.pem is written 0600 and must not be committed. KMS/HSM custody is commercial BlockSiFr, not this package.
  • pctr serve is plain HTTP on localhost. Put it behind TLS and your own authentication before it leaves the machine.

Apache-2.0.