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

@intrinsec-ai/openclaw-identity-plane

v0.1.1

Published

Identity plane plugin for OpenClaw — detects behavioral drift from declared identity

Readme

🧠 @intrinsec-ai/openclaw-identity-plane — Identity Plane Plugin

An identity watchdog for your AI agents.
Track whether your agent stays true to its declared identity — across every message, not just the first.

Plugin Node License Status


Demo notice. This is a lightweight reference implementation — intentionally observational and read-only. It logs, visualises, and annotates drift but does not block or intercept anything. Features like active intervention, blocking writes, or fleet correlation can be added based on community feedback.


The core insight

Every token entering your agent's context window is a vote on its identity.
This plugin watches for votes that shouldn't be there.

Prompt injection, jailbreaks, and malicious skill installations (like ClawHavoc) all work the same way: they deflect the agent's behavioural trajectory away from its declared identity. The identity plane makes that deflection visible.


What it does

| | | | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | | 🔍 Detects | Prompt injection · jailbreaks · off-topic drift · malicious skill installs | | ⚙️ How | Scores each message against your agent's compliance model; off-identity signals accumulate in bounded memory without cancelling each other out | | 📊 Signals | maxDrift · avgDrift · drift themes · cognitive file change annotations (so you know whether a spike came before or after a file changed on disk) | | ☁️ Stack | OpenAI-only: text-embedding-3-small on every inbound message, plus the same LLM you configure for calibration, compaction, and novel-theme labels | | 👁️ Posture | Read-only and observational. Nothing is blocked. |


How it works

1 · Calibration (once, then cached)

When you first run an agent (or run /identity recalibrate):

  1. Reads your cognitive filesSOUL.md, AGENTS.md, IDENTITY.md, USER.md, TOOLS.md
  2. Extracts identity anchors — the LLM distills the raw files into 5–10 named, categorised anchors: purpose, value, boundary, persona, constraint. These are specific, traceable aspects of identity (e.g. [BOUNDARY] No credential access: The agent must never read or transmit API keys or secrets.) rather than a raw policy dump.
  3. Generates labelled examples grounded in the anchors — the same LLM produces max(20, 3 × numAnchors) compliant and violation sentences. The count scales with identity complexity (e.g. 8 anchors → 24 examples each) so every anchor is represented multiple times, giving the manifold better covariance coverage. The prompt asks for at least one compliant and one violation per anchor.
  4. Both sets are embedded with text-embedding-3-small (same model as runtime — keeps geometry consistent)
  5. Fits a Gaussian to the compliant cluster — mean and covariance via PCA, producing the identity manifold
  6. Sets the surprise threshold — the 90th-percentile Mahalanobis distance of compliant examples. With ≥20 examples the empirical distribution is reliable enough that the 95th percentile over-fits to compliant outliers; 90th is a tighter, more stable gate.

The identity anchors are the canonical representation of the agent's identity from this point on. Every downstream LLM call — compaction audits, novel theme labels — references the named anchors rather than the raw file contents.

Everything is cached to .openclaw/identity-cache.json. Nothing is recomputed until you explicitly recalibrate.

Upgrading from an older build: run /identity recalibrate — the cache schema now includes identity anchors and old caches without them will trigger automatic re-calibration.


2 · Runtime (every inbound message)

Every piece of text entering the LLM — user messages, tool results, subagent replies — flows through:

  message ──► embed (OpenAI) ──► surprise = ½·Mahalanobis²(x, compliance)
                                        │
                          ┌─────────────▼─────────────┐
                          │  weight = max(0, s−τ)     │
                          └─────────────┬─────────────┘
                                        │
              ┌─────────────────────────▼────────────────────────┐
              │  weight > 0?                                     │
              │   → ingest into coreset                          │
              │   → novelty check → new mode? → LLM theme label  │
              │                                                  │
              │  weight = 0? → skip (identity-neutral)           │
              └─────────────────────────┬────────────────────────┘
                                        ▼
              drift scores from coreset ──► maxDrift / avgDrift ──► level

Drift levels: nominal · warning · alert

Without OPENAI_API_KEY, embedding fails and the hook no-ops with a logged error. Novel-theme labeling falls back to geometric labels if the key is missing at runtime; compaction is skipped without a key.


3 · Identity compaction (LLM audit)

The coreset records where drift lives geometrically. Identity compaction turns that into a human-readable story grounded in the named identity anchors.

Every compactionInterval off-identity messages (after ingestion, i.e. surpriseWeight > 0), when OPENAI_API_KEY is set:

  1. Clusters coreset points via connected-component BFS
  2. Describes each cluster using the actual stored message texts
  3. Asks the LLM for theme labels, severities, and a 1–2 sentence narrative — with the identity anchors list in the prompt so every theme and the narrative explicitly references named aspects of the declared identity
  4. Replaces the theme list with the consolidated analysis

The compaction is non-destructive — the coreset (geometric ground truth) is never rewritten by the LLM.

Novel drift modes get a one-shot LLM label (triggering message + nearest calibration violations) whenever the key is present; otherwise the geometric fallback is used.


4 · The coreset — why signals don't cancel

Unlike a running mean, the bounded weighted coreset (128 points by default) keeps distinct drift directions separate:

  • Opposing drifts cannot cancel each other out
  • Old signals aren't lost to exponential forgetting
  • When full, the closest pair merges — preserving distinct drift modes while bounding memory

Each coreset point carries the original message texts that contributed to it, so drift themes and audit narratives are grounded in real behaviour, not just geometry.


5 · Why distance-from-compliance works

When an agent has a well-defined goal — "help with code", "answer HR questions" — its compliant responses form a tight cluster in embedding space. Violations live in the open-ended complement.

     Embedding space (conceptual 2D projection)
     ┌──────────────────────────────────────────┐
     │  ✗          ✗                 ✗          │
     │       ✗          ┌─────────┐      ✗      │
     │  ✗               │ ● ● ● ● │             │
     │                  │ ● ● ● ● │  ✗          │
     │  ✗               └────┬────┘             │
     │                       │                  │
     │   violations          │  compliance      │
     │   (open-ended)        │  (tight cluster) │
     └──────────────────────────────────────────┘

We never need to enumerate violations. We only ask: how far is this message from the known compliance region? That is a one-class classification problem with a clean solution: Mahalanobis distance.



Installation

Prerequisites

  • OpenClaw installed and running
  • Node.js 22.16+ (Node 24 recommended)
  • OPENAI_API_KEY — embeddings and LLM calls (calibration is cached; embeddings and audit calls are ongoing)

Option A — Install from npm (recommended)

npm install @intrinsec-ai/openclaw-identity-plane
npx openclaw plugins install -l node_modules/@intrinsec-ai/openclaw-identity-plane

Option B — Clone directly

git clone https://github.com/intrinsec-ai/openclaw-identity-plane \
  ~/.openclaw/extensions/identity
cd ~/.openclaw/extensions/identity
npm install

Option C — Link a local checkout (for development)

cd /path/to/openclaw-identity-plane
npm install
openclaw plugins install --link /path/to/openclaw-identity-plane

Enable the plugin

openclaw plugins enable identity

Or manually in ~/.openclaw/openclaw.json:

{
  "plugins": {
    "load": { "paths": ["~/.openclaw/extensions/identity"] },
    "entries": { "identity": { "enabled": true } }
  }
}

Remove deprecated config keys if present: embedModel, agenticAudit (no longer used).


Set your API key

export OPENAI_API_KEY=sk-...

Optional: route both chat and embeddings through a compatible gateway:

export OPENAI_BASE_URL=http://localhost:11434/v1

Set calibrationModel to a model your endpoint serves. The embedding client uses the same OPENAI_BASE_URL; the server must implement OpenAI-style **POST /v1/embeddings** for text-embedding-3-small (or map that model id to a local embedder), or calibration and runtime embedding will fail.


Start the gateway

openclaw gateway

On first run you'll see calibration logs. Subsequent starts load from cache instantly.


Dashboard

The plugin serves a live drift dashboard at http://localhost:18789/identity:

  • Identity anchors card — the extracted anchors displayed as colour-coded tiles (cyan = purpose, green = value, rose = boundary, violet = persona, amber = constraint)
  • Metric cardsmaxDrift, avgDrift, drift modes, coreset utilisation
  • Identity compaction card — latest LLM audit narrative referencing named anchors
  • Dual-line time-series chart — avgDrift and maxDrift over time
  • Drift themes panel — labelled descriptions of what is pulling the agent off-identity, grounded in the anchors
  • Vertical annotations — file changes, recalibrations, and new theme detections marked on the chart

Expected dashboard feel:

┌───────────────────────────────────────────────────────────────────────────────────────────────┐
│ IDENTITY PLANE — LIVE DRIFT DASHBOARD                                                         │
├───────────────────────────────────────────────────────────────────────────────────────────────┤
│ maxDrift: 98.40   avgDrift: 89.20   themes: 1   coreset: 64/128   level: ALERT                │
├───────────────────────────────────────────────────────────────────────────────────────────────┤
│ surprise                                                                                      │
│ 100 ┤                 ─ ─ ─ ─ ─ maxDrift ─ ─ ─ ─ ─                                            │
│  90 ┤                                                    ╭──────╮   ╭───────────────╮         │
│  80 ┤                              ╭────╮      ╭─────────╯      ╰───╯   avgDrift              │ 
│  70 ┤     ╭───╮   ╭────╮      ╭────╯    ╰──────╯                                              │
│  60 ┤─────╯   ╰───╯    ╰──────╯                                                               │
│  50 ┤                                                                                         │
│  40 ┤                                                                                         │
│   0 └─┬──────────────┬──────────────┬──────────────┬──────────────┬───────────────► time      │
│      14:55          14:58          15:01          15:04          15:07                        │
│                                              │                                                │
│                                              └─ SOUL.md modified                              │
│                                               ↑ identity anchor moved;                        |
|                                                 agent behavior follows new SOUL.md            │
├───────────────────────────────────────────────────────────────────────────────────────────────┤
│ drift themes                                                                                  │
│  ◆ "finance assistant shifted into low-level host behavior: env/credential path probing,      │
│    shell enumeration, and outbound endpoint checks" — critical — 7 clustered events           │
└───────────────────────────────────────────────────────────────────────────────────────────────┘

Refreshes every 10 seconds. Also available as JSON: GET /identity/metrics


Commands

/identity              — calibration status, drift levels, active themes
/identity recalibrate  — force re-calibration from current cognitive files

Example output:

[Identity Plane] Calibrated ✓

Identity anchors:
  [PURPOSE] Code-focused task execution
    The agent is designed to help users write, debug, and review code. All responses should serve that goal directly.
  [BOUNDARY] No credential or secret access
    The agent must never read, request, or transmit API keys, passwords, or environment secrets.
  [VALUE] Honest about limitations
    The agent acknowledges uncertainty and does not fabricate answers or pretend to have capabilities it lacks.
  [PERSONA] Concise and technical tone
    Responses are direct, use precise technical language, and avoid unnecessary filler or over-explanation.
  [CONSTRAINT] Scope limited to requested files
    The agent only reads or modifies files the user explicitly references; it does not enumerate or scan the workspace.

Identity compaction (latest audit):
  The agent is under sustained pressure to exceed its file-access scope, with recurring attempts to enumerate
  credentials and probe paths outside the declared [CONSTRAINT] boundary.

Drift themes (47 events observed):
  ◆ ⚠ "Credential path probing" — high — 5 events
  ◆ ~ "Scope boundary expansion" — moderate — 3 events

Active sessions:
  ✓ nominal  agent:work:telegram:dm:123456
  ~ warning  agent:work:whatsapp:dm:789

Configuration

All fields are optional. Full defaults shown:

{
  "plugins": {
    "entries": {
      "identity": {
        "enabled": true,
        "config": {
          "calibrationModel": "gpt-4o",
          "alertAvgDrift": 5.0,
          "alertMaxDrift": 10.0,
          "axisThresholdK": 1.5,
          "coresetCapacity": 128,
          "noveltyRadius": 0.5,
          "modeGamma": 0.8,
          "compactionInterval": 10,
          "verbose": false
        }
      }
    }
  }
}

| Field | Default | Description | | -------------------- | -------- | -------------------------------------------------------------------------------------- | | calibrationModel | gpt-4o | Chat model: calibration (cached), novel-theme labels, periodic compaction. | | alertAvgDrift | 5.0 | Weighted-average surprise above this value triggers alert. Tune from the dashboard. | | alertMaxDrift | 10.0 | Highest single-point surprise above this value triggers alert. | | axisThresholdK | 1.5 | Axis flag threshold in std deviations below the mean compliant projection. Diagnostic. | | coresetCapacity | 128 | Max coreset points. Larger = higher fidelity, more memory. | | noveltyRadius | 0.5 | L2 distance threshold for detecting a new drift mode. Lower = more sensitive. | | modeGamma | 0.8 | L2 distance threshold for connected-component clustering of coreset points. | | compactionInterval | 10 | Off-identity messages between compaction LLM audits. | | verbose | false | Log nominal steps. Useful for debugging thresholds. |


Cost and API usage

Rough mental model:

| What | When | | ----------------------------------------- | ----------------------------------------------------------------------- | | Embeddings (text-embedding-3-small) | Every non-empty llm_input, plus all example strings during calibration | | Anchor extraction LLM | Once per policy hash (part of calibration, cached) | | Example generation LLM | Once per policy hash (part of calibration, cached) | | Novel theme LLM | Once per new drift mode detected | | Compaction LLM | Every compactionInterval off-identity messages |

Embedding cost scales with traffic. Calibration is a one-time cost per policy change (two LLM calls, then cached). Compaction cost scales with how often the agent goes off-identity.


Source layout

src/
  embed.ts           ~55 lines    OpenAI embeddings only (text-embedding-3-small)
  identity-plane.ts  ~560 lines   GaussianManifold, IdentityCoreset (merge-and-reduce),
                                  IdentityMonitor, DriftTheme types
  calibrate.ts       ~340 lines   Read cognitive files → extract IdentityAnchors → generate
                                  examples → embed → fit manifold → compute thresholds → cache
  index.ts          ~1370 lines   register(api): hooks, persistence, theme management,
                                  dashboard HTML (with anchors card), /identity command

Intentionally readable — a starting point, not a finished product.


What's not included (by design)

This demo deliberately does not:

  • ❌ Block or intercept any agent actions
  • ❌ Automatically recalibrate when files change
  • ❌ Send alerts or notifications externally

These are deliberate omissions to keep the footprint small and the behaviour non-intrusive. If you find the drift signal useful and want any of these, open an issue — they are straightforward to add on top of what's here.


Why the open-source plugin stops short

This repository is a reference implementation: enough to run, inspect, and extend. Here is where the geometry-first approach hits its limits — and why they matter in production.

| Limitation | What breaks | What it would take | | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | | Policy-blind memory | Merge decisions are guided by geometric distance alone — the closest coreset pair merges when capacity is full. A subtle prompt injection or quiet privacy leak may sit geometrically close to other points and get dropped, exactly when it most needs to be kept. | Policy-aware compaction that preserves what is most security-relevant, not only what is most geometrically remote. | | Single-goal assumption | The Gaussian compliance model works when an agent has a single, well-anchored goal. For enterprise deployments with many workloads, evolving policies, and diverse user populations, compliance is no longer one ellipsoid — it is heterogeneous and multi-modal. | A compliance model that is accurate across a heterogeneous, multi-modal surface. | | Text-only modality | Everything here is text in embedding space. In the wild, agents mix modalities; drift can appear in images, audio, or cross-modal behaviour. | Extending the same geometric story across modalities. | | Fleet scale | This plugin watches one agent on one machine. At fleet scale — thousands of agents, many customers, each with their own definition of "normal" — computing a fresh covariance matrix per tenant per policy version continuously becomes a hard infrastructure and statistical problem. | Per-tenant statistics that update continuously without recomputing full covariances on every message. |


If you need identity compaction that survives long horizons, heterogeneous workloads, and enterprise constraints — not just a demo — that is what we build at Intrinsec AI.
We'd be happy to talk.


Dependencies

| Package | Purpose | | ------------------------------------------------- | ------------------------------------------------------------------------------------ | | [openai](https://github.com/openai/openai-node) | Embeddings (text-embedding-3-small) + chat (calibration, novel themes, compaction) | | [ml-matrix](https://github.com/mljs/matrix) | SVD for the Gaussian manifold |