/** * serve-descriptor — the ONE validator for the untrusted daemon-discovery * artifact `.openlore/serve.json`. * * The descriptor is a repo-local, attacker-writable file that OpenLore reads at * three sites — the `serve` CLI, the serve-client the stdio MCP server delegates * through, and the Pi extension. Each reader then FETCHES the host/port the file * names for a liveness probe and, on a healthy answer, POSTs the project * directory and full tool arguments to it. A poisoned descriptor is therefore an * SSRF / egress vector, a leak of the directory + tool args, and a result- * poisoning channel into the agent's context (mcp-security: Untrusted Artifact * Deserialization). One threat model must not have three postures. * * This module is the one lock, extracted verbatim from `serve.ts`'s existing * reader: loopback-only host, integer port 1–65535, integer pid > 0, token * absent-or-string. No check is invented here beyond the ones `serve` already * applied. A descriptor that fails any check is treated exactly as ABSENT — the * reader returns null and the caller takes its existing no-daemon path (spawn a * fresh daemon or fall back to in-process dispatch). No field of an invalid * descriptor ever becomes a fetch target, a request header, or a signal target. * * Dependency-light by contract (mcp-security ServeDescriptorValidatedAtEveryReader * + the MCP↔Pi parity doctrine): it imports only node builtins and the loopback * predicate it shares with the HTTP guard, so the Pi host can import it without * pulling in the analyzer. */ /** * The validated daemon-discovery descriptor. `startedAt` / `version` are * advisory metadata (normalized to '' when absent or ill-typed); the other four * fields are security-critical and are only present on a descriptor that passed * {@link validateServeDescriptor}. */ export interface ServeDescriptor { port: number; pid: number; host: string; token?: string; startedAt: string; version: string; } /** * Validate an already-parsed value as a {@link ServeDescriptor}. Returns the * normalized descriptor, or null if ANY security-critical field is * missing / ill-typed / out of range, or the host is not a loopback form. */ export declare function validateServeDescriptor(parsed: unknown): ServeDescriptor | null; /** * Read + validate a serve.json at `descriptorPath`. Any failure — missing file, * malformed JSON, or a descriptor that fails {@link validateServeDescriptor} — * resolves to null, so a poisoned descriptor is indistinguishable from an absent * one and no field of it ever reaches a fetch, a header, or a signal target. */ export declare function readServeDescriptor(descriptorPath: string): Promise; //# sourceMappingURL=serve-descriptor.d.ts.map