/** * untrusted-surface-language.ts, saying what a thing is, in the noun it has. * * ── Why this is not cosmetic ────────────────────────────────────────────── * * The refusal the owner met said their Gmail was controlled by "anyone able to * write to those pages". A mailbox is not a page and nobody writes to it; they * send to it. Reading that sentence, the honest conclusion is that the boundary * does not know what it just looked at, and a boundary that visibly does not * understand its own evidence is one the reader stops believing, which is the * failure the taint module's header warns about in as many words. * * The wrong noun got there the ordinary way: the rule was written for the * browser, the mail surface was added later, and it inherited the browser's * sentence because there was only one sentence. So the surfaces get their own * words here, in one place, rather than each refusal site inventing them. * * ── What the wording has to carry ───────────────────────────────────────── * * Two things, per surface: * * - what the thing IS, with its origin, "the web page at https://x.example", * "a message in your mailbox from email:x.example (claimed)"; * - who can put text in it, publishers of a site, anyone who knows an * address, anyone in a channel, whoever produced a document. * * The second is the load-bearing half. It is the reason the content carries no * authority, and stating it in terms the reader can check is what makes a * refusal reconstructable rather than an assertion. */ /** * Surfaces whose content is written by someone other than the owner. * * `'calendar-event'` is its own member rather than a case of `'document'`. * Where a calendar event came from is an inviter's address or a subscription * URL the daemon polls, and that is precisely the fact a reader of the ledger * needs: "content from alice@example.invalid (claimed organizer)" and "content * from a feed at calendars.example.invalid" are different provenance, and * folding both into "document" would erase the difference in the one place it * decides whether a refusal reads as sensible. */ export type UntrustedSurface = 'web-page' | 'email' | 'channel-message' | 'document' | 'calendar-event'; /** One (surface, origin) pair that contributed exposure to the current turn. */ export interface UntrustedExposure { readonly surface: UntrustedSurface; readonly origin: string; } /** The thing itself, named with its origin. */ export declare function describeUntrustedSource(exposure: UntrustedExposure): string; /** Who is able to put text into that surface, the reason it carries no authority. */ export declare function describeWhoControls(surface: UntrustedSurface): string; /** * A list of exposures as one readable clause, grouped so a turn that read * fifteen pages does not produce fifteen sentences. * * Grouping is by surface: the "who controls it" half is a property of the * surface, so repeating it per origin is noise, while merging surfaces would * attach a mailbox's sentence to a web page. */ export declare function describeExposures(exposures: readonly UntrustedExposure[]): string; //# sourceMappingURL=untrusted-surface-language.d.ts.map