
Security News
GPT-6 Astra Attempts Supply Chain Attacks Against Open Source Maintainers in Testing
GPT-6 Astra hits 100% on ExploitBench and finds zero-days autonomously, while independent tests reveal scope violations and monitoring gaps.
once-kernel
Advanced tools
Idempotency kernel for side-effecting operations. 1,000 racing callers, exactly one execution — proven, not asserted.
Idempotency for side effects that cost money. 1,000 racing callers, exactly one execution — proven on every commit, not asserted in a README.
npm install once-kernel
import { Once } from "once-kernel";
import { SqliteStore } from "once-kernel/sqlite";
const once = new Once({ store: new SqliteStore({ path: "./once.db" }) });
// Called once, twice, or by fifty racing workers — the card is charged once.
const receipt = await once.run(
`charge:${orderId}`, // the key
{ amount: 4900, currency: "usd" }, // the payload — part of the identity
() => stripe.charges.create({ amount: 4900, currency: "usd" }),
);
Every caller gets the same receipt. The charge happens once.
The bug is not two simultaneous calls. That one is easy and everybody's in-memory
Set handles it.
The bug is the worker that dies between reserving the key and finishing the
effect. A Set leaves that key claimed forever and the effect never runs at all.
Or the process restarts, the Set is empty, and the effect runs twice.
Retries are the other half. An agent whose request times out will re-send it. The server already did the work; the response just never arrived. Nothing failed loudly — it succeeded twice.
once handles both: a durable record, a lease that expires if you crash, and a
fence token so the worker that stalled cannot overwrite the one that replaced it.
Atomics barrier, against one shared
database. The execution count is read from a separate table, not
self-reported. Ten cold runs, ten times one execution.undefined.generation counter advancing so downstream systems can fence the dead worker.{a,b} and {b,a} are one operation —
which matters when an LLM reformats its arguments between retries.once stops the second request from being
sent — it cannot un-charge one that was.MemoryStore is single-process and dies with your program. That is
fine for tests and wrong for production. Use SqliteStore, or implement the
four-method Store interface against Postgres.This is a port of once-kernel on PyPI,
and it hashes payloads identically: both use RFC 8785 (JSON Canonicalization
Scheme). A Python service and a Node service can key the same operation and agree
about whether it already ran.
That claim is tested, not hoped for — test/vectors/python-jcs-vectors.json is
generated by the Python implementation and asserted against on every commit.
Hand-written expectations would only prove this file agrees with itself.
JavaScript has one number type. By the time once sees 1234567890123456789,
the parser has already rounded it to 1234567890123456800 — the precision is
gone before this library is called. Pass large identifiers as strings.
const once = new Once({
store, // default: MemoryStore
defaultTtlSec, // how long a completed record is remembered
defaultLeaseSec = 30, // how long before a crashed worker's key is reclaimed
maxResultBytes = 65536,
});
await once.run(key, payload, fn, { ttlSec, leaseSec, waitTimeoutMs, pollMs });
Lower-level, if you need to control the boundary yourself:
const { execute, record } = await once.begin(key, payload);
if (!execute) return record.result; // someone else already did it
try {
const result = await doTheThing();
await once.complete(key, record.fenceToken, result);
} catch (e) {
await once.fail(key, record.fenceToken, String(e), /* allowRetry */ true);
throw e;
}
complete and fail are compare-and-swap on record.fenceToken. A stalled
worker that wakes up after losing its lease gets false and changes nothing.
| Error | Meaning |
|---|---|
IdempotencyConflict | Same key, different payload. A caller bug — do not retry blindly. |
InProgressError | Another caller holds the key right now. run() waits for you. |
WaitTimeout | Waited past waitTimeoutMs for an in-flight call to settle. |
ResultTooLarge | Result exceeds maxResultBytes. Store it elsewhere, keep a reference. |
CanonicalizationError | Payload contains something JSON cannot represent (NaN, undefined, Date, BigInt). Rejected rather than silently coerced — coercion is how two payloads collide into one hash. |
SqliteStore uses Node's built-in node:sqlite. This package has zero runtime
dependencies.
Every mutation is a single SQL statement with its guard in the WHERE clause, so
two processes racing the same key resolve inside the database engine. Reading and
then writing in JavaScript would be a time-of-check-to-time-of-use race — exactly
the bug this library exists to prevent.
To use Postgres or Redis, implement Store: get, createInProgress,
casComplete, casFail, reclaimIfLeaseDead, heartbeat. Run
test/store-conformance.test.ts against it; that suite is the contract.
Node 22.5+ (for node:sqlite). No build step, no native modules, no dependencies.
Apache-2.0
FAQs
Idempotency kernel for side-effecting operations. 1,000 racing callers, exactly one execution — proven, not asserted.
The npm package once-kernel receives a total of 12 weekly downloads. As such, once-kernel popularity was classified as not popular.
We found that once-kernel demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
GPT-6 Astra hits 100% on ExploitBench and finds zero-days autonomously, while independent tests reveal scope violations and monitoring gaps.

Product
Socket can now send alerts and supply chain attack notifications to Microsoft Teams, with filters that route the right updates to each channel.

Security News
pnpm 12 rewrites the package manager in Rust, cutting install times by up to 90% while preserving pnpm 11 workflows and lockfiles.