/**
 * MentorStageA — the structural "two hats" boundary for the Framework-Onboarding
 * Mentor System (docs/specs/FRAMEWORK-ONBOARDING-MENTOR-SPEC.md §4, §19.3).
 *
 * Stage A drives the mentee agent conversationally "as the user," and the whole
 * value depends on it being BLIND to the mentee's internals — so wild-behaviour
 * issues actually surface instead of being unconsciously steered around. Round-1
 * convergence flagged that a prompt instruction ("don't peek") is willpower, not
 * structure. This module provides the structural pieces the §19.4 job wires:
 *
 *   1. STAGE_A_ALLOWED_TOOLS — the tool grant for the spawned Stage-A sub-agent.
 *      It is EMPTY: the conversation surface is *injected into the prompt*, never
 *      *fetched* by the sub-agent, so Stage A needs no log/code/rollout/fs tools
 *      at all. SessionManager.spawnSession({ allowedTools }) enforces this at the
 *      CLI layer (`--allowedTools` / Codex read-only sandbox) — structural, not a
 *      hook or a wish.
 *
 *   2. buildStageAContext(surface) — assembles the Stage-A prompt from ONLY the
 *      user-visible conversation surface. There is no parameter through which an
 *      internal (log line, code path, rollout, PR diff) can enter.
 *
 *   3. detectStageALeak(transcript, surface) — the mandatory leakage detector
 *      (§4.3). Because no mechanism can prove a model never *recalls* across ticks,
 *      this scans each Stage-A transcript for references to internals it could not
 *      have seen from the surface. It ships with a positive-control + a periodic
 *      canary so a dead/no-op detector is distinguishable from a clean run.
 *
 * This module is pure logic (no I/O, no routes). The §19.4 job calls
 * buildStageAContext → spawns with STAGE_A_ALLOWED_TOOLS → runs detectStageALeak
 * on the transcript → captures any leak to the ledger as an instar-integration-gap.
 */
import type { ForensicFinding } from './FrameworkIssueLedger.js';
/**
 * The Stage-A tool grant. EMPTY by design: the conversation surface is injected
 * into the prompt (§4), so the sub-agent never needs to read anything. An empty
 * allowlist passed to SessionManager.spawnSession denies every tool — the
 * strongest structural form of "conversation only."
 */
export declare const STAGE_A_ALLOWED_TOOLS: readonly string[];
/**
 * The user-visible conversation surface — the ONLY inputs Stage A may see (§3.1).
 * Deliberately contains no logs, code, rollouts, or PR diffs; those are Stage B's
 * domain (§3.2).
 */
export interface ConversationSurface {
    /** The mentee's framework (parametric — codex-cli, cursor, ...). */
    framework: string;
    /** The agent-to-agent conversation so far (what a user would see). */
    threadlineHistory: string;
    /** Outwardly-visible task status (e.g. "open PR #N", "said done", "waiting"). */
    assignedTaskStatus?: string;
    /** Titles of the mentee's open commitments/initiatives — titles only. */
    openCommitments?: string[];
    /** Time since last contact, ms (a user-observable signal). */
    timeSinceLastContactMs?: number;
    /**
     * The mentor's OWN onboarding backlog — an ordered list of concrete next tasks
     * to walk the mentee through (capability checks, starter dev tasks). This is the
     * mentor's plan, NOT a mentee internal: it is exactly what a real onboarding
     * mentor would have in mind, so it is surface-legitimate (included in surfaceText
     * for the leak check). When present and the mentee is idle, it lets the mentor
     * `assign-next` a concrete task instead of defaulting to a low-signal
     * `observe-only` — the active task-driving pattern that proved high-signal while
     * dogfooding Codey over Telegram (vs passive observe on an idle mentee). Empty or
     * absent → the prompt omits the agenda block and behaviour is unchanged (the
     * passive-observe default). Sourced from `mentor.onboardingAgenda` config.
     */
    onboardingAgenda?: string[];
    /**
     * Agenda items the mentor has ALREADY driven recently (matched against its own
     * recent sent prompts). Stage A judges "already covered" only from the bounded
     * `threadlineHistory` window, so once an assignment scrolls out the item looks
     * fresh again and the mentor re-drives it — making the mentee re-verify the same
     * capabilities on a loop (low-yield). This compact list survives the window so
     * Stage A can PREFER not-yet-driven items, and choose observe-only when the whole
     * agenda is recently covered (rather than mindlessly re-cycling). Surface-legitimate
     * (the mentor's own assignment history) → included in surfaceText.
     */
    recentlyDrivenAgenda?: string[];
}
export interface LeakResult {
    /** True if Stage A referenced an internal it could not have seen from the surface. */
    leaked: boolean;
    /** The specific internal references found in the transcript but absent from the surface. */
    hits: string[];
}
/** Flatten a surface into the text Stage A was legitimately given. */
export declare function surfaceText(surface: ConversationSurface): string;
/**
 * The mandatory leakage detector (§4.3). Returns the internal references that
 * appear in the Stage-A transcript but NOT in the conversation surface it was
 * given — i.e. things it could only know if forensic knowledge leaked in. A
 * reference that legitimately appeared in the surface (the user mentioned a PR#)
 * is NOT a leak.
 */
export declare function detectStageALeak(transcript: string, surface: ConversationSurface): LeakResult;
/**
 * A synthetic transcript containing a known internal reference. The canary proves
 * the detector is alive: detectStageALeak(LEAK_CANARY_TRANSCRIPT, LEAK_CANARY_SURFACE)
 * MUST report leaked=true. A periodic canary that stops firing means the detector
 * has silently rotted — surfaced as an alarm by the §19.4 job (§4.3 / §15).
 */
export declare const LEAK_CANARY_SURFACE: ConversationSurface;
export declare const LEAK_CANARY_TRANSCRIPT = "I can see your retry logic in src/messaging/Retry.ts:142 is broken \u2014 fix it before the next PR #999.";
/** Run the canary; true == detector is working. The job alarms if this is ever false. */
export declare function runLeakCanary(): boolean;
/**
 * Build the Stage-A prompt from ONLY the conversation surface. There is no
 * parameter here through which an internal could enter — the function signature
 * IS the boundary. The preamble tells the sub-agent it is the "user" and must
 * decide exactly one action; the surface is the only context it gets.
 */
export declare function buildStageAContext(surface: ConversationSurface): string;
/** A mentee reply as recorded in `mentor-replies.jsonl` (content + timestamp). */
export interface MenteeReplyLine {
    /** Epoch ms of the reply. */
    ts: number;
    /** The reply text (what a user would see in the conversation). */
    message: string;
}
/** A mentor prompt as recorded in `mentor-sent.jsonl` (content + timestamp). */
export interface MentorSentLine {
    /** Epoch ms of the prompt. */
    ts: number;
    /** The prompt text (what the mentor sent to the mentee). */
    message: string;
}
/**
 * Build the conversation surface from the mentor's own plan (agenda) + the
 * user-visible conversation (the mentor's prompts + mentee's recent replies). This is the
 * replacement for the old empty-surface stub: a blind mentor (empty surface)
 * could only ever observe-only or produce a generic check-in. Two-hats is
 * preserved — every field here is user-visible (the mentor's own prompts, the
 * mentee's own replies, and the mentor's own agenda), never a mentee internal;
 * surfaceText covers them so the leak detector treats agenda-derived tasks as legitimate.
 *
 * Pure + deterministic (caller injects `nowMs`) so it is unit-testable without
 * file IO; the server reads `mentor-sent.jsonl` / `mentor-replies.jsonl` and
 * passes the parsed lines.
 */
export declare function buildConversationSurface(input: {
    framework: string;
    onboardingAgenda?: string[];
    mentorSent?: MentorSentLine[];
    menteeReplies?: MenteeReplyLine[];
    nowMs: number;
    /** Cap the history fed to Stage A (most-recent wins). Default 8. */
    maxTurns?: number;
    /** Back-compat alias for maxTurns. */
    maxReplies?: number;
}): ConversationSurface;
/**
 * Parse `mentor-sent.jsonl` content into MentorSentLines for the surface.
 * Pure + defensive: skips blank/malformed lines, coerces `ts` (string|number),
 * drops entries without text, and — when `menteeAgent` is given — keeps only
 * prompts addressed to that mentee when `toAgent` is present. Never throws.
 */
export declare function parseMentorSent(raw: string, menteeAgent?: string): MentorSentLine[];
/**
 * Parse `mentor-replies.jsonl` content into MenteeReplyLines for the surface.
 * Pure + defensive: skips blank/malformed lines, coerces `ts` (string|number),
 * drops entries without text, and — when `menteeAgent` is given — keeps only
 * that mentee's replies (single-mentee installs have just one). Never throws.
 */
export declare function parseMenteeReplies(raw: string, menteeAgent?: string): MenteeReplyLine[];
/**
 * Convert a detected Stage-A leak into a ledger finding (§4.3): the mentor system
 * eating its own dog food — a leak is an instar-integration-gap in the mentor's
 * own two-hats enforcement. The §19.4 job hands this to ledger.captureRun.
 */
export declare function leakToFinding(framework: string, result: LeakResult, tickId?: string): ForensicFinding;
//# sourceMappingURL=MentorStageA.d.ts.map