License Artifacts
In this section
There is one artifact: your license key. This page is the complete inventory of everything the engine reads or writes on its account, what a legacy install needs to migrate, and what the key issuer must mint.
The inventory
Artifact | Location | Written by | Required |
|---|---|---|---|
The key, as | process environment | you | one of these two |
The key, as a file |
| you | one of these two |
That is the whole list. The engine writes no license state to disk — no cache, no grace file, no activation record. There is nothing to clean up, nothing to copy when you move a deployment, and nothing that can go stale and give a wrong answer later.
The key
A license key is a complete, self-contained Ed25519-signed JWT. It verifies offline, against a public key compiled into the engine's binary: no network call, at install, at first boot, or ever. Air-gapped deployments are a first-class case, not a workaround.
Resolution order — first hit wins:
BRAINY_LICENSE— the environment variable. Always wins, so a deploy can inject the key with no filesystem write at all: CI, immutable images, serverless, Vault / Secret Manager.~/.config/soulcraft/brainy-license— the machine file. One key per machine. Mode0600; contents are the key itself, and a trailing newline is fine (echo "$KEY" > filedoes the right thing).
# either one — the env var is the recommended shape for anything deployed
export BRAINY_LICENSE="sc_brainy_..."
mkdir -p ~/.config/soulcraft
printf '%s\n' "sc_brainy_..." > ~/.config/soulcraft/brainy-license
chmod 600 ~/.config/soulcraft/brainy-licenseBASHCheck what the engine actually sees — the same resolver, the same verifier a real open uses, so the readout cannot disagree with a running database:
npx brainy license statusBASHIt prints the source, product, tier, expiry, renewal window and a key fingerprint. It never prints the key, writes no file, and opens no socket.
Expiry, and what it does not do
state | what happens |
|---|---|
more than 30 days left | opens; silent |
within 30 days | opens at full speed, and says how many days remain — one line at open, one a day after |
expired | at the next open, the engine registers no native providers and prints why, with the cure |
A running database is never darkened. The key is checked when the engine opens and at no other moment, so a key that lapses under a serving brain changes nothing: queries keep being answered and writes keep landing, for as long as that process lives. Nothing on a timer, on a network, or on disk can revoke a database that is already up.
And nothing here gates your data. A license buys speed. Open Brainy reads and writes the identical store with no key at all, so an unlicensed or expired engine is a slow engine, never a locked one. There is no kill switch.
The perpetual fallback (paidThrough)
LICENSE clause 3(a) is a term, not just a behavior: every version of the Software released while a key was valid keeps running with full native acceleration forever, even after that key lapses. Renewing buys coverage for future releases — it never revokes what a key already covered.
A key that carries the optional paidThrough claim (a Unix-seconds coverage boundary) is verified against this build's own release date — a value baked into the binary at build time — instead of against wall-clock time:
comparison | verdict |
|---|---|
| valid, perpetually, for THIS build — independent of wall-clock. A key that has long since lapsed still opens every build it once covered. |
| refused — loudly, and never locking: this build was published after the key's coverage window closed. Cure: renew, or run any release from inside the covered window at full speed forever. |
| the key is judged on |
Wall-clock time still matters while a build IS covered: the same 30-day renewal-window narration this page describes above for exp applies to paidThrough too — once now is inside 30 days of the coverage boundary, brainy license status narrates a countdown, purely informational, telling you when future releases will need a renewed key. It can never turn a build that already cleared the table above back into a refusal.
A release's date is its UTC calendar day, taken at 00:00:00Z; the issuer mints paidThrough for the END of a covered day (23:59:59Z, the same convention exp already uses) so a coverage boundary landing on the same calendar day as a release still covers it.
There is no telemetry
None. Not opt-out, not opt-in. The engine contains no beacon, no analytics, no phone-home of any kind: license verification is offline, and nothing in the engine ever contacts Soulcraft. (An optional beacon existed in a pre-release draft of 11.0.0 and was removed before the cut — the absence is pinned by a test, so it cannot quietly grow back. If you carried BRAINY_LICENSE_TELEMETRY=off from that draft, the variable is now meaningless and can be deleted.)
Migrating a pre-11 install
Everything below keeps working — you are not required to change anything. The migration is a tidy-up, not a break.
you have | still works? | do this when convenient |
|---|---|---|
| yes, forever — with one log line naming the current variable | rename it to |
a key starting | yes, forever — issued keys never break | nothing; it stays valid to its own expiry |
| no — retired in 11.0.0 | move the key into |
| no — retired in 11.0.0 | delete the step; set the key directly |
a short activation code ( | no — retired in 11.0.0 | get your full key from https://soulcraft.com/account |
Retired artifacts, by name
None of these are read or written any more, and all are safe to delete:
artifact | retired in | replaced by |
|---|---|---|
| 11.0.0 |
|
| 11.0.0 | nothing — no license state is written to disk |
| 11.0.0 | nothing |
| 11.0.0 | nothing to point anywhere |
| 11.0.0 | nothing — there is no exchange |
| 11.0.0 |
|
Containers, CI, and hermetic tests
Pass the key as BRAINY_LICENSE. That is the entire guidance — there is no cache directory to redirect, no writable $HOME required, and nothing to bake into an image. A read-only root filesystem is fine.
For a monorepo, the old "which directory did the process start in?" question is gone with .soulcraft.json: the env var is process-wide and the machine file is machine-wide, so neither depends on the working directory.
The issuer's contract
A key is minted as sc_brainy_<header>.<payload>.<signature> — a standard JWT, Ed25519 (alg: EdDSA), signed by the issuing key whose public half the engine carries.
claim | value |
|---|---|
| licensee email |
|
|
|
|
|
|
| issued-at, Unix seconds |
| expiry, Unix seconds — |
| key id, for issuance tracking |
| subscription id |
| optional — Unix seconds; the perpetual-fallback coverage boundary (LICENSE clause 3a, see above). Absent = the key is judged on |
| optional — an array of add-on entitlement strings, e.g. |
Every paid tier gets the same gate: full acceleration. Tiers price the scale a brain runs at; they never gate a runtime capability. Renew by minting a fresh key with a later exp (and, for a flat-annual key, a later paidThrough) — there is nothing to revoke, and nothing to synchronize.
Add-on capabilities
capabilities is the one deliberate exception to "a tier never gates a capability" — a short, optional list of ADD-ON doors a key is entitled to, orthogonal to tier and to paidThrough. Today it names one:
capability | gates |
|---|---|
|
|
A key minted before this claim existed carries none, and there is no local cure for that beyond a freshly issued key that carries it — that absence is the entire point of an add-on SKU, not a bug to route around. Everything else about the key — tier, expiry, the paidThrough fallback — is completely unaffected by which capabilities it does or does not carry.