/** * Attributed testers per run. Justified against D-Many-viewers-are-normal's * 40-person demo, NOT against the platform's MaxConcurrentStreams = 256 — those * count different things. 256 is per-session CONCURRENT CONNECTIONS, and one tab * opens 2-6 under HTTP/1.1, so 64 tabs already exceeds what the platform admits * and the platform's cap binds first. Memory does not choose this number: 64 * entries is about 4 KB. * * That argument holds ONLY because minting requires a WebSocket the harness * opened — see `resolve` versus `attribute`. A door that could mint without a * stream would not be bounded by the platform's stream cap at all, and filling * this registry is a denial of the creator's live terminal, not merely of an id. */ export declare const MAX_TESTERS = 64; /** * Refused keys remembered, so the cap warning prints ONCE per refused session * rather than once per batch. * * This set is what makes print-once bounded. The key is client-supplied, so * without a cap here its size is a number a client chooses by cycling * sessionStorage. Past this many, further sessions are still refused but no * longer remembered — so a pathological client can re-trigger its own warning * line. That is the correct failure: noisy, local and self-inflicted, versus * unbounded memory on the creator's machine. */ export declare const MAX_REFUSED_TOMBSTONES = 256; /** What the relay learned from one batch's key. */ export interface Attribution { /** The tester id, or undefined when this key is not attributed. */ readonly tester?: string; /** * True exactly once per refused session — the batch that should print the cap * warning. Every later batch from the same refused key reports false. */ readonly warnCapReached: boolean; } export declare class TesterRegistry { private readonly maxTesters; private readonly maxRefused; /** Insertion-ordered, so ids read in arrival order. */ private readonly byKey; /** Refused keys, for print-once. Holds no id — these were never assigned one. */ private readonly refused; private next; constructor(maxTesters?: number, maxRefused?: number); /** * Resolve a client-supplied key to a tester id, assigning one on first sight. * * The key is validated against the SAME grammar the client mints, with no * sanitize-and-keep branch — the readViewerLabel discipline, applied to the * field beside the label that never had it. A key that misses the grammar is * un-attributed: its events are still ingested, only the tester tag is absent. * * Entries are NEVER removed for the life of the process. That mirrors * viewersSeen in the event store and for its stated reason: the ring buffer * holds events that outlive their producer, and dropping a tester's id would * make its already-stored events unfilterable — worse than never having * labelled them. `--tester t1` must keep answering for the tester who just hit * the bug, because that is the moment the creator runs it. */ attribute(key: unknown): Attribution; /** * Resolve a key WITHOUT ever assigning one — the read-only door. * * The annotation POST uses this, and the distinction is load-bearing. That * route is UNAUTHENTICATED and reachable by anyone holding the preview's * capability URL, so if it could mint, 64 bare `fetch` calls would exhaust the * registry before the creator's own phone ever connected. Entries are never * evicted, so that state would be permanent for the run — and because the * terminal only prints attributed events, the creator's live stream would go * blank for every real tester. * * Minting requires a WebSocket the harness actually opened. An annotation can * therefore be attributed to a tester that already exists, and is otherwise * un-attributed, which is the correct failure: the creator still gets their * bug report, it just carries no id. */ resolve(key: unknown): string | undefined; /** Ids assigned so far, in arrival order. Never includes a refused session. */ testers(): string[]; /** How many keys hold an id. Bounded by maxTesters. */ get size(): number; /** Whether this id was ever assigned — for `--tester` miss messages. */ has(tester: string): boolean; } /** * Is this a well-formed tester id? Used at the query boundary so a malformed * `--tester` filters to nothing rather than erroring or matching broadly. */ export declare function isTesterId(s: unknown): s is string;