/** * D1 v1.12.10 — Redact-on-egress for SleepResult cross-tenant counters. * * `api.sleep` returns host-wide counters (deduped.crossDups, which counts * cross-LAYER pairs, audit counters, ambient totals); they describe the * host's full memory state, not any one tenant. Today the route is * loopback-only + admin-gated since v1.12.0 sub-1, so all callers see the * full picture honestly. * * Once `HIPPO_BIND_ALL` ships (per D3 lock-step sequencing), non-loopback * admin Bearer callers would see another tenant's accounting data in the * SleepResult. That's a metadata-leak path. * * Redact-on-egress (chosen via D1 picks): when the caller is non-loopback * AND non-self admin, zero out cross-tenant counters before serialization. * Loopback admins still get the full picture (host ops legitimately need * dedup quality + total counts). * * Today this is layered-defence dead code (loopback-only gate is upstream). * Lands now so the gate is in place when D3 ships non-loopback serving; * "behind a flag first" historically means "flag flips before gates close." */ import type { SleepResult } from './api.js'; export interface RedactSleepCtx { /** True when the request came from 127.0.0.1 / ::1. Pass-through everything. */ isLoopback: boolean; /** * The caller's tenant. Today's only non-loopback admin is the deployment * operator whose own tenant matches the row owner of the audit_prune / * audit_create rows. When `callerTenant === '__host__'` (synthetic * representing a future "host operator" actor), pass-through. */ callerTenant: string; } /** * Returns a SleepResult that's safe to serialize to a non-loopback non-self * caller. Loopback OR `__host__` caller = pass-through unchanged. * * Redaction surface (the host-wide aggregate counters specifically): * - deduped.crossDups (pairs whose kept and removed layers differ, summed across tenants) * - deduped.semDups, .epiDups (aggregate dedup activity across tenants) * - audit.errorsRemoved, .warningCount (aggregate audit-pipeline activity) * - ambient.totalMemories, .avgStrength (aggregate corpus shape) * - graph.tenants, .entities, .relations (cross-tenant graph rebuild totals) * * NOT redacted (per-invocation activity counters, not cross-tenant accounting): * - active, removed, mergedEpisodic, newSemantic (this invocation's totals) * - dryRun (echo of input) * - shared (counted within api.sleep's per-call work) * - secretSkipped (v1.25.0 — sibling of `shared`, produced by the same * autoShare call; same per-invocation class, deliberately NOT given a * divergent rule) * - rejectedSkipped (AT1 — secretSkipped's own sibling, same autoShare * call, same per-invocation class) * - details (text descriptions, no aggregate numerics) */ export declare function redactSleepResultForCaller(result: SleepResult, ctx: RedactSleepCtx): SleepResult; //# sourceMappingURL=sleep-redact.d.ts.map