/** * Licence verification (task 127) — pure, synchronous, offline. * * Cumulus is freely installable and evaluable. What a licence unlocks is * *persistent web-app agent capacity*: an unlicensed namespace may mint at most * `DEMO_VISITOR_THREAD_CAP` distinct visitor threads. Everything else — personal * threads, the CLI, the TUI, every non-namespaced use — is never gated. * * A key is `cumulus-lic-v1..`. * The payload is readable by anyone (it is a claim, not a secret); the signature * is what makes it unforgeable. The signature covers the payload SEGMENT bytes * verbatim — the base64url text, not a re-serialization of the parsed JSON — so * there is no canonicalization ambiguity between signer and verifier. * * `major` is the only version scoping (Karl, 2026-08-06): a key issued for * major 1 unlocks every 1.x.y and no 2.x. Crossing a major is a renewal event. * There is no expiry field and no phone-home. * * This module knows nothing about namespaces as a config shape — it takes plain * strings. The namespace capacity rule lives in the gateway layer * (`gateway/namespaces.ts`), the same boundary task 097 P5 drew. * * Honest limitation, stated in the task doc too: `dist/` is readable JavaScript * and this check is deletable. It is a compliance mechanism, not DRM. */ /** Distinct visitor threads an UNLICENSED namespace may mint. */ export declare const DEMO_VISITOR_THREAD_CAP = 5; /** Where an unlicensed operator is told to go. */ export declare const LICENSE_CONTACT = "ops@luckydrawdesign.com"; /** Key string prefix; bumping this is a format break, not a licence break. */ export declare const LICENSE_KEY_PREFIX = "cumulus-lic-v1"; /** * Lucky Draw's Ed25519 public verification key, raw 32 bytes, base64url. * Public by design — it can verify but cannot sign. Rotating it invalidates * every issued key, so it changes only in a new major release. */ export declare const LICENSE_PUBLIC_KEY_B64 = "JjwM5B0kzouidZHoK4OMwDaEp4HpUFs7WlrVRoXQL6M"; export interface LicensePayload { /** Who the key was issued to. Recorded, displayed, not otherwise enforced. */ licensee: string; /** Major version this key unlocks. */ major: number; /** Namespaces unlocked. Absent or `["*"]` = all. */ namespaces?: string[]; /** Issue date, informational. */ issued?: string; note?: string; } export type LicenseFailureReason = 'absent' | 'malformed' | 'bad-signature' | 'major-mismatch'; export type LicenseStatus = { licensed: true; licensee: string; namespaces: string[] | null; major: number; } | { licensed: false; reason: LicenseFailureReason; }; /** * Verify a licence key against the running gateway's major version. * * Never throws — a malformed key is a status, not an exception, because this is * called on the request path and from the daemon banner. * * @param key the `licenseKey` config value (may be undefined/empty) * @param currentMajor the gateway's own package.json major * @param publicKeyB64 override for tests (a test keypair); defaults to Lucky Draw's */ export declare function verifyLicense(key: string | undefined, currentMajor: number, publicKeyB64?: string): LicenseStatus; /** Is namespace `ns` covered by this licence? `namespaces: null` = all. */ export declare function namespaceLicensed(status: LicenseStatus, ns: string): boolean; /** Human-readable one-liner for the daemon banner and the 402 body. */ export declare function describeLicenseFailure(reason: LicenseFailureReason): string; /** Parse a semver-ish version string's major. Returns 0 when unparseable. */ export declare function majorOf(version: string): number; //# sourceMappingURL=license.d.ts.map