/**
 * TopicProfileWriteSurface — the ONE platform-agnostic write engine behind all
 * Topic Profile write surfaces (TOPIC-PROFILE-SPEC §5.2, §10.1–§10.4):
 * conversational ingress, the /topic command, the rewired /route command, the
 * token-trust HTTP route, the §10.1 propose-confirm lane, and the §5.2(b)
 * recovery writes (undo / clear / re-apply).
 *
 * Regime law implemented here (the spec's hardest-won invariants):
 *
 *  - §5.2(d): FRAMEWORK-arm writes via the pre-existing `/route` surface (and
 *    equivalent conversational switches) are EXEMPT from BOTH gating knobs —
 *    always a LIVE store write, never routed to the §14 dry-run shadow — and
 *    wherever the new §8 orchestration is not fully live (`enabled:false` OR
 *    `dryRun:true`), the switch is served end-to-end by the LEGACY path,
 *    byte-for-byte today's shipped behavior (immediate kill + CONTINUATION
 *    respawn with the resume-UUID drop).
 *  - The NEW axes (model / modelTier / thinkingMode / escalationOverride) are
 *    gated: refused while disabled; shadowed (`intendedProfile`) under
 *    dryRun; live only when `enabled && !dryRun`.
 *  - §5.2(b): the recovery writes — re-apply and CLEAR — are LIVE writes in
 *    EVERY regime (never refused as new pins, never shadowed), but their
 *    APPLICATION arm is regime-governed: outside the fully-live regime there
 *    is NO profile-triggered kill — the write applies at the next natural
 *    spawn / boot-sweep reconcile, and the confirmation says so out loud.
 *  - §10.1: `updatedBy` is stamped server-side from the VERIFIED principal —
 *    operator-attributed only on the platform-authenticated surfaces; HTTP is
 *    token-trust (`updatedBy:'api-token'`), never operator-attributed, and a
 *    body-supplied updatedBy is ignored by construction (it never reaches
 *    this module). Writes refuse when the sender is not the topic's bound
 *    operator (or, for token writes, when NO bound operator exists).
 *  - §8: EVERY accepted write discloses — one line, delta-carrying, carrying
 *    the audit sequence stamp so the relay's exact-duplicate window can never
 *    silently swallow a repeat notice. The undo snapshot (`previous`) shifts
 *    once per disclosed write (no §8 coalescing window exists until the
 *    orchestrator serves the fully-live regime, so every accepted write here
 *    is individually disclosed — the spec's outside-a-window cadence).
 *
 * §8 ORCHESTRATION SEAM (TODO-wire): `deps.orchestrator` is the call site for
 * TopicProfileOrchestrator (built in parallel). When present AND the regime
 * is fully-live, profile-triggered respawns hand off to it (debounce, idle
 * re-confirm, classification, parking). Until it is wired:
 *  - framework switches are served by the legacy respawn in every regime
 *    (today's shipped behavior — the §5.2(d) contract, audited
 *    `orchestration-unavailable` when it happens in the fully-live regime);
 *  - new-axis live writes apply at the next natural spawn, told out loud.
 */
import type { TopicProfileStore } from './TopicProfileStore.js';
import type { TopicProfileResolver } from './TopicProfileResolver.js';
import { type ProfilePatchInput, type ProfileValidationError, type ValidatedProfilePatch } from './topicProfileValidation.js';
/** The two gating knobs, resolved live (§5.2/§14). */
export interface ProfileWriteRegime {
    enabled: boolean;
    dryRun: boolean;
}
/** The VERIFIED principal a write runs as (§10.1 — stamped server-side). */
export type ProfileWritePrincipal = {
    kind: 'operator';
    platform: string;
    uid: string;
} | {
    kind: 'token';
};
export type ProfileWriteOrigin = 'conversational' | 'slash-topic' | 'slash-route' | 'http' | 'propose-confirm';
/**
 * §8 interface seam for TopicProfileOrchestrator (built in parallel — see the
 * module doc). Structural-only: the write surface calls this AFTER the live
 * store write; the orchestrator owns the debounced, idle-gated respawn.
 */
export interface ProfileOrchestratorLike {
    onProfileWrite(topicKey: string, info: {
        frameworkChanged: boolean;
        origin: ProfileWriteOrigin;
    }): void | Promise<void>;
}
export interface ProfileWriteResult {
    ok: boolean;
    /** Operator-facing reply text (refusal or confirmation+disclosure). */
    reply: string;
    /** Structured refusal when ok:false. */
    refusal?: {
        reason: string;
        validation?: ProfileValidationError;
    };
    /** True when the accepted write changed nothing (no-op). */
    noop?: boolean;
    /** Fields that landed LIVE in the store. */
    appliedLive?: string[];
    /** Fields recorded to the §14 dry-run shadow. */
    shadowed?: string[];
    /** Fields refused by the disabled gate (mixed-delta split, §10.1). */
    refusedFields?: string[];
    /** A §10.4 parked pin was superseded by this write (named in the reply). */
    supersededParked?: boolean;
    /** The legacy immediate respawn fired (§5.2(d)). */
    legacyRespawned?: boolean;
}
export interface ReapplyResult extends ProfileWriteResult {
    /** §10.4 cooldown: the re-apply needs an explicit confirm first. */
    needsConfirm?: boolean;
}
export interface TopicProfileWriteSurfaceDeps {
    store: TopicProfileStore;
    resolver: TopicProfileResolver;
    /** Live gating knobs (enabled via resolveDevAgentGate; dryRun from config). */
    regime: () => ProfileWriteRegime;
    /** The topic's bound operator (§10.1) — null when none bound. */
    boundOperator: (topicKey: string) => {
        platform: string;
        uid: string;
    } | null;
    /** Active `/local-model` binding (§5.2 — refuses cloud model pins). */
    localModelBinding: (topicKey: string) => {
        provider: string;
    } | null;
    /**
     * §5.2(d) legacy respawn — today's exact `/route` behavior: drop the resume
     * UUID, kill, CONTINUATION respawn. Only invoked for framework-arm changes.
     * Returns respawned:false when the topic has no live session (write still
     * lands; takes effect at next spawn).
     */
    legacyFrameworkRespawn: (topicKey: string) => Promise<{
        respawned: boolean;
        error?: string;
    }>;
    /** §8 orchestrator seam (TODO-wire — null until the parallel build lands). */
    orchestrator?: ProfileOrchestratorLike | null;
    /**
     * §5.3 transfer-carrier cancel marker (TopicProfileTransferCarrier.
     * onLocalWriteDurable). Called immediately after a successful `await
     * store.mutate(...)` — mutate resolves only after its flush durably landed,
     * so a FlushRefusedError throw cancels nothing (the §5.3 round-8 rule).
     * Operator and token-trust HTTP writes cancel a pending transfer pull;
     * system writes never reach this surface.
     */
    onLocalWriteDurable?: (topicKey: string, origin: 'operator' | 'http') => void;
    /**
     * Post the §8 disclosure line to the topic's owning platform conversation.
     * Callers whose command REPLY is the disclosure-of-record (slash surfaces)
     * suppress this via discloseInReply instead.
     */
    disclose: (topicKey: string, text: string) => Promise<void>;
    /**
     * §10.3 audit sink. Returns the audit sequence stamp included in rendered
     * disclosures (or void — a timestamp is used instead).
     */
    audit: (event: Record<string, unknown>) => string | void;
    /** §10.4 re-apply cooldown (hardcoded v1 constant unless injected). */
    reapplyCooldownMs?: number;
    now?: () => number;
}
export declare class TopicProfileWriteSurface {
    private readonly deps;
    private readonly now;
    constructor(deps: TopicProfileWriteSurfaceDeps);
    applyWrite(req: {
        topicKey: string | number;
        patch: ProfilePatchInput;
        principal: ProfileWritePrincipal;
        origin: ProfileWriteOrigin;
        /** The caller's reply carries the disclosure-of-record (slash surfaces). */
        discloseInReply?: boolean;
        /** §10.1 propose-confirm provenance flag for the audit. */
        agentComposedPayload?: boolean;
    }): Promise<ProfileWriteResult>;
    undo(req: {
        topicKey: string | number;
        principal: ProfileWritePrincipal;
        origin: ProfileWriteOrigin;
        discloseInReply?: boolean;
    }): Promise<ProfileWriteResult>;
    /** CLEAR — a recovery write: LIVE in every regime, never shadowed. */
    clear(req: {
        topicKey: string | number;
        principal: ProfileWritePrincipal;
        origin: ProfileWriteOrigin;
        discloseInReply?: boolean;
    }): Promise<ProfileWriteResult>;
    /**
     * RE-APPLY the §10.4 parked (intended-but-unhealthy) pin — a recovery
     * write: LIVE in every regime. Carries the §10.4 cooldown guard: re-applying
     * the same profile that just tripped the breaker requires an explicit
     * confirm (the caller arms the shared confirm slot with the returned echo).
     */
    reapply(req: {
        topicKey: string | number;
        principal: ProfileWritePrincipal;
        origin: ProfileWriteOrigin;
        /** The operator already confirmed through the §10.4 cooldown echo. */
        confirmed?: boolean;
        discloseInReply?: boolean;
    }): Promise<ReapplyResult>;
    /**
     * Validate + render the SERVER-side echo for an agent-composed proposal.
     * The echo names each arm's fate under the live regime BEFORE the confirm
     * (mixed-delta split, round-12) — what the operator confirms is mechanically
     * what will be written. The caller arms the shared confirm slot with the
     * returned patch+echo and sends the echo to the topic.
     */
    renderProposalEcho(topicKey: string | number, patch: ProfilePatchInput): {
        ok: true;
        echo: string;
        patch: ValidatedProfilePatch;
    } | {
        ok: false;
        reply: string;
        validation?: ProfileValidationError;
    };
    renderReadout(topicKey: string | number): string;
    private authorize;
    private principalStamp;
    /**
     * §5.3 — notify the transfer carrier a local write durably landed (cancels
     * any pending transfer-pull REPLACE for the topic). Only ever called AFTER
     * `await store.mutate(...)` resolved; a flush-refused mutate throws first
     * and cancels nothing (the round-8 rule by construction).
     */
    private notifyLocalWriteDurable;
    private profileSnapshot;
    private renderDelta;
    private writeFailure;
}
//# sourceMappingURL=topicProfileWriteSurface.d.ts.map