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

@alma-harness/runtime

v0.41.0

Published

Official store composition for governed Alma conversations.

Readme

@alma-harness/runtime

Official storage composition, a deployment that derives governed runners, and a simple text conversation facade. The root export has types only. Use /deployment to configure once, /agent for query and resume, /memory or /postgres for storage, and the lower-level factories for advanced routing.

Configure once: /deployment

import { createRuntimeDeployment } from '@alma-harness/runtime/deployment';
const deployment = createRuntimeDeployment({
  runtime, clients: { anthropic, openai }, prices, priceVersion,
  consumers: ['product'], caps, retentionMs: 60_000,
  limits: { deadlineMs: 8_000, runTimeoutMs: 120_000, stepTimeoutMs: 60_000, maxCalls: 24,
            maxInputChars: 64_000, maxRequestChars: 1_000_000, maxOutputChars: 100_000 },
  onBackgroundError: reportAccountingIssue,
  batch: { clients: { openai: openaiBatch }, retentionMs: 7 * 86_400_000 }, // optional
});
const titles = deployment.singleCall({ policy, policyVersion, outputContractVersion, system: [], maxTokens: 64 });
const pick = deployment.structuredCall({ policy, policyVersion, outputContractVersion, system, maxTokens, tools, toolChoice });
const chat = deployment.conversation({ policy, policyVersion, configRevision, resultContractVersion, system, tools,
  caps: perTurnCaps, limits: { maxCalls: 8 } });
const extract = deployment.batchCall({ policy, policyVersion, outputContractVersion, configRevision, system, tools, toolChoice,
  maxTokens, validate, retries, retryDelayMs, submitWindowMs });

Each factory returns the runner that createSingleCallRunner, createStructuredCallRunner, createConversationRunner or createBatchCallRunner builds from the same values, with their validation, bindings and replay (specs: runtime-deployment, deployment-batch-call).

  • Owned by the deployment: the runtime's stores and audit log, clients, prices, priceVersion, consumers, the result retention and a conversation's step. An operation that passes any of them, even as undefined, throws TypeError.

  • Overridable per operation: caps replaces whole, limits merge field by field, and onBackgroundError replaces.

  • Required limits, no defaults: single and structured calls need deadlineMs, maxInputChars and maxOutputChars. A conversation needs runTimeoutMs, stepTimeoutMs, maxCalls, maxInputChars, maxRequestChars and maxOutputChars.

  • Snapshot: prices, caps, limits, consumers, the clients and the store map are copied at construction. The deployment owns no pools.

  • Batch calls:

    • they need runtime.stores.batch and the deployment's batch.clients;
    • they take runTimeoutMs, maxRequestChars and maxOutputChars, within the batch runner's own maxima;
    • their results are kept for batch.retentionMs, which defaults to the deployment's retention;
    • the observer receives the attempt's batch key as operationKey;
    • /deployment needs @alma-harness/batch installed.

    A host moving pending batches from its own composition keeps them only with an unchanged schema, provider account and effective configuration (see the spec).

  • Resolved values: deployment.resolved and each runner's resolved hold the retention and the limits it was built with, frozen (spec: deployment-resolved-values).

  • Versioning stays yours: bump policyVersion, priceVersion, outputContractVersion, configRevision or inputRevision when what they name changes. A configuration revision covers all execution behavior, including models, policy, prompts, tools, hooks, context sources, generation controls, prices, caps, limits, retries, contracts and provider accounts. It leaves out only what changes neither behavior, resource identity nor authorization, such as a database login or a key rotated within one account. Retrying an existing execution under a changed revision conflicts, so binding those would block pending work.

Start and resume a conversation: /agent

import { createConversationAgent } from '@alma-harness/runtime/agent';
const agent = createConversationAgent({
  id: 'assistant', revision: 'v1', runtime,
  model: { ref: model, client, prices },
  instructions: 'You are a helpful assistant.',
  intent: { tier: 'standard', sensitivity: 'personal' },
  limits: { caps: { perTurnUsd: 0.25 }, retentionMs: 60_000 },
  onBackgroundError: reportAccountingIssue, // audit defaults to runtime.stores.audit
});
const user = agent.forUser({ org, uid }); // verified by the host
const first = await user.query({ prompt: 'Hello', messageId: 'delivery-1' });
if (first.view.status === 'completed')
  await user.query({ resume: first.sessionId, prompt: 'Continue', messageId: 'delivery-2' });
const observed = await user.read({ sessionId: first.sessionId, messageId: 'delivery-1' });

See the quickstart.

  • One immutable revision covers the whole configuration, trusted capabilities included.
  • Versioned defaults: 120s timeout, 24 calls, 64,000 input characters, 1,000,000 request characters and 100,000 output characters.
  • resume selects existing history in the bound scope. An unknown or foreign session throws ConversationResumeError. The host authorizes the session: an id is not a credential.
  • The first session id derives from agent, scope and messageId (conversationAgentSessionId). To retry a lost response, repeat the same request.
  • Every query returns { sessionId, messageId, rootKey, view }. Inspect view.status before using its result. read never dispatches.
  • What the facade does not do: it adds no input queue, retry, scheduler or erasure barrier.

Explicit runner composition

import { createMemoryRuntime } from '@alma-harness/runtime/memory';
import { createConversationRunner } from '@alma-harness/conversation';
const runtime = createMemoryRuntime({ stepResultPolicy: policy, rootResultPolicy: policy });
const runner = createConversationRunner({ ...hostConfig, ...runtime.stores, step: { ...hostConfig.step, ...runtime.stores.step } });

Memory is ephemeral: a restart loses history, admission and replay protection. close() never erases stores or reconciles uncertain work.

PostgreSQL: /postgres

import { createPostgresRuntime, migratePostgresRuntime } from '@alma-harness/runtime/postgres';
const namespace = { schema: 'agent_execution', rootSchema: 'agent_results', onPoolError: report };
await migratePostgresRuntime({ ...namespace, connectionString: migrationURL }); // migration principal, outside requests
const runtime = createPostgresRuntime({ ...namespace, connectionString: runtimeURL,
  poolMax: { execution: 2, roots: 1 }, stepResultPolicy: policy, rootResultPolicy: policy });
  • Two dedicated schemas with different lowercase names. Connection URLs with startup options are rejected.
  • The migration installs the adapters, grants schema USAGE to alma_app and alma_retention, and revokes CREATE. It never grants login membership: the operator gives the runtime login alma_app, without superuser, BYPASSRLS or ownership. It is repeatable, not atomic across schemas: after a failure, fix the cause and rerun.
  • Upgrade window: a database last migrated by one of the two previous minor releases migrates in place. An older one upgrades in steps (spec: upgrade-window).
  • Pools: construction opens no connection. Two bounded pools, five connections each by default, set by poolMax: { execution, roots }. Budget instances × (execution + roots + batch) plus migrations, maintenance and a reserve against the database's capacity.
  • Batch stores: batch: { schema, resultPolicy, poolMax? } opens a third pool, five connections by default, and builds runtime.stores.batch on a store schema that installs batch and results. Pass that schema in stores to migration and verification.
  • Connections: connection: { applicationName, idleTimeoutMs } (spec: pool-connection-options).
    • applicationName is a label of 1 to 40 characters of [A-Za-z0-9_.:-]. Each pool connects as <label>:execution, :roots and :batch, so pg_stat_activity tells them apart. Without a label Alma sets no name, and the URL's or PGAPPNAME applies. A label beside a URL that carries application_name is refused.
    • idleTimeoutMs sets how long an idle connection stays open: 1,000 to 600,000, 10,000 by default.
    • Keep-alive: every pool enables TCP keep-alive. When the first probe goes out is the operating system's setting.
  • onPoolError(error, schema) is required and synchronous. It reports idle-client failures and must not throw.
  • runtime.stores.audit writes to the execution namespace, on the execution pool.
  • Retention and erasure: register sessions, both result stores and stores.batch.results in the host's audited retention and erasure. A reconciliation_required turn's session is freed before it returns; the host decides whether to send again (spec: failed-turn-release).

Verifying the database

import { checkPostgresRuntime, verifyPostgresRuntime } from '@alma-harness/runtime/postgres';
const logins = [{ name: 'api', role: 'alma_app' }, { name: 'maintenance_discovery', role: 'alma_maintenance' }];
const report = await verifyPostgresRuntime({ connectionString: migrationURL, schema, rootSchema, logins }); // deploy job
if (!report.ok) throw new Error(JSON.stringify(report.differences));
await checkPostgresRuntime({ connectionString: runtimeURL, schema, rootSchema, logins }); // startup, read-only

verifyPostgresRuntime compares the deployed pair with a shadow that this version migrates inside a transaction that always rolls back. It needs no manifest or snapshot (specs: runtime-verification, verification-digest-order, store-verification).

  • What it enforces:
    • Alma's roles are NOLOGIN and members of no role;
    • each listed login reaches exactly its role;
    • no default grants, global or in a covered schema, to the actors or PUBLIC; none to other roles in a covered schema, or global from the migration principal;
    • no untrusted event trigger, publication or external SECURITY DEFINER routine;
    • the discovery roles' column ceilings;
    • no grant the migration does not make, to anyone;
    • no rewrite rules or inheritance edges;
    • no SET on session_replication_role.
  • Trust is given by fingerprint (trustedRoutines, trustedPublications, trustedEventTriggers).
  • The report carries hashes (diagnostics: true shows bounded text), and is capped at 500 differences.
  • A clean run certifies a digest from one snapshot into alma_runtime_verification.

checkPostgresRuntime re-enforces every invariant as the runtime login. It then compares the live catalog with that digest, and throws RuntimeVerificationError (invariant, unverified, version or drift). Roles are cluster-wide: another product adding a member to an Alma role is drift until you verify again. Requires PostgreSQL 16 or later.

Store schemas. Pass the same stores list, for example [{ schema: 'agent_memory', install: ['memory', 'audit'] }], to migration, verification and the check.

  • Kinds: memory, audit, routines, routineRuns, batch and results. Up to eight dedicated schemas.
  • Verified whole: a store schema holds only what its kinds' migrations create.
  • Routines: routines adds alma_scheduler to the checked roles.

Fencing a scope

import { createPostgresScopeFence } from '@alma-harness/runtime/postgres';
const fences = createPostgresScopeFence({ ...namespace, connectionString: runtimeURL, stores });
const { status, record } = await fences.fence(scope, { actionId: 'erase-42', actor: 'privacy-desk' });
await fences.close();

A fence is permanent: no API lifts it (spec: scope-fence). Once fence resolves, Alma grants the scope no new authority to dispatch a model call or to reserve a place for content, and no writer inserts the scope's content anywhere (spec: scope-erasure).

  • Refused with ScopeFencedError (@alma-harness/execution), which carries no content:
    • a new turn, and a new single, structured or batch call key;
    • every new result reservation. An enrichment run reports reconciliation_required and writes no plan;
    • a session append, a memory episode or fact, a routine registration, and a routine run record.
  • Still served: reads, replays of stored keys, maintenance recovery and usage acknowledgement.
  • In flight: work that already held its claim and reservations may dispatch and store its result. A turn admitted before the fence returns reconciliation_required at its next step or append. On PostgreSQL, a new key in a session that turn still occupies answers busy. A fence erases nothing: erase the scope next.
  • Where: the pair's execution namespace holds the canonical record, copied into the roots namespace and every store schema installing batch, results, memory, routines or routineRuns. The first record wins; a later fence returns it as existing. Only a resolved fence proves every schema is fenced, so retry a failed one, under any actionId. A schema fenced on its own with another record makes fence reject and name it, for an operator to reconcile. get reads the pair only.
  • Not a guard against the host: the gates refuse inserts. A writer that edits Alma's rows by hand as the app login acts on the host's authority.
  • Connections: connect as the application login. At most one connection, none at construction.
  • Memory: createMemoryRuntime exposes runtime.stores.fences, which gates its own stores.
  • Upgrading: the fence tables and gates change the verified catalog, so the startup check reports drift until you verify again. Fence only after migrating, verifying with the complete stores list, starting every process on this version, and retiring every older writer.

Erasing a scope

import { createPostgresScopeErasure } from '@alma-harness/runtime/postgres';
const erasure = createPostgresScopeErasure({ ...namespace, connectionString: runtimeURL, stores,
  batchClients: (configRevision, provider) => batchClientFor(configRevision, provider) });
const report = await erasure.erase(scope, { actionId: 'erase-42', actor: 'privacy-desk' });
if (report.status === 'pending') retryAfter(report.waitingUntil); // then call erase again
await erasure.close();

One call erases an owner from the pair and every declared store schema (spec: scope-erasure). Pass the same stores list as migration and verification. Each call:

  1. fences the scope, and keeps an existing fence and its record;
  2. erases content: sessions, labels (sealed), step, root, batch and store results (tombstones), memory episodes and facts, and routines (deleted);
  3. closes pending work:
    • running and submitted routine runs become failed with the reason scope erased, and every run loses its handle and any other reason;
    • uncertain admissions are released with the fence's actionId as their resolution, at most 100 a call. No operator login is needed: the fence authorizes it;
  4. discards the scope's batches at the provider (spec: provider-batch-retention). batchClients returns the client of the account a configuration revision used, or undefined. A running batch is cancelled and stays open until a later call deletes it. A submission still in flight without a handle stays open until its submit deadline, which sets waitingUntil;
  5. proves it: report.tables lists every scope table with its rows, the open rows that still hold content or unclosed work, and why the rest is kept (tombstone, closed, journal, accounting, audit, fence). report.provider gives the scope's batches and those not confirmed deleted. status is erased only when every open is 0.
  • Pending: read tables[].open for the cause. A turn admitted before the fence and still inside its deadline sets waitingUntil; call again after it. More than 100 uncertain admissions take another call. A content row still open after a call is an inconsistency to investigate, not a wait.

  • Retries: each step commits on its own and is idempotent. A failed call throws after writing scope:failed to the pair's audit trail; the next call completes it. Every call writes scope:erased or scope:pending.

  • In flight: neither kind of call stores a result.

    • One that reads its reservation after the erasure stops without dispatching: it rejects, and its journal records it not_dispatched.
    • One already past that read may still dispatch under the claim it held before the fence. It completes with an unavailable result, and its cost is recorded.
  • What stays: identifiers, amounts, usage, times and hashes, never message text Alma wrote. Two host-authored strings stay on the append-only audit trail: a routing policy's rationale and an access event's resource. Choose pseudonymous identifiers, and keep user text out of both.

  • Not counted: the maintenance and projection cursors, which hold only a scope's key, and the tenant-day spend, which has no uid.

  • Connections: connect as the application login. During a call, at most one connection per schema it touches; none between calls.

  • Provider batches: each call asks the provider again, one retrieval and up to three deletions per OpenAI batch, so a retry confirms nothing remains. A throttled or failed request leaves its batch open. What the provider keeps regardless:

    • an OpenAI batch object, with identifiers, counts and error messages;
    • a batch whose acceptance was lost, until its expiry (OpenAI) or 29 days (Anthropic);
    • prompt caches and logs.

    A batch cancelled before collection may be billed and never recorded.

  • Out of scope: the host's own data, and retained turn claims of older deployments, which a host erases with createMemoryErasure({ turns }).

Maintenance: /maintenance

import { createPostgresMaintenance } from '@alma-harness/runtime/maintenance';
const maintenance = createPostgresMaintenance({ schema, rootSchema, stepResultPolicy, rootResultPolicy, onPoolError,
  discovery: { connectionString: discoveryURL }, worker: { connectionString: workerURL } });
const report = await maintenance.maintain({ limit: 50, signal }); // schedule it

maintain finds scopes with due work and sweeps them, least recently visited first (spec: runtime-maintenance):

  • it expires admissions, roots and executions;
  • it completes executions from retained results;
  • it acknowledges usage.

It never dispatches, and its report holds counts only. A settled execution is due once recovery could take it: past its recovery lease, or else its deadline. A completed call missing its root receipt is found through its pending usage row (spec: maintenance-scan). The scan's index and the discovery role's recovery_until grant change the verified catalog: verify again after migrating.

Logins:

  • a discovery login in alma_maintenance only, which sees identifiers, states and times across scopes;
  • a worker login in alma_app only, which is not the request path's.

Neither may be in alma_retention. Every call checks this.

Connections: at most three per instance: two on the discovery login and one worker connection, which also serves each call's login check (specs: upkeep-connection-budget, login-check-connection). connection takes the same options as the runtime's. The worker's pools and the discovery pool connect as <label>:maintenance:execution, :roots and :discovery.

Receipt projections: /projections

import { createPostgresProjections } from '@alma-harness/runtime/projections';
const projections = createPostgresProjections({ schema, rootSchema, stepResultPolicy, rootResultPolicy, onPoolError,
  discovery: { connectionString: projectionURL }, worker: { connectionString: workerURL } });
await projections.drain('cost-dashboard', async delivery => { /* dedupe on (scope, consumer, settlementId) */ }, { limit: 50 });
await projections.quiesce(scope, () => erasure.erase(scope, request), { timeoutMs: 30_000 });

drain delivers each pending governed receipt of one consumer, with its session attribution: available, erased or none (spec: receipt-projections).

  • Acknowledgement: a receipt is acknowledged only after the handler resolves, so commit the deduplication and the effect together.
  • Delivery: fair, and never loses a receipt.
  • Logins: a discovery login in alma_projection only, and a worker login in alma_app only, as for maintenance.
  • Connections: connection as for maintenance, with names under <label>:projections:.
  • Erasure: quiesce waits for a drain working the scope, then runs your erasure. A destination that stores labels must serialize with erasure through gate rows, as the spec shows.

Projections drain only the pair's execution namespace.

Conversation operations: /operations

createConversationOperations inspects, repairs and resolves one admission, with capabilities the host supplies. The alma-operations CLI runs them from bounded JSON on stdin with a local --host module. See the operator runbook.

A call whose journal is not_dispatched never left, and counts as accounted at no cost, so it no longer blocks resolution (spec: never-sent-calls).

A turn its runner released needs no resolution: inspect shows turn-failed-v1:, and resolve answers binding_conflict (spec: failed-turn-release).

An operation_failed caused by a database error carries its SQLSTATE in error.sqlstate, and the CLI prints it: {"error":"operation_failed","sqlstate":"42501"}. No message, detail or query of that error leaves (spec: uncertain-turn-causes).

runtime.stores.labels is the session label store (spec: session-labels). Wire it into erasure as createMemoryErasure({ sessionLabels }).