/**
 * PlacementResponderReader — resolves WHICH machine served a reply, for the
 * RealChannelDriver's injected `resolveResponderMachine` seam
 * (docs/specs/live-user-channel-proof-standard.md §5.6 — the deterministic
 * cross-machine proof). It maps a (surface, channelId) to the topic that
 * `GET /pool/placement?topic=N` is keyed on, reads the authoritative owner, and
 * returns that machine id.
 *
 * Why this is the right reader: `/pool/placement` is the authoritative placement
 * surface (it proxies to the lease-holder, so any machine can answer), and its
 * `owner` field is the machine currently serving the topic — exactly "who replied"
 * after a transfer. We read `owner` (not `pinnedTo`): a pin is the INTENT to place;
 * `owner` is who actually holds it. For the capstone that distinction is the whole
 * point — a pin that didn't move the seat is the original bug.
 *
 * Parameterized for testability: the HTTP GET + the (surface, channelId)→topicId
 * mapping are injected, so this is unit-testable with no live server. MUST NOT throw
 * on a transient read error — it returns null so the RealChannelDriver degrades to an
 * unattributed reply rather than failing the whole scenario.
 */
export class PlacementResponderReader {
    d;
    constructor(deps) { this.d = deps; }
    log(m) { this.d.logger?.(`[placement-responder-reader] ${m}`); }
    /** The function shape RealChannelDriver injects: (surface, channelId) → machine id | null. */
    resolve = async (surface, channelId) => {
        const topicId = this.d.topicForChannel(surface, channelId);
        if (!topicId) {
            this.log(`no placement-tracked topic for ${surface}:${channelId}`);
            return null;
        }
        try {
            const p = await this.d.fetchPlacement(topicId);
            return p?.owner ?? null;
        }
        catch (err) {
            // @silent-fallback-ok: a transient /pool/placement read failure degrades this
            // best-effort responder-machine lookup to null — the RealChannelDriver then
            // proceeds with an unattributed reply rather than throwing the whole scenario.
            // The failure is logged with topic context; it is not a gating/authority path.
            this.log(`fetchPlacement failed for topic ${topicId}: ${err instanceof Error ? err.message : String(err)}`);
            return null;
        }
    };
}
//# sourceMappingURL=PlacementResponderReader.js.map