import type { MemoryScopeRef } from '@jungjaehoon/mama-core'; import { type ChannelGrant } from '@jungjaehoon/mama-core/context-compile'; import { type IndexedEvent, type ParsedSourceRef, type ProvenanceResolution } from './provenance-resolver.js'; /** The columns the predicate needs. Shared so a test reads exactly what production does. */ export declare const EVENT_INDEX_COLUMNS = "event_index_id, source_connector, source_id, channel, content,\n event_datetime, source_timestamp_ms, memory_scope_kind, memory_scope_id,\n project_id, tenant_id"; export interface EventRow { event_index_id: unknown; source_connector: unknown; source_id: unknown; channel: unknown; content: unknown; event_datetime: unknown; source_timestamp_ms: unknown; memory_scope_kind: unknown; memory_scope_id: unknown; project_id: unknown; tenant_id: unknown; } export interface LiveProvenanceOptions { /** Scopes active NOW. Not the scopes the memory was written under. */ scopes: MemoryScopeRef[]; /** * Raw connectors this caller may read. No grant means NO raw events, never all of * them - the reader fails closed here and so must this. An earlier version accepted * `null` to mean "scope alone decides", which turned a missing envelope into a * connector-wide grant. */ connectors: readonly string[]; /** * The channels of each connector this caller may read, when the caller holds a grant. * Present means the grant decides, exactly as it does in the reader. Absent means the * pre-grant rule applies, so a caller that has not been given one is unaffected. */ channels?: ChannelGrant; /** Project and tenant window, mirroring the reader's filters on the same columns. */ projectIds?: readonly string[]; tenantId?: string | null; /** * Visibility clamp on observation time, in epoch ms. Only the MAX is threaded from the * call site, deliberately: the reader's lower bound comes solely from `range.start_ms`, * which is caller-chosen narrowing, while the upper bound folds in `as_of`, which is an * authority clamp. A future reader should not "fix" the asymmetry. The reader bounds raw candidates * by `COALESCE(event_datetime, source_timestamp_ms)`; without a counterpart here, an * `as_of` boundary would hold for reading and not for citation. Nothing assigns * `envelope.scope.as_of` today, so these are null in practice - implemented now * because a filter with no counterpart is exactly the shape the tenant leak had. */ minObservedMs?: number | null; maxObservedMs?: number | null; excerptChars?: number; /** Redaction to apply to excerpts, so this surface scrubs what recall scrubs. */ redact?: (text: string) => string; } /** * Parse a stored source ref into what it actually is. * * The shapes here were measured, not guessed. Of the source refs on this machine 13,403 * are `memory:`, 1,748 are `envelope:`, 9 are `message:` and none are `raw:`. An earlier * version of this parser understood only `raw:` and reported every real memory as * `unsupported_ref` - a tool that was wired, callable, and answered nothing. */ export declare function parseSourceRef(ref: string): ParsedSourceRef; /** * Whether an event may be shown under the authority active now. * * When a channel grant is supplied this DELEGATES to the shared rule rather than copying * it. The previous version copied the reader clause for clause and said so in a comment, * which held until the reader changed - then the copy silently became a different rule * that refused excerpts for the very events the reader was citing. The differential test * meant to catch that kept passing, because its fixtures never set a grant. * * "A shared predicate would be better than a faithful copy" is what the old comment here * said. It was right. * * Without a grant the pre-grant rule still applies, so callers that have not been given * one behave exactly as before. */ export declare function isEventVisibleNow(event: IndexedEvent, options: { scopes: readonly MemoryScopeRef[]; connectors: readonly string[]; channels?: ChannelGrant; projectIds?: readonly string[]; tenantId?: string | null; minObservedMs?: number | null; maxObservedMs?: number | null; }): boolean; /** * Row to the struct the predicate judges. * * Exported because it is the layer BELOW the predicate, and a differential that * hand-builds its own struct proves the predicate mirrors the reader while leaving this * mapping unjudged - which is where a scope-column coercion bug already lived once. */ export declare function toIndexedEvent(row: EventRow): IndexedEvent; /** * Whether a message ref may be named. * * `sourceMessageRef` is built as `source:channelId:turnId` (message-router.ts), and a * channel scope id as `source:channelId` (scope-context.ts) - so a ref belongs to a * caller's channel exactly when an active channel scope is its prefix. Compared as a * prefix rather than parsed, because a turn id can itself contain a colon * (`generated:`) and splitting on the last one would silently mis-attribute it. * * This matters beyond tidiness: every memory carrying such a ref is also bound to * global:system, which every caller holds, so an unchecked ref handed a private channel * identifier to any agent that could read the memory at all. */ export declare function isMessageRefVisible(ref: string, scopes: readonly MemoryScopeRef[]): boolean; /** Resolve one memory's support against the live index and the scopes active now. */ export declare function resolveMemoryProvenanceLive(memoryId: string, options: LiveProvenanceOptions): Promise; //# sourceMappingURL=provenance-live.d.ts.map