/**
 * eventMeta — build EventMeta from a footprintjs TraversalContext.
 *
 * Pattern: Adapter (GoF) — translates footprintjs's per-stage context into
 *          agentfootprint's per-event metadata shape.
 * Role:    Used by every core recorder to attach meta to emitted events.
 * Emits:   N/A (helper only).
 */
import type { TraversalContext } from 'footprintjs';
import type { EventMeta, EventSourcePosition } from '../events/types.js';
/**
 * Minimal "stage origin" shape — the common subset of footprintjs's
 * TraversalContext (from FlowRecorder events), RecorderContext (from
 * Recorder data-flow events), and EmitEvent (from EmitRecorder).
 *
 * Note: `subflowPath` type varies across footprintjs event shapes:
 *   - TraversalContext.subflowPath → `string | undefined` (/-separated)
 *   - EmitEvent.subflowPath        → `readonly string[]`
 *   - RecorderContext              → N/A (derived from runtimeStageId)
 *
 * We accept both shapes and normalize inside `buildEventMeta`.
 */
export interface StageOrigin {
    readonly runtimeStageId?: string;
    readonly subflowPath?: string | readonly string[];
    /** Source emission time, when this origin is an emit rather than a flow hook. */
    readonly timestamp?: number;
    /** Already validated wire coordinates; never read from live executor state. */
    readonly sourcePosition?: EventSourcePosition;
}
export interface RunContext {
    /** Millisecond wall-clock timestamp when the run started. */
    readonly runStartMs: number;
    /** Unique run id (demultiplex concurrent runs sharing one dispatcher). */
    readonly runId: string;
    /** Optional OTEL trace id forwarded from executor.run({ env: { traceId } }). */
    readonly traceId?: string;
    /** Optional correlation id for cross-event tying (retrieval→injection→LLM). */
    readonly correlationId?: string;
    /** Composition ancestry path (e.g. ['Sequence:bot', 'Agent:classify']). */
    readonly compositionPath: readonly string[];
    /** Optional turn/iter indices from agent runtime. */
    readonly turnIndex?: number;
    readonly iterIndex?: number;
    /** The hosting conversation this run belongs to, when it belongs to one
     *  (9.4.0). Absent for an unhosted or anonymous run — never fabricated. */
    readonly sessionId?: string;
    /** WHO the caller NAMED for this run (9.11.0) — from an explicit
     *  `run({ identity })` only, never from the synthesized `runIdentity` and
     *  never derived from a session. Absent for an anonymous run. */
    readonly principal?: string;
    /** The tenant the caller NAMED for this run (9.11.0). Same rule as
     *  {@link RunContext.principal}. */
    readonly tenant?: string;
}
/**
 * Build an EventMeta from a stage origin + run-level context.
 *
 * Accepts footprintjs's TraversalContext (FlowRecorder events), RecorderContext
 * (WriteEvent / CommitEvent / etc.), or a bare StageOrigin. When the origin
 * has no runtimeStageId (rare — manual emit during tests), the meta degrades
 * gracefully to 'unknown#0'.
 */
export declare function buildEventMeta(origin: StageOrigin | TraversalContext | undefined, run: RunContext): EventMeta;
/**
 * The run id an event carries when it was produced OUTSIDE any run — a
 * consumer's own `agent.emit(...)`, the hosting door's redemption facts.
 * One spelling, owned here beside the builder of every other run id.
 */
export declare const CONSUMER_SCOPE_RUN_ID = "consumer-scope";
/**
 * Does an event belong to `run`? — the ONE answer to "which run is this event
 * for?", asked by every collector that keeps a single run's events: the run's
 * own recording (the `recordings` dial) and the self-explain evidence.
 *
 * Those collectors subscribe to the whole dispatcher and keep what arrives
 * while their run is in flight. On an instance that serves more than one
 * session — `standingAgent({ agent })`, where every session shares one agent —
 * the dispatcher also carries facts produced for SOMEBODY ELSE at that moment:
 * a screen redeeming its own chart, a host filing for its own turn, a tool
 * upload from an earlier run landing late. Kept by timing alone, those facts
 * entered the wrong person's recording, which that person could then redeem.
 *
 * Two clauses, in order:
 *  1. **An event that names a run belongs to that run, and no other.** A run's
 *     own events carry its id through {@link buildEventMeta}; a fact emitted
 *     through an artifact binding carries the run the BINDING was created for
 *     (captured at bind time, never read from whichever run is live when the
 *     fact lands).
 *  2. **An event of no run** ({@link CONSUMER_SCOPE_RUN_ID}) **belongs to runs
 *     of the session it was produced for** — the hosting door stamps what it
 *     produces (`RunnerBase.emitAttributed`) — **or, naming no session, to
 *     whatever run is in flight**, exactly as before: a consumer's own
 *     `agent.emit(...)` from inside a tool.
 */
export declare function eventBelongsToRun(meta: Partial<Pick<EventMeta, 'runId' | 'sessionId'>> | undefined, run: Pick<RunContext, 'runId' | 'sessionId'>): boolean;
/**
 * Parse footprintjs's `/`-separated subflow path into a readonly array.
 *
 * The source of truth for runtimeStageId parsing lives in footprintjs at
 * `foottrace::parseRuntimeStageId`. We only need the path-split
 * convenience here; the `/` separator is stable across footprintjs
 * versions (covered by their `parseRuntimeStageId` tests).
 */
export declare function parseSubflowPath(raw: string | undefined): readonly string[];
//# sourceMappingURL=eventMeta.d.ts.map