import { type Context } from '../../api.js';
import type { ChannelMeta } from './scope.js';
import type { SlackMessageEvent } from './types.js';
export interface IngestInput {
    teamId: string;
    channel: ChannelMeta;
    message: SlackMessageEvent;
    /** Slack event_id for the envelope (or for backfill, a synthesized stable id). */
    eventId: string;
}
export type IngestStatus = 'ingested' | 'duplicate' | 'skipped' | 'skipped_duplicate';
export interface IngestResult {
    status: IngestStatus;
    memoryId: string | null;
}
/**
 * Ingest a Slack message into hippo as a kind='raw' memory.
 *
 * - Idempotency-checked via slack_event_log (Slack retries within 1 minute).
 * - The memory write and the slack_event_log mark commit atomically through
 *   `api.remember`'s `afterWrite` hook — a crash between the two cannot
 *   produce a duplicate on the next retry.
 * - The afterWrite hook uses an explicit `INSERT OR IGNORE` + changes-check:
 *   if a concurrent worker beat us to slack_event_log between the pre-check
 *   and the SAVEPOINT, we throw `DuplicateEventError` to roll back the memory
 *   write. The pre-check `hasSeenEvent` stays as a fast path for the common
 *   already-seen case, but the afterWrite throw is what makes idempotency
 *   correct under two-worker concurrency (v0.39 commit 3 fix).
 * - Empty-body messages return 'skipped' but still mark seen so a replay
 *   returns 'duplicate' rather than re-running the transform.
 */
export declare function ingestMessage(ctx: Context, input: IngestInput): IngestResult;
//# sourceMappingURL=ingest.d.ts.map