export declare const PI_TELEMETRY_ENV_KEYS: readonly ["PI_TELEMETRY_OWNER_PID", "PI_TELEMETRY_SESSION_ID", "PI_TELEMETRY_TRACE_ID"]; export declare const PI_TELEMETRY_PROCESS_ROLE_KEY: "PI_TELEMETRY_PROCESS_ROLE"; export declare const PI_TELEMETRY_SUBAGENT_ROLE: "subagent"; export declare const PI_TELEMETRY_SUBAGENT_DETAIL_KEYS: readonly ["PI_SUBAGENT_CHILD_AGENT", "PI_TELEMETRY_SUBAGENT_NAME", "PI_TELEMETRY_SUBAGENT_AGENT"]; export declare const HINDSIGHT_API_URL_KEY: "HINDSIGHT_API_URL"; export declare const LANGFUSE_CREDENTIAL_ENV_KEYS: readonly ["LANGFUSE_PUBLIC_KEY", "LANGFUSE_SECRET_KEY"]; export declare const LANGFUSE_ENDPOINT_ENV_KEYS: readonly ["LANGFUSE_BASE_URL", "LANGFUSE_BASEURL", "LANGFUSE_HOST"]; export type PiTelemetryEnvKey = (typeof PI_TELEMETRY_ENV_KEYS)[number]; export type TelemetryProcessRole = "main" | "subagent"; export interface TelemetryRuntime { pid: number; ppid: number; /** Inject in tests to avoid relying on real process state. */ isProcessLive?: (pid: number) => boolean; /** Inject in tests or launchers that know a wrapper/supervisor ancestry. */ isProcessAncestor?: (ancestorPid: number, descendantPid: number) => boolean; /** Explicit launch-path allowlist for a known telemetry subagent. */ isIntendedSubagent?: boolean; } export type HindsightApiUrlAction = "absent" | "preserved" | "set" | "removed-blank"; export interface SupervisorTelemetryEnvDecision { piTelemetry: PiTelemetryEnvDecision; hindsightApiUrlAction: HindsightApiUrlAction; langfuse: { publicKeyPresent: boolean; secretKeyPresent: boolean; endpointConfigured: boolean; includePayloads: boolean; }; } export interface SupervisorTelemetryEnvOptions { /** Optional non-empty URL to inject for supervised sessions. Empty values are treated as absent. */ hindsightApiUrl?: string | null; /** * Runtime for the child Pi process whose env is being prepared. Omit this when * preparing env before spawn; inherited PI_TELEMETRY_* is then scrubbed * conservatively because the future child PID/parentage cannot be proven yet. */ childRuntime?: TelemetryRuntime; } export interface PiTelemetryEnvDecision { telemetryProcessRole: TelemetryProcessRole; processPid: number; parentPid: number; ownerPid?: number; hasTelemetryEnv: boolean; hasSubagentMarker: boolean; preserve: boolean; scrubbed: boolean; reason: "absent" | "invalid-owner-pid" | "owner-is-current-process" | "owner-not-live" | "missing-session-or-trace" | "owner-is-not-parent" | "owner-is-not-ancestor" | "valid-direct-child" | "valid-marked-descendant"; } /** Parse a PID string, returning a positive base-10 integer or undefined. */ export declare function parseTelemetryOwnerPid(value: string | undefined): number | undefined; /** Check whether a process with the given PID is live; EPERM means live but inaccessible. */ export declare function isProcessLive(pid: number): boolean; /** * Return true when `ancestorPid` is in `descendantPid`'s OS parent chain. * * This lets marked telemetry children launched through wrappers preserve the * parent trace without trusting a marker inherited from an unrelated live Pi * process. On platforms without `/proc`, this falls back to `ps` when * available; direct-child compatibility still works through `ownerPid === ppid`. */ export declare function isProcessAncestor(ancestorPid: number, descendantPid: number): boolean; export declare function classifyPiTelemetryEnv(env?: Record, runtime?: TelemetryRuntime): PiTelemetryEnvDecision; /** Return true only when inherited telemetry describes a compatible direct-child or marked subagent launch. */ export declare function shouldPreservePiTelemetryEnv(env?: Record, runtime?: TelemetryRuntime): boolean; /** * Delete stale, partial, or unrelated Pi telemetry env vars before telemetry extensions load. * * If @amaster.ai/pi-telemetry is installed separately, this package must be * loaded first; that extension snapshots PI_TELEMETRY_* during its factory. * * Top-level Pi processes launched by supervisors can inherit old PI_TELEMETRY_* values. * Preserve them only for a coherent legacy direct-child launch, a marked owner * in the current process ancestry, or an injected fresh launch-path allowlist; * otherwise scrub all telemetry linkage keys so the process starts a fresh * top-level trace. */ export declare function scrubStalePiTelemetryEnv(env?: Record, runtime?: TelemetryRuntime): PiTelemetryEnvDecision; /** * Normalize telemetry-related env before launching a supervised tmux/workflow Pi session. * * Policy: * - never pass `HINDSIGHT_API_URL=` as a blank override; delete it so Hindsight can * use normal config discovery, or inject an explicit non-empty URL; * - scrub inherited PI_TELEMETRY_* before spawn unless an explicit childRuntime proves * the env belongs to that child; * - report only boolean Langfuse presence so runbooks can diagnose setup without * printing secrets. */ export declare function prepareSupervisorTelemetryEnv(env?: Record, options?: SupervisorTelemetryEnvOptions): SupervisorTelemetryEnvDecision; export declare function normalizeHindsightApiUrlEnv(env?: Record, overrideUrl?: string | null): HindsightApiUrlAction;