@juspay/neurolink
Version:
The pipe layer of an AI nervous system: one interface connecting provider neurons to your application, across three inference types — generate, stream and decide. `decide` returns typed, calibrated judgements from a non-generative model (~400ms, ~$0.00002
102 lines (101 loc) • 5.19 kB
TypeScript
/**
* Leases — how a lender keeps control of a credential that lives on someone
* else's machine.
*
* In **live** sharing the lender's gate is in the request path, so control is
* immediate and total. **Complete** sharing trades that away: the borrower holds
* its own credential on the lender's account and calls the upstream directly, so
* the lender is not consulted per request. What is left is this — a signed,
* time-boxed statement of consent that the borrower enforces on itself and must
* keep renewing.
*
* The design turns on one number: **how long may the borrower run without
* hearing from me.** `offlineGraceMs` is that number. Set it to zero and
* complete mode collapses into live mode's availability; set it to a day and the
* borrower keeps working through a weekend when the lender's laptop is shut, at
* the cost of a day's revocation latency. Both are legitimate; neither is free.
*
* `notAfter` is the backstop that does not depend on the borrower's cooperation
* at all — it is baked into the signed payload, so a borrower that simply never
* calls home still stops.
*
* **Signing.** HMAC-SHA256 keyed by a per-grant secret shared with the borrower
* at provisioning time. Asymmetric signatures would be tidier, but the key
* distribution problem they solve does not exist here — exactly two parties are
* involved and they already share a secret — and the package's browser bundle
* stubs `node:crypto` down to a subset with no Ed25519 in it.
*
* @module proxy/shareLease
*/
import type { ProxyShareGates, ProxyShareGrant, ProxyShareLease, ProxyShareLeaseRefusal, ProxyShareLeaseVerdict, ProxyShareProvisionClaim } from "../types/index.js";
/** A week: long enough to survive a holiday, short enough to be a real bound. */
export declare const DEFAULT_LEASE_TTL_MS = 604800000;
/** Fifteen minutes — frequent enough that a pause lands the same session. */
export declare const DEFAULT_HEARTBEAT_MS = 900000;
/** Twenty-four hours of running unheard-from. The headline trade-off. */
export declare const DEFAULT_OFFLINE_GRACE_MS = 86400000;
/**
* Narrow a verdict to its refusing half.
*
* One of the package's build steps compiles without `strictNullChecks`, where
* TypeScript will not narrow a boolean discriminant. An explicit predicate holds
* in both modes — see the same pattern in `sharePolicy.isShareRefusal`.
*/
export declare function isLeaseRefusal(verdict: ProxyShareLeaseVerdict): verdict is ProxyShareLeaseRefusal;
export declare function generateLeaseSecret(): string;
/**
* Issue a lease for a grant.
*
* The gates are snapshotted rather than referenced: the borrower enforces what
* the lender agreed to at issue time, and a tightened policy reaches them at the
* next heartbeat rather than silently mid-lease.
*/
export declare function issueLease(grant: ProxyShareGrant, now?: number): ProxyShareLease;
/** Does this lease actually come from the lender it claims to? */
export declare function isLeaseAuthentic(lease: ProxyShareLease, secret: string): boolean;
/**
* May the borrower serve from this lease right now?
*
* Three independent stops, in the order that matters:
*
* 1. **Unsigned** — someone edited the file. Nothing else is worth checking.
* 2. **Expired** — `notAfter` passed. Immune to a borrower that never checks in.
* 3. **Grace elapsed** — the lender has been unreachable for longer than it
* agreed to be trusted for. This is the one that makes "the lender turned
* their laptop off" survivable and "the lender revoked me" eventually
* binding.
*/
export declare function evaluateLease(args: {
lease: ProxyShareLease;
secret: string;
lastHeartbeatAt?: number;
now?: number;
}): ProxyShareLeaseVerdict;
/** Should the borrower check in now? */
export declare function isHeartbeatDue(lease: ProxyShareLease, lastHeartbeatAt: number | undefined, now?: number): boolean;
/** The gates a resident grant must enforce on itself, from its lease. */
export declare function leasedGates(lease: ProxyShareLease): ProxyShareGates;
/**
* Assemble what the borrower collects once the lender has authorized.
*
* Carries no token, by construction. The borrower already holds the verifier
* that turns the enclosed code into tokens, and it exchanges the two on its own
* machine — so nothing here is worth intercepting, and the lender never holds a
* credential for the account it just authorized.
*
* `accountLabel` is the lender's *suggestion*, not the key the credential ends
* up under. The borrower names the account itself — `<peer>-shared` unless
* `--label` says otherwise — and refuses to install over an existing one,
* because Anthropic quota snapshots are keyed by the bare label and two
* accounts sharing one would merge each other's windows. Derived from both
* parties' names so that a lender running `share list` and a borrower running
* `auth list` are looking at recognisably the same thing.
*/
export declare function buildProvisionClaim(args: {
grant: ProxyShareGrant;
lenderName: string;
lenderUrl?: string;
code: string;
state: string;
now?: number;
}): ProxyShareProvisionClaim;