/** * Entitlement verifier — single source of truth for effective tier and * purchasedPlugins on a Maxy/Real-Agent install. Pre-launch security gate * for paid tiers. * * Doctrine: account.json is agent-writable; entitlement is not. Effective * tier and purchasedPlugins derive from a Rubytech-signed Ed25519 payload, * not from raw account.json values. Editing account.json directly has no * runtime effect; the verifier compares disk against signed and uses signed. * * ┌────────────────────────────┐ * │ session start │ * └─────────────┬──────────────┘ * ▼ * ┌────────────────────────────┐ * │ read brand.json │ * │ commercialMode? (default │ * │ false on personal-mode) │ * └────────┬───────────────┬───┘ * │false │true * ▼ ▼ * source=implicit-trust read entitlement.json * (raw account.json) │ * ├─missing──▶ anonymous-fallback (lock) * ├─malformed─▶ anonymous-fallback * ├─pubkey-tampered─▶ anonymous-fallback * ├─bad sig──▶ anonymous-fallback * ├─binding mismatch─▶ anonymous-fallback * ├─clock skew──▶ anonymous-fallback * ├─expired+grace─▶ signed-grace * ├─expired post-grace─▶ anonymous-fallback (lock) * └─valid─▶ signed * * Threat model: this code closes the agent-self-elevation bypass and the * casual operator vim-edit bypass. A determined operator with shell access * who replaces the vendored pubkey AND regenerates the SHA-256 hash baked * into PUBKEY_SHA256 below can still defeat the verifier — that is the * accepted out-of-scope per task 831 ("raise bypass cost to break the * signature, not to edit JSON"). Hardware binding is the only counter and * is explicitly out of scope. */ export declare const PUBKEY_SHA256 = "8eee6bcb33545fd13b16d3199a5735ca5db5062834c7b49dfe4f23801d99db79"; export type EntitlementSource = "signed" | "signed-grace" | "implicit-trust" | "anonymous-fallback"; export interface ResolvedEntitlement { tier: string; purchasedPlugins: string[]; source: EntitlementSource; issued: string | null; expires: string | null; } export interface AccountConfigSubset { accountId: string; customerEmail?: string; tier?: string; purchasedPlugins?: string[]; } export interface BrandConfigSubset { /** Absolute path to ~/ where entitlement.json is delivered. */ configDir: string; /** Absolute path to platform/ root; pubkey lives at /lib/entitlement/rubytech-pubkey.pem. */ platformRoot: string; /** True only when this brand has flipped to commercial entitlement enforcement. */ commercialMode?: boolean; } /** * Resolve effective entitlement for the current install. Sync — Ed25519 * verify is a CPU-bound primitive on the order of 0.3ms; no async surface. * * @param brand Brand config (read from platform/config/brand.json by caller) * @param account Account config (read from data/accounts//account.json) * @returns Effective entitlement plus the source tag for observability. */ export declare function resolveEntitlement(brand: BrandConfigSubset, account: AccountConfigSubset): ResolvedEntitlement; /** Test-only: clear the memoization cache. Not used in production. */ export declare function _clearMemo(): void; //# sourceMappingURL=index.d.ts.map