/**
 * ArchivalManager — on-demand archival primitive for sub-sessions. Pattern
 * doc §12.3 (Retention and Archival).
 *
 * Convention #9 (Registry + Manager + Store): Manager-shape with explicit
 * deps for the {@link SessionStore}, {@link WorkspaceBackendRegistry}, and a
 * pluggable {@link ArchiveBackend}. Convention #5 deny-by-default: absent
 * backend → {@link ArchiveNotConfiguredError} on every `archive()` call.
 *
 * Atomic invariant (pattern doc §12.3):
 *
 *   1. Read sub-session + owning session + messages + optional summary
 *   2. backend.store(bundle) — archive durability confirmed
 *   3. Flip sub-session to `status: 'archived'` + attach archiveRef/archivedAt
 *   4. Workspace driver dispose (idempotent)
 *
 * Step 2 is the durability boundary: if the process crashes between step 2
 * and step 3, the archive exists but the live record is still non-archived
 * — recovery is to re-invoke `archive()`, which sees a non-terminal status
 * and replays. Step 3 is the single point of no return.
 *
 * A completed archive leaves the sub-session in-place with `status:
 * 'archived'` + an attached `archiveRef`. Pattern doc §12.3 calls this the
 * tombstone: `SessionStore.drill` still finds it through the normal linkage
 * path, so the archive is navigable without a parallel index.
 */
import type { SubSessionId, TenantId } from '../../types/ids/index.js';
import type { WorkspaceId } from '../../types/session/ids.js';
import type { SessionStore } from '../../types/session/store.js';
import type { WorkspaceRef } from '../../types/workspace/ref.js';
import type { WorkspaceBackendRegistry } from '../workspace/registry.js';
import type { ArchiveBackend, SubSessionTombstone } from './backend.js';
/**
 * Raised when {@link ArchivalManager.archive} or {@link ArchivalManager.restore}
 * is invoked against a project whose retention policy does not supply an
 * {@link ArchiveBackend}. Convention #5 — explicit error rather than silent
 * no-op.
 */
export declare class ArchiveNotConfiguredError extends Error {
    constructor();
}
/**
 * Raised when {@link ArchivalManager.archive} targets a sub-session that is
 * not eligible for archival. The three reasons map to pattern doc §12.3
 * (archival only applies to idle / merged / rejected / failed sub-sessions).
 */
export declare class SubSessionNotArchivableError extends Error {
    readonly details: {
        readonly subSessionId: SubSessionId;
        readonly reason: 'not_idle' | 'already_archived' | 'missing';
    };
    constructor(details: {
        subSessionId: SubSessionId;
        reason: 'not_idle' | 'already_archived' | 'missing';
    });
}
/**
 * Raised when {@link ArchivalManager.restore} is called against a
 * sub-session that is not currently archived. Distinct from
 * {@link SubSessionNotArchivableError} because the semantics are inverted:
 * restore requires an archived record, archive rejects one.
 */
export declare class SubSessionNotArchivedError extends Error {
    readonly details: {
        readonly subSessionId: SubSessionId;
        readonly reason: 'not_archived' | 'missing' | 'missing_archive_ref';
    };
    constructor(details: {
        subSessionId: SubSessionId;
        reason: 'not_archived' | 'missing' | 'missing_archive_ref';
    });
}
/**
 * Lookup callback resolving a live {@link WorkspaceRef} from the id stored
 * on a {@link SubSession}. Injected by the caller because Phase 8 does not
 * ship a dedicated workspace store — the ref typically lives in a handoff
 * assignment or is held by the agent lifecycle manager. Return `null` when
 * the ref is unknown or already disposed; the manager archives without
 * workspace data in that case (the disk backend allows it).
 */
export type WorkspaceResolver = (workspaceId: WorkspaceId, tenantId: TenantId) => Promise<WorkspaceRef | null>;
export interface ArchivalManagerDeps {
    readonly sessionStore: SessionStore;
    readonly workspaceRegistry: WorkspaceBackendRegistry;
    /**
     * Archive backend. Absent = archival disabled for this manager
     * (`archive()`/`restore()` throw {@link ArchiveNotConfiguredError}).
     */
    readonly archiveBackend?: ArchiveBackend;
    /**
     * Optional workspace resolver. When absent, `archive()` skips workspace
     * snapshotting (only the ref would be captured) and workspace disposal
     * (nothing to dispose). This is the conservative default and matches
     * pattern doc §7.1 (lazy workspace provisioning).
     */
    readonly workspaceResolver?: WorkspaceResolver;
    /**
     * Optional logger hook for `sub_session.archived` emission. Pattern doc
     * §12.3 requires the event; full event-bus wiring is a platform concern
     * (a later phase of the roadmap). Phase 8 ships the log seam so tests
     * can observe without the bus.
     */
    readonly onArchived?: (tombstone: SubSessionTombstone) => void;
    readonly onRestored?: (subSessionId: SubSessionId, tenantId: TenantId) => void;
}
export declare class ArchivalManager {
    private readonly deps;
    constructor(deps: ArchivalManagerDeps);
    /**
     * Archive an eligible sub-session. See module header for the atomic
     * invariant and recovery semantics.
     *
     * Returns the {@link SubSessionTombstone} shape — the same identity +
     * archive fields the store now carries on the live record.
     */
    archive(subSessionId: SubSessionId, tenantId: TenantId): Promise<SubSessionTombstone>;
    /**
     * Reverse of {@link archive}. Reads the tombstone, invokes
     * `backend.restore`, then flips the sub-session back to `idle`. Does NOT
     * re-materialize the workspace — the caller decides whether to
     * re-provision via a {@link WorkspaceBackendDriver}.
     *
     * The restored `ArchiveInput` bundle is NOT returned here because the
     * concrete pattern in Phase 8 is "flip status and make navigable again";
     * consumers that need the bundle itself can call the backend directly.
     */
    restore(subSessionId: SubSessionId, tenantId: TenantId): Promise<void>;
    private requireBackend;
}
//# sourceMappingURL=archive.d.ts.map