@nervur-org/modules
v0.4.0
Published
Common host modules and contracts for nervurd grounds — storage, journal, index, hooks, deploy.
Readme
@nervur-org/modules
The common host modules a nervurd ground installs from npm, and the
contracts they serve. A module is custody's own code: authority-free,
loaded by the daemon from a file path named in the ground's config —
never fetched, never phoning home.
npm i @nervur-org/modulesA config names each slot as a file, or a file with settings — the two
in-process forms this package ships. A slot may instead bind a remote
being behind a contract, which is the third form: the same config shape,
a different kind of module, and outside this package's own concern —
nervurd's own docs state it, and the knock mechanism (emits,
receives, every) that every module of either kind shares to wake a
being.
{
"modules": {
"storage": {
"file": "./node_modules/@nervur-org/modules/disk-storage.mjs",
"settings": { "dir": "/var/lib/acme/storage" }
},
"journal": {
"file": "./node_modules/@nervur-org/modules/watch-journal.mjs",
"settings": { "dir": "/var/lib/acme/journal" }
}
}
}Every factory here is called once with the settings object ({} when a
slot names a bare file); a setting it needs and does not find throws a
plain sentence naming it, and that sentence is what the daemon's boot
refusal, and nervur check, carry.
What ships:
- disk-storage.mjs —
{ dir, ticketTtl? }. A sealed local blob store: AES-256-GCM per blob, HMAC names, per-address scoping. The archive's foundation. Beside the whole-bufferput/get/drop(sealed, capped at 6,000,000 bytes) it grows a streaming face for bulk blobs over that cap:scope(address).ticket({ direction: 'up' | 'down', digest, size })mints a single-use bearer token, scoped to that address at mint, that dies on first redemption or afterticketTtlmilliseconds (60,000 by default).redeem(token)— a host-only face no program ever sees — spends it once, handing back scope-bound stream handles:write/commit/abortfor an up-ticket, staged then renamed and refused whole on any digest or size mismatch;read()for a down-ticket, serving only a blob already standing under its declared digest and size. Bulk blobs lie plain at rest, named by digest under each scope's ownbulk/folder — sealing them is a standing debt, postponed to the bucket era (conversations/active/nervur-large-files.md).nervurd's own/blob/<token>door is what actually redeems a ticket; see its docs. - watch-journal.mjs —
{ dir }, or{ dir, face: 'reader' }to settle only the reader (head,page,verify) — the form for standing an auditor being on the same journal aconfig.watchslot writes. The watch as an append-only journal on disk. - fulltext-index.mjs —
{ dir }. A sealed fulltext index (one encrypted state file per address, Unicode tokens, diacritics whole). The librarian's memory. - signed-hook.mjs —
{ secretEnv, header? }. HMAC verification over a raw webhook body;secretEnvnames the environment variable holding the secret,headerdefaults tox-signature. The daemon's/hook/<knock>entry. - folder-watch.mjs —
{ dir, every? }. A knock module: a file landing in a folder wakes a being, no wire touched;every(default 100ms) is the poll interval. - deploy-website-cf — no settings; every value (repo, branch,
account, token) travels as a call parameter from the calling being's
own cells, per Article X. Granting a being this door grants it code
execution on the host machine: it clones a repo and runs that repo's
own
deploy(andbuild) npm scripts, unsandboxed. Its log redacts only thetokenparameter's value — nothing else the child process printed is filtered. - revolut-business.mjs —
{ base?, assertionSeconds? }. Revolut's Business API for a ground's own account: signs the client-assertion JWT, spends the refresh token for a session, reads accounts and transactions, and pays. Authority-free likedeploy-website-cf— every value travels as a call parameter from the calling being's own cells — and it caches no token, because one cache shared by several beings is one being spending another's grant.basepoints it at the sandbox. The speciesnervur.revolut-businessin@nervur-org/speciesis the being that drives it. - revolut-merchant.mjs —
{ base?, version?, toleranceSeconds? }. Revolut's Merchant API for taking payments: creates orders, reads them, refunds them, and registers the vendor's webhook. Authority-free the same way — the secret key travels as a call parameter from the calling being's own cells. It carries two faces: the module face above, and areceivesknock face that verifies nothing and wraps the delivery whole — body, signature, timestamp — because the signing secret is the being's own cell, never this host's env; the being's settle door judges the delivery through the module'sverified, which holds the clock and the HMAC.basepoints it at the sandbox;toleranceSeconds(default 300) bounds how old a delivery may claim to be. The speciesnervur.revolut-merchantin@nervur-org/speciesis the being that drives it. - contracts/ — the contract files the modules' beings satisfy.
The source published is the source proven: the nervur bench drives these same files through real grounds. No build step, no dependencies.
