Source: authStrategies/RemoteAuth.js

'use strict';

const crypto = require('crypto');
const nodeFs = require('fs');
const os = require('os');

/* Require Optional Dependencies */
var fs = nodeFs;
try {
    fs = require('fs-extra');
} catch {
    // Native PostgreSQL mode only needs the Node.js fs implementation.
}
try {
    var unzipper = require('unzipper');
} catch {
    // Validated by the legacy RemoteAuth constructor below.
}
let archiverAvailable = false;
try {
    require.resolve('archiver');
    archiverAvailable = true;
} catch {
    // Validated by the legacy RemoteAuth constructor below.
}
let zipArchiveConstructorPromise;

const loadZipArchiveConstructor = async () => {
    zipArchiveConstructorPromise ||= import('archiver').then(
        ({ ZipArchive }) => {
            if (typeof ZipArchive !== 'function') {
                throw new Error('wwebjs_archiver_zip_export_missing');
            }
            return ZipArchive;
        },
    );
    return zipArchiveConstructorPromise;
};

const path = require('path');
const { Events } = require('./../util/Constants');
const { isBrowserConnected } = require('./../util/Puppeteer');
const {
    BrowserSessionBridge,
    compareCanonicalAppStateSyncKeys,
    normalizeCanonicalAppStateForProviderHandoff,
    normalizeCanonicalAppStateForPortablePersistence,
    normalizeCanonicalAuthoritativeAppStateForPortablePersistence,
    normalizeCanonicalAppStateForSnapshotResync,
    normalizedSnapshotResyncCollections,
    reconcileCanonicalAppStateForPersistence,
    reconcileCanonicalAppStateSyncKeysForPersistence,
} = require('./../session/BrowserSessionBridge');
const {
    CANONICAL_PQ_KEY_MODE_GENERATE_AFTER_RECONNECT,
    CANONICAL_PRIVATE_MODULE_ABI,
    assertCanonicalTargetProviderCompatibility,
    canonicalBrowserProjectionToStore,
    canonicalStoreProjectionToBrowser,
} = require('./../session/CanonicalSessionBridge');
const { SESSION_STORE_KIND } = require('./../session/PostgresSessionStore');
const {
    WhatsAppSessionCompatibilityError,
} = require('./../session/SessionErrors');
const BaseAuthStrategy = require('./BaseAuthStrategy');

const CANONICAL_WEBSOCKET_GATE_PATH = path.join(
    __dirname,
    '..',
    'session',
    'canonical-websocket-gate',
);
const CANONICAL_WEBSOCKET_GATE_RULESET = 'canonical_websocket_gate';
const PROFILE_CHANGED_DURING_CHECKPOINT =
    'whatsapp_artifact_profile_changed_during_checkpoint';
const CANONICAL_OFFLINE_CHECKPOINT_TRANSIENT_BLOCKERS = new Set([
    'app_state_sync_keys.read_failed',
    'app_state_versions.read_failed',
    'app_state_versions.row_incompatible',
    'app_state_mutation_macs.read_failed',
]);

const comparableJid = (jid) => {
    const normalized = String(jid || '')
        .trim()
        .toLowerCase();
    if (!normalized) return '';
    const separator = normalized.lastIndexOf('@');
    const rawUser =
        separator === -1 ? normalized : normalized.slice(0, separator);
    const rawServer =
        separator === -1 ? 's.whatsapp.net' : normalized.slice(separator + 1);
    const server = rawServer === 'c.us' ? 's.whatsapp.net' : rawServer;
    return `${rawUser.split(':')[0]}@${server}`;
};

const canonicalDeviceJid = (jid) => {
    const normalized = String(jid || '')
        .trim()
        .toLowerCase();
    const separator = normalized.lastIndexOf('@');
    if (separator <= 0 || separator === normalized.length - 1) return '';
    const local = normalized.slice(0, separator);
    const rawServer = normalized.slice(separator + 1);
    const server = rawServer === 'c.us' ? 's.whatsapp.net' : rawServer;
    return `${local}@${server}`;
};

const canonicalDeviceJidHash = (jid) => {
    const canonical = canonicalDeviceJid(jid);
    return canonical
        ? crypto.createHash('sha256').update(canonical).digest('hex')
        : null;
};

const hasNonzeroDeviceId = (jid) => {
    const canonical = canonicalDeviceJid(jid);
    const separator = canonical.lastIndexOf('@');
    const match = /:([0-9]+)$/u.exec(canonical.slice(0, separator));
    return Boolean(match && Number(match[1]) > 0);
};

const safeFailureCode = (value, fallback) =>
    typeof value === 'string' && /^[a-z0-9_.-]{1,100}$/iu.test(value)
        ? value
        : fallback;

const stableNativeFailureCode = (error, fallback) => {
    const explicit = safeFailureCode(error?.code, '');
    if (explicit) return explicit;
    const message = String(error?.message || '');
    return /^wwebjs_[a-z0-9_]{1,93}$/u.test(message) ? message : fallback;
};

const CONNECTED_PROFILE_NAVIGATION_SUPERSEDED =
    'wwebjs_connected_profile_navigation_superseded';
const TRANSIENT_NAVIGATION_ERROR_CODES = new Set([
    CONNECTED_PROFILE_NAVIGATION_SUPERSEDED,
    'wwebjs_legacy_volume_navigation_superseded',
]);
const isTransientNavigationError = (error) =>
    TRANSIENT_NAVIGATION_ERROR_CODES.has(error?.code) ||
    /Execution context was destroyed|Execution context is not available in detached frame|Cannot find context with specified id|Attempted to use detached Frame|Navigating frame was detached|frame was detached|net::ERR_ABORTED/iu.test(
        String(error?.message || error),
    );

const LEGACY_VOLUME_NAVIGATION_SETTLE_TIMEOUT_MS = 1000;
const LEGACY_VOLUME_NAVIGATION_SETTLE_POLL_MS = 20;
const LEGACY_VOLUME_RUNTIME_CAPABILITY_WAIT_MS = 15000;
const LEGACY_VOLUME_IDENTITY_READ_MAX_ATTEMPTS = 20;
const LEGACY_VOLUME_IDENTITY_READ_RETRY_MS = 250;
const isTransientCompanionIdentityReadError = (error) => {
    const code = String(error?.code || error?.message || '');
    return (
        code === 'wwebjs_companion_identity_read_failed' ||
        /^Invariant Violation: Minified invariant #[0-9]+(?:;.*)?$/iu.test(code)
    );
};

const safeAggregateErrorDetails = (error) => {
    const candidates = [
        error?.details,
        error?.cause?.details,
        ...(Array.isArray(error?.errors)
            ? error.errors.map((entry) => entry?.details)
            : []),
    ];
    const aggregate = {};
    for (const details of candidates) {
        if (!details || typeof details !== 'object' || Array.isArray(details)) {
            continue;
        }
        for (const [key, value] of Object.entries(details)) {
            if (
                (key === 'status' || key === 'reason') &&
                typeof value === 'string' &&
                /^[a-z0-9_.-]{1,100}$/iu.test(value)
            ) {
                aggregate[key] ??= value;
                continue;
            }
            if (
                /_count$/u.test(key) &&
                Number.isSafeInteger(value) &&
                value >= 0
            ) {
                aggregate[key] ??= value;
            }
        }
    }
    return aggregate;
};

const CANONICAL_APP_STATE_TABLES = [
    'whatsapp_app_state_sync_keys',
    'whatsapp_app_state_version',
    'whatsapp_app_state_mutation_macs',
];
const CANONICAL_APP_STATE_COLLECTIONS = Object.freeze([
    'critical_block',
    'critical_unblock_low',
    'regular',
    'regular_high',
    'regular_low',
]);

const canonicalBytesEqual = (left, right) => {
    const leftBytes = Buffer.from(left || []);
    const rightBytes = Buffer.from(right || []);
    return leftBytes.equals(rightBytes);
};

const CANONICAL_PROJECTION_TABLE_PRIMARY_KEYS = Object.freeze({
    whatsapp_identity_keys: Object.freeze(['their_id']),
    whatsapp_pre_keys: Object.freeze(['key_id']),
    whatsapp_pq_pre_keys: Object.freeze(['key_id']),
    whatsapp_pq_pre_key_state: Object.freeze([]),
    whatsapp_signal_sessions: Object.freeze(['their_id', 'scope']),
    whatsapp_sender_keys: Object.freeze(['chat_id', 'sender_id']),
    whatsapp_app_state_sync_keys: Object.freeze(['key_id']),
    whatsapp_app_state_version: Object.freeze(['name']),
    whatsapp_app_state_mutation_macs: Object.freeze([
        'name',
        'index_mac',
        'version',
    ]),
    whatsapp_contacts: Object.freeze(['their_jid']),
    whatsapp_chat_settings: Object.freeze(['chat_jid']),
    whatsapp_message_secrets: Object.freeze([
        'chat_jid',
        'sender_jid',
        'message_id',
    ]),
    whatsapp_privacy_tokens: Object.freeze(['their_jid']),
    whatsapp_nct_salt: Object.freeze([]),
    whatsapp_lid_map: Object.freeze(['lid']),
    whatsapp_event_buffer: Object.freeze(['ciphertext_hash']),
    whatsapp_retry_buffer: Object.freeze(['chat_jid', 'message_id']),
});

const canonicalDigestByteView = (value) => {
    if (Buffer.isBuffer(value)) return value;
    if (value instanceof ArrayBuffer) return Buffer.from(value);
    if (ArrayBuffer.isView(value)) {
        return Buffer.from(value.buffer, value.byteOffset, value.byteLength);
    }
    return undefined;
};

const createCanonicalDigestWriter = (hash) => {
    const lengthBytes = Buffer.allocUnsafe(8);
    const numberBytes = Buffer.allocUnsafe(8);
    const writeLength = (length) => {
        lengthBytes.writeBigUInt64BE(BigInt(length));
        hash.update(lengthBytes);
    };
    const writeTag = (tag) => hash.update(tag, 'ascii');
    const writeStringPayload = (value) => {
        writeLength(Buffer.byteLength(value, 'utf8'));
        hash.update(value, 'utf8');
    };
    const writeBytesPayload = (value) => {
        writeLength(value.byteLength);
        hash.update(value);
    };

    const writeValue = (value, context) => {
        const byteView = canonicalDigestByteView(value);
        if (byteView) {
            writeTag('y');
            writeBytesPayload(byteView);
            return;
        }
        if (value === null) {
            writeTag('n');
            return;
        }
        if (value === undefined) {
            writeTag('u');
            return;
        }
        if (typeof value === 'boolean') {
            writeTag(value ? 't' : 'f');
            return;
        }
        if (typeof value === 'number') {
            writeTag('d');
            numberBytes.writeDoubleBE(value);
            hash.update(numberBytes);
            return;
        }
        if (typeof value === 'bigint') {
            writeTag('i');
            writeStringPayload(value.toString());
            return;
        }
        if (typeof value === 'string') {
            writeTag('s');
            writeStringPayload(value);
            return;
        }
        if (value instanceof Date) {
            writeTag('z');
            writeStringPayload(value.toISOString());
            return;
        }
        if (Array.isArray(value)) {
            writeTag('a');
            writeLength(value.length);
            for (const item of value) writeValue(item);
            return;
        }
        if (typeof value !== 'object') {
            throw new TypeError('wwebjs_canonical_projection_digest_invalid');
        }

        const keys = Object.keys(value)
            .filter((key) => value[key] !== undefined)
            .sort();
        writeTag('o');
        writeLength(keys.length);
        for (const key of keys) {
            writeStringPayload(key);
            if (context === 'tables') {
                if (
                    !Object.hasOwn(
                        CANONICAL_PROJECTION_TABLE_PRIMARY_KEYS,
                        key,
                    ) ||
                    !Array.isArray(value[key])
                ) {
                    throw new TypeError(
                        'wwebjs_canonical_projection_digest_table_invalid',
                    );
                }
                writeCanonicalTableRows(hash, key, value[key]);
                continue;
            }
            writeValue(
                value[key],
                context === 'projection' &&
                    (key === 'tables' || key === 'passthrough_tables')
                    ? 'tables'
                    : undefined,
            );
        }
    };

    return writeValue;
};

const canonicalDigestValue = (value) => {
    const hash = crypto.createHash('sha256');
    createCanonicalDigestWriter(hash)(value);
    return hash.digest();
};

const writeCanonicalTableRows = (hash, table, rows) => {
    const primaryKey = CANONICAL_PROJECTION_TABLE_PRIMARY_KEYS[table];
    const orderedRows = rows
        .map((row) => ({
            row,
            primaryKeyDigest: canonicalDigestValue(
                primaryKey.map((column) => row?.[column]),
            ),
            // Invalid duplicate PKs must still compare independently of their
            // physical enumeration order. Normalization rejects them later;
            // this tie-breaker only keeps the snapshot check deterministic.
            rowDigest: canonicalDigestValue(row),
        }))
        .sort(
            (left, right) =>
                Buffer.compare(left.primaryKeyDigest, right.primaryKeyDigest) ||
                Buffer.compare(left.rowDigest, right.rowDigest),
        );
    const writeValue = createCanonicalDigestWriter(hash);
    hash.update('a', 'ascii');
    const lengthBytes = Buffer.allocUnsafe(8);
    lengthBytes.writeBigUInt64BE(BigInt(orderedRows.length));
    hash.update(lengthBytes);
    for (const { row } of orderedRows) writeValue(row);
};

const canonicalProjectionSnapshotDigest = (projection) => {
    const hash = crypto.createHash('sha256');
    createCanonicalDigestWriter(hash)(projection, 'projection');
    return hash.digest();
};

const canonicalProjectionSnapshotsEqual = (left, right) =>
    crypto.timingSafeEqual(
        canonicalProjectionSnapshotDigest(left),
        canonicalProjectionSnapshotDigest(right),
    );

const profileProjectionChangedError = (before, after) => {
    const syncKeyComparison = compareCanonicalAppStateSyncKeys(before, after);
    const safeSyncKeyDetails = Object.fromEntries(
        Object.entries(syncKeyComparison).filter(([key, value]) => {
            return (
                key !== 'status' &&
                key !== 'reason' &&
                (typeof value === 'number' || typeof value === 'boolean')
            );
        }),
    );
    const error = new Error(PROFILE_CHANGED_DURING_CHECKPOINT);
    error.code = PROFILE_CHANGED_DURING_CHECKPOINT;
    error.details = {
        phase: 'canonical_projection_changed',
        app_state_tables_changed: !canonicalAppStateTablesEqual(before, after),
        ...safeSyncKeyDetails,
    };
    return error;
};

const canonicalAppStateTablesEqual = (left, right) => {
    const leftSyncKeys = left?.tables?.whatsapp_app_state_sync_keys;
    const rightSyncKeys = right?.tables?.whatsapp_app_state_sync_keys;
    const leftVersions = left?.tables?.whatsapp_app_state_version;
    const rightVersions = right?.tables?.whatsapp_app_state_version;
    const leftMacs = left?.tables?.whatsapp_app_state_mutation_macs;
    const rightMacs = right?.tables?.whatsapp_app_state_mutation_macs;
    if (
        !Array.isArray(leftSyncKeys) ||
        !Array.isArray(rightSyncKeys) ||
        !Array.isArray(leftVersions) ||
        !Array.isArray(rightVersions) ||
        !Array.isArray(leftMacs) ||
        !Array.isArray(rightMacs) ||
        leftSyncKeys.length !== rightSyncKeys.length ||
        leftVersions.length !== rightVersions.length ||
        leftMacs.length !== rightMacs.length
    ) {
        return false;
    }
    const syncKeyById = new Map(
        leftSyncKeys.map((row) => [
            Buffer.from(row.key_id || []).toString('base64'),
            row,
        ]),
    );
    for (const row of rightSyncKeys) {
        const previous = syncKeyById.get(
            Buffer.from(row.key_id || []).toString('base64'),
        );
        if (
            !previous ||
            previous.timestamp !== row.timestamp ||
            !canonicalBytesEqual(previous.key_data, row.key_data) ||
            !canonicalBytesEqual(previous.fingerprint, row.fingerprint)
        ) {
            return false;
        }
    }
    const versionByName = new Map(leftVersions.map((row) => [row.name, row]));
    for (const row of rightVersions) {
        const previous = versionByName.get(row.name);
        if (
            !previous ||
            previous.version !== row.version ||
            !canonicalBytesEqual(previous.hash, row.hash)
        ) {
            return false;
        }
    }
    const macByKey = new Map(
        leftMacs.map((row) => [
            `${row.name}\u0000${row.version}\u0000${Buffer.from(
                row.index_mac || [],
            ).toString('base64')}`,
            row,
        ]),
    );
    for (const row of rightMacs) {
        const key = `${row.name}\u0000${row.version}\u0000${Buffer.from(
            row.index_mac || [],
        ).toString('base64')}`;
        const previous = macByKey.get(key);
        if (
            !previous ||
            !canonicalBytesEqual(previous.value_mac, row.value_mac)
        ) {
            return false;
        }
    }
    return true;
};

const expandCanonicalAppStateDirtyPlan = (
    dirtyPlan,
    { baseline, browserProjection, persistenceProjection },
) => {
    if (!dirtyPlan || dirtyPlan.fullReplace) return dirtyPlan;
    const normalizationChangedAppState = !canonicalAppStateTablesEqual(
        browserProjection,
        persistenceProjection,
    );
    const persistedAppStateChanged = !canonicalAppStateTablesEqual(
        baseline,
        persistenceProjection,
    );
    if (!normalizationChangedAppState && !persistedAppStateChanged) {
        return dirtyPlan;
    }
    if (normalizationChangedAppState) {
        return {
            ...dirtyPlan,
            fullReplace: true,
            device: true,
            tables: [],
        };
    }
    return {
        ...dirtyPlan,
        tables: [
            ...new Set([...dirtyPlan.tables, ...CANONICAL_APP_STATE_TABLES]),
        ],
    };
};

/**
 * Remote-based authentication
 * @param {object} options - options
 * @param {object} options.store - Remote database store instance
 * @param {string} options.clientId - Client id to distinguish instances if you are using multiple, otherwise keep null if you are using only one instance
 * @param {string} options.dataPath - Change the default path for saving session files, default is: "./.wwebjs_auth/"
 * @param {number} options.backupSyncIntervalMs - Sets the time interval for periodic session backups. Accepts values starting from 60000ms {1 minute}
 * @param {number} options.initialSyncDelayMs - Delay before the first checkpoint for a newly paired session
 * @param {function} options.identityResolver - Trusted resolver for the companion fingerprint; required for verified native PostgreSQL mode
 * @param {boolean} options.requireFingerprintVerification - Fail readiness unless the trusted fingerprint matches. Defaults to true in production.
 * @param {boolean} options.allowNoiseMetadataBootstrap - Allow the official WWeb noise metadata regeneration path when importing a native-provider candidate.
 * @param {number} options.canonicalFlushDebounceMs - Debounce for critical canonical-only flushes. Defaults to 1000ms.
 * @param {number} options.canonicalAppStateCatchUpTimeoutMs - Maximum handoff app-state catch-up time. Defaults to 120000ms.
 * @param {number} options.canonicalAppStatePollIntervalMs - App-state watermark polling interval. Defaults to 2000ms.
 * @param {number} options.rmMaxRetries - Sets the maximum number of retries for removing the session directory
 */
class RemoteAuth extends BaseAuthStrategy {
    constructor({
        clientId,
        dataPath,
        store,
        backupSyncIntervalMs,
        initialSyncDelayMs = 60000,
        identityResolver,
        requireFingerprintVerification = process.env.NODE_ENV === 'production',
        allowNoiseMetadataBootstrap = false,
        canonicalFlushDebounceMs = 1000,
        canonicalAppStateCatchUpTimeoutMs = 120000,
        canonicalAppStatePollIntervalMs = 2000,
        rmMaxRetries,
    } = {}) {
        const nativePostgres = store?.kind === SESSION_STORE_KIND;
        if (
            !nativePostgres &&
            (!fs.emptyDir || !unzipper || !archiverAvailable)
        )
            throw new Error(
                'Optional Dependencies [fs-extra, unzipper, archiver] are required to use RemoteAuth. Make sure to run npm install correctly and remove the --no-optional flag',
            );
        super();

        const idRegex = /^[-_\w]+$/i;
        if (clientId && !idRegex.test(clientId)) {
            throw new Error(
                'Invalid clientId. Only alphanumeric characters, underscores and hyphens are allowed.',
            );
        }
        if (!backupSyncIntervalMs || backupSyncIntervalMs < 60000) {
            throw new Error(
                'Invalid backupSyncIntervalMs. Accepts values starting from 60000ms {1 minute}.',
            );
        }
        if (!Number.isFinite(initialSyncDelayMs) || initialSyncDelayMs < 0) {
            throw new Error('Invalid initialSyncDelayMs.');
        }
        if (
            !Number.isFinite(canonicalFlushDebounceMs) ||
            canonicalFlushDebounceMs < 100 ||
            canonicalFlushDebounceMs > 30000
        ) {
            throw new Error('Invalid canonicalFlushDebounceMs.');
        }
        if (
            !Number.isSafeInteger(canonicalAppStateCatchUpTimeoutMs) ||
            canonicalAppStateCatchUpTimeoutMs < 1000 ||
            canonicalAppStateCatchUpTimeoutMs > 600000
        ) {
            throw new Error('Invalid canonicalAppStateCatchUpTimeoutMs.');
        }
        if (
            !Number.isSafeInteger(canonicalAppStatePollIntervalMs) ||
            canonicalAppStatePollIntervalMs < 100 ||
            canonicalAppStatePollIntervalMs > 10000 ||
            canonicalAppStatePollIntervalMs > canonicalAppStateCatchUpTimeoutMs
        ) {
            throw new Error('Invalid canonicalAppStatePollIntervalMs.');
        }
        if (!store) throw new Error('Remote database store is required.');
        if (
            identityResolver !== undefined &&
            typeof identityResolver !== 'function'
        ) {
            throw new Error('wwebjs_companion_identity_resolver_invalid');
        }
        if (
            nativePostgres &&
            requireFingerprintVerification &&
            typeof identityResolver !== 'function'
        ) {
            throw new Error('wwebjs_companion_identity_resolver_required');
        }

        this.store = store;
        this.nativePostgres = nativePostgres;
        this.clientId = clientId;
        this.backupSyncIntervalMs = backupSyncIntervalMs;
        this.initialSyncDelayMs = initialSyncDelayMs;
        this.identityResolver = identityResolver;
        this.requireFingerprintVerification = requireFingerprintVerification;
        this.allowNoiseMetadataBootstrap = allowNoiseMetadataBootstrap === true;
        this.canonicalFlushDebounceMs = canonicalFlushDebounceMs;
        this.canonicalAppStateCatchUpTimeoutMs =
            canonicalAppStateCatchUpTimeoutMs;
        this.canonicalAppStatePollIntervalMs = canonicalAppStatePollIntervalMs;
        this.providerHandoffCheckpointDrainTimeoutMs = Math.min(
            90000,
            Math.max(30000, canonicalAppStateCatchUpTimeoutMs),
        );
        this.dataPath = path.resolve(dataPath || './.wwebjs_auth/');
        try {
            fs.accessSync(process.cwd(), fs.constants.W_OK);
            this.zipDir = process.cwd();
        } catch {
            this.zipDir = this.dataPath;
        }
        this.tempDir = `${this.dataPath}/wwebjs_temp_session_${this.clientId}`;
        this.requiredDirs = [
            'Default',
            'IndexedDB',
            'Local Storage',
        ]; /* => Required Files & Dirs in WWebJS to restore session */
        this.rmMaxRetries = rmMaxRetries ?? 4;
        this.authReady = false;
        this.nativeInitialPairingReadyRuntimeEpoch = undefined;
        this.nativeReadyCheckpointRuntimeEpoch = undefined;
        this.shutdownRequested = false;
        this.shutdownPromise = undefined;
        this.shutdownProjectionCaptureFailed = false;
        this.checkpointTail = Promise.resolve();
        this.periodicCheckpoint = undefined;
        this.profileDirty = true;
        this.criticalCheckpointTimer = undefined;
        this.canonicalActivationCheckpointInProgress = false;
        this.canonicalActivationCheckpointGeneration = 0;
        this.projectionHydrated = false;
        this.providerHandoffKey = undefined;
        this.providerHandoffPromise = undefined;
        this.providerHandoffCheckpointAdmissionClosed = false;
        this.preparedProviderHandoff = undefined;
        this.effectiveAllowNoiseMetadataBootstrap = false;
        this.pendingPostQuantumBootstrap = false;
        this.pendingPostQuantumRollbackRecovery = undefined;
        this.pendingCanonicalAppStateCatchUp = false;
        this.preserveExistingProfileArtifactDuringCanonicalCatchUp = false;
        this.pendingCanonicalAppStateSyncKeyCount = 0;
        this.pendingCanonicalAppStateProjection = undefined;
        this.canonicalActivationReadyProjection = undefined;
        this.canonicalActivationUsesPromotedProfileArtifact = false;
        this.lastCanonicalProjection = undefined;
        this.lastPersistedCanonicalProjection = undefined;
        this.initialPairingAuthorized = false;
        this.handoffSourceCanonicalProjection = undefined;
        this.canonicalReconnectProjection = undefined;
        this.canonicalReconnectExpectedRegistrationState = undefined;
        this.canonicalSealedReloadRegistrationSummary = undefined;
        this.canonicalActivationResumeProjection = undefined;
        this.canonicalActiveRestartReplay = false;
        this.canonicalActiveRestartAppStateOverlayRequired = false;
        this.canonicalActiveRestartCanonicalGeneration = undefined;
        this.canonicalActiveRestartAttestedProjection = undefined;
        this.canonicalReusableHandoffNativeAppState = false;
        this.canonicalNativeAppStateAuthoritative = false;
        this.canonicalDeferredOnlineRegisteredLaunch = false;
        this.canonicalCandidatePromoted = false;
        this.canonicalActivationMarkerPresent = false;
        this.canonicalWebSocketGateRequired = false;
        this.canonicalWebSocketGateExtensionId = undefined;
        this.canonicalWebSocketGateServiceWorker = undefined;
        this.canonicalWebSocketGateStagingDir = undefined;
        this.canonicalWebSocketGateMonitor = undefined;
        this.canonicalWebSocketGateViolation = false;
        this.nativeFailurePostBrowserCleanupPromise = undefined;
        this.nativeFailureStopPromise = undefined;
        this.nativeFailureFinalizationPromise = undefined;
        this.nativeFailureBrowserTerminationConfirmed = false;
        this.nativeFailureRecoveryProjection = undefined;
    }

    validateClientOptions(options) {
        if (!this.nativePostgres) return;
        if (this.store.webVersionIntegrityPinned) {
            if (options.webVersion !== this.store.webVersion) {
                throw new Error('wwebjs_web_version_incompatible');
            }
            if (
                options.webVersionCache?.type === 'none' ||
                options.webVersionCache?.strict !== true
            ) {
                throw new Error('wwebjs_strict_web_cache_required');
            }
            return;
        }
        // An unpinned PostgreSQL session always follows the document served by
        // WhatsApp. Do not let Client's bundled-cache default silently turn
        // that mode back into a fixed build. The bridge binds the actual
        // window.Debug.VERSION after its private-module ABI preflight.
        options.webVersionCache = { type: 'none' };
    }

    /**
     * Keep the live/latest store binding aligned with the document that
     * produced the trusted companion identity. A controlled native-stall
     * recovery may reload WhatsApp Web after the earlier ABI preflight and
     * the live endpoint can legitimately serve a newer (or adjacent rollout)
     * build. getCompanionIdentity() attests the module ABI, web version and
     * companion fingerprint from that same document, so an unpinned store may
     * safely rebind here. Integrity-pinned stores remain strictly fail-closed.
     */
    reconcileResolvedIdentityWebVersion(resolvedIdentity) {
        if (!this.requireFingerprintVerification) return;
        const actualVersion = resolvedIdentity?.webVersion;
        const expectedVersion = this.store.webVersion;
        if (actualVersion === expectedVersion) return;

        if (this.store.webVersionIntegrityPinned === true) {
            const error = new Error(
                'wwebjs_companion_identity_web_version_mismatch',
            );
            error.expected = expectedVersion;
            error.actual = actualVersion;
            throw error;
        }
        if (typeof this.store.bindRuntimeWebVersion !== 'function') {
            throw new Error('wwebjs_runtime_web_version_binding_unavailable');
        }

        this.store.bindRuntimeWebVersion(
            actualVersion,
            resolvedIdentity?.moduleAbi,
        );
        if (this.store.webVersion !== actualVersion) {
            throw new Error('wwebjs_runtime_web_version_binding_failed');
        }
        this.logNative(
            'runtime.identity_web_version_rebound',
            {
                previous_web_version: expectedVersion,
                web_version: actualVersion,
                module_abi: resolvedIdentity?.moduleAbi,
                integrity_pinned: false,
                reason: 'trusted_identity_after_controlled_navigation',
            },
            { force: true },
        );
    }

    /**
     * A cross-provider candidate must load WhatsApp's runtime before its
     * canonical credentials can be written. A dedicated MV3 extension blocks
     * every WebSocket at Chromium's request boundary during that first load,
     * so the empty bootstrap profile cannot request a pairing ref or race the
     * source companion. The extension is removed only while the page is
     * offline, after the imported tuple passed its readback gate.
     */
    async installCanonicalWebSocketGate() {
        if (!this.canonicalWebSocketGateRequired) return false;
        const browser = this.client?.pupBrowser;
        const page = this.client?.pupPage;
        if (
            !browser?.process?.() ||
            typeof browser.installExtension !== 'function' ||
            typeof browser.uninstallExtension !== 'function' ||
            typeof page?.createCDPSession !== 'function'
        ) {
            throw new Error(
                'wwebjs_canonical_websocket_gate_runtime_unavailable',
            );
        }
        const stagingDir = await nodeFs.promises.mkdtemp(
            path.join(os.tmpdir(), 'wwebjs-canonical-ws-gate-'),
        );
        await nodeFs.promises.chmod(stagingDir, 0o700);
        this.canonicalWebSocketGateStagingDir = stagingDir;
        try {
            for (const filename of [
                'manifest.json',
                'background.js',
                'rules.json',
            ]) {
                const source = path.join(
                    CANONICAL_WEBSOCKET_GATE_PATH,
                    filename,
                );
                nodeFs.accessSync(source, nodeFs.constants.R_OK);
                const target = path.join(stagingDir, filename);
                await nodeFs.promises.copyFile(source, target);
                await nodeFs.promises.chmod(target, 0o600);
            }
        } catch (error) {
            await this.removeCanonicalWebSocketGateStagingDir();
            throw error;
        }
        const monitor = await page.createCDPSession();
        await monitor.send('Network.enable');
        const state = { created: 0, handshakes: 0 };
        const onCreated = () => {
            state.created += 1;
        };
        const onHandshake = () => {
            state.handshakes += 1;
            this.canonicalWebSocketGateViolation = true;
            void page.setOfflineMode(true).catch(() => {});
        };
        monitor.on('Network.webSocketCreated', onCreated);
        monitor.on('Network.webSocketWillSendHandshakeRequest', onHandshake);
        monitor.on('Network.webSocketHandshakeResponseReceived', onHandshake);
        this.canonicalWebSocketGateMonitor = {
            session: monitor,
            state,
            onCreated,
            onHandshake,
        };
        let extensionId;
        try {
            extensionId = await browser.installExtension(stagingDir);
        } catch (error) {
            await this.disposeCanonicalWebSocketGateMonitor();
            await this.removeCanonicalWebSocketGateStagingDir();
            throw error;
        }
        if (
            typeof extensionId !== 'string' ||
            !/^[a-p]{32}$/u.test(extensionId)
        ) {
            await this.disposeCanonicalWebSocketGateMonitor();
            await this.removeCanonicalWebSocketGateStagingDir();
            throw new Error('wwebjs_canonical_websocket_gate_install_invalid');
        }
        let serviceWorker;
        try {
            const serviceWorkerTarget = await browser.waitForTarget(
                (target) =>
                    target.type() === 'service_worker' &&
                    target.url() ===
                        `chrome-extension://${extensionId}/background.js`,
                { timeout: 5000 },
            );
            serviceWorker = await serviceWorkerTarget.worker();
            const enabledRulesets = await serviceWorker?.evaluate(() =>
                globalThis.chrome.declarativeNetRequest.getEnabledRulesets(),
            );
            if (
                !Array.isArray(enabledRulesets) ||
                enabledRulesets.length !== 1 ||
                enabledRulesets[0] !== CANONICAL_WEBSOCKET_GATE_RULESET
            ) {
                throw new Error(
                    'wwebjs_canonical_websocket_gate_ruleset_not_ready',
                );
            }
        } catch (error) {
            await browser.uninstallExtension(extensionId).catch(() => {});
            await this.disposeCanonicalWebSocketGateMonitor();
            await this.removeCanonicalWebSocketGateStagingDir();
            throw error;
        }
        this.canonicalWebSocketGateExtensionId = extensionId;
        this.canonicalWebSocketGateServiceWorker = serviceWorker;
        this.logNative(
            'handoff.initial_websocket_gate_installed',
            { dedicated_browser: true },
            { force: true },
        );
        return true;
    }

    assertCanonicalWebSocketGateHeld() {
        if (!this.canonicalWebSocketGateRequired) return;
        if (
            !this.canonicalWebSocketGateExtensionId ||
            !this.canonicalWebSocketGateMonitor ||
            this.canonicalWebSocketGateViolation
        ) {
            const error = new Error(
                'wwebjs_canonical_initial_websocket_gate_violated',
            );
            error.code = error.message;
            throw error;
        }
    }

    async disposeCanonicalWebSocketGateMonitor() {
        const monitor = this.canonicalWebSocketGateMonitor;
        this.canonicalWebSocketGateMonitor = undefined;
        if (!monitor) return;
        monitor.session.off?.('Network.webSocketCreated', monitor.onCreated);
        monitor.session.off?.(
            'Network.webSocketWillSendHandshakeRequest',
            monitor.onHandshake,
        );
        monitor.session.off?.(
            'Network.webSocketHandshakeResponseReceived',
            monitor.onHandshake,
        );
        await monitor.session.detach?.().catch(() => {});
    }

    async removeCanonicalWebSocketGateStagingDir() {
        const stagingDir = this.canonicalWebSocketGateStagingDir;
        this.canonicalWebSocketGateStagingDir = undefined;
        if (!stagingDir) return;
        const expectedParent = path.resolve(os.tmpdir());
        const resolved = path.resolve(stagingDir);
        if (
            path.dirname(resolved) !== expectedParent ||
            !path.basename(resolved).startsWith('wwebjs-canonical-ws-gate-')
        ) {
            throw new Error(
                'wwebjs_canonical_websocket_gate_cleanup_path_invalid',
            );
        }
        await nodeFs.promises.rm(resolved, {
            recursive: true,
            force: true,
            maxRetries: this.rmMaxRetries,
        });
    }

    async releaseCanonicalWebSocketGateOffline() {
        if (!this.canonicalWebSocketGateRequired) return false;
        if (
            !this.canonicalCandidatePromoted ||
            this.store.revisionStatus !== 'active'
        ) {
            throw new Error(
                'wwebjs_canonical_websocket_gate_release_before_promotion',
            );
        }
        this.assertCanonicalWebSocketGateHeld();
        this.browserBridge?.assertNoCanonicalCredentialViolation?.();
        // A temporary CDP lifecycle session used by the profile snapshot can
        // restore Chromium's physical online signal when it detaches. The MV3
        // request gate is still held here, so reassert the target-wide
        // Puppeteer override and prove the page is offline before removing
        // that final request-boundary protection.
        await this.client.pupPage.setOfflineMode(true);
        this.assertCanonicalWebSocketGateHeld();
        this.browserBridge?.assertNoCanonicalCredentialViolation?.();
        const pageOffline =
            (await this.client.pupPage.evaluate(
                () => navigator.onLine === false,
            )) === true;
        if (!pageOffline) {
            throw new Error(
                'wwebjs_canonical_websocket_gate_release_requires_offline',
            );
        }
        const serviceWorker = this.canonicalWebSocketGateServiceWorker;
        if (typeof serviceWorker?.evaluate !== 'function') {
            throw new Error(
                'wwebjs_canonical_websocket_gate_worker_unavailable',
            );
        }
        const blockedSocketAttempts =
            this.canonicalWebSocketGateMonitor?.state?.created || 0;
        const enabledRulesets = await serviceWorker.evaluate(
            async (rulesetId) => {
                await globalThis.chrome.declarativeNetRequest.updateEnabledRulesets(
                    { disableRulesetIds: [rulesetId] },
                );
                return globalThis.chrome.declarativeNetRequest.getEnabledRulesets();
            },
            CANONICAL_WEBSOCKET_GATE_RULESET,
        );
        if (
            !Array.isArray(enabledRulesets) ||
            enabledRulesets.includes(CANONICAL_WEBSOCKET_GATE_RULESET)
        ) {
            throw new Error(
                'wwebjs_canonical_websocket_gate_disable_not_acknowledged',
            );
        }
        // Extensions.uninstall can wait indefinitely for Chromium's MV3
        // service-worker teardown while the browser is running. Disabling the
        // only static ruleset is the request-boundary release itself and is
        // acknowledged above. Keep the now-inert extension directory until
        // Chromium has stopped so cleanup cannot race a live extension.
        await this.client.pupPage.setOfflineMode(true);
        const remainedOffline =
            (await this.client.pupPage.evaluate(
                () => navigator.onLine === false,
            )) === true;
        if (!remainedOffline || this.canonicalWebSocketGateViolation) {
            throw new Error(
                'wwebjs_canonical_websocket_gate_release_not_quiesced',
            );
        }
        this.browserBridge?.assertNoCanonicalCredentialViolation?.();
        this.canonicalWebSocketGateExtensionId = undefined;
        this.canonicalWebSocketGateServiceWorker = undefined;
        await this.disposeCanonicalWebSocketGateMonitor();
        this.logNative(
            'handoff.initial_websocket_gate_released',
            {
                offline: true,
                blocked_socket_attempts: blockedSocketAttempts,
            },
            { force: true },
        );
        return true;
    }

    async beforeBrowserInitialized() {
        this.shutdownRequested = false;
        this.shutdownPromise = undefined;
        this.shutdownProjectionCaptureFailed = false;
        this.nativeFailureStopPromise = undefined;
        this.nativeFailureFinalizationPromise = undefined;
        this.nativeFailurePostBrowserCleanupPromise = undefined;
        this.nativeFailureBrowserTerminationConfirmed = false;
        this.nativeFailureRecoveryProjection = undefined;
        this.nativeInitialPairingReadyRuntimeEpoch = undefined;
        this.nativeReadyCheckpointRuntimeEpoch = undefined;
        this.projectionHydrated = false;
        this.shutdownProjection = undefined;
        this.effectiveAllowNoiseMetadataBootstrap = false;
        this.pendingPostQuantumBootstrap = false;
        this.pendingPostQuantumRollbackRecovery = undefined;
        this.pendingCanonicalAppStateCatchUp = false;
        this.preserveExistingProfileArtifactDuringCanonicalCatchUp = false;
        this.pendingCanonicalAppStateSyncKeyCount = 0;
        this.pendingCanonicalAppStateProjection = undefined;
        this.canonicalActivationReadyProjection = undefined;
        this.canonicalActivationUsesPromotedProfileArtifact = false;
        this.lastCanonicalProjection = undefined;
        this.lastPersistedCanonicalProjection = undefined;
        this.initialPairingAuthorized = false;
        this.handoffSourceCanonicalProjection = undefined;
        this.canonicalReconnectProjection = undefined;
        this.canonicalReconnectExpectedRegistrationState = undefined;
        this.canonicalSealedReloadRegistrationSummary = undefined;
        this.canonicalActivationResumeProjection = undefined;
        this.canonicalActiveRestartReplay = false;
        this.canonicalActiveRestartAppStateOverlayRequired = false;
        this.canonicalActiveRestartCanonicalGeneration = undefined;
        this.canonicalActiveRestartAttestedProjection = undefined;
        this.canonicalReusableHandoffNativeAppState = false;
        this.canonicalNativeAppStateAuthoritative = false;
        this.canonicalCandidatePromoted = false;
        this.canonicalActivationMarkerPresent = false;
        this.canonicalWebSocketGateRequired = false;
        this.canonicalWebSocketGateExtensionId = undefined;
        this.canonicalWebSocketGateServiceWorker = undefined;
        this.canonicalWebSocketGateMonitor = undefined;
        this.canonicalWebSocketGateViolation = false;
        await this.browserBridge?.close();
        await this.removeCanonicalWebSocketGateStagingDir();
        this.browserBridge = undefined;
        const puppeteerOpts = this.client.options.puppeteer;
        const sessionDirName = this.clientId
            ? `RemoteAuth-${this.clientId}`
            : 'RemoteAuth';
        const dirPath = path.join(this.dataPath, sessionDirName);

        if (
            puppeteerOpts.userDataDir &&
            puppeteerOpts.userDataDir !== dirPath
        ) {
            throw new Error(
                'RemoteAuth is not compatible with a user-supplied userDataDir.',
            );
        }

        this.userDataDir = dirPath;
        this.sessionName = sessionDirName;

        if (this.nativePostgres) {
            await this.store.open({
                onLeaseLost: (error) => this.handleLeaseLoss(error),
            });
            try {
                let activeActivationNoiseMetadataBootstrapRequired = false;
                await this.extractNativeSession();
                this.canonicalWebSocketGateRequired =
                    this.store.isHandoffRevision?.() === true;
                if (!this.canonicalWebSocketGateRequired) {
                    const pendingActivation =
                        await this.store.loadPendingCanonicalActivation?.();
                    if (pendingActivation) {
                        const pendingProjection = pendingActivation.projection;
                        if (!pendingProjection) {
                            throw new Error(
                                'wwebjs_canonical_activation_projection_missing',
                            );
                        }
                        this.handoffSourceCanonicalProjection =
                            pendingProjection;
                        this.canonicalActivationResumeProjection =
                            pendingProjection;
                        this.pendingCanonicalAppStateCatchUp = Boolean(
                            pendingActivation.appStateHydrationRequired,
                        );
                        this.canonicalActivationMarkerPresent = true;
                        this.pendingCanonicalAppStateSyncKeyCount =
                            pendingProjection.tables
                                ?.whatsapp_app_state_sync_keys?.length || 0;
                        this.pendingPostQuantumBootstrap = Boolean(
                            pendingActivation.pqBootstrapRequired,
                        );
                        this.canonicalCandidatePromoted = true;
                        activeActivationNoiseMetadataBootstrapRequired =
                            pendingActivation.noiseMetadataBootstrapRequired ===
                            true;
                        // Active activation recovery must replay the latest
                        // canonical DB projection before its first WebSocket.
                        this.canonicalWebSocketGateRequired = true;
                        this.logNative(
                            'canonical_activation.resumed',
                            {
                                pending_sync_key_count:
                                    this.pendingCanonicalAppStateSyncKeyCount,
                                pq_bootstrap_required:
                                    this.pendingPostQuantumBootstrap,
                            },
                            { force: true },
                        );
                    } else if (this.store.revisionStatus === 'active') {
                        if (
                            typeof this.store.loadCanonicalRestartAuthority !==
                            'function'
                        ) {
                            throw new Error(
                                'wwebjs_profile_anchor_restart_authority_unavailable',
                            );
                        }
                        let restartAuthority =
                            await this.store.loadCanonicalRestartAuthority();
                        let activeProjection = restartAuthority?.projection;
                        if (!activeProjection?.device?.jid) {
                            throw new Error(
                                'wwebjs_active_canonical_projection_missing',
                            );
                        }
                        const portableRestartProjection =
                            normalizeCanonicalAppStateForPortablePersistence(
                                activeProjection,
                            );
                        if (
                            portableRestartProjection.snapshot_resync_collection_count >
                            0
                        ) {
                            const repaired =
                                await this.store.saveCanonicalProjection({
                                    projection:
                                        portableRestartProjection.projection,
                                    source: 'restart_app_state_snapshot_resync_repair',
                                });
                            activeProjection =
                                portableRestartProjection.projection;
                            restartAuthority = {
                                ...restartAuthority,
                                projection: activeProjection,
                                appStateOverlayRequired: true,
                                canonicalGeneration:
                                    repaired.canonicalGeneration ??
                                    restartAuthority.canonicalGeneration,
                            };
                            this.logNative(
                                'canonical_restart.app_state_source_repaired',
                                {
                                    snapshot_resync_collection_count:
                                        portableRestartProjection.snapshot_resync_collection_count,
                                    removed_version_row_count:
                                        portableRestartProjection.removed_version_row_count,
                                    removed_mutation_mac_count:
                                        portableRestartProjection.removed_mutation_mac_count,
                                    collection_ids:
                                        portableRestartProjection.collection_ids,
                                    canonical_generation:
                                        restartAuthority.canonicalGeneration,
                                },
                                { force: true },
                            );
                        }
                        this.handoffSourceCanonicalProjection =
                            activeProjection;
                        this.canonicalActivationResumeProjection =
                            activeProjection;
                        this.pendingPostQuantumBootstrap =
                            activeProjection.capabilities
                                ?.pq_server_rollback_acknowledged === true;
                        this.canonicalActiveRestartReplay = true;
                        this.canonicalActiveRestartAppStateOverlayRequired =
                            restartAuthority.appStateOverlayRequired === true;
                        this.canonicalActiveRestartCanonicalGeneration =
                            restartAuthority.canonicalGeneration;
                        // Canonical-only critical checkpoints can be newer
                        // than the last profile artifact. Replay the database
                        // projection under the first-WebSocket gate on every
                        // active PostgreSQL restart.
                        this.canonicalWebSocketGateRequired = true;
                        this.logNative(
                            'canonical_restart.replay_required',
                            {
                                canonical_record_count:
                                    activeProjection.record_count,
                                profile_artifact_id:
                                    restartAuthority.profileArtifactId,
                                canonical_generation:
                                    restartAuthority.canonicalGeneration,
                                legacy_authority:
                                    restartAuthority.legacy === true,
                                app_state_overlay_required:
                                    this
                                        .canonicalActiveRestartAppStateOverlayRequired,
                                pq_bootstrap_required:
                                    this.pendingPostQuantumBootstrap,
                            },
                            { force: true },
                        );
                    }
                }
                this.effectiveAllowNoiseMetadataBootstrap = Boolean(
                    this.allowNoiseMetadataBootstrap &&
                    (this.canonicalActivationMarkerPresent === true
                        ? activeActivationNoiseMetadataBootstrapRequired
                        : this.store.requiresNoiseMetadataBootstrap()),
                );
                this.logNative('handoff.noise_bootstrap_policy_resolved', {
                    requested: this.allowNoiseMetadataBootstrap,
                    effective: this.effectiveAllowNoiseMetadataBootstrap,
                    source_provider: this.store.sourceProvider,
                    revision_source: this.store.revisionSource,
                    active_activation_resume:
                        this.canonicalActivationMarkerPresent === true,
                });
                const pendingPqRollback =
                    await this.store.loadPendingPostQuantumServerRollback?.();
                if (pendingPqRollback) {
                    this.pendingPostQuantumRollbackRecovery = pendingPqRollback;
                    this.pendingPostQuantumBootstrap = true;
                    // Keep the first WebSocket behind the canonical gate. An
                    // intent means the delete RPC may have reached WhatsApp,
                    // even when no ACK was durably recorded before a crash.
                    this.canonicalWebSocketGateRequired = true;
                    this.logNative(
                        'handoff.pq_source_recovery_resumed',
                        {
                            marker_state: pendingPqRollback.state,
                            handoff_id: pendingPqRollback.handoff_id,
                        },
                        { force: true },
                    );
                }
                if (
                    this.canonicalWebSocketGateRequired ||
                    this.canonicalActivationMarkerPresent
                ) {
                    if (
                        puppeteerOpts.browser ||
                        puppeteerOpts.page ||
                        puppeteerOpts.browserWSEndpoint ||
                        puppeteerOpts.browserURL
                    ) {
                        throw new Error(
                            'wwebjs_canonical_activation_dedicated_browser_required',
                        );
                    }
                    if (
                        puppeteerOpts.protocol &&
                        puppeteerOpts.protocol !== 'cdp'
                    ) {
                        throw new Error(
                            'wwebjs_canonical_websocket_gate_cdp_required',
                        );
                    }
                    if (
                        (puppeteerOpts.args || []).some((argument) =>
                            String(argument).startsWith('--disable-extensions'),
                        )
                    ) {
                        throw new Error(
                            'wwebjs_canonical_websocket_gate_extensions_disabled',
                        );
                    }
                }
            } catch (error) {
                throw await this.finalizeNativeFailure(
                    error,
                    'handoff_profile_restore_failed',
                );
            }
        } else {
            await this.extractRemoteSession();
        }

        this.client.options.puppeteer = {
            ...puppeteerOpts,
            userDataDir: dirPath,
            ...(this.canonicalWebSocketGateRequired
                ? {
                      pipe: true,
                      enableExtensions: true,
                      protocol: 'cdp',
                  }
                : {}),
        };
    }

    async afterBrowserInitialized() {
        if (!this.nativePostgres) return;
        try {
            await this.installCanonicalWebSocketGate();
        } catch (error) {
            throw await this.finalizeNativeFailure(
                error,
                'handoff_initial_websocket_gate_failed',
            );
        }
        this.browserBridge = new BrowserSessionBridge({
            page: this.client.pupPage,
            expectedVersion: this.store.webVersion,
            enforceExpectedVersion: this.store.webVersionIntegrityPinned,
            logger: this.store.logger,
            onCriticalMutation: () => this.scheduleCriticalCheckpoint(),
            onCanonicalProviderState: async (providerState) => {
                this.pendingCanonicalProviderState = providerState;
            },
            allowNoiseMetadataBootstrap:
                this.effectiveAllowNoiseMetadataBootstrap,
        });
        const inheritedPageNetworkFence =
            this.browserBridge.networkQuiesced === true;
        try {
            await this.browserBridge.install();
            if (this.canonicalWebSocketGateRequired) {
                // Install the navigation-scoped guard on about:blank, before
                // Client performs the first WhatsApp navigation. This closes
                // the bootstrap window where an empty profile can rotate or
                // clear credentials before the canonical database projection
                // is hydrated. The MV3 gate independently blocks all WSS.
                await this.browserBridge.armCanonicalCredentialGuard({
                    ttlMs: 300000,
                    navigationScoped: true,
                });
            } else if (inheritedPageNetworkFence) {
                // BrowserSessionBridge.close() fences the Page/CDP target,
                // while a server-side logout deliberately reuses that Page.
                // Release only a fence inherited from the previous bridge;
                // canonical handoff/replay startup must remain offline.
                await this.browserBridge.resumeNetwork();
                this.logNative(
                    'browser_bridge.reused_page_network_resumed',
                    {
                        revision_status: this.store.revisionStatus,
                        revision_source: this.store.revisionSource,
                    },
                    { force: true },
                );
            }
        } catch (error) {
            throw await this.finalizeNativeFailure(
                error,
                'handoff_browser_bridge_install_failed',
            );
        }
    }

    async beforeClientInjected() {
        if (!this.nativePostgres || this.projectionHydrated) return;
        try {
            const stagedProviderHandoff =
                this.store.isHandoffRevision?.() === true;
            // The PostgreSQL revision is the authoritative handoff signal.
            // Do not let a caller's ordinary authentication deadline shrink
            // the guarded offline import/reload path back to 30 seconds.
            const canonicalRuntimeTimeoutMs = stagedProviderHandoff
                ? 120000
                : Math.min(this.client.options.authTimeoutMs || 30000, 120000);
            const canonicalModuleTimeoutMs = stagedProviderHandoff
                ? 60000
                : Math.min(this.client.options.authTimeoutMs || 30000, 60000);
            const canonicalRegistrationRepairTimeoutMs = stagedProviderHandoff
                ? 30000
                : Math.min(this.client.options.authTimeoutMs || 30000, 30000);
            this.assertCanonicalWebSocketGateHeld();
            await this.browserBridge.waitForRuntimeStable({
                timeoutMs: canonicalRuntimeTimeoutMs,
            });
            const compatibility = await this.browserBridge.assertCompatible({
                waitForModulesMs: canonicalModuleTimeoutMs,
                capabilityStage: 'initial_runtime',
            });
            this.store.bindRuntimeWebVersion(
                compatibility.actualVersion,
                compatibility.moduleAbi,
            );
            const activationResumeProjection =
                this.canonicalActivationResumeProjection;
            const resumingCanonicalActivation =
                this.canonicalActivationMarkerPresent;
            // A durable activation marker means commitActivation() already
            // promoted the target-local profile in an earlier runtime. Keep
            // that artifact through final readiness; its canonical overlay
            // is sufficient to replay the live browser delta, while rotating
            // the artifact again would evict the handoff-protected recovery
            // anchor before finalizeActivation() can close the fence.
            this.canonicalActivationUsesPromotedProfileArtifact =
                resumingCanonicalActivation;
            const replayingActiveRevision = this.canonicalActiveRestartReplay;
            const allowEstablishedOfflineState =
                resumingCanonicalActivation || replayingActiveRevision;
            const offlineSocketStates = allowEstablishedOfflineState
                ? ['OPENING', 'TIMEOUT', 'UNLAUNCHED']
                : ['OPENING', 'UNLAUNCHED'];
            let canonicalProjection =
                activationResumeProjection ||
                (await this.store.consumePendingCanonicalProjection());
            if (
                !canonicalProjection &&
                this.canonicalWebSocketGateRequired &&
                this.store.revisionSource === 'secure_import'
            ) {
                const providerProjection =
                    await this.store.consumePendingProjection();
                if (!providerProjection) {
                    throw new Error(
                        'wwebjs_secure_import_provider_projection_missing',
                    );
                }
                if (
                    providerProjection.web_version !==
                    compatibility.actualVersion
                ) {
                    throw new Error(
                        'wwebjs_secure_import_web_version_mismatch',
                    );
                }
                // The provider projection came from an authenticated Chrome
                // tab, not from a trusted canonical store. Restore it while
                // both network layers are fenced, reload with only HTTP
                // bootstrap traffic enabled, and derive the canonical form
                // before the existing activation path is allowed to proceed.
                await this.browserBridge.quiesceNetwork();
                await this.browserBridge.armCanonicalCredentialGuard({
                    ttlMs: 300000,
                    navigationScoped: true,
                });
                await this.browserBridge.importProjection(providerProjection);
                this.projectionHydrated = true;
                this.assertCanonicalWebSocketGateHeld();
                const bootstrapReload =
                    await this.browserBridge.resumeNetworkAndReload({
                        timeoutMs: canonicalRuntimeTimeoutMs,
                    });
                this.assertCanonicalWebSocketGateHeld();
                await this.browserBridge.waitForRuntimeStable({
                    timeoutMs: canonicalRuntimeTimeoutMs,
                });
                const bootstrapCompatibility =
                    await this.browserBridge.assertCompatible({
                        waitForModulesMs: canonicalModuleTimeoutMs,
                        capabilityStage: 'secure_import_browser_bootstrap',
                    });
                if (
                    bootstrapCompatibility.actualVersion !==
                    providerProjection.web_version
                ) {
                    throw new Error(
                        'wwebjs_secure_import_web_version_mismatch',
                    );
                }
                this.store.bindRuntimeWebVersion(
                    bootstrapCompatibility.actualVersion,
                    bootstrapCompatibility.moduleAbi,
                );
                await this.browserBridge.quiesceNetwork();
                await this.browserBridge.armCanonicalCredentialGuard({
                    ttlMs: 300000,
                    navigationScoped: true,
                });
                const exportedCanonical =
                    await this.browserBridge.exportCanonicalProjection({
                        allowIncompleteAppStateOverlay: true,
                    });
                const persisted =
                    await this.store.persistExternalBrowserBootstrapCanonicalProjection(
                        exportedCanonical,
                    );
                canonicalProjection = persisted.projection;
                this.logNative(
                    'secure_import.browser_projection_canonicalized',
                    {
                        web_version: bootstrapCompatibility.actualVersion,
                        record_count: canonicalProjection.record_count,
                        size_bytes: canonicalProjection.size_bytes,
                        navigation_source: bootstrapReload.navigationSource,
                        explicit_reload_count:
                            bootstrapReload.explicitReloadCount,
                    },
                    { force: true },
                );
            }
            if (canonicalProjection) {
                this.markCanonicalProjectionPersisted(canonicalProjection);
                this.handoffSourceCanonicalProjection = canonicalProjection;
                await this.browserBridge.quiesceNetwork();
                // BrowserSessionBridge proves a full Baileys ML-KEM inventory
                // in the Node realm before this page task starts. Keep one
                // bounded import deadline for every staged projection; the
                // renderer no longer receives a four-minute crypto allowance.
                const canonicalImportTaskTimeoutMs = 120000;
                const credentialGuardTtlMs = Math.min(
                    300000,
                    Math.max(
                        240000,
                        canonicalImportTaskTimeoutMs + 60000,
                        (this.client.options.authTimeoutMs || 30000) * 4,
                    ),
                );
                await this.browserBridge.armCanonicalCredentialGuard({
                    ttlMs: credentialGuardTtlMs,
                    navigationScoped: true,
                });
                const preserveExistingAppState =
                    replayingActiveRevision ||
                    this.store.canPreserveReusableHandoffProfileAppState?.(
                        canonicalProjection,
                    ) === true;
                this.canonicalReusableHandoffNativeAppState = Boolean(
                    preserveExistingAppState && !replayingActiveRevision,
                );
                let preserveExistingSignalTables = false;
                let preserveExistingSignalComponents;
                if (this.canonicalReusableHandoffNativeAppState) {
                    const signalTablePreservation =
                        await this.resolveReusableHandoffSignalTablePreservation(
                            canonicalProjection,
                        );
                    if (signalTablePreservation === true) {
                        preserveExistingSignalTables = true;
                    } else if (
                        signalTablePreservation &&
                        typeof signalTablePreservation === 'object'
                    ) {
                        preserveExistingSignalComponents =
                            signalTablePreservation;
                    }
                }
                const imported =
                    await this.browserBridge.importCanonicalProjection(
                        canonicalProjection,
                        {
                            allowNoiseMetadataBootstrap:
                                this.effectiveAllowNoiseMetadataBootstrap,
                            requireRoutingInfo:
                                this.effectiveAllowNoiseMetadataBootstrap,
                            preserveExistingAppState,
                            preserveExistingSignalTables,
                            ...(preserveExistingSignalComponents
                                ? { preserveExistingSignalComponents }
                                : {}),
                            // A staged cross-provider handoff may spend longer
                            // than Puppeteer's single Runtime.callFunctionOn
                            // deadline while IndexedDB initializes. Run that
                            // import as a monitored page task; ordinary active
                            // revision replay keeps the direct fast path.
                            ...(stagedProviderHandoff
                                ? {
                                      backgroundTask: true,
                                      backgroundTaskTimeoutMs:
                                          canonicalImportTaskTimeoutMs,
                                  }
                                : {}),
                        },
                    );
                if (stagedProviderHandoff) {
                    // The background task owns most of its TTL at high PQ
                    // cardinality. Renew immediately after the successful
                    // proof so registration inspection and the controlled
                    // reload never inherit only the timeout margin.
                    await this.browserBridge.armCanonicalCredentialGuard({
                        ttlMs: credentialGuardTtlMs,
                        navigationScoped: true,
                    });
                }
                if (this.pendingCanonicalProviderState) {
                    await this.store.saveCanonicalProviderState(
                        this.pendingCanonicalProviderState,
                    );
                    this.pendingCanonicalProviderState = undefined;
                }
                if (
                    imported.reload_required !== false ||
                    imported.reconnect_required !== true
                ) {
                    throw new Error(
                        'wwebjs_canonical_import_reconnect_contract_invalid',
                    );
                }
                this.pendingPostQuantumBootstrap =
                    imported.pq_key_mode ===
                        CANONICAL_PQ_KEY_MODE_GENERATE_AFTER_RECONNECT ||
                    Boolean(this.pendingPostQuantumRollbackRecovery);
                this.pendingCanonicalAppStateCatchUp =
                    imported.app_state_import_mode ===
                        'deferred_authenticated_full_sync' &&
                    (imported.pending_app_state_sync_keys > 0 ||
                        canonicalProjection.tables.whatsapp_app_state_version
                            .length > 0 ||
                        canonicalProjection.capabilities
                            ?.app_state_snapshot_resync_required === true);
                this.pendingCanonicalAppStateSyncKeyCount = Number(
                    imported.pending_app_state_sync_keys || 0,
                );
                if (
                    this.pendingCanonicalAppStateCatchUp &&
                    this.pendingCanonicalAppStateSyncKeyCount <= 0
                ) {
                    throw new Error(
                        'wwebjs_canonical_app_state_sync_keys_missing',
                    );
                }
                const preReconnectRegistration =
                    await this.browserBridge.inspectCanonicalRegistrationState();
                const preReconnectSummary =
                    this.summarizeCanonicalRegistrationState(
                        preReconnectRegistration,
                        canonicalProjection,
                        imported.expected_registration_state,
                    );
                this.logNative(
                    'handoff.registration_state.pre_reconnect',
                    preReconnectSummary,
                    { force: true },
                );
                this.assertCanonicalRegistrationState(preReconnectSummary);
                this.assertCanonicalWebSocketGateHeld();
                const canonicalReload =
                    await this.browserBridge.reloadCanonicalImportedRuntime({
                        timeoutMs: canonicalRuntimeTimeoutMs,
                        waitForModulesMs: canonicalModuleTimeoutMs,
                        credentialGuardTtlMs,
                        // A current WWeb bootstrap may clear its registered
                        // tuple while the MV3 gate deliberately blocks WSS.
                        // This only permits the reload to return offline; the
                        // source projection is fully resealed and strictly
                        // validated below before the gate can be released.
                        allowRegistrationRepair: true,
                    });
                if (stagedProviderHandoff) {
                    // The reload bridge rearms before its ABI and online/offline
                    // proofs, which may consume up to 90 seconds. Reset the
                    // full TTL here so the second 120-second import/reseal can
                    // never inherit that spent window.
                    await this.browserBridge.armCanonicalCredentialGuard({
                        ttlMs: credentialGuardTtlMs,
                        navigationScoped: true,
                    });
                }
                this.assertCanonicalWebSocketGateHeld();
                const websocketHandshakeCount =
                    this.canonicalWebSocketGateMonitor?.state?.handshakes || 0;
                if (websocketHandshakeCount !== 0) {
                    throw new Error(
                        'wwebjs_canonical_reload_websocket_handshake_detected',
                    );
                }
                if (canonicalReload.explicitReloadCount !== 1) {
                    throw new Error('wwebjs_canonical_reload_count_invalid');
                }
                this.store.bindRuntimeWebVersion(
                    canonicalReload.actualVersion,
                    canonicalReload.moduleAbi,
                );
                const sealedReloadContinuity =
                    this.canUseCanonicalSealedReloadContinuity({
                        stagedProviderHandoff,
                        resumingCanonicalActivation,
                        replayingActiveRevision,
                        preserveExistingAppState,
                        imported,
                        canonicalReload,
                        websocketHandshakeCount,
                    });
                let resealed = imported;
                let postReloadSummary;
                if (sealedReloadContinuity) {
                    const continuityState =
                        await this.browserBridge.inspectCanonicalReloadContinuityState(
                            { requireAcknowledged: false },
                        );
                    this.canonicalSealedReloadRegistrationSummary =
                        Object.freeze({ ...preReconnectSummary });
                    postReloadSummary =
                        this.mergeCanonicalSealedReloadRegistrationSummary(
                            continuityState,
                        );
                    this.logNative(
                        'handoff.reseal_skipped_by_reload_continuity',
                        {
                            proof_source:
                                'pre_reload_cryptographic_seal_and_navigation_guard',
                            signal_storage_initialization_mode:
                                imported.signal_storage_initialization_mode,
                            document_epoch_changed: true,
                            explicit_reload_count: 1,
                            websocket_handshake_count: 0,
                        },
                        { force: true },
                    );
                } else {
                    resealed =
                        await this.browserBridge.importCanonicalProjection(
                            canonicalProjection,
                            {
                                allowNoiseMetadataBootstrap:
                                    this.effectiveAllowNoiseMetadataBootstrap,
                                requireRoutingInfo:
                                    this.effectiveAllowNoiseMetadataBootstrap,
                                // When the first import had to construct WWeb-only
                                // noise metadata, reuse that exact recovery token.
                                // Generating a second one would make the DB/source
                                // projection differ from the final document.
                                noiseBootstrap:
                                    imported.generated_provider_state,
                                preserveExistingAppState,
                                preserveExistingSignalTables,
                                ...(preserveExistingSignalComponents
                                    ? { preserveExistingSignalComponents }
                                    : {}),
                                ...(stagedProviderHandoff
                                    ? {
                                          backgroundTask: true,
                                          backgroundTaskTimeoutMs:
                                              canonicalImportTaskTimeoutMs,
                                      }
                                    : {}),
                            },
                        );
                    this.assertCanonicalResealContract(imported, resealed);
                    if (stagedProviderHandoff) {
                        // Reset the full post-reseal window before any provider
                        // state write, optional registration repair, artifact
                        // upload, activation CAS or reconnect preparation.
                        await this.browserBridge.armCanonicalCredentialGuard({
                            ttlMs: credentialGuardTtlMs,
                            navigationScoped: true,
                        });
                    }
                    if (this.pendingCanonicalProviderState) {
                        await this.store.saveCanonicalProviderState(
                            this.pendingCanonicalProviderState,
                        );
                        this.pendingCanonicalProviderState = undefined;
                    }
                    const postReloadRegistration =
                        await this.browserBridge.inspectCanonicalRegistrationState();
                    postReloadSummary =
                        this.summarizeCanonicalRegistrationState(
                            postReloadRegistration,
                            canonicalProjection,
                            resealed.expected_registration_state,
                        );
                }
                this.logNative(
                    'handoff.registration_state.post_reload',
                    {
                        ...postReloadSummary,
                        proof_source: sealedReloadContinuity
                            ? 'sealed_reload_continuity'
                            : 'fresh_signal_read',
                        document_epoch_changed: true,
                        explicit_reload_count: 1,
                        websocket_handshake_count: websocketHandshakeCount,
                    },
                    { force: true },
                );
                this.assertCanonicalRegistrationState(postReloadSummary);
                if (
                    canonicalReload.registrationRepairRequired === true ||
                    canonicalReload.runtimeBootstrapRequired === true ||
                    replayingActiveRevision
                ) {
                    if (
                        replayingActiveRevision &&
                        canonicalReload.registrationRepairRequired !== true
                    ) {
                        // A restored active profile already owns a valid
                        // registration tuple. Even when the reload initially
                        // reports WAComms + OPENING, that offline bootstrap can
                        // collapse immediately after network release into a
                        // model-only CONNECTED state with no live comms
                        // stream. Stop that provisional runtime while WSS is
                        // still fenced and dispatch one official high-level
                        // launch only after the network is live.
                        await this.browserBridge.deferCanonicalRegisteredLaunchOffline();
                        this.canonicalDeferredOnlineRegisteredLaunch = true;
                    } else {
                        await this.browserBridge.repairCanonicalRegistrationOffline(
                            {
                                timeoutMs: canonicalRegistrationRepairTimeoutMs,
                            },
                        );
                    }
                    const repairedRegistration =
                        await this.browserBridge.inspectCanonicalRegistrationState();
                    const repairedSummary =
                        this.summarizeCanonicalRegistrationState(
                            repairedRegistration,
                            canonicalProjection,
                            resealed.expected_registration_state,
                        );
                    this.assertCanonicalRegistrationState(repairedSummary);
                    this.assertCanonicalReconnectSafetyState(repairedSummary, {
                        requireConnected: false,
                        allowedSocketStates: ['OPENING', 'UNLAUNCHED'],
                    });
                    this.logNative(
                        'handoff.registration_state.post_reload_repaired',
                        repairedSummary,
                        { force: true },
                    );
                }
                await this.browserBridge.acknowledgeCanonicalCredentialProtection();
                this.assertCanonicalWebSocketGateHeld();
                this.projectionHydrated = true;
                this.canonicalReconnectProjection = canonicalProjection;
                this.canonicalReconnectExpectedRegistrationState =
                    resealed.expected_registration_state;
                this.canonicalActivationResumeProjection = undefined;
                await this.browserBridge.prepareCanonicalCandidateOffline({
                    allowEstablished: allowEstablishedOfflineState,
                });
                for (let probe = 1; probe <= 3; probe += 1) {
                    await this.delay(250);
                    await this.assertCanonicalCandidateReady(
                        `offline_stability_${probe}`,
                        {
                            requireConnected: false,
                            allowedSocketStates: offlineSocketStates,
                            allowSealedReloadContinuityProof:
                                sealedReloadContinuity,
                        },
                    );
                }

                this.preserveExistingProfileArtifactDuringCanonicalCatchUp =
                    replayingActiveRevision || resumingCanonicalActivation;
                if (replayingActiveRevision) {
                    if (
                        resealed.app_state_import_mode !==
                            'preserved_native_profile' ||
                        resealed.pending_app_state_sync_keys !== 0
                    ) {
                        throw new WhatsAppSessionCompatibilityError(
                            'wwebjs_canonical_active_restart_native_app_state_invalid',
                        );
                    }
                    if (this.canonicalActiveRestartAppStateOverlayRequired) {
                        this.pendingCanonicalAppStateSyncKeyCount =
                            canonicalProjection.tables
                                ?.whatsapp_app_state_sync_keys?.length || 0;
                        if (this.pendingCanonicalAppStateSyncKeyCount <= 0) {
                            throw new WhatsAppSessionCompatibilityError(
                                'wwebjs_canonical_app_state_sync_keys_missing',
                            );
                        }
                        this.pendingCanonicalAppStateCatchUp = true;
                        this.canonicalNativeAppStateAuthoritative = false;
                        this.logNative(
                            'canonical_restart.app_state_overlay_required',
                            {
                                canonical_generation:
                                    this
                                        .canonicalActiveRestartCanonicalGeneration,
                                sync_key_count:
                                    this.pendingCanonicalAppStateSyncKeyCount,
                                app_state_import_mode:
                                    resealed.app_state_import_mode,
                            },
                            { force: true },
                        );
                    } else {
                        // The typed authority proves the profile's app-state
                        // baseline and current canonical generation agree.
                        // Only that case may keep the restored native tables
                        // authoritative without an authenticated overlay.
                        this.canonicalNativeAppStateAuthoritative = true;
                        this.logNative(
                            'canonical_restart.profile_artifact_preserved',
                            {
                                reason: 'authority_app_state_coherent',
                                canonical_generation:
                                    this
                                        .canonicalActiveRestartCanonicalGeneration,
                                app_state_import_mode:
                                    resealed.app_state_import_mode,
                            },
                            { force: true },
                        );
                    }
                } else if (this.canonicalReusableHandoffNativeAppState) {
                    await this.checkpointReusableCanonicalHandoffOffline({
                        resealed,
                        preserveExistingProfileArtifact:
                            resumingCanonicalActivation,
                        ...(sealedReloadContinuity
                            ? {
                                  trustedCanonicalProjection:
                                      canonicalProjection,
                              }
                            : {}),
                    });
                } else if (!resumingCanonicalActivation) {
                    await this.checkpointCanonicalCandidateOffline({
                        source: this.store.revisionSource || 'handoff',
                        preserveExistingProfileArtifact: false,
                    });
                } else {
                    // commit_whatsapp_session_activation() promotes the
                    // staging artifact before the authenticated app-state
                    // overlay starts. A post-PONR retry must keep that exact
                    // last-known-good profile: taking another snapshot from
                    // the partially materialized live profile both races the
                    // journal and changes the anchor that recovery is meant
                    // to attest.
                    this.logNative(
                        'checkpoint.offline_candidate_profile_preserved',
                        {
                            reason: 'activation_resume_app_state_pending',
                        },
                        { force: true },
                    );
                }
                // A staging/handoff revision needs this first complete
                // candidate artifact. From this point onward it is also the
                // last-known-good rollback source and must not be replaced by
                // the partially materialized live Chromium profile.
                if (this.pendingCanonicalAppStateCatchUp) {
                    this.preserveExistingProfileArtifactDuringCanonicalCatchUp = true;
                }
                await this.assertCanonicalCandidateReady(
                    'offline_after_artifact_upload',
                    {
                        requireConnected: false,
                        allowedSocketStates: offlineSocketStates,
                        allowSealedReloadContinuityProof:
                            sealedReloadContinuity,
                    },
                );
                if (!replayingActiveRevision) {
                    await this.store.markCanonicalActivationPending({
                        appStateHydrationRequired:
                            this.pendingCanonicalAppStateCatchUp,
                        pqBootstrapRequired: this.pendingPostQuantumBootstrap,
                    });
                    this.canonicalActivationMarkerPresent = true;
                }
                await this.store.renewLease();
                this.store.assertLocalLease();
                await this.assertCanonicalCandidateReady(
                    'offline_before_promotion',
                    {
                        requirePublicEventGate: true,
                        requireConnected: false,
                        allowedSocketStates: offlineSocketStates,
                        allowSealedReloadContinuityProof:
                            sealedReloadContinuity,
                    },
                );
                this.assertCanonicalWebSocketGateHeld();
                if (!replayingActiveRevision && !resumingCanonicalActivation) {
                    await this.store.commitActivation();
                }
                if (this.store.revisionStatus !== 'active') {
                    throw new Error(
                        'wwebjs_canonical_offline_promotion_not_active',
                    );
                }
                this.canonicalCandidatePromoted = true;
                await this.releaseCanonicalWebSocketGateOffline();
                // Extension removal is a Chromium-level transition. Re-run
                // the bridge quiescence barrier so its page-level state and
                // journal are synchronized before the in-page reconnect ABI
                // checks navigator.onLine.
                await this.browserBridge.quiesceNetwork();
                const reconnect =
                    await this.browserBridge.rearmCanonicalImportedSocket({
                        timeoutMs: Math.min(
                            this.client.options.authTimeoutMs || 30000,
                            30000,
                        ),
                        allowEstablished: allowEstablishedOfflineState,
                    });
                await this.browserBridge.releaseCanonicalImportedNetwork();
                this.canonicalDeferredOnlineRegisteredLaunch = false;
                const appStateCatchUpRequired =
                    this.pendingCanonicalAppStateCatchUp;
                await this.browserBridge.waitForCanonicalConnected({
                    timeoutMs: Math.min(
                        180000,
                        Math.max(
                            60000,
                            (this.client.options.authTimeoutMs || 30000) * 4,
                        ),
                    ),
                    // Imported app-state keys cannot be restored until the
                    // authenticated transport exists. Requiring hasSynced at
                    // this point creates a circular gate: WhatsApp waits for
                    // those keys while the bridge waits for WhatsApp.
                    requireSynced: !appStateCatchUpRequired,
                });
                await this.completePendingCanonicalAppStateBeforeReadiness();
                // ONLINE and public READY remain fail-closed: after restoring
                // app-state, require a second fresh proof with hasSynced=true.
                if (appStateCatchUpRequired) {
                    await this.browserBridge.waitForCanonicalConnected({
                        timeoutMs: Math.min(
                            30000,
                            this.canonicalAppStateCatchUpTimeoutMs,
                        ),
                        requireSynced: true,
                    });
                }
                await this.assertCanonicalCandidateReady('promoted_connected');
                this.canonicalSealedReloadRegistrationSummary = undefined;
                // Keep both credential and pairing guards armed through the
                // final offline activation checkpoint. They are released by
                // checkpointCanonicalActivationReady only after the durable
                // artifact, activation CAS, reconnect, and final identity
                // proof have all succeeded.
                this.logNative('handoff.browser_reconnect_resumed', {
                    projection_kind: 'canonical',
                    previous_socket_state: reconnect.previous_socket_state,
                    socket_state: reconnect.socket_state,
                    promoted_offline: true,
                    bootstrapped_by_reload:
                        reconnect.bootstrapped_by_reload === true,
                    explicit_reload_count: 1,
                });
                return;
            }
            if (this.canonicalWebSocketGateRequired) {
                throw new Error('wwebjs_canonical_handoff_projection_missing');
            }
            const projection = await this.store.consumePendingProjection();
            if (!projection) return;

            await this.browserBridge.quiesceNetwork();
            await this.browserBridge.importProjection(projection);
            this.projectionHydrated = true;
            this.logNative('handoff.browser_reload_started');
            const reload = await this.browserBridge.resumeNetworkAndReload({
                timeoutMs: canonicalRuntimeTimeoutMs,
            });
            const reloadedCompatibility =
                await this.browserBridge.assertCompatible({
                    waitForModulesMs: canonicalModuleTimeoutMs,
                    capabilityStage: 'legacy_reload',
                });
            this.store.bindRuntimeWebVersion(
                reloadedCompatibility.actualVersion,
                reloadedCompatibility.moduleAbi,
            );
            this.logNative('handoff.browser_reload_completed', {
                navigation_source: reload.navigationSource,
                explicit_reload_count: reload.explicitReloadCount,
            });
        } catch (error) {
            throw await this.finalizeNativeFailure(
                error,
                stableNativeFailureCode(
                    error,
                    'handoff_browser_hydration_failed',
                ),
            );
        }
    }

    /**
     * Stop every local writer before a rollback or lease release. Concurrent
     * failure paths share one promise so Chromium and the bridge are closed at
     * most once during an initialization lifecycle.
     */
    isCanonicalActivationRecoveryRequired() {
        return Boolean(
            this.nativePostgres &&
            !this.authReady &&
            // Journal callbacks remain active while the canonical projection
            // is imported and while its one controlled reload is settling.
            // Never persist that transient browser state: an export can become
            // structurally complete before every source record has been
            // restored. The dirty journal is deliberately retained and is
            // covered by the explicit post-hydration checkpoint instead.
            this.projectionHydrated &&
            this.store.revisionStatus === 'active' &&
            (this.canonicalActivationMarkerPresent ||
                this.canonicalCandidatePromoted),
        );
    }

    isCanonicalActiveRestartAttestationPending() {
        return Boolean(
            this.nativePostgres &&
            !this.authReady &&
            this.canonicalActiveRestartReplay,
        );
    }

    /**
     * Returns only in-memory evidence backed by the durable active-revision
     * activation marker. The Client uses this during failure cleanup to
     * advertise forward recovery without ever claiming ONLINE or exposing a
     * replacement QR after the point of no return.
     */
    isPostPointOfNoReturnRecoveryPending() {
        return Boolean(
            this.nativePostgres &&
            !this.authReady &&
            this.store.revisionStatus === 'active' &&
            (this.canonicalActivationMarkerPresent ||
                this.canonicalCandidatePromoted),
        );
    }

    async captureCanonicalActivationRecoveryProjection() {
        if (!this.isCanonicalActivationRecoveryRequired()) return undefined;
        this.store.assertLocalLease();
        // While app-state is catching up, the browser can legitimately expose
        // half-applied collection rows. The last offline checkpoint is already
        // fenced, identity-validated and contains the complete source state,
        // so it is the only safe canonical recovery projection. Chromium is
        // still captured after its process is stopped below.
        if (
            this.pendingCanonicalAppStateCatchUp &&
            this.lastCanonicalProjection
        ) {
            await this.browserBridge.flush();
            return {
                projection: this.lastCanonicalProjection,
                dirtyPlan: this.browserBridge.getCanonicalDirtyPlan?.(),
            };
        }
        let lastError;
        for (let attempt = 1; attempt <= 3; attempt += 1) {
            try {
                await this.browserBridge.flush();
                const dirtyPlan = this.browserBridge.getCanonicalDirtyPlan?.();
                const browserProjection =
                    await this.browserBridge.exportCanonicalProjection();
                const persistenceCandidate = this
                    .pendingCanonicalAppStateCatchUp
                    ? this.buildCanonicalOfflineCheckpointProjection(
                          browserProjection,
                      )
                    : browserProjection;
                const projection =
                    this.reconcileCanonicalProjectionForPersistence(
                        persistenceCandidate,
                        {
                            baseline:
                                this.canonicalActivationReadyProjection ||
                                this.getPersistedCanonicalProjection(),
                            preserveNativeAppState: Boolean(
                                this.canonicalActivationReadyProjection,
                            ),
                        },
                    );
                const tail = await this.browserBridge.flush();
                const finalDirtyPlan =
                    this.browserBridge.getCanonicalDirtyPlan?.();
                const canonicalTailChanged =
                    tail?.critical === true ||
                    (dirtyPlan &&
                        finalDirtyPlan &&
                        finalDirtyPlan.generation !== dirtyPlan.generation);
                if (canonicalTailChanged) {
                    throw new Error(
                        'wwebjs_canonical_activation_recovery_tail_unstable',
                    );
                }
                if (tail?.dirty) {
                    this.logNative(
                        'checkpoint.activation_recovery_noncritical_tail',
                        {
                            event_count: tail.events?.length || 0,
                            dropped_count: tail.dropped || 0,
                            local_storage_event_count:
                                tail.events?.filter(
                                    (event) => event?.area === 'local_storage',
                                ).length || 0,
                            indexeddb_event_count:
                                tail.events?.filter(
                                    (event) => event?.area === 'indexeddb',
                                ).length || 0,
                            canonical_table_count:
                                finalDirtyPlan?.tables?.length || 0,
                            canonical_tables: finalDirtyPlan?.tables || [],
                        },
                        { force: true },
                    );
                }
                return { projection, dirtyPlan };
            } catch (error) {
                lastError = error;
                this.logNative(
                    'checkpoint.activation_recovery_capture_retry',
                    {
                        attempt,
                        error_code: safeFailureCode(
                            error?.code || error?.message,
                            'wwebjs_canonical_activation_recovery_capture_retry',
                        ),
                    },
                    { force: true },
                );
                if (attempt < 3) await this.delay(25);
            }
        }
        throw new Error('wwebjs_canonical_activation_recovery_capture_failed', {
            cause: lastError,
        });
    }

    async terminateNativeBrowser(browser) {
        if (!browser) return true;
        const child = browser.process?.();
        const childTrackable = Boolean(
            child &&
            ('exitCode' in child ||
                'signalCode' in child ||
                typeof child.kill === 'function'),
        );
        const childExited = () =>
            childTrackable &&
            (child.exitCode !== null && child.exitCode !== undefined
                ? true
                : child.signalCode !== null && child.signalCode !== undefined);
        let closeError;
        try {
            if (isBrowserConnected(browser)) {
                if (typeof browser.close !== 'function') {
                    throw new Error('wwebjs_browser_close_unavailable');
                }
                await browser.close();
            }
        } catch (error) {
            closeError = error;
        }

        if (childTrackable && !childExited()) {
            try {
                if (typeof child.kill !== 'function') {
                    throw new Error('wwebjs_browser_process_kill_unavailable');
                }
                child.kill('SIGKILL');
                if (!childExited() && typeof child.once === 'function') {
                    await new Promise((resolve) => {
                        let settled = false;
                        const finish = () => {
                            if (settled) return;
                            settled = true;
                            clearTimeout(timeout);
                            resolve();
                        };
                        const timeout = setTimeout(finish, 5000);
                        child.once('exit', finish);
                        child.once('close', finish);
                    });
                }
            } catch (error) {
                closeError = closeError
                    ? new AggregateError(
                          [closeError, error],
                          'wwebjs_browser_termination_failed',
                      )
                    : error;
            }
        }

        const confirmed = childTrackable
            ? childExited()
            : !isBrowserConnected(browser);
        if (!confirmed) {
            throw new Error('wwebjs_browser_termination_unconfirmed', {
                cause: closeError,
            });
        }
        if (closeError) {
            this.logNativeFailure('client.failure_browser_close_recovered', {
                error: closeError,
            });
        }
        return true;
    }

    async stopNativeFailureWriters() {
        if (!this.nativePostgres) return [];
        this.shutdownRequested = true;
        this.authReady = false;
        this.stopBackupSync();
        if (this.nativeFailureStopPromise) {
            return this.nativeFailureStopPromise;
        }
        const operation = (async () => {
            const failures = [];
            const page = this.client?.pupPage;
            let offline = false;
            let recovery = this.nativeFailureRecoveryProjection;
            let networkCutTimeout;
            try {
                if (typeof page?.setOfflineMode !== 'function') {
                    throw new Error(
                        'wwebjs_failure_network_quiescence_unavailable',
                    );
                }
                await Promise.race([
                    page.setOfflineMode(true),
                    new Promise((_, reject) => {
                        networkCutTimeout = setTimeout(
                            () =>
                                reject(
                                    new Error(
                                        'wwebjs_failure_network_quiescence_timeout',
                                    ),
                                ),
                            2000,
                        );
                    }),
                ]);
                offline = true;
            } catch (error) {
                this.logNativeFailure('client.failure_network_cut_failed', {
                    error,
                });
            } finally {
                clearTimeout(networkCutTimeout);
            }
            if (
                !recovery &&
                offline &&
                this.isCanonicalActivationRecoveryRequired()
            ) {
                if (
                    this.pendingCanonicalAppStateCatchUp ||
                    this
                        .preserveExistingProfileArtifactDuringCanonicalCatchUp ||
                    this.canonicalActivationUsesPromotedProfileArtifact
                ) {
                    // An active-revision replay deliberately keeps the last
                    // known-good profile artifact untouched until its live
                    // canonical projection has passed the stability and
                    // identity gates. Capturing the half-settled browser here
                    // cannot improve recovery and, if export itself fails,
                    // must not hide the primary initialization failure.
                    this.logNative(
                        'checkpoint.activation_recovery_profile_preserved',
                        {
                            reason: 'active_restart_live_attestation_failed',
                        },
                        { force: true },
                    );
                } else {
                    try {
                        recovery =
                            await this.captureCanonicalActivationRecoveryProjection();
                        this.nativeFailureRecoveryProjection = recovery;
                    } catch (error) {
                        failures.push(error);
                        this.logNativeFailure(
                            'checkpoint.activation_recovery_capture_failed',
                            { error },
                        );
                    }
                }
            }
            const browser = this.client?.pupBrowser;
            let browserStopped = false;
            try {
                browserStopped = await this.terminateNativeBrowser(browser);
                this.nativeFailureBrowserTerminationConfirmed = browserStopped;
            } catch (error) {
                failures.push(error);
                this.logNativeFailure('client.failure_browser_close_failed', {
                    error,
                    offline,
                });
                this.nativeFailureBrowserTerminationConfirmed = false;
            }
            // Browser termination is deliberately before bridge.close(). A
            // blocked journal flush can delay cleanup, but can no longer keep
            // a stale fenced writer online.
            if (browserStopped) {
                try {
                    await this.browserBridge?.close?.();
                } catch (error) {
                    failures.push(error);
                    this.logNativeFailure(
                        'client.failure_bridge_close_failed',
                        { error },
                    );
                }
            }
            if (recovery && browserStopped) {
                if (
                    this.pendingCanonicalAppStateCatchUp ||
                    this
                        .preserveExistingProfileArtifactDuringCanonicalCatchUp ||
                    this.canonicalActivationUsesPromotedProfileArtifact
                ) {
                    this.nativeFailureRecoveryProjection = undefined;
                    this.logNative(
                        'checkpoint.activation_recovery_profile_preserved',
                        {
                            reason: 'active_restart_app_state_pending',
                        },
                        { force: true },
                    );
                } else {
                    try {
                        const checkpoint = await this.store.checkpointProfile({
                            profilePath: this.userDataDir,
                            canonicalProjection: recovery.projection,
                            source: 'checkpoint',
                            promote: false,
                        });
                        this.browserBridge?.acknowledgeCanonicalDirtyPlan?.(
                            recovery.dirtyPlan,
                        );
                        this.markCanonicalProjectionPersisted(
                            recovery.projection,
                        );
                        this.nativeFailureRecoveryProjection = undefined;
                        this.profileDirty = false;
                        this.logNative(
                            'checkpoint.activation_recovery_completed',
                            {
                                artifact_id: checkpoint.artifactId,
                                canonical_record_count:
                                    recovery.projection.record_count,
                            },
                            { force: true },
                        );
                    } catch (error) {
                        failures.push(error);
                        this.logNativeFailure(
                            'checkpoint.activation_recovery_persist_failed',
                            { error },
                        );
                    }
                }
            } else if (recovery && !browserStopped) {
                const error = new Error(
                    'wwebjs_canonical_activation_recovery_browser_not_stopped',
                );
                failures.push(error);
                this.logNativeFailure(
                    'checkpoint.activation_recovery_persist_failed',
                    { error },
                );
            }
            if (browserStopped) {
                await this.disposeCanonicalWebSocketGateMonitor().catch(
                    (error) => {
                        failures.push(error);
                    },
                );
                await this.removeCanonicalWebSocketGateStagingDir().catch(
                    (error) => {
                        failures.push(error);
                    },
                );
                this.canonicalWebSocketGateExtensionId = undefined;
                this.canonicalWebSocketGateServiceWorker = undefined;
            }
            return failures;
        })();
        this.nativeFailureStopPromise = operation;
        void operation
            .finally(() => {
                if (
                    !this.nativeFailureBrowserTerminationConfirmed &&
                    this.nativeFailureStopPromise === operation
                ) {
                    this.nativeFailureStopPromise = undefined;
                }
            })
            .catch(() => {});
        return operation;
    }

    /**
     * Fail closed while the fencing lease is still owned: stop browser writes,
     * attempt the handoff rollback, and release the lease only after Chromium
     * termination is proven. Cleanup failures are aggregated with the primary
     * error using fixed messages so credentials or key material never become
     * log/event labels.
     */
    async finalizeNativeFailure(primaryError, errorCode) {
        if (!this.nativePostgres) return primaryError;
        if (!this.nativeFailureFinalizationPromise) {
            const rollbackCode = safeFailureCode(
                errorCode,
                'wwebjs_native_session_failure',
            );
            const primaryErrorNames = new Set([
                'AggregateError',
                'Error',
                'TypeError',
                'WhatsAppSessionCompatibilityError',
                'WhatsAppSessionError',
                'WhatsAppSessionLeaseLostError',
            ]);
            this.logNativeFailure('client.failure_primary', {
                error_code: stableNativeFailureCode(
                    primaryError,
                    'wwebjs_native_session_primary_failure',
                ),
                error_name: primaryErrorNames.has(primaryError?.name)
                    ? primaryError.name
                    : 'Error',
                cleanup_code: rollbackCode,
            });
            const operation = (async () => {
                const failures = [...(await this.stopNativeFailureWriters())];
                try {
                    if (
                        this.nativeFailureBrowserTerminationConfirmed &&
                        !this.canonicalCandidatePromoted &&
                        this.store.isHandoffRevision()
                    ) {
                        await this.rollbackHandoff(rollbackCode);
                    }
                } catch (error) {
                    failures.push(error);
                } finally {
                    if (!this.nativeFailureBrowserTerminationConfirmed) {
                        if (
                            !failures.some(
                                (error) =>
                                    error?.message ===
                                    'wwebjs_browser_termination_unconfirmed',
                            )
                        ) {
                            failures.push(
                                new Error(
                                    'wwebjs_browser_termination_unconfirmed',
                                ),
                            );
                        }
                        this.logNativeFailure(
                            'client.failure_lease_release_blocked',
                            {
                                error: new Error(
                                    'wwebjs_browser_termination_unconfirmed',
                                ),
                            },
                        );
                    } else {
                        try {
                            const leaseWasHeld = Boolean(
                                this.store.fencingToken,
                            );
                            const released = await this.store.releaseLease();
                            if (leaseWasHeld && released !== true) {
                                const error = new Error(
                                    'whatsapp_session_lease_release_rejected',
                                );
                                failures.push(error);
                                this.logNativeFailure(
                                    'client.failure_lease_release_failed',
                                    { error },
                                );
                            }
                        } catch (error) {
                            failures.push(error);
                            this.logNativeFailure(
                                'client.failure_lease_release_failed',
                                { error },
                            );
                        }
                    }
                }
                if (this.nativeFailureBrowserTerminationConfirmed) {
                    this.clearCanonicalCandidateReferences();
                }
                return failures;
            })();
            this.nativeFailureFinalizationPromise = operation;
        }
        const cleanupFailures = await this.nativeFailureFinalizationPromise;
        if (!this.nativeFailureBrowserTerminationConfirmed) {
            this.nativeFailureFinalizationPromise = undefined;
        }
        if (cleanupFailures.length === 0) return primaryError;
        return new AggregateError(
            [primaryError, ...cleanupFailures],
            'wwebjs_native_session_failure_cleanup_failed',
            { cause: primaryError },
        );
    }

    logNative(event, fields, options) {
        try {
            this.store.logger?.log?.(event, fields, options);
        } catch {
            // Diagnostic output must never change session state.
        }
    }

    logNativeFailure(event, fields) {
        this.logNative(event, fields, { force: true });
    }

    /**
     * Collapse concurrent failure paths onto one fenced rollback. A transient
     * database failure is retried while the lease is still owned; callers must
     * not release the lease until this method resolves.
     */
    async rollbackHandoff(errorCode) {
        if (!this.nativePostgres || !this.store.isHandoffRevision()) {
            return false;
        }
        if (this.handoffRollbackPromise) return this.handoffRollbackPromise;
        const operation = (async () => {
            const failures = [];
            for (let attempt = 1; attempt <= 3; attempt += 1) {
                try {
                    await this.store.rollback(errorCode);
                    return true;
                } catch (error) {
                    failures.push(error);
                    this.logNativeFailure('handoff.rollback_attempt_failed', {
                        attempt,
                        error_code: safeFailureCode(
                            error?.code,
                            'wwebjs_handoff_rollback_attempt_failed',
                        ),
                    });
                    if (!this.store.isHandoffRevision()) return true;
                    if (attempt < 3) {
                        await this.delay(attempt === 1 ? 100 : 250);
                    }
                }
            }
            throw new AggregateError(
                failures,
                'wwebjs_handoff_rollback_failed',
            );
        })();
        this.handoffRollbackPromise = operation;
        try {
            return await operation;
        } finally {
            this.handoffRollbackPromise = undefined;
        }
    }

    summarizeCanonicalRegistrationState(
        state,
        projection,
        expectedRegistrationState,
    ) {
        const expectedFingerprint =
            expectedRegistrationState?.companion_fingerprint;
        const expectedPnHash = canonicalDeviceJidHash(projection?.device?.jid);
        const expectedLidHash = projection?.device?.lid
            ? canonicalDeviceJidHash(projection.device.lid)
            : null;
        const hashMatches = (actual, expected) =>
            /^[0-9a-f]{64}$/u.test(expected || '') && actual === expected;
        return {
            is_registered: state?.is_registered === true,
            has_noise_info: state?.has_noise_info === true,
            noise_shape_valid: state?.noise_shape_valid === true,
            has_me_device_pn: state?.has_me_device_pn === true,
            me_device_pn_device_id_present:
                state?.me_device_pn_device_id_present === true,
            me_device_pn_device_id_nonzero:
                state?.me_device_pn_device_id_nonzero === true,
            me_device_pn_hash_match:
                Boolean(expectedPnHash) &&
                state?.me_device_pn_hash === expectedPnHash,
            has_me_device_lid: state?.has_me_device_lid === true,
            me_device_lid_device_id_present:
                state?.me_device_lid_device_id_present === true,
            me_device_lid_device_id_nonzero:
                state?.me_device_lid_device_id_nonzero === true,
            me_device_lid_hash_match:
                expectedLidHash === null ||
                state?.me_device_lid_hash === expectedLidHash,
            has_registration_info: state?.has_registration_info === true,
            registration_id_match:
                Number.isSafeInteger(
                    expectedRegistrationState?.registration_id,
                ) &&
                state?.registration_id ===
                    expectedRegistrationState.registration_id,
            registration_shape_valid: state?.registration_shape_valid === true,
            noise_public_hash_match: hashMatches(
                state?.noise_public_hash,
                expectedRegistrationState?.noise_public_hash,
            ),
            noise_keypair_math_valid:
                expectedRegistrationState?.noise_keypair_math_valid === true &&
                state?.noise_keypair_math_valid === true,
            identity_public_hash_match: hashMatches(
                state?.identity_public_hash,
                expectedRegistrationState?.identity_public_hash,
            ),
            identity_keypair_math_valid:
                expectedRegistrationState?.identity_keypair_math_valid ===
                    true && state?.identity_keypair_math_valid === true,
            has_signed_identity: state?.has_signed_identity === true,
            signed_identity_shape_valid:
                state?.signed_identity_shape_valid === true,
            signed_identity_hash_match: hashMatches(
                state?.signed_identity_hash,
                expectedRegistrationState?.signed_identity_hash,
            ),
            has_signed_pre_key: state?.has_signed_pre_key === true,
            signed_pre_key_shape_valid:
                state?.signed_pre_key_shape_valid === true,
            signed_pre_key_id_match:
                Number.isSafeInteger(
                    expectedRegistrationState?.signed_pre_key_id,
                ) &&
                state?.signed_pre_key_id ===
                    expectedRegistrationState.signed_pre_key_id,
            signed_pre_key_keypair_math_valid:
                expectedRegistrationState?.signed_pre_key_keypair_math_valid ===
                    true && state?.signed_pre_key_keypair_math_valid === true,
            signed_pre_key_signature_valid:
                expectedRegistrationState?.signed_pre_key_signature_valid ===
                    true && state?.signed_pre_key_signature_valid === true,
            companion_fingerprint_match: hashMatches(
                state?.companion_fingerprint,
                expectedFingerprint,
            ),
            bootstrap_session_record_present:
                state?.bootstrap_session_record_present === true,
            bootstrap_md_session_id_present:
                state?.bootstrap_md_session_id_present === true,
            bootstrap_mms4_record_present:
                state?.bootstrap_mms4_record_present === true,
            bootstrap_mms4_shape_valid:
                state?.bootstrap_mms4_shape_valid === true,
            bootstrap_routing_info_present:
                state?.bootstrap_routing_info_present === true,
            routing_info_hash_match:
                expectedRegistrationState?.routing_info_hash == null ||
                state?.routing_info_hash ===
                    expectedRegistrationState.routing_info_hash,
            bootstrap_noise_record_present:
                state?.bootstrap_noise_record_present === true,
            bootstrap_noise_iv_present:
                state?.bootstrap_noise_iv_present === true,
            bootstrap_encryption_salt_present:
                state?.bootstrap_encryption_salt_present === true,
            bootstrap_signal_meta_row_count: Number.isSafeInteger(
                state?.bootstrap_signal_meta_row_count,
            )
                ? state.bootstrap_signal_meta_row_count
                : 0,
            bootstrap_signal_base_key_row_count: Number.isSafeInteger(
                state?.bootstrap_signal_base_key_row_count,
            )
                ? state.bootstrap_signal_base_key_row_count
                : 0,
            bootstrap_registration_meta_present:
                state?.bootstrap_registration_meta_present === true,
            bootstrap_adv_identity_meta_present:
                state?.bootstrap_adv_identity_meta_present === true,
            canonical_credential_guard_active:
                state?.canonical_credential_guard_active === true,
            canonical_pairing_watchdog_active:
                state?.canonical_pairing_watchdog_active === true,
            canonical_pairing_detected:
                state?.canonical_pairing_detected === true,
            canonical_pairing_ref_present:
                state?.canonical_pairing_ref_present === true,
            canonical_runtime_launch_state: [
                'starting',
                'dispatched',
                'completed',
                'failed',
                'none',
            ].includes(state?.canonical_runtime_launch_state)
                ? state.canonical_runtime_launch_state
                : 'none',
            has_synced: state?.has_synced === true,
            socket_state: state?.socket_state || 'unknown',
        };
    }

    assertCanonicalRegistrationState(state) {
        const requiredChecks = [
            ['registration_flag', 'is_registered'],
            ['noise_present', 'has_noise_info'],
            ['noise_shape', 'noise_shape_valid'],
            ['device_pn_present', 'has_me_device_pn'],
            ['device_pn_id_present', 'me_device_pn_device_id_present'],
            ['device_pn_id_nonzero', 'me_device_pn_device_id_nonzero'],
            ['device_pn_match', 'me_device_pn_hash_match'],
            ['device_lid_id_present', 'me_device_lid_device_id_present'],
            ['device_lid_id_nonzero', 'me_device_lid_device_id_nonzero'],
            ['device_lid_match', 'me_device_lid_hash_match'],
            ['registration_present', 'has_registration_info'],
            ['registration_id_match', 'registration_id_match'],
            ['registration_shape', 'registration_shape_valid'],
            ['noise_public_match', 'noise_public_hash_match'],
            ['noise_keypair_math', 'noise_keypair_math_valid'],
            ['identity_public_match', 'identity_public_hash_match'],
            ['identity_keypair_math', 'identity_keypair_math_valid'],
            ['signed_identity_present', 'has_signed_identity'],
            ['signed_identity_shape', 'signed_identity_shape_valid'],
            ['signed_identity_match', 'signed_identity_hash_match'],
            ['signed_pre_key_present', 'has_signed_pre_key'],
            ['signed_pre_key_shape', 'signed_pre_key_shape_valid'],
            ['signed_pre_key_id_match', 'signed_pre_key_id_match'],
            [
                'signed_pre_key_keypair_math',
                'signed_pre_key_keypair_math_valid',
            ],
            ['signed_pre_key_signature', 'signed_pre_key_signature_valid'],
            ['companion_fingerprint_match', 'companion_fingerprint_match'],
            ['routing_info_match', 'routing_info_hash_match'],
        ];
        const reasonCategories = requiredChecks
            .filter(([, field]) => state?.[field] !== true)
            .map(([category]) => category);
        if (reasonCategories.length > 0) {
            this.logNative(
                'handoff.registration_gate_rejected',
                {
                    reason_categories: reasonCategories,
                    failure_count: reasonCategories.length,
                },
                { force: true },
            );
            const error = new Error(
                'wwebjs_canonical_registration_state_invalid',
            );
            error.code = 'wwebjs_canonical_registration_state_invalid';
            throw error;
        }
    }

    assertCanonicalResealContract(initialImport, resealedImport) {
        const expectedFields = [
            'registration_id',
            'noise_public_hash',
            'identity_public_hash',
            'signed_identity_hash',
            'companion_fingerprint',
            'signed_pre_key_id',
            'routing_info_hash',
            'noise_keypair_math_valid',
            'identity_keypair_math_valid',
            'signed_pre_key_keypair_math_valid',
            'signed_pre_key_signature_valid',
        ];
        const invariantFields = [
            'imported_records',
            'imported_signal_sessions',
            'imported_sender_keys',
            'imported_pq_pre_key_count',
            'imported_pq_last_resort_key_count',
            'imported_pq_migrated',
            'pending_app_state_sync_keys',
            'app_state_import_mode',
            'pq_key_mode',
            'pq_storage_mode',
            'routing_info_imported',
            'signal_session_resync_required',
        ];
        const initialExpected = initialImport?.expected_registration_state;
        const resealedExpected = resealedImport?.expected_registration_state;
        const expectedMismatches = expectedFields.filter(
            (field) =>
                Object.prototype.hasOwnProperty.call(
                    initialExpected || {},
                    field,
                ) === false ||
                Object.prototype.hasOwnProperty.call(
                    resealedExpected || {},
                    field,
                ) === false ||
                initialExpected[field] !== resealedExpected[field],
        );
        const invariantMismatches = invariantFields.filter(
            (field) =>
                initialImport?.[field] !== undefined &&
                (Object.prototype.hasOwnProperty.call(
                    resealedImport || {},
                    field,
                ) === false ||
                    initialImport[field] !== resealedImport[field]),
        );
        if (
            resealedImport?.reload_required !== false ||
            resealedImport?.reconnect_required !== true ||
            expectedMismatches.length > 0 ||
            invariantMismatches.length > 0 ||
            (initialImport?.generated_provider_state &&
                (resealedImport?.generated_provider_state ||
                    resealedImport?.noise_metadata_mode !== 'preserved'))
        ) {
            this.logNative(
                'handoff.reseal_contract_rejected',
                {
                    reload_contract_valid:
                        resealedImport?.reload_required === false,
                    reconnect_contract_valid:
                        resealedImport?.reconnect_required === true,
                    expected_mismatches: expectedMismatches,
                    invariant_mismatches: invariantMismatches,
                    generated_provider_state_reused:
                        !initialImport?.generated_provider_state ||
                        (!resealedImport?.generated_provider_state &&
                            resealedImport?.noise_metadata_mode ===
                                'preserved'),
                },
                { force: true },
            );
            const error = new Error(
                'wwebjs_canonical_post_reload_reseal_mismatch',
            );
            error.code = error.message;
            throw error;
        }
    }

    canUseCanonicalSealedReloadContinuity({
        stagedProviderHandoff,
        resumingCanonicalActivation,
        replayingActiveRevision,
        preserveExistingAppState,
        imported,
        canonicalReload,
        websocketHandshakeCount,
    }) {
        return Boolean(
            stagedProviderHandoff === true &&
            resumingCanonicalActivation !== true &&
            replayingActiveRevision !== true &&
            preserveExistingAppState === true &&
            this.canonicalReusableHandoffNativeAppState === true &&
            imported?.app_state_import_mode === 'preserved_native_profile' &&
            imported?.pending_app_state_sync_keys === 0 &&
            imported?.signal_storage_initialization_mode ===
                'preinitialized_bootstrap_proof' &&
            canonicalReload?.explicitReloadCount === 1 &&
            canonicalReload?.registrationRepairRequired === false &&
            // A freshly reloaded registered document may intentionally stop at
            // UNLAUNCHED while WSS is fenced. The official offline launch below
            // can initialize that runtime without reopening Signal storage.
            // Any other bootstrap-required shape still takes the conservative
            // full reseal path.
            (canonicalReload?.runtimeBootstrapRequired === false ||
                (canonicalReload?.runtimeBootstrapRequired === true &&
                    canonicalReload?.socketState === 'UNLAUNCHED')) &&
            websocketHandshakeCount === 0,
        );
    }

    async resolveReusableHandoffSignalTablePreservation(canonicalProjection) {
        if (!this.canonicalReusableHandoffNativeAppState) return false;
        try {
            const restoredNativeProjection =
                await this.browserBridge.exportCanonicalProjection({
                    // App-state equivalence was already proven against the
                    // reusable-profile authority immediately before this
                    // readback. A transient private SyncDB read failure must
                    // not hide an otherwise complete Signal projection and
                    // force an expensive bulk-table replacement. The bridge
                    // still rejects every non-app-state blocker, so any
                    // uncertainty in device/identity/pre-key/PQ/session/
                    // sender-key material keeps the conservative full-replace
                    // path below.
                    allowIncompleteAppStateOverlay: true,
                });
            if (
                typeof this.store
                    .getReusableHandoffProfileSignalTableEquivalence ===
                'function'
            ) {
                const proof =
                    this.store.getReusableHandoffProfileSignalTableEquivalence(
                        canonicalProjection,
                        restoredNativeProjection,
                    );
                const matches = proof?.componentMatches;
                const requiredMatchNames = [
                    'device',
                    'identity_keys',
                    'pre_keys',
                    'pq_pre_keys',
                    'pq_pre_key_state',
                    'signal_sessions',
                    'sender_keys',
                ];
                if (
                    !proof ||
                    proof.appStateAuthorityMatched !== true ||
                    !matches ||
                    requiredMatchNames.some(
                        (name) => typeof matches[name] !== 'boolean',
                    ) ||
                    matches.device !== true
                ) {
                    return false;
                }
                const components = Object.freeze({
                    identity_keys: matches.identity_keys,
                    pre_keys: matches.pre_keys,
                    // The PQ inventory and its counters are one atomic native
                    // component. Preserving only one side would make upload
                    // boundaries ambiguous after reconnect.
                    pq_pre_keys:
                        matches.pq_pre_keys && matches.pq_pre_key_state,
                    signal_sessions: matches.signal_sessions,
                    sender_keys: matches.sender_keys,
                });
                const values = Object.values(components);
                if (values.every(Boolean)) return true;
                if (!values.some(Boolean)) return false;
                this.logNative(
                    'handoff.reusable_profile_signal_component_selection',
                    {
                        preserved_components: Object.entries(components)
                            .filter(([, matched]) => matched)
                            .map(([name]) => name),
                        replaced_components: Object.entries(components)
                            .filter(([, matched]) => !matched)
                            .map(([name]) => name),
                    },
                    { force: true },
                );
                return components;
            }
            return (
                this.store.canPreserveReusableHandoffProfileSignalTables?.(
                    canonicalProjection,
                    restoredNativeProjection,
                ) === true
            );
        } catch {
            this.logNative(
                'handoff.reusable_profile_signal_table_equivalence_unavailable',
                {
                    error_code:
                        'wwebjs_reusable_profile_signal_projection_unavailable',
                },
                { force: true },
            );
            return false;
        }
    }

    mergeCanonicalSealedReloadRegistrationSummary(runtimeState) {
        if (!this.canonicalSealedReloadRegistrationSummary) {
            throw new Error('wwebjs_canonical_reload_continuity_proof_missing');
        }
        return {
            ...this.canonicalSealedReloadRegistrationSummary,
            is_registered: runtimeState?.is_registered === true,
            canonical_credential_guard_active:
                runtimeState?.canonical_credential_guard_active === true,
            canonical_pairing_watchdog_active:
                runtimeState?.canonical_pairing_watchdog_active === true,
            canonical_pairing_detected:
                runtimeState?.canonical_pairing_detected === true,
            canonical_pairing_ref_present:
                runtimeState?.canonical_pairing_ref_present === true,
            canonical_runtime_launch_state:
                runtimeState?.canonical_runtime_launch_state || 'none',
            has_synced: runtimeState?.has_synced === true,
            socket_state: runtimeState?.socket_state || 'unknown',
        };
    }

    assertCanonicalReconnectSafetyState(
        state,
        {
            requireConnected = false,
            requireGuard = true,
            requireWatchdog = true,
            allowedSocketStates = ['OPENING', 'CONNECTED'],
        } = {},
    ) {
        const socketStateValid = requireConnected
            ? state?.socket_state === 'CONNECTED' && state?.has_synced === true
            : allowedSocketStates.includes(state?.socket_state);
        const deferredRegisteredLaunchValid =
            state?.socket_state !== 'UNLAUNCHED' ||
            ['dispatched', 'completed'].includes(
                state?.canonical_runtime_launch_state,
            ) ||
            (this.canonicalDeferredOnlineRegisteredLaunch === true &&
                state?.canonical_runtime_launch_state === 'none');
        if (
            (requireGuard &&
                state?.canonical_credential_guard_active !== true) ||
            (requireWatchdog &&
                state?.canonical_pairing_watchdog_active !== true) ||
            state?.canonical_pairing_detected === true ||
            state?.canonical_pairing_ref_present === true ||
            state?.canonical_runtime_launch_state === 'failed' ||
            deferredRegisteredLaunchValid !== true ||
            !socketStateValid
        ) {
            const error = new Error(
                requireConnected
                    ? 'wwebjs_canonical_ready_state_invalid'
                    : 'wwebjs_canonical_reconnect_stability_invalid',
            );
            error.code = error.message;
            throw error;
        }
    }

    async assertCanonicalCandidateReady(
        stage,
        {
            requirePublicEventGate = false,
            requireConnected = true,
            requireGuard = true,
            requireWatchdog = true,
            allowedSocketStates,
            allowSealedReloadContinuityProof = false,
        } = {},
    ) {
        if (
            !this.canonicalReconnectProjection ||
            !this.canonicalReconnectExpectedRegistrationState
        ) {
            return undefined;
        }
        if (allowSealedReloadContinuityProof && requireConnected) {
            throw new Error(
                'wwebjs_canonical_reload_continuity_online_forbidden',
            );
        }
        this.browserBridge.assertNoCanonicalCredentialViolation?.();
        const summary = allowSealedReloadContinuityProof
            ? this.mergeCanonicalSealedReloadRegistrationSummary(
                  await this.browserBridge.inspectCanonicalReloadContinuityState(
                      { requireAcknowledged: true },
                  ),
              )
            : this.summarizeCanonicalRegistrationState(
                  await this.browserBridge.inspectCanonicalRegistrationState(),
                  this.canonicalReconnectProjection,
                  this.canonicalReconnectExpectedRegistrationState,
              );
        this.assertCanonicalRegistrationState(summary);
        this.assertCanonicalReconnectSafetyState(summary, {
            requireConnected,
            requireGuard,
            requireWatchdog,
            ...(allowedSocketStates ? { allowedSocketStates } : {}),
        });
        if (requirePublicEventGate) {
            if (
                typeof this.client?.assertPublicEventGateHealthy !== 'function'
            ) {
                throw new Error('wwebjs_public_event_gate_unavailable');
            }
            this.client.assertPublicEventGateHealthy();
        }
        this.logNative(
            'handoff.registration_state.ready_gate',
            { ...summary, stage },
            { force: true },
        );
        return summary;
    }

    clearCanonicalCandidateReferences() {
        this.handoffSourceCanonicalProjection = undefined;
        this.canonicalReconnectProjection = undefined;
        this.canonicalReconnectExpectedRegistrationState = undefined;
        this.canonicalSealedReloadRegistrationSummary = undefined;
        this.canonicalActivationResumeProjection = undefined;
        this.canonicalActiveRestartReplay = false;
        this.canonicalActiveRestartAppStateOverlayRequired = false;
        this.canonicalActiveRestartCanonicalGeneration = undefined;
        this.canonicalActiveRestartAttestedProjection = undefined;
        this.canonicalReusableHandoffNativeAppState = false;
        this.canonicalActivationReadyProjection = undefined;
        this.canonicalActivationUsesPromotedProfileArtifact = false;
        this.pendingCanonicalProviderState = undefined;
        this.pendingCanonicalAppStateProjection = undefined;
    }

    getPersistedCanonicalProjection() {
        return (
            this.lastPersistedCanonicalProjection ||
            this.lastCanonicalProjection
        );
    }

    markCanonicalProjectionPersisted(projection) {
        if (!projection?.tables) {
            throw new Error('wwebjs_canonical_projection_missing');
        }
        this.lastPersistedCanonicalProjection = projection;
        this.lastCanonicalProjection = projection;
        return projection;
    }

    reconcileCanonicalProjectionForPersistence(
        browserProjection,
        {
            baseline = this.getPersistedCanonicalProjection(),
            clearSnapshotResyncMarker = false,
            preserveNativeAppState = this
                .canonicalNativeAppStateAuthoritative === true,
        } = {},
    ) {
        const baselineSnapshotResyncCollections =
            normalizedSnapshotResyncCollections(baseline?.capabilities, {
                optional: true,
            });
        const browserSnapshotResyncCollections =
            normalizedSnapshotResyncCollections(
                browserProjection?.capabilities,
                { optional: true },
            );
        if (
            baselineSnapshotResyncCollections.length > 0 &&
            browserSnapshotResyncCollections.length > 0 &&
            JSON.stringify(baselineSnapshotResyncCollections) !==
                JSON.stringify(browserSnapshotResyncCollections)
        ) {
            throw new WhatsAppSessionCompatibilityError(
                'wwebjs_canonical_app_state_snapshot_resync_capability_invalid',
            );
        }
        const snapshotResyncCollections =
            baselineSnapshotResyncCollections.length > 0
                ? baselineSnapshotResyncCollections
                : browserSnapshotResyncCollections;
        if (preserveNativeAppState) {
            let persistenceProjection = browserProjection;
            const syncKeys =
                browserProjection?.tables?.whatsapp_app_state_sync_keys;
            const versions =
                browserProjection?.tables?.whatsapp_app_state_version;
            const mutationMacs =
                browserProjection?.tables?.whatsapp_app_state_mutation_macs;
            if (
                !Array.isArray(syncKeys) ||
                !Array.isArray(versions) ||
                !Array.isArray(mutationMacs)
            ) {
                throw new WhatsAppSessionCompatibilityError(
                    'wwebjs_canonical_app_state_projection_invalid',
                );
            }
            const materializedCollections = new Set(
                versions.map((row) => row?.name),
            );
            const missingMaterializedCollections =
                CANONICAL_APP_STATE_COLLECTIONS.filter(
                    (name) => !materializedCollections.has(name),
                );
            if (missingMaterializedCollections.length > 0) {
                throw new WhatsAppSessionCompatibilityError(
                    'wwebjs_canonical_app_state_checkpoint_pending',
                    {
                        reason: 'native_profile_materialization_incomplete',
                        materialized_collection_count:
                            CANONICAL_APP_STATE_COLLECTIONS.length -
                            missingMaterializedCollections.length,
                        missing_materialized_collection_count:
                            missingMaterializedCollections.length,
                        required_materialized_collection_count:
                            CANONICAL_APP_STATE_COLLECTIONS.length,
                    },
                );
            }
            if (baseline?.tables) {
                const syncKeyComparison = compareCanonicalAppStateSyncKeys(
                    baseline,
                    browserProjection,
                );
                if (syncKeyComparison.status !== 'ready') {
                    throw new WhatsAppSessionCompatibilityError(
                        'wwebjs_canonical_app_state_diverged',
                        syncKeyComparison,
                    );
                }
                persistenceProjection =
                    reconcileCanonicalAppStateSyncKeysForPersistence(
                        baseline,
                        browserProjection,
                    ).projection;
            }
            const committedVersionByName = new Map(
                versions.map((row) => [row?.name, row?.version]),
            );
            const hasFutureOrInvalidMutationMac = mutationMacs.some((row) => {
                const committedVersion = committedVersionByName.get(row?.name);
                return (
                    !Number.isSafeInteger(committedVersion) ||
                    !Number.isSafeInteger(row?.version) ||
                    row.version < 0 ||
                    row.version > committedVersion
                );
            });
            const requiresPortableNormalization =
                snapshotResyncCollections.length > 0 ||
                hasFutureOrInvalidMutationMac;
            if (!requiresPortableNormalization) {
                return persistenceProjection;
            }
            if (syncKeys.length === 0) {
                throw new WhatsAppSessionCompatibilityError(
                    'wwebjs_canonical_app_state_snapshot_resync_sync_key_missing',
                );
            }
            // Always cross the authoritative native projection through the
            // portable normalizer. Comparing a projection with itself cannot
            // reveal rows above its own committed collection watermark, so
            // an early self-comparison would accidentally retain WWeb-only
            // future MACs in the cross-provider canonical checkpoint.
            const portable =
                normalizeCanonicalAuthoritativeAppStateForPortablePersistence(
                    persistenceProjection,
                );
            if (portable.removed_future_mutation_mac_count > 0) {
                this.logNative(
                    'canonical_checkpoint.app_state_native_baseline_normalized',
                    {
                        removed_future_mutation_mac_count:
                            portable.removed_future_mutation_mac_count,
                        materialized_collection_count:
                            portable.materialized_collection_count,
                    },
                    { force: true },
                );
            }
            return portable.projection;
        }
        const snapshotResyncCollectionSet = new Set(snapshotResyncCollections);
        const baselineAllowsSnapshotResync =
            baselineSnapshotResyncCollections.length > 0;
        let snapshotResync = {
            projection: browserProjection,
            snapshot_resync_collection_count: 0,
            removed_version_row_count: 0,
            removed_mutation_mac_count: 0,
            collection_ids: [],
        };
        if (baselineAllowsSnapshotResync) {
            snapshotResync = normalizeCanonicalAppStateForSnapshotResync(
                browserProjection,
                {
                    eligibleCollectionNames: snapshotResyncCollectionSet,
                },
            );
        }
        const persistenceProjection = snapshotResync.projection;
        const trustedBaseline = baseline || persistenceProjection;
        const reconciled = reconcileCanonicalAppStateForPersistence(
            trustedBaseline,
            persistenceProjection,
        );
        if (snapshotResync.snapshot_resync_collection_count > 0) {
            this.logNative(
                'canonical_checkpoint.app_state_snapshot_resync',
                {
                    snapshot_resync_collection_count:
                        snapshotResync.snapshot_resync_collection_count,
                    removed_version_row_count:
                        snapshotResync.removed_version_row_count,
                    removed_mutation_mac_count:
                        snapshotResync.removed_mutation_mac_count,
                    collection_ids: snapshotResync.collection_ids,
                },
                { force: true },
            );
        }
        if (reconciled.comparison.normalized_future_substitution_count > 0) {
            this.logNative(
                'canonical_checkpoint.app_state_reconciled',
                {
                    normalized_future_substitution_count:
                        reconciled.comparison
                            .normalized_future_substitution_count,
                    persisted_future_target_mac_count:
                        reconciled.comparison.persisted_future_target_mac_count,
                },
                { force: true },
            );
        }
        const materializedCollectionNames = new Set(
            reconciled.projection.tables.whatsapp_app_state_version.map(
                (row) => row.name,
            ),
        );
        const missingMaterializedCollectionCount =
            snapshotResyncCollections.reduce(
                (count, name) =>
                    count + (materializedCollectionNames.has(name) ? 0 : 1),
                0,
            );
        const materializedCollectionCount =
            snapshotResyncCollections.length -
            missingMaterializedCollectionCount;
        if (
            clearSnapshotResyncMarker &&
            snapshotResyncCollections.length > 0 &&
            (snapshotResync.snapshot_resync_collection_count > 0 ||
                missingMaterializedCollectionCount > 0)
        ) {
            throw new WhatsAppSessionCompatibilityError(
                'wwebjs_canonical_app_state_checkpoint_pending',
                {
                    reason: 'snapshot_resync_not_materialized',
                    snapshot_resync_collection_count:
                        snapshotResync.snapshot_resync_collection_count,
                    materialized_collection_count: materializedCollectionCount,
                    missing_materialized_collection_count:
                        missingMaterializedCollectionCount,
                    required_materialized_collection_count:
                        snapshotResyncCollections.length,
                },
            );
        }
        const preserveSnapshotResyncMarker =
            snapshotResyncCollections.length > 0 && !clearSnapshotResyncMarker;
        return {
            ...reconciled.projection,
            capabilities: {
                ...reconciled.projection.capabilities,
                app_state_snapshot_resync_required:
                    preserveSnapshotResyncMarker,
                app_state_snapshot_resync_collections:
                    preserveSnapshotResyncMarker
                        ? [...snapshotResyncCollections]
                        : [],
            },
        };
    }

    buildCanonicalOfflineCheckpointProjection(browserProjection) {
        const source = this.canonicalReconnectProjection;
        if (!source?.tables || !browserProjection?.tables) {
            throw new Error(
                'wwebjs_canonical_offline_checkpoint_projection_missing',
            );
        }
        const sourceSnapshotResyncCollections =
            normalizedSnapshotResyncCollections(source.capabilities, {
                optional: true,
            });
        const merged = {
            ...browserProjection,
            complete: true,
            blockers: [],
            capabilities: {
                ...browserProjection.capabilities,
                app_state_snapshot_resync_required:
                    sourceSnapshotResyncCollections.length > 0,
                app_state_snapshot_resync_collections: [
                    ...sourceSnapshotResyncCollections,
                ],
            },
            provider_state:
                browserProjection.provider_state || source.provider_state,
            transport_state:
                browserProjection.transport_state || source.transport_state,
            tables: {
                ...browserProjection.tables,
                whatsapp_app_state_sync_keys:
                    source.tables.whatsapp_app_state_sync_keys,
                whatsapp_app_state_version:
                    source.tables.whatsapp_app_state_version,
                whatsapp_app_state_mutation_macs:
                    source.tables.whatsapp_app_state_mutation_macs,
            },
        };
        const normalized = canonicalBrowserProjectionToStore(
            canonicalStoreProjectionToBrowser(merged, {
                webVersion: browserProjection.web_version,
            }),
        );
        if (source.passthrough_tables) {
            normalized.passthrough_tables = source.passthrough_tables;
        }
        return normalized;
    }

    async validateCanonicalCandidateIdentityOffline(
        projection,
        { persistProjection = true } = {},
    ) {
        const jid = projection?.device?.jid;
        const fingerprint = projection?.device?.device_fingerprint;
        if (!jid || !fingerprint) {
            throw new Error('wwebjs_canonical_offline_identity_missing');
        }
        const identityPreflight = await this.store.preflightReadyIdentity({
            jid,
            companionFingerprint: fingerprint,
            canonicalProjection: projection,
        });
        if (!persistProjection) {
            return identityPreflight.canonicalProjection;
        }
        await this.store.saveCanonicalProjection({
            projection: identityPreflight.canonicalProjection,
            source: 'offline_handoff_preflight',
        });
        const validation = await this.store.validateReadyIdentity({
            jid,
            companionFingerprint: fingerprint,
        });
        if (
            !validation.fingerprintVerified &&
            !validation.fingerprintRegistered
        ) {
            throw new Error('wwebjs_companion_fingerprint_not_verified');
        }
        this.markCanonicalProjectionPersisted(
            identityPreflight.canonicalProjection,
        );
        return identityPreflight.canonicalProjection;
    }

    async checkpointCanonicalCandidateOffline({
        source,
        preserveExistingProfileArtifact = false,
        allowIncompleteAppStateOverlay = false,
        trustedCanonicalProjection,
    } = {}) {
        if (
            trustedCanonicalProjection !== undefined &&
            !this.canonicalSealedReloadRegistrationSummary
        ) {
            throw new Error(
                'wwebjs_canonical_reload_continuity_checkpoint_forbidden',
            );
        }
        this.logNative('checkpoint.offline_candidate_started');
        const maxAttempts = 6;
        for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
            await this.browserBridge.flush();
            const initialDirtyPlan =
                this.browserBridge.getCanonicalDirtyPlan?.();
            let browserProjection;
            if (trustedCanonicalProjection !== undefined) {
                await this.browserBridge.inspectCanonicalReloadContinuityState({
                    requireAcknowledged: true,
                });
                browserProjection = trustedCanonicalProjection;
                this.logNative(
                    'checkpoint.offline_candidate_sealed_projection_reused',
                    {
                        proof_source:
                            'pre_reload_cryptographic_seal_and_reload_guard',
                    },
                    { force: true },
                );
            } else {
                try {
                    browserProjection =
                        await this.browserBridge.exportCanonicalProjection({
                            allowIncompleteAppStateOverlay,
                        });
                } catch (error) {
                    const blockers = Array.isArray(error?.details?.blockers)
                        ? [...new Set(error.details.blockers)].filter(
                              (entry) => typeof entry === 'string',
                          )
                        : [];
                    const transientAppStateRead =
                        error?.code ===
                            'wwebjs_canonical_projection_incomplete' &&
                        blockers.length > 0 &&
                        blockers.every((entry) =>
                            CANONICAL_OFFLINE_CHECKPOINT_TRANSIENT_BLOCKERS.has(
                                entry,
                            ),
                        );
                    if (!transientAppStateRead || attempt >= maxAttempts) {
                        throw error;
                    }
                    this.logNative(
                        'checkpoint.offline_candidate_retry',
                        {
                            attempt,
                            reason: 'app_state_projection_transient',
                            blockers: blockers.sort(),
                        },
                        { force: true },
                    );
                    await this.delay(Math.min(attempt * 250, 1000));
                    continue;
                }
            }
            const canonicalProjection =
                this.buildCanonicalOfflineCheckpointProjection(
                    browserProjection,
                );
            await this.validateCanonicalCandidateIdentityOffline(
                canonicalProjection,
                {
                    persistProjection: !preserveExistingProfileArtifact,
                },
            );
            if (!preserveExistingProfileArtifact) {
                try {
                    await this.withCanonicalProfileSnapshotFreeze(() =>
                        this.store.checkpointProfile({
                            profilePath: this.userDataDir,
                            canonicalProjection,
                            source:
                                source ||
                                this.store.revisionSource ||
                                'handoff',
                            promote: false,
                        }),
                    );
                } catch (error) {
                    const errorCode = String(
                        error?.code || error?.message || '',
                    );
                    if (
                        errorCode !==
                        'whatsapp_artifact_profile_changed_during_checkpoint'
                    ) {
                        throw error;
                    }
                    this.logNative(
                        'checkpoint.offline_candidate_retry',
                        {
                            attempt,
                            tail_dirty: true,
                            reason: 'profile_changed_during_checkpoint',
                        },
                        { force: true },
                    );
                    if (attempt < maxAttempts) await this.delay(attempt * 100);
                    continue;
                }
            }
            const tail = await this.browserBridge.flush();
            const finalDirtyPlan = this.browserBridge.getCanonicalDirtyPlan?.();
            const stable =
                !tail?.dirty &&
                (!initialDirtyPlan ||
                    !finalDirtyPlan ||
                    finalDirtyPlan.generation === initialDirtyPlan.generation);
            if (stable) {
                if (!preserveExistingProfileArtifact) {
                    this.browserBridge.acknowledgeCanonicalDirtyPlan?.(
                        initialDirtyPlan,
                    );
                    await this.browserBridge.markClean();
                    this.profileDirty = false;
                    this.markCanonicalProjectionPersisted(canonicalProjection);
                }
                this.logNative(
                    preserveExistingProfileArtifact
                        ? 'checkpoint.offline_candidate_profile_preserved'
                        : 'checkpoint.offline_candidate_completed',
                    {
                        attempt_count: attempt,
                        ...(preserveExistingProfileArtifact
                            ? {
                                  reason: 'active_restart_app_state_pending',
                              }
                            : {}),
                    },
                    { force: true },
                );
                return true;
            }
            this.logNative(
                'checkpoint.offline_candidate_retry',
                { attempt, tail_dirty: tail?.dirty === true },
                { force: true },
            );
            if (attempt < maxAttempts) await this.delay(attempt * 100);
        }
        throw new Error(
            'wwebjs_canonical_offline_checkpoint_mutated_during_upload',
        );
    }

    async checkpointReusableCanonicalHandoffOffline({
        resealed,
        preserveExistingProfileArtifact = false,
        trustedCanonicalProjection,
    } = {}) {
        if (
            resealed?.app_state_import_mode !== 'preserved_native_profile' ||
            resealed?.pending_app_state_sync_keys !== 0
        ) {
            throw new WhatsAppSessionCompatibilityError(
                'wwebjs_reusable_handoff_native_app_state_invalid',
            );
        }

        // A reusable profile belongs to an older WWebJS revision. Its native
        // app-state may be reused only after the checksum gate, but the first
        // activation CAS deliberately requires an offline artifact owned by
        // the target revision. A post-PONR retry is the inverse case: that
        // target-local artifact is already promoted and its predecessor is
        // retained as the handoff rollback proof, so rotating it again must
        // remain forbidden until the handoff completes.
        await this.checkpointCanonicalCandidateOffline({
            source: this.store.revisionSource || 'handoff',
            preserveExistingProfileArtifact,
            allowIncompleteAppStateOverlay: true,
            ...(trustedCanonicalProjection
                ? { trustedCanonicalProjection }
                : {}),
        });
        this.canonicalNativeAppStateAuthoritative = true;
        this.preserveExistingProfileArtifactDuringCanonicalCatchUp = true;
        this.logNative(
            'handoff.reusable_profile_app_state_authoritative',
            {
                app_state_import_mode: resealed.app_state_import_mode,
                pending_app_state_sync_keys: 0,
                target_profile_checkpointed: !preserveExistingProfileArtifact,
                target_profile_preserved: preserveExistingProfileArtifact,
            },
            { force: true },
        );
        return true;
    }

    async withCanonicalProfileSnapshotFreeze(operation) {
        await this.browserBridge.freezeCanonicalProfileSnapshot();
        let result;
        let hasPrimaryError = false;
        let primaryError;
        try {
            result = await operation();
        } catch (error) {
            hasPrimaryError = true;
            primaryError = error;
        }
        try {
            await this.browserBridge.resumeCanonicalProfileSnapshot();
        } catch (resumeError) {
            if (hasPrimaryError) {
                throw new AggregateError(
                    [primaryError, resumeError],
                    'wwebjs_canonical_profile_checkpoint_resume_failed',
                    { cause: primaryError },
                );
            }
            throw resumeError;
        }
        if (hasPrimaryError) throw primaryError;
        return result;
    }

    async checkpointCanonicalActivationReady() {
        return this.checkpointCanonicalGuardedReady({
            finalizeActivation: true,
        });
    }

    async checkpointCanonicalActiveRestartReady() {
        return this.checkpointCanonicalGuardedReady({
            finalizeActivation: false,
        });
    }

    getCanonicalActivationCheckpointState() {
        const profileSnapshotFrozen =
            this.browserBridge?.canonicalProfileSnapshotFreeze !== undefined;
        const activationRecoveryRequired =
            this.isCanonicalActivationRecoveryRequired();
        const activeRestartAttestationPending =
            this.isCanonicalActiveRestartAttestationPending();
        return {
            inProgress:
                this.canonicalActivationCheckpointInProgress === true ||
                profileSnapshotFrozen ||
                activationRecoveryRequired ||
                activeRestartAttestationPending,
            generation: this.canonicalActivationCheckpointGeneration,
            profileSnapshotFrozen,
            activationRecoveryRequired,
            activeRestartAttestationPending,
        };
    }

    async checkpointCanonicalGuardedReady({ finalizeActivation }) {
        if (this.canonicalActivationCheckpointInProgress) {
            throw new Error(
                'wwebjs_canonical_activation_checkpoint_already_running',
            );
        }
        if (
            this.canonicalActivationCheckpointGeneration >=
            Number.MAX_SAFE_INTEGER
        ) {
            throw new Error(
                'wwebjs_canonical_activation_checkpoint_generation_exhausted',
            );
        }
        this.canonicalActivationCheckpointGeneration += 1;
        this.canonicalActivationCheckpointInProgress = true;
        clearTimeout(this.criticalCheckpointTimer);
        this.criticalCheckpointTimer = undefined;
        try {
            // A journal notification may already have queued a canonical-only
            // checkpoint. Drain it before taking the one activation artifact
            // so database and profile writers cannot race each other.
            await this.checkpointTail;
            return await this.performCanonicalActivationReadyCheckpoint({
                finalizeActivation,
            });
        } finally {
            this.canonicalActivationCheckpointInProgress = false;
        }
    }

    async performCanonicalActivationReadyCheckpoint({
        finalizeActivation = true,
    } = {}) {
        if (
            this.pendingCanonicalAppStateCatchUp ||
            this.pendingPostQuantumBootstrap
        ) {
            throw new Error('wwebjs_canonical_activation_work_incomplete');
        }
        const checkpointStage = finalizeActivation
            ? 'activation_ready'
            : 'active_restart_ready';
        this.logNative(`checkpoint.${checkpointStage}_started`, undefined, {
            force: true,
        });
        await this.browserBridge.quiesceNetwork();
        // The first canonical reconnect deliberately moves destructive
        // credential protection from `sealed` to `live`. A later readiness
        // snapshot must establish a fresh offline suppression boundary before
        // freezing Chromium; otherwise reconnect proof would either accept a
        // live credential writer or fail because the runtime is not sealed.
        await this.browserBridge.armCanonicalCredentialGuard({
            ttlMs: Math.min(
                300000,
                Math.max(
                    240000,
                    (this.client.options.authTimeoutMs || 30000) * 4,
                ),
            ),
            navigationScoped: true,
        });
        await this.browserBridge.acknowledgeCanonicalCredentialProtection();
        let checkpoint;
        let canonicalProjection;
        let retainedAttestedProjection;
        const resumedPromotedProfile = Boolean(
            finalizeActivation &&
            this.canonicalActivationUsesPromotedProfileArtifact,
        );
        // A resumed activation can reuse its current target-local artifact
        // only when it is already a distinct, full checkpoint written after
        // the point of no return. The original promoted artifact is the
        // rollback proof and must never be presented as the post-activation
        // readiness proof. This read is only an optimization decision; the
        // database finalization CAS still validates the complete contract.
        const retainPromotedProfileArtifact = Boolean(
            resumedPromotedProfile &&
            typeof this.store.canReusePromotedProfileForActivationCheckpoint ===
                'function' &&
            (await this.store.canReusePromotedProfileForActivationCheckpoint()),
        );
        if (resumedPromotedProfile) {
            this.logNative(
                'checkpoint.activation_ready_profile_strategy',
                {
                    reuse_post_activation_artifact:
                        retainPromotedProfileArtifact,
                    create_fresh_post_activation_artifact:
                        !retainPromotedProfileArtifact,
                },
                { force: true },
            );
        }
        for (let attempt = 1; attempt <= 4; attempt += 1) {
            await this.browserBridge.flush();
            const initialDirtyPlan =
                this.browserBridge.getCanonicalDirtyPlan?.();
            const browserProjection =
                await this.browserBridge.exportCanonicalProjection();
            retainedAttestedProjection = false;
            try {
                canonicalProjection =
                    this.reconcileCanonicalProjectionForPersistence(
                        browserProjection,
                        {
                            baseline:
                                finalizeActivation &&
                                this.canonicalActivationReadyProjection
                                    ? this.canonicalActivationReadyProjection
                                    : this.getPersistedCanonicalProjection(),
                            preserveNativeAppState: Boolean(
                                finalizeActivation &&
                                this.canonicalActivationReadyProjection,
                            ),
                        },
                    );
            } catch (error) {
                if (
                    finalizeActivation ||
                    error?.code !==
                        'wwebjs_canonical_app_state_checkpoint_pending' ||
                    !this.canonicalActiveRestartAttestedProjection?.tables
                ) {
                    throw error;
                }
                // The authenticated two-sample identity gate immediately
                // before this checkpoint already proved a complete portable
                // projection. Taking WWeb offline can briefly expose an
                // incomplete IndexedDB app-state view while the native store
                // closes its live sync transaction. Persist the attested
                // snapshot into the existing profile anchor and retain the
                // dirty journal so a post-READY critical checkpoint captures
                // every later mutation.
                canonicalProjection =
                    this.canonicalActiveRestartAttestedProjection;
                retainedAttestedProjection = true;
                this.logNative(
                    'checkpoint.active_restart_attested_projection_retained',
                    {
                        reason:
                            error.details?.reason ||
                            'offline_app_state_materialization_pending',
                        attempt,
                        pending_tail_retained: true,
                    },
                    { force: true },
                );
            }
            if (
                !finalizeActivation &&
                this.canonicalNativeAppStateAuthoritative &&
                !canonicalAppStateTablesEqual(
                    this.canonicalActiveRestartAttestedProjection ||
                        this.getPersistedCanonicalProjection(),
                    canonicalProjection,
                )
            ) {
                // App-state remains live between the authenticated two-sample
                // gate and this final offline checkpoint (PQ recovery is one
                // legitimate writer in that interval). The browser profile is
                // already the typed authority, and the reconciler above has
                // revalidated its sync-key lineage, complete collection set,
                // row shapes and portable watermarks against the durable
                // baseline. Re-attest the now-quiesced projection instead of
                // turning safe forward progress into an endless restart loop.
                this.logNative(
                    'checkpoint.active_restart_app_state_reattested',
                    {
                        reason: 'authoritative_native_progress',
                        attempt,
                    },
                    { force: true },
                );
                this.canonicalActiveRestartAttestedProjection =
                    canonicalProjection;
            }
            try {
                checkpoint = finalizeActivation
                    ? retainPromotedProfileArtifact
                        ? await this.store.saveCanonicalProjection({
                              projection: canonicalProjection,
                              source: 'activation_ready_promoted_profile',
                              dirtyPlan: initialDirtyPlan,
                          })
                        : await this.withCanonicalProfileSnapshotFreeze(() =>
                              this.store.checkpointProfile({
                                  profilePath: this.userDataDir,
                                  canonicalProjection,
                                  source: 'checkpoint',
                                  promote: false,
                              }),
                          )
                    : this.canonicalActiveRestartAppStateOverlayRequired
                      ? await this.withCanonicalProfileSnapshotFreeze(() =>
                            this.store.checkpointProfile({
                                profilePath: this.userDataDir,
                                canonicalProjection,
                                source: 'active_restart_overlay_rebased',
                                promote: true,
                            }),
                        )
                      : await this.store.saveCanonicalProjection({
                            projection: canonicalProjection,
                            source: 'active_restart_ready',
                            dirtyPlan: initialDirtyPlan,
                        });
            } catch (error) {
                const errorCode = String(error?.code || error?.message || '');
                if (
                    errorCode !==
                    'whatsapp_artifact_profile_changed_during_checkpoint'
                ) {
                    throw error;
                }
                checkpoint = undefined;
            }
            const tail = await this.browserBridge.flush();
            const finalDirtyPlan = this.browserBridge.getCanonicalDirtyPlan?.();
            const canonicalTailChanged =
                tail?.critical === true ||
                (initialDirtyPlan &&
                    finalDirtyPlan &&
                    finalDirtyPlan.generation !== initialDirtyPlan.generation);
            if (
                !checkpoint ||
                (canonicalTailChanged && !retainedAttestedProjection)
            ) {
                this.logNative(
                    `checkpoint.${checkpointStage}_retry`,
                    {
                        attempt,
                        profile_changed_during_checkpoint: !checkpoint,
                        tail_dirty: tail?.dirty === true,
                        tail_critical: tail?.critical === true,
                        event_count: tail?.events?.length || 0,
                        dropped_count: tail?.dropped || 0,
                        local_storage_event_count:
                            tail?.events?.filter(
                                (event) => event?.area === 'local_storage',
                            ).length || 0,
                        indexeddb_event_count:
                            tail?.events?.filter(
                                (event) => event?.area === 'indexeddb',
                            ).length || 0,
                        initial_generation: initialDirtyPlan?.generation || 0,
                        final_generation: finalDirtyPlan?.generation || 0,
                        canonical_full_replace:
                            finalDirtyPlan?.fullReplace === true,
                        canonical_device_changed:
                            finalDirtyPlan?.device === true,
                        canonical_table_count:
                            finalDirtyPlan?.tables?.length || 0,
                        canonical_tables: finalDirtyPlan?.tables || [],
                    },
                    { force: true },
                );
                checkpoint = undefined;
                if (attempt < 4) {
                    await this.delay(attempt * 100);
                    continue;
                }
                break;
            }
            if (tail?.dirty) {
                this.logNative(
                    `checkpoint.${checkpointStage}_noncritical_tail`,
                    {
                        attempt,
                        event_count: tail.events?.length || 0,
                        dropped_count: tail.dropped || 0,
                        local_storage_event_count:
                            tail.events?.filter(
                                (event) => event?.area === 'local_storage',
                            ).length || 0,
                        indexeddb_event_count:
                            tail.events?.filter(
                                (event) => event?.area === 'indexeddb',
                            ).length || 0,
                        canonical_table_count:
                            finalDirtyPlan?.tables?.length || 0,
                        canonical_tables: finalDirtyPlan?.tables || [],
                    },
                    { force: true },
                );
            }
            if (retainedAttestedProjection || retainPromotedProfileArtifact) {
                this.profileDirty = true;
                if (retainPromotedProfileArtifact) {
                    this.logNative(
                        'checkpoint.activation_ready_promoted_profile_retained',
                        {
                            reason: 'post_ponr_handoff_retry',
                            attempt,
                            pending_tail_retained: true,
                        },
                        { force: true },
                    );
                }
            } else {
                this.browserBridge.acknowledgeCanonicalDirtyPlan?.(
                    initialDirtyPlan,
                );
                await this.browserBridge.markClean();
                this.profileDirty = false;
            }
            this.markCanonicalProjectionPersisted(canonicalProjection);
            break;
        }
        if (!checkpoint) {
            throw new Error(
                'wwebjs_canonical_activation_checkpoint_mutated_during_upload',
            );
        }
        if (
            !checkpoint?.artifactId ||
            !/^[0-9a-f-]{36}$/i.test(checkpoint.artifactId) ||
            !/^[0-9a-f]{64}$/.test(checkpoint.checksumSha256 || '')
        ) {
            throw new Error(
                'wwebjs_canonical_activation_checkpoint_proof_invalid',
            );
        }

        // This update deliberately happens only after the offline artifact
        // and canonical tail are durable and stable. No network is released
        // between this proof and the database finalization CAS.
        if (finalizeActivation) {
            // The gate reads canonical tables from PostgreSQL. Checkpoint it
            // only after the frozen profile transaction replaced those rows,
            // so recovery can never attest the pre-sync candidate artifact.
            const appStateResyncGate =
                await this.store.checkpointAppStateSnapshotResyncGate?.();
            if (appStateResyncGate && !appStateResyncGate.ready) {
                throw new Error(
                    'whatsapp_session_app_state_snapshot_resync_pending',
                );
            }
            await this.store.markCanonicalActivationPending({
                appStateHydrationRequired: false,
                pqBootstrapRequired: false,
                readyCheckpointArtifactId: checkpoint.artifactId,
                readyCheckpointChecksumSha256: checkpoint.checksumSha256,
            });
        }
        await this.store.renewLease();
        this.store.assertLocalLease();
        if (typeof this.client?.assertPublicEventGateHealthy !== 'function') {
            throw new Error('wwebjs_public_event_gate_unavailable');
        }
        this.client.assertPublicEventGateHealthy();
        if (finalizeActivation) {
            await this.store.finalizeActivation();
            this.canonicalActivationMarkerPresent = false;
        } else if (this.store.revisionStatus !== 'active') {
            throw new Error(
                'wwebjs_canonical_active_restart_revision_not_active',
            );
        }

        const reconnect = await this.browserBridge.rearmCanonicalImportedSocket(
            {
                timeoutMs: Math.min(
                    this.client.options.authTimeoutMs || 30000,
                    30000,
                ),
                allowEstablished: true,
            },
        );
        await this.browserBridge.releaseCanonicalImportedNetwork();
        await this.browserBridge.waitForCanonicalConnected({
            timeoutMs: Math.min(
                180000,
                Math.max(
                    60000,
                    (this.client.options.authTimeoutMs || 30000) * 4,
                ),
            ),
        });
        await this.assertCanonicalCandidateReady(
            finalizeActivation
                ? 'activation_checkpoint_reconnected'
                : 'active_restart_checkpoint_reconnected',
            { requirePublicEventGate: true },
        );
        this.client.assertPublicEventGateHealthy();
        await this.browserBridge.disarmCanonicalCredentialGuard({
            strict: true,
        });
        await this.browserBridge.disarmCanonicalPairingWatchdog();
        this.logNative(
            `checkpoint.${checkpointStage}_completed`,
            {
                socket_state: 'CONNECTED',
                has_synced: true,
                previous_socket_state: reconnect.previous_socket_state,
            },
            { force: true },
        );
        return true;
    }

    shouldDelayPublicEventsUntilReady() {
        return Boolean(
            this.nativePostgres &&
            !this.authReady &&
            (this.store.isHandoffRevision?.() === true ||
                this.canonicalReconnectProjection ||
                this.canonicalActivationMarkerPresent ||
                this.canonicalWebSocketGateRequired),
        );
    }

    async onInitializationFailure(error) {
        if (!this.nativePostgres) return;
        this.logNativeFailure('client.initialization_failed', { error });
        const failureCode = stableNativeFailureCode(
            error,
            'handoff_client_initialization_failed',
        );
        const failure = await this.finalizeNativeFailure(error, failureCode);
        if (failure !== error) throw failure;
    }

    /**
     * Client invokes this only after Chromium has been closed. Keeping local
     * profile deletion and owned-pool shutdown on this side of that boundary
     * prevents Chrome from recreating files while cleanup runs.
     */
    async afterInitializationFailureBrowserClosed(initializationError) {
        if (!this.nativePostgres) return;
        if (!this.nativeFailurePostBrowserCleanupPromise) {
            this.nativeFailurePostBrowserCleanupPromise = (async () => {
                const failures = [];
                if (!this.nativeFailureBrowserTerminationConfirmed) {
                    // Client may have completed browser.close() after the
                    // strategy's first kill attempt failed. Retry the fenced
                    // finalization now: a captured post-CAS projection must be
                    // checkpointed before any rollback or lease release.
                    this.nativeFailureStopPromise = undefined;
                    this.nativeFailureFinalizationPromise = undefined;
                    const retryPrimary =
                        initializationError instanceof Error
                            ? initializationError
                            : new Error('wwebjs_client_initialization_failed');
                    const retried = await this.finalizeNativeFailure(
                        retryPrimary,
                        retryPrimary.code ||
                            'handoff_client_post_browser_close',
                    );
                    if (retried !== retryPrimary) failures.push(retried);
                    if (!this.nativeFailureBrowserTerminationConfirmed) {
                        const error = new Error(
                            'wwebjs_browser_termination_unconfirmed',
                        );
                        failures.push(error);
                        throw new AggregateError(
                            failures,
                            'wwebjs_native_post_browser_cleanup_failed',
                            { cause: error },
                        );
                    }
                }
                try {
                    await this.removeLocalSession();
                } catch (error) {
                    failures.push(error);
                    this.logNativeFailure(
                        'client.failure_local_profile_remove_failed',
                        { error },
                    );
                }
                try {
                    await this.store.close();
                } catch (error) {
                    failures.push(error);
                    this.logNativeFailure('client.failure_store_close_failed', {
                        error,
                    });
                }
                this.clearCanonicalCandidateReferences();
                if (failures.length > 0) {
                    throw new AggregateError(
                        failures,
                        'wwebjs_native_post_browser_cleanup_failed',
                    );
                }
            })();
        }
        return this.nativeFailurePostBrowserCleanupPromise;
    }

    async logout({ preserveInitialPairing = false } = {}) {
        const keepInitialPairingRevision =
            preserveInitialPairing === true && this.isInitialPairingPending();
        this.shutdownRequested = true;
        this.stopBackupSync();
        await this.checkpointTail.catch(() => {});
        this.authReady = false;
        if (this.nativePostgres) {
            await this.browserBridge?.close();
            if (keepInitialPairingRevision) {
                this.logNative(
                    'pairing.restart_session_preserved',
                    {
                        revision_status: this.store.revisionStatus,
                        revision_source: this.store.revisionSource,
                    },
                    { force: true },
                );
            } else {
                await this.store.delete();
            }
            // A server-side/mobile logout navigates the still-open page back
            // to pairing and Client immediately initializes this strategy
            // again. Keep the pool reusable in that path; an explicit
            // Client.logout() has already closed Chromium and can close it.
            if (isBrowserConnected(this.client.pupBrowser)) {
                await this.store.releaseLease();
            } else {
                await this.store.close();
            }
        } else {
            await this.deleteRemoteSession();
        }
        this.canonicalNativeAppStateAuthoritative = false;
        await this.removeLocalSession();
    }

    isInitialPairingPending() {
        return Boolean(
            this.nativePostgres &&
            this.authReady !== true &&
            this.store.revisionStatus === 'staging' &&
            this.store.revisionSource === 'pairing',
        );
    }

    async destroy() {
        await this.shutdown();
    }

    async disconnect() {
        this.shutdownRequested = true;
        this.stopBackupSync();
        // Client calls destroy() immediately after this hook. The final
        // checkpoint belongs to shutdown(); saving here as well would rotate
        // the active/previous revisions twice with the same Chromium profile.
        await this.checkpointTail;
    }

    async beforeBrowserDestroyed() {
        if (
            !this.nativePostgres ||
            (!this.authReady && !this.isCanonicalActivationRecoveryRequired())
        ) {
            return;
        }
        if (this.isCanonicalActiveRestartAttestationPending()) {
            this.logNative(
                'checkpoint.shutdown_projection_skipped',
                { reason: 'active_restart_attestation_pending' },
                { force: true },
            );
            return;
        }
        this.stopBackupSync();
        await this.checkpointTail;
        if (!this.browserBridge) return;
        if (this.shutdownProjection) return;
        const browserConnected = isBrowserConnected(this.client?.pupBrowser);
        const pageClosed = this.client?.pupPage?.isClosed?.() === true;
        if (
            this.nativeFailureBrowserTerminationConfirmed ||
            !browserConnected ||
            pageClosed
        ) {
            // Failure cleanup may have already stopped Chromium, captured the
            // recovery projection, checkpointed it, and released the lease.
            // A dead Page is itself the definitive writer fence; asking the
            // bridge for a second in-page quiescence proof can only manufacture
            // a ProtocolError and turn a successful cleanup into a false
            // shutdown failure.
            this.logNative(
                'checkpoint.shutdown_projection_skipped',
                {
                    reason: 'runtime_already_stopped',
                    browser_connected: browserConnected,
                    page_closed: pageClosed,
                    failure_browser_stopped:
                        this.nativeFailureBrowserTerminationConfirmed === true,
                },
                { force: true },
            );
            return;
        }
        let canonicalProjection;
        try {
            await this.browserBridge.quiesceNetwork();
            await this.browserBridge.flush();
            const browserProjection =
                await this.browserBridge.exportCanonicalProjection();
            // A promoted handoff can be shutting down while the browser is
            // still catching up the source app-state. Persisting the
            // browser-only view here would replace durable source keys/MACs
            // with an incomplete projection and make the next restart
            // unrecoverable.
            const persistenceCandidate = this.pendingCanonicalAppStateCatchUp
                ? this.buildCanonicalOfflineCheckpointProjection(
                      browserProjection,
                  )
                : browserProjection;
            canonicalProjection =
                this.reconcileCanonicalProjectionForPersistence(
                    persistenceCandidate,
                );
            this.shutdownProjection = { canonicalProjection };
            this.shutdownProjectionCaptureFailed = false;
        } catch (error) {
            // Chromium can still mutate its LevelDB profile until the network
            // fence and the matching canonical export have both succeeded.
            // Client.destroy() deliberately closes Chromium even when this
            // hook fails. Remember that missing proof so the post-close phase
            // cannot combine the newer profile with an older, previously
            // persisted projection and replace the last coherent artifact.
            this.shutdownProjectionCaptureFailed = true;
            const contextUnavailableAfterOffline = Boolean(
                error?.code === 'wwebjs_network_quiescence_failed' &&
                error?.details?.offline_command_applied === true &&
                error?.details?.context_unavailable_after_offline === true,
            );
            this.logNativeFailure('checkpoint.shutdown_projection_failed', {
                existing_profile_artifact_preserved: true,
                context_unavailable_after_offline:
                    contextUnavailableAfterOffline,
                error_code: safeFailureCode(
                    error?.code || error?.message,
                    'wwebjs_shutdown_projection_capture_failed',
                ),
            });
            if (contextUnavailableAfterOffline) {
                // CDP accepted the target-wide offline fence, but WhatsApp's
                // offline navigation replaced the document for the entire
                // bounded proof window. There is no safe page projection to
                // pair with the newer profile. Preserve the last coherent
                // artifact and allow Client.destroy() to close Chromium; all
                // other quiescence failures still propagate fail-closed.
                this.logNative(
                    'checkpoint.shutdown_projection_context_preserved',
                    {
                        existing_profile_artifact_preserved: true,
                        transient_navigation_retries:
                            error.details.transient_navigation_retries,
                    },
                    { force: true },
                );
                return;
            }
            throw error;
        }
        await this.browserBridge.close();
        this.logNative('checkpoint.shutdown_projection_captured', {
            canonical_record_count: canonicalProjection.record_count,
            canonical_size_bytes: canonicalProjection.size_bytes,
        });
    }

    /**
     * Persists a final checkpoint without deleting the remote session, then
     * removes the ephemeral Chromium profile.
     */
    async shutdown() {
        if (!this.shutdownPromise) {
            this.shutdownPromise = this.performShutdown();
        }
        return this.shutdownPromise;
    }

    async performShutdown() {
        this.shutdownRequested = true;
        this.stopBackupSync();
        let requireLeaseRelease = false;
        await this.checkpointTail;
        if (this.nativeFailureFinalizationPromise) {
            await this.nativeFailureFinalizationPromise;
        } else if (this.nativeFailureStopPromise) {
            await this.nativeFailureStopPromise;
        }
        const failureBrowserAlreadyStopped =
            this.nativeFailureBrowserTerminationConfirmed === true;
        const activationRecoveryRequired =
            this.isCanonicalActivationRecoveryRequired();
        const activeRestartAttestationPending =
            this.isCanonicalActiveRestartAttestationPending();
        if (
            !failureBrowserAlreadyStopped &&
            !activeRestartAttestationPending &&
            (this.authReady || activationRecoveryRequired)
        ) {
            if (this.nativePostgres) {
                if (
                    !this.shutdownProjection &&
                    isBrowserConnected(this.client.pupBrowser)
                ) {
                    await this.beforeBrowserDestroyed();
                }
                const canonicalProjection =
                    this.shutdownProjection?.canonicalProjection;
                if (canonicalProjection) {
                    if (this.store.revisionStatus === 'active') {
                        await this.store.saveCanonicalProjection({
                            projection: canonicalProjection,
                            source: 'shutdown',
                        });
                        requireLeaseRelease = true;
                        this.logNative(
                            'checkpoint.shutdown_profile_anchor_completed',
                            {
                                profile_checkpoint_mode:
                                    'immutable_profile_anchor_plus_fresh_canonical_v1',
                                canonical_record_count:
                                    canonicalProjection.record_count,
                                canonical_size_bytes:
                                    canonicalProjection.size_bytes,
                            },
                            { force: true },
                        );
                    } else {
                        await this.checkpointStableNativeProfile(
                            {
                                profilePath: this.userDataDir,
                                canonicalProjection,
                                source:
                                    this.store.revisionStatus === 'staging'
                                        ? this.store.revisionSource || 'pairing'
                                        : 'checkpoint',
                            },
                            { reason: 'shutdown' },
                        );
                    }
                    this.markCanonicalProjectionPersisted(canonicalProjection);
                } else {
                    // A post-close profile is checkpointable only when its
                    // exact canonical projection was captured after the
                    // pre-close writer fence. Falling back to an older
                    // projection creates an internally inconsistent artifact
                    // while retiring the last known-good one.
                    this.logNative(
                        'checkpoint.shutdown_profile_preserved',
                        {
                            reason: this.shutdownProjectionCaptureFailed
                                ? 'projection_capture_failed'
                                : 'projection_capture_unavailable',
                            existing_profile_artifact_preserved: true,
                        },
                        { force: true },
                    );
                }
            } else {
                await this.checkpoint({ force: true, reason: 'shutdown' });
            }
        }
        this.authReady = false;
        await this.browserBridge?.close();
        if (this.nativePostgres) {
            await this.store.close(
                requireLeaseRelease ? { requireLeaseRelease: true } : undefined,
            );
            // Client.destroy()/logout() invokes this strategy only after the
            // dedicated Chromium process has stopped. The released extension
            // was deliberately left inert until this point.
            if (!isBrowserConnected(this.client.pupBrowser)) {
                this.canonicalWebSocketGateExtensionId = undefined;
                this.canonicalWebSocketGateServiceWorker = undefined;
                await this.disposeCanonicalWebSocketGateMonitor();
                await this.removeCanonicalWebSocketGateStagingDir();
            }
        }
        this.canonicalNativeAppStateAuthoritative = false;
        await this.removeLocalSession();
    }

    async onAuthenticationNeeded() {
        if (this.nativePostgres) {
            const handoff = this.store.isHandoffRevision();
            const pairingAllowed = await this.store.isPairingAllowed();
            this.initialPairingAuthorized = pairingAllowed && !handoff;
            if (!pairingAllowed) {
                if (handoff) {
                    await this.rollbackHandoff('handoff_requested_qr');
                }
                return {
                    failed: true,
                    restart: false,
                    failureEventPayload: handoff
                        ? 'wwebjs_handoff_requested_qr'
                        : 'wwebjs_postgres_session_requested_qr',
                };
            }
        }
        return {
            failed: false,
            restart: false,
            failureEventPayload: undefined,
        };
    }

    async restoreCanonicalAppStateAfterNativeIdle(sourceProjection) {
        const maxAttempts = 3;
        const startedAt = Date.now();
        const deadlineAt = startedAt + this.canonicalAppStateCatchUpTimeoutMs;
        for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
            const remainingForStage = () => {
                const remainingMs = deadlineAt - Date.now();
                if (remainingMs >= 1000) return remainingMs;
                throw new WhatsAppSessionCompatibilityError(
                    'wwebjs_canonical_app_state_restore_window_unstable',
                    { attempt_count: attempt - 1 },
                );
            };
            const restoreWindowProof =
                await this.browserBridge.waitForCanonicalAppStateRestoreIdle({
                    timeoutMs: Math.min(60000, remainingForStage()),
                    pollIntervalMs: Math.max(
                        100,
                        Math.min(1000, this.canonicalAppStatePollIntervalMs),
                    ),
                    requiredStableSamples: 2,
                });
            await this.browserBridge.quiesceNetwork({
                timeoutMs: Math.min(15000, remainingForStage()),
            });
            try {
                return await this.browserBridge.restoreCanonicalAppState(
                    sourceProjection,
                    {
                        timeoutMs: Math.min(30000, remainingForStage()),
                        syncJobTtlMs: this.canonicalAppStateCatchUpTimeoutMs,
                        requireOffline: true,
                        passiveBlockedCollections: Array.isArray(
                            restoreWindowProof?.passive_blocked_collections,
                        )
                            ? restoreWindowProof.passive_blocked_collections
                            : [],
                        passiveRetryCollections: Array.isArray(
                            restoreWindowProof?.passive_retry_collections,
                        )
                            ? restoreWindowProof.passive_retry_collections
                            : [],
                    },
                );
            } catch (error) {
                const errorCode = String(error?.code || error?.message || '');
                if (
                    errorCode !==
                    'wwebjs_canonical_app_state_restore_window_changed'
                ) {
                    throw error;
                }
                this.logNative(
                    'canonical_activation.app_state_restore_window_retry',
                    {
                        attempt,
                        max_attempts: maxAttempts,
                        destructive_mutation_started: false,
                        duration_ms: Date.now() - startedAt,
                    },
                    { force: true },
                );
                if (attempt >= maxAttempts) {
                    throw new WhatsAppSessionCompatibilityError(
                        'wwebjs_canonical_app_state_restore_window_unstable',
                        {
                            attempt_count: attempt,
                            destructive_mutation_started: false,
                        },
                        { cause: error },
                    );
                }
                await this.browserBridge.resumeNetwork();
                const reconnectRemainingMs = remainingForStage();
                await this.browserBridge.waitForCanonicalConnected({
                    timeoutMs: Math.min(30000, reconnectRemainingMs),
                    requireSynced: true,
                });
            }
        }
        throw new WhatsAppSessionCompatibilityError(
            'wwebjs_canonical_app_state_restore_window_unstable',
            { attempt_count: maxAttempts },
        );
    }

    async completePendingCanonicalAppStateBeforeReadiness() {
        if (!this.pendingCanonicalAppStateCatchUp) return false;
        if (
            this.pendingCanonicalAppStateSyncKeyCount <= 0 ||
            !this.handoffSourceCanonicalProjection
        ) {
            throw new Error('wwebjs_canonical_app_state_sync_keys_missing');
        }
        const sourceProjection = this.handoffSourceCanonicalProjection;
        const authoritativeNativeReset = Boolean(
            this.canonicalActiveRestartReplay &&
            this.canonicalActiveRestartAppStateOverlayRequired,
        );
        // The authenticated transport keeps its final database encryption
        // material and stream behind WhatsApp's official critical-sync
        // acknowledgement. The canonical source snapshot is already fully
        // validated and public events remain fenced, so persist that durable
        // acknowledgement before using the product API to restore encrypted
        // sync keys and run the real full collection sync.
        await this.browserBridge.finalizeCanonicalAppStateReadiness({
            timeoutMs: Math.min(30000, this.canonicalAppStateCatchUpTimeoutMs),
        });
        // The authenticated transport may already have started WhatsApp's
        // native collection scheduler. Let it reach a proven idle boundary
        // while online, then fence the network and replace encrypted material.
        // If work appears in the small barrier-to-fence window, retry only
        // before any clear/write has started.
        const restoreResult =
            await this.restoreCanonicalAppStateAfterNativeIdle(
                sourceProjection,
            );
        if (
            !Number.isSafeInteger(restoreResult?.sync_job_generation) ||
            restoreResult.sync_job_generation <= 0
        ) {
            throw new WhatsAppSessionCompatibilityError(
                'wwebjs_canonical_app_state_sync_generation_invalid',
            );
        }
        await this.browserBridge.resumeNetwork();
        await this.browserBridge.startCanonicalAppStateSync({
            expectedGeneration: restoreResult.sync_job_generation,
            syncJobTtlMs: this.canonicalAppStateCatchUpTimeoutMs,
        });
        const caughtUp =
            await this.browserBridge.waitForCanonicalAppStateCatchUp(
                sourceProjection,
                {
                    timeoutMs: this.canonicalAppStateCatchUpTimeoutMs,
                    pollIntervalMs: this.canonicalAppStatePollIntervalMs,
                    expectedSyncGeneration: restoreResult.sync_job_generation,
                    allowPreservedNativeAppStateBaseline:
                        authoritativeNativeReset,
                },
            );
        // A completed official sync can leave WWeb's native store with
        // browser-only future mutation rows. The bridge then returns a
        // portable projection that deliberately preserves the snapshot-resync
        // marker. Keep that marker durable: the active WWeb profile is usable,
        // while a later Baileys/WhatsMeow handoff must still request an
        // authenticated server snapshot instead of importing those rows.
        const snapshotResyncPreserved =
            caughtUp.snapshot_resync_preserved === true;
        this.pendingCanonicalAppStateProjection =
            this.reconcileCanonicalProjectionForPersistence(
                caughtUp.projection,
                {
                    baseline: sourceProjection,
                    clearSnapshotResyncMarker: !snapshotResyncPreserved,
                    preserveNativeAppState: authoritativeNativeReset,
                },
            );
        if (authoritativeNativeReset) {
            // The official generation plus the two-sample native attestation
            // has superseded the stale canonical overlay. Keep the live
            // profile authoritative through identity validation; the final
            // active-restart checkpoint will rotate profile and canonical
            // together while the persistent overlay flag is still present.
            this.canonicalNativeAppStateAuthoritative = true;
        }
        this.pendingCanonicalAppStateCatchUp = false;
        this.pendingCanonicalAppStateSyncKeyCount = 0;
        this.preserveExistingProfileArtifactDuringCanonicalCatchUp = false;
        this.logNative(
            'canonical_activation.pre_ready_app_state_completed',
            {
                collection_count: caughtUp.collection_count,
                duration_ms: caughtUp.duration_ms,
                sync_job_generation: restoreResult.sync_job_generation,
                authoritative_native_reset: authoritativeNativeReset,
            },
            { force: true },
        );
        return true;
    }

    /**
     * The initial PostgreSQL pairing checkpoint races with the last app-state
     * IndexedDB transaction even after the readiness sample was stable. The
     * live Chromium profile can also change while its artifact is streamed.
     * Retry only those two explicit transient conditions and keep every other
     * checkpoint failure fatal.
     */
    async checkpointInitialNativePairingReady() {
        const startedAt = Date.now();
        const deadlineAtMs = startedAt + this.canonicalAppStateCatchUpTimeoutMs;
        let attempt = 0;
        let lastPendingDetails;
        let lastTransient = 'app_state';

        while (Date.now() < deadlineAtMs) {
            attempt += 1;
            try {
                return await this.checkpoint({
                    emit: true,
                    force: true,
                    reason: 'ready',
                    connectedProfileSnapshot: true,
                });
            } catch (error) {
                const errorCode = String(error?.code || error?.message || '');
                const profileChanged =
                    errorCode === PROFILE_CHANGED_DURING_CHECKPOINT;
                const appStatePending =
                    errorCode ===
                    'wwebjs_canonical_app_state_checkpoint_pending';
                if (!profileChanged && !appStatePending) {
                    throw error;
                }
                lastPendingDetails = error.details;
                lastTransient = profileChanged ? 'profile' : 'app_state';
                const elapsedMs = Date.now() - startedAt;
                const remainingMs = deadlineAtMs - Date.now();
                this.logNative(
                    profileChanged
                        ? 'checkpoint.initial_pairing_profile_unstable'
                        : 'checkpoint.initial_pairing_app_state_pending',
                    {
                        attempt,
                        duration_ms: elapsedMs,
                        remaining_ms: Math.max(0, remainingMs),
                        ...(profileChanged && error.details?.path
                            ? { changed_path: error.details.path }
                            : {}),
                    },
                    { force: true },
                );
                if (profileChanged) {
                    if (remainingMs <= 0) break;
                    const retryDelayMs = Math.min(
                        remainingMs,
                        Math.min(2000, Math.max(250, attempt * 250)),
                    );
                    await this.delay(retryDelayMs);
                    continue;
                }
                if (
                    remainingMs <= 0 ||
                    !this.lastCanonicalProjection ||
                    typeof this.browserBridge
                        .waitForCanonicalAppStateCatchUp !== 'function'
                ) {
                    break;
                }
                try {
                    await this.browserBridge.waitForCanonicalAppStateCatchUp(
                        this.lastCanonicalProjection,
                        {
                            timeoutMs: this.canonicalAppStateCatchUpTimeoutMs,
                            pollIntervalMs:
                                this.canonicalAppStatePollIntervalMs,
                            deadlineAtMs,
                        },
                    );
                } catch (caughtError) {
                    if (
                        caughtError?.code !==
                        'wwebjs_canonical_app_state_catch_up_timeout'
                    ) {
                        throw caughtError;
                    }
                    lastPendingDetails =
                        caughtError.details || lastPendingDetails;
                    break;
                }
            }
        }

        throw new WhatsAppSessionCompatibilityError(
            lastTransient === 'profile'
                ? 'wwebjs_canonical_initial_profile_stability_timeout'
                : 'wwebjs_canonical_initial_app_state_stability_timeout',
            {
                phase: 'ready_checkpoint',
                attempt_count: attempt,
                duration_ms: Date.now() - startedAt,
                transient: lastTransient,
                ...(lastPendingDetails
                    ? { last_pending: lastPendingDetails }
                    : {}),
            },
        );
    }

    async afterAuthReady() {
        const readinessDocumentEpoch = this.client?._connectionDocumentEpoch;
        const readinessNavigationSequence =
            this.client?._mainFrameNavigationSequence;
        const readinessRuntimeEpoch = this.client?._connectionRuntimeEpoch;
        const readinessPage = this.client?.pupPage;
        const durableReadyNavigationSuccessor = Boolean(
            this.nativePostgres &&
            this.authReady === true &&
            this.store.revisionStatus === 'active' &&
            Number.isSafeInteger(readinessRuntimeEpoch) &&
            this.nativeReadyCheckpointRuntimeEpoch === readinessRuntimeEpoch &&
            !this.canonicalActiveRestartReplay &&
            !this.canonicalActivationMarkerPresent &&
            !this.canonicalCandidatePromoted &&
            !this.providerHandoffCheckpointAdmissionClosed &&
            !this.shutdownRequested,
        );
        const initialPairingReadyNavigationSuccessor =
            this.isInitialPairingReadyNavigationSuccessorAllowed({
                runtimeEpoch: readinessRuntimeEpoch,
                documentEpoch: readinessDocumentEpoch,
                navigationSequence: readinessNavigationSequence,
            });
        const readinessWasSuperseded = () =>
            readinessDocumentEpoch !== this.client?._connectionDocumentEpoch ||
            readinessNavigationSequence !==
                this.client?._mainFrameNavigationSequence;
        const navigationSupersededReadiness = async (error) => {
            const errorCode = String(error?.code || error?.message || '');
            const replacementDocumentProjectionPending =
                errorCode === 'wwebjs_canonical_projection_incomplete';
            const replacementDocumentIdentityPending =
                isTransientCompanionIdentityReadError(error);
            if (
                !isTransientNavigationError(error) &&
                !replacementDocumentProjectionPending &&
                !replacementDocumentIdentityPending
            ) {
                return false;
            }
            if (readinessWasSuperseded()) return true;

            // Puppeteer can reject Runtime.callFunctionOn a few milliseconds
            // before emitting the matching main-frame navigation event. Give
            // only the fenced legacy-volume bootstrap a short observation
            // window before destructive finalization. The same Page and
            // runtime must remain authoritative; browser/page replacement is
            // not inferred as a recoverable navigation.
            const deadline =
                Date.now() + LEGACY_VOLUME_NAVIGATION_SETTLE_TIMEOUT_MS;
            while (Date.now() < deadline) {
                if (
                    this.client?._connectionRuntimeEpoch !==
                        readinessRuntimeEpoch ||
                    (readinessPage !== undefined &&
                        this.client?.pupPage !== readinessPage) ||
                    readinessPage?.isClosed?.() === true
                ) {
                    return false;
                }
                await new Promise((resolve) =>
                    setTimeout(
                        resolve,
                        LEGACY_VOLUME_NAVIGATION_SETTLE_POLL_MS,
                    ),
                );
                if (readinessWasSuperseded()) return true;
            }
            return false;
        };
        const sessionExists = this.nativePostgres
            ? this.store.revisionStatus === 'active' ||
              this.store.isHandoffRevision()
            : await this.store.sessionExists({
                  session: this.sessionName,
              });
        const legacyVolumeMigrationBootstrap = Boolean(
            this.nativePostgres &&
            this.store.revisionSource === 'legacy_volume_migration' &&
            ['staging', 'validating'].includes(this.store.revisionStatus),
        );
        const initialNativePairing = Boolean(
            this.nativePostgres &&
            this.initialPairingAuthorized &&
            !sessionExists &&
            !this.lastCanonicalProjection,
        );
        // The database-backed empty-pairing proof is a one-shot capability.
        // A second readiness attempt must obtain a fresh proof instead of
        // reusing authorization from a failed or superseded QR lifecycle.
        this.initialPairingAuthorized = false;
        this.authReady = false;
        if (
            !sessionExists &&
            !legacyVolumeMigrationBootstrap &&
            !initialPairingReadyNavigationSuccessor &&
            this.initialSyncDelayMs > 0
        ) {
            await this.delay(this.initialSyncDelayMs);
        }
        this.assertNotShuttingDown();

        // READY must only be published after at least one durable checkpoint.
        if (this.nativePostgres) {
            try {
                if (this.pendingCanonicalAppStateCatchUp) {
                    throw new Error(
                        'wwebjs_canonical_app_state_pre_ready_incomplete',
                    );
                }
                let readinessBrowserProjection;
                const completesSnapshotResync = Boolean(
                    this.pendingCanonicalAppStateProjection &&
                    normalizedSnapshotResyncCollections(
                        this.pendingCanonicalAppStateProjection.capabilities,
                        { optional: true },
                    ).length === 0,
                );
                if (this.pendingCanonicalAppStateProjection) {
                    readinessBrowserProjection =
                        this.pendingCanonicalAppStateProjection;
                } else if (
                    initialNativePairing ||
                    initialPairingReadyNavigationSuccessor ||
                    legacyVolumeMigrationBootstrap
                ) {
                    if (
                        typeof this.browserBridge
                            .waitForInitialCanonicalAppStateStability !==
                        'function'
                    ) {
                        throw new WhatsAppSessionCompatibilityError(
                            legacyVolumeMigrationBootstrap
                                ? 'wwebjs_canonical_legacy_volume_app_state_gate_unavailable'
                                : 'wwebjs_canonical_initial_app_state_gate_unavailable',
                        );
                    }
                    if (legacyVolumeMigrationBootstrap) {
                        if (
                            typeof this.browserBridge.assertCompatible !==
                            'function'
                        ) {
                            throw new WhatsAppSessionCompatibilityError(
                                'wwebjs_canonical_legacy_volume_runtime_gate_unavailable',
                            );
                        }
                        // The official app-state synchronizer can replace the
                        // main document while a LocalAuth profile is being
                        // promoted. A successor document may report
                        // authenticated before its private module registry is
                        // fully rehydrated. Require the complete canonical ABI
                        // for a bounded interval before exporting. This never
                        // accepts an incomplete projection: a permanently
                        // incompatible runtime still fails closed.
                        await this.browserBridge.assertCompatible({
                            waitForModulesMs:
                                LEGACY_VOLUME_RUNTIME_CAPABILITY_WAIT_MS,
                            pollIntervalMs: 250,
                            capabilityStage: 'runtime',
                        });
                        if (readinessWasSuperseded()) {
                            const superseded = new Error(
                                'wwebjs_legacy_volume_navigation_superseded',
                            );
                            superseded.code = superseded.message;
                            throw superseded;
                        }
                    }
                    // A legacy LocalAuth profile is already authenticated, but
                    // it has no canonical PostgreSQL baseline yet. Treat its
                    // first browser projection like the first durable pairing
                    // snapshot: wait for two compatible, complete samples and
                    // let the official app-state synchronizer resolve only the
                    // bounded transient cases. A one-shot export here races
                    // IndexedDB materialization and can reject a valid profile.
                    const stability =
                        await this.browserBridge.waitForInitialCanonicalAppStateStability(
                            {
                                timeoutMs:
                                    this.canonicalAppStateCatchUpTimeoutMs,
                                pollIntervalMs:
                                    this.canonicalAppStatePollIntervalMs,
                                allowLegacyProfileTransientProjection:
                                    legacyVolumeMigrationBootstrap,
                            },
                        );
                    readinessBrowserProjection = stability.projection;
                } else if (
                    this.canonicalActiveRestartReplay ||
                    this.canonicalReusableHandoffNativeAppState
                ) {
                    if (
                        !this.canonicalReconnectProjection ||
                        typeof this.browserBridge
                            .waitForCanonicalAppStateCatchUp !== 'function'
                    ) {
                        throw new WhatsAppSessionCompatibilityError(
                            'wwebjs_canonical_active_restart_stability_gate_unavailable',
                        );
                    }
                    // The restored native profile owns app-state on an active
                    // same-provider restart. Canonical replay may update
                    // Signal/device material, but must not clear or force a
                    // full app-state sync. Require two mutually compatible
                    // live exports before identity validation instead. The
                    // bridge treats only the documented partial collection
                    // row as transient during this bounded wait.
                    const stability =
                        await this.browserBridge.waitForCanonicalAppStateCatchUp(
                            this.canonicalReconnectProjection,
                            {
                                timeoutMs:
                                    this.canonicalAppStateCatchUpTimeoutMs,
                                pollIntervalMs:
                                    this.canonicalAppStatePollIntervalMs,
                                allowPreservedNativeAppStateBaseline:
                                    this
                                        .preserveExistingProfileArtifactDuringCanonicalCatchUp ||
                                    this.canonicalReusableHandoffNativeAppState,
                            },
                        );
                    readinessBrowserProjection = stability.projection;
                } else {
                    readinessBrowserProjection =
                        await this.browserBridge.exportCanonicalProjection();
                }
                const readinessCanonicalProjection =
                    this.reconcileCanonicalProjectionForPersistence(
                        readinessBrowserProjection,
                        {
                            clearSnapshotResyncMarker: completesSnapshotResync,
                            preserveNativeAppState:
                                this.canonicalReusableHandoffNativeAppState ===
                                    true ||
                                (this.canonicalActiveRestartReplay === true &&
                                    (this
                                        .canonicalNativeAppStateAuthoritative ===
                                        true ||
                                        !this
                                            .canonicalActiveRestartAppStateOverlayRequired)),
                        },
                    );
                let resolvedIdentity = {};
                if (this.identityResolver) {
                    let lastIdentityReadError;
                    const maxIdentityReadAttempts =
                        legacyVolumeMigrationBootstrap
                            ? LEGACY_VOLUME_IDENTITY_READ_MAX_ATTEMPTS
                            : 1;
                    for (
                        let attempt = 1;
                        attempt <= maxIdentityReadAttempts;
                        attempt += 1
                    ) {
                        try {
                            resolvedIdentity = await this.identityResolver(
                                this.client,
                            );
                            lastIdentityReadError = undefined;
                            break;
                        } catch (error) {
                            lastIdentityReadError = error;
                            if (
                                !legacyVolumeMigrationBootstrap ||
                                !isTransientCompanionIdentityReadError(error) ||
                                attempt >= maxIdentityReadAttempts
                            ) {
                                throw error;
                            }
                            // The projection has not been persisted yet. A
                            // transient lazy-store getter failure can be
                            // retried safely in the same document; a document
                            // replacement is handed to Client's serialized
                            // successor flight instead.
                            if (readinessWasSuperseded()) throw error;
                            this.logNative(
                                'session.identity_validation_read_retry',
                                {
                                    attempt,
                                    max_attempts: maxIdentityReadAttempts,
                                    retry_delay_ms:
                                        LEGACY_VOLUME_IDENTITY_READ_RETRY_MS,
                                },
                                { force: true },
                            );
                            await this.delay(
                                LEGACY_VOLUME_IDENTITY_READ_RETRY_MS,
                            );
                            if (readinessWasSuperseded()) throw error;
                        }
                    }
                    if (lastIdentityReadError) throw lastIdentityReadError;
                }
                const trustedFingerprint =
                    resolvedIdentity?.companionFingerprint ||
                    resolvedIdentity?.deviceFingerprint;
                if (
                    this.requireFingerprintVerification &&
                    resolvedIdentity?.moduleAbi !== CANONICAL_PRIVATE_MODULE_ABI
                ) {
                    throw new Error('wwebjs_companion_identity_abi_mismatch');
                }
                this.reconcileResolvedIdentityWebVersion(resolvedIdentity);
                if (
                    this.requireFingerprintVerification &&
                    !trustedFingerprint
                ) {
                    throw new Error(
                        'wwebjs_companion_fingerprint_not_verified',
                    );
                }
                const browserJid =
                    this.client.info?.wid?._serialized ||
                    this.client.info?.wid?.user;
                if (
                    resolvedIdentity?.jid &&
                    comparableJid(resolvedIdentity.jid) !==
                        comparableJid(browserJid)
                ) {
                    throw new Error('wwebjs_identity_resolver_jid_mismatch');
                }
                const identityPreflight =
                    await this.store.preflightReadyIdentity({
                        jid: browserJid,
                        companionFingerprint: trustedFingerprint,
                        canonicalProjection: readinessCanonicalProjection,
                    });
                const activationCheckpointOwnsProjection =
                    this.canonicalActivationMarkerPresent === true;
                if (this.canonicalActiveRestartReplay) {
                    // The active revision's last profile artifact and its
                    // canonical projection are one crash-consistency unit.
                    // Keep the live-attested projection in memory until the
                    // final profile checkpoint persists both together.
                    this.canonicalActiveRestartAttestedProjection =
                        identityPreflight.canonicalProjection;
                } else if (activationCheckpointOwnsProjection) {
                    // The official app-state sync can legitimately leave
                    // browser-only future MAC rows in Chromium. Retain the
                    // exact portable projection that passed identity
                    // preflight so the final frozen profile checkpoint
                    // reconciles live browser progress against this new
                    // authority, rather than against the retired provider's
                    // source snapshot.
                    this.canonicalActivationReadyProjection =
                        identityPreflight.canonicalProjection;
                } else if (!activationCheckpointOwnsProjection) {
                    await this.store.saveCanonicalProjection({
                        projection: identityPreflight.canonicalProjection,
                        source: 'ready_preflight',
                    });
                }
                // A post-PONR target remains `preparing` until the final
                // activation CAS. Its old candidate artifact is intentionally
                // not eligible for ordinary active-anchor adoption. Let the
                // frozen activation checkpoint publish the live profile and
                // this preflighted canonical authority as one new unit, then
                // evaluate the resync gate from those durable bytes.
                const appStateResyncGate = activationCheckpointOwnsProjection
                    ? undefined
                    : await this.store.checkpointAppStateSnapshotResyncGate?.();
                if (appStateResyncGate && !appStateResyncGate.ready) {
                    throw new Error(
                        'whatsapp_session_app_state_snapshot_resync_pending',
                    );
                }
                if (
                    !this.canonicalActiveRestartReplay &&
                    !activationCheckpointOwnsProjection
                ) {
                    this.markCanonicalProjectionPersisted(
                        identityPreflight.canonicalProjection,
                    );
                }
                this.pendingCanonicalAppStateProjection = undefined;
                const validation = await this.store.validateReadyIdentity({
                    jid: browserJid,
                    companionFingerprint: trustedFingerprint,
                });
                if (
                    this.requireFingerprintVerification &&
                    (!trustedFingerprint ||
                        (!validation.fingerprintVerified &&
                            !validation.fingerprintRegistered))
                ) {
                    throw new Error(
                        'wwebjs_companion_fingerprint_not_verified',
                    );
                }
                if (this.pendingPostQuantumBootstrap) {
                    try {
                        if (this.pendingPostQuantumRollbackRecovery) {
                            // An intent is sufficient: the delete RPC may
                            // have reached the server before the source
                            // crashed. Recreate and upload a fresh bundle,
                            // persist the canonical result under the current
                            // fence, and only then remove the recovery marker.
                            const pqRecovery =
                                await this.browserBridge.recoverPostQuantumAfterClassicalHandoffAbort();
                            const recoveredBrowserProjection =
                                await this.browserBridge.exportCanonicalProjection();
                            const recoveredProjection =
                                this.reconcileCanonicalProjectionForPersistence(
                                    recoveredBrowserProjection,
                                    {
                                        preserveNativeAppState:
                                            this
                                                .canonicalActiveRestartReplay ===
                                                true &&
                                            (this
                                                .canonicalNativeAppStateAuthoritative ===
                                                true ||
                                                !this
                                                    .canonicalActiveRestartAppStateOverlayRequired),
                                    },
                                );
                            await this.store.saveCanonicalProjection({
                                projection: recoveredProjection,
                                source: 'startup_pq_source_recovery',
                            });
                            await this.store.completePostQuantumServerRollbackRecovery(
                                this.pendingPostQuantumRollbackRecovery,
                                pqRecovery,
                            );
                            this.markCanonicalProjectionPersisted(
                                recoveredProjection,
                            );
                            this.pendingPostQuantumRollbackRecovery = undefined;
                        } else {
                            await this.browserBridge.ensurePostQuantumReady();
                        }
                        this.pendingPostQuantumBootstrap = false;
                    } catch (error) {
                        let persistenceError;
                        try {
                            await this.checkpoint({
                                force: true,
                                reason: 'post_quantum_failure_state',
                            });
                        } catch (caughtError) {
                            persistenceError = caughtError;
                        }
                        if (persistenceError) {
                            throw new AggregateError(
                                [error, persistenceError],
                                'wwebjs_post_quantum_state_persistence_failed',
                                { cause: error },
                            );
                        }
                        throw error;
                    }
                }
            } catch (error) {
                this.authReady = false;
                if (
                    (legacyVolumeMigrationBootstrap ||
                        initialPairingReadyNavigationSuccessor ||
                        durableReadyNavigationSuccessor) &&
                    (await navigationSupersededReadiness(error))
                ) {
                    // The replacement document owns the serialized successor
                    // readiness flight in Client. This pre-checkpoint attempt
                    // has no authority to stop Chromium, roll back the
                    // candidate or release the lease. The successor reruns
                    // every identity and generation proof on the fresh realm.
                    // This exception is intentionally limited to a fenced
                    // same-runtime successor. A fresh pairing only enters
                    // this path after identity preflight established durable
                    // canonical authority for the staging revision; an
                    // unproven QR lifecycle still needs a new one-shot proof.
                    this.logNative(
                        'session.identity_validation_navigation_superseded',
                        {
                            error_code: stableNativeFailureCode(
                                error,
                                'wwebjs_navigation_context_replaced',
                            ),
                            navigation_sequence: readinessNavigationSequence,
                            current_navigation_sequence:
                                this.client?._mainFrameNavigationSequence,
                            document_epoch: readinessDocumentEpoch,
                            current_document_epoch:
                                this.client?._connectionDocumentEpoch,
                        },
                        { force: true },
                    );
                    if (isTransientNavigationError(error)) throw error;
                    const superseded = new Error(
                        'wwebjs_legacy_volume_navigation_superseded',
                        { cause: error },
                    );
                    superseded.code = superseded.message;
                    throw superseded;
                }
                let errorCode = 'handoff_identity_validation_failed';
                if (this.store.isHandoffRevision()) {
                    errorCode =
                        error.code ||
                        (/^wwebjs_[a-z0-9_]+$/u.test(error.message || '')
                            ? error.message
                            : 'handoff_identity_validation_failed');
                }
                this.logNativeFailure('session.identity_validation_failed', {
                    error,
                });
                throw await this.finalizeNativeFailure(error, errorCode);
            }
        }
        if (this.nativePostgres && this.canonicalActiveRestartReplay) {
            // Arm the persistent mode only after the two-sample browser gate,
            // companion identity preflight and durable canonical validation
            // all succeeded. It intentionally survives clearing the transient
            // replay references so every later checkpoint keeps the live
            // native profile's app-state bytes and the original marker.
            this.canonicalNativeAppStateAuthoritative = true;
        }
        let persisted;
        let canonicalReadyCheckpoint = false;
        try {
            if (this.nativePostgres && this.canonicalActivationMarkerPresent) {
                persisted = await this.checkpointCanonicalActivationReady();
                canonicalReadyCheckpoint = true;
            } else if (
                this.nativePostgres &&
                this.canonicalActiveRestartReplay
            ) {
                persisted = await this.checkpointCanonicalActiveRestartReady();
                canonicalReadyCheckpoint = true;
            } else if (durableReadyNavigationSuccessor) {
                persisted = await this.checkpointReadyNavigationSuccessor({
                    runtimeEpoch: readinessRuntimeEpoch,
                    documentEpoch: readinessDocumentEpoch,
                    navigationSequence: readinessNavigationSequence,
                });
            } else if (
                initialNativePairing ||
                initialPairingReadyNavigationSuccessor ||
                legacyVolumeMigrationBootstrap
            ) {
                if (
                    initialNativePairing &&
                    Number.isSafeInteger(readinessRuntimeEpoch)
                ) {
                    // Identity preflight and the canonical ready projection
                    // are durable before the live Chromium artifact starts.
                    // Preserve only this same-runtime provenance so a normal
                    // WhatsApp main-frame replacement during the frozen
                    // profile checkpoint can continue on its successor
                    // document without accepting a new or unrelated QR flow.
                    this.nativeInitialPairingReadyRuntimeEpoch =
                        readinessRuntimeEpoch;
                }
                persisted = await this.checkpointInitialNativePairingReady();
            } else {
                persisted = await this.checkpoint({
                    emit: true,
                    force: true,
                    reason: 'ready',
                });
            }
        } catch (error) {
            this.authReady = false;
            if (
                (legacyVolumeMigrationBootstrap ||
                    initialNativePairing ||
                    initialPairingReadyNavigationSuccessor ||
                    durableReadyNavigationSuccessor) &&
                (await navigationSupersededReadiness(error))
            ) {
                throw error;
            }
            if (this.nativePostgres) {
                this.nativeInitialPairingReadyRuntimeEpoch = undefined;
                throw await this.finalizeNativeFailure(
                    error,
                    error.code || 'handoff_checkpoint_failed',
                );
            }
            throw error;
        }
        if (!persisted) {
            if (durableReadyNavigationSuccessor && readinessWasSuperseded()) {
                const superseded = new Error(
                    'wwebjs_legacy_volume_navigation_superseded',
                );
                superseded.code = superseded.message;
                throw superseded;
            }
            const error = new Error(
                'Unable to persist the initial RemoteAuth checkpoint.',
            );
            if (this.nativePostgres) {
                this.nativeInitialPairingReadyRuntimeEpoch = undefined;
                throw await this.finalizeNativeFailure(
                    error,
                    'handoff_checkpoint_not_persisted',
                );
            }
            throw error;
        }
        if (
            this.nativePostgres &&
            this.store.revisionStatus === 'active' &&
            Number.isSafeInteger(readinessRuntimeEpoch)
        ) {
            // A same-runtime main-frame replacement can occur after the
            // initial profile promotion but before Client publishes READY.
            // Retain narrowly scoped durable provenance so the successor
            // document can repeat identity validation and append a canonical
            // checkpoint without treating the already-promoted revision as a
            // fresh active-process restart.
            this.nativeReadyCheckpointRuntimeEpoch = readinessRuntimeEpoch;
        }
        this.nativeInitialPairingReadyRuntimeEpoch = undefined;
        if (this.nativePostgres) {
            if (this.canonicalActivationMarkerPresent) {
                throw new Error(
                    'wwebjs_canonical_activation_finalize_incomplete',
                );
            }
            if (canonicalReadyCheckpoint) {
                // Once the frozen ready checkpoint has committed, Chromium's
                // active WWeb profile is the app-state authority. Official
                // sync can keep browser-only mutation MAC rows above the
                // portable collection watermark; every later periodic or
                // critical checkpoint must therefore pass through the native
                // portable normalizer instead of comparing those rows
                // strictly against the just-committed activation baseline.
                // The activation checkpoint itself already used the exact
                // identity-preflighted baseline, so arm this mode only after
                // that crash-consistent profile+canonical commit succeeds.
                this.canonicalNativeAppStateAuthoritative = true;
                this.client.emit(Events.REMOTE_SESSION_SAVED);
            }
            if (initialNativePairing || legacyVolumeMigrationBootstrap) {
                const activePairingSnapshotResyncCollections =
                    this.store.revisionStatus === 'active'
                        ? normalizedSnapshotResyncCollections(
                              this.getPersistedCanonicalProjection()
                                  ?.capabilities,
                              { optional: true },
                          )
                        : [];
                // A fresh pairing normally stays on the strict canonical
                // reconciler. The sole exception is the explicit
                // snapshot-resync fallback: Chromium's complete native
                // profile remains authoritative while the active projection
                // carries that marker. Handoff targets never enter here.
                this.canonicalNativeAppStateAuthoritative =
                    activePairingSnapshotResyncCollections.length > 0;
            }
            this.preserveExistingProfileArtifactDuringCanonicalCatchUp = false;
            this.clearCanonicalCandidateReferences();
            this.canonicalCandidatePromoted = false;
        }
        this.assertNotShuttingDown();
        this.authReady = true;
        this.initialPairingAuthorized = false;
        if (
            this.nativePostgres &&
            (this.profileDirty || this.browserBridge?.dirty)
        ) {
            this.scheduleCriticalCheckpoint();
        }
        this.startBackupSync();
    }

    startBackupSync() {
        if (this.backupSync) return;
        this.backupSync = setInterval(() => {
            void this.checkpoint({
                periodic: true,
                reason: 'periodic',
            }).catch(() => {});
        }, this.backupSyncIntervalMs);
    }

    /**
     * Queues a serialized durable checkpoint. Periodic calls are coalesced so
     * a slow store can never build an unbounded interval backlog.
     */
    checkpoint({
        emit = false,
        force = false,
        periodic = false,
        reason = 'manual',
        connectedProfileSnapshot = false,
    } = {}) {
        if (this.providerHandoffCheckpointAdmissionClosed) {
            return Promise.resolve(false);
        }
        if (this.isCanonicalActiveRestartAttestationPending()) {
            return Promise.resolve(false);
        }
        if (!force && !this.authReady) return Promise.resolve(false);
        if (
            this.nativePostgres &&
            periodic &&
            !this.profileDirty &&
            !this.browserBridge?.dirty
        ) {
            return Promise.resolve(false);
        }
        if (periodic && this.periodicCheckpoint) {
            return this.periodicCheckpoint;
        }

        const queued = this.checkpointTail.then(() =>
            this.performCheckpoint({
                emit,
                force,
                reason,
                connectedProfileSnapshot,
            }),
        );
        this.checkpointTail = queued.catch(() => {});

        if (periodic) {
            this.periodicCheckpoint = queued;
            void queued
                .finally(() => {
                    if (this.periodicCheckpoint === queued) {
                        this.periodicCheckpoint = undefined;
                    }
                })
                .catch(() => {});
        }

        return queued;
    }

    isReadyNavigationSuccessorCheckpointAllowed({
        runtimeEpoch,
        documentEpoch,
        navigationSequence,
    }) {
        return Boolean(
            this.nativePostgres &&
            this.store.revisionStatus === 'active' &&
            Number.isSafeInteger(runtimeEpoch) &&
            this.nativeReadyCheckpointRuntimeEpoch === runtimeEpoch &&
            this.client?._connectionRuntimeEpoch === runtimeEpoch &&
            this.client?._connectionDocumentEpoch === documentEpoch &&
            this.client?._mainFrameNavigationSequence === navigationSequence &&
            !this.canonicalActiveRestartReplay &&
            !this.canonicalActivationMarkerPresent &&
            !this.canonicalCandidatePromoted &&
            !this.providerHandoffCheckpointAdmissionClosed &&
            !this.shutdownRequested,
        );
    }

    isInitialPairingReadyNavigationSuccessorAllowed({
        runtimeEpoch,
        documentEpoch,
        navigationSequence,
    }) {
        return Boolean(
            this.nativePostgres &&
            this.authReady !== true &&
            this.store.revisionStatus === 'staging' &&
            this.store.revisionSource === 'pairing' &&
            Number.isSafeInteger(runtimeEpoch) &&
            this.nativeInitialPairingReadyRuntimeEpoch === runtimeEpoch &&
            this.client?._connectionRuntimeEpoch === runtimeEpoch &&
            this.client?._connectionDocumentEpoch === documentEpoch &&
            this.client?._mainFrameNavigationSequence === navigationSequence &&
            this.lastPersistedCanonicalProjection?.tables &&
            !this.canonicalActiveRestartReplay &&
            !this.canonicalActivationMarkerPresent &&
            !this.canonicalCandidatePromoted &&
            !this.providerHandoffCheckpointAdmissionClosed &&
            !this.shutdownRequested,
        );
    }

    checkpointReadyNavigationSuccessor(expected) {
        if (!this.isReadyNavigationSuccessorCheckpointAllowed(expected)) {
            return Promise.resolve(false);
        }
        const queued = this.checkpointTail.then(() => {
            if (!this.isReadyNavigationSuccessorCheckpointAllowed(expected)) {
                return false;
            }
            return this.performCanonicalCheckpoint(
                'ready_navigation_successor',
                { allowPreReadyNavigationSuccessor: expected },
            );
        });
        this.checkpointTail = queued.catch(() => {});
        return queued;
    }

    async storeRemoteSession(options = {}) {
        return this.checkpoint({ emit: options.emit, force: true });
    }

    async checkpointStableNativeProfile(
        options,
        { reason = 'checkpoint', maxAttempts = 4 } = {},
    ) {
        for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
            try {
                return await this.store.checkpointProfile(options);
            } catch (error) {
                const errorCode = String(error?.code || error?.message || '');
                if (
                    errorCode !== PROFILE_CHANGED_DURING_CHECKPOINT ||
                    attempt >= maxAttempts
                ) {
                    throw error;
                }
                this.profileDirty = true;
                this.logNative(
                    'checkpoint.profile_snapshot_retry',
                    {
                        reason,
                        attempt,
                        max_attempts: maxAttempts,
                        mutation_phase: safeFailureCode(
                            error?.details?.phase,
                            'profile_changed',
                        ),
                    },
                    { force: true },
                );
                await this.delay(attempt * 100);
            }
        }
        throw new Error('wwebjs_profile_checkpoint_retry_exhausted');
    }

    canonicalProjectionSnapshotValidator(canonicalProjection) {
        return async () => {
            // buildProfileArtifact proves that the selected LevelDB/profile
            // inventory stayed stable while it was streamed. Close the
            // remaining temporal gap before persistRevision: a canonical
            // writer may have advanced after the first export but before the
            // artifact metadata transaction.
            await this.browserBridge.flush();
            const validationBrowserProjection =
                await this.browserBridge.exportCanonicalProjection();
            const validationCanonicalProjection =
                this.reconcileCanonicalProjectionForPersistence(
                    validationBrowserProjection,
                );
            if (
                !canonicalProjectionSnapshotsEqual(
                    canonicalProjection,
                    validationCanonicalProjection,
                )
            ) {
                throw profileProjectionChangedError(
                    canonicalProjection,
                    validationCanonicalProjection,
                );
            }
        };
    }

    async performCheckpoint({
        emit,
        force,
        reason,
        connectedProfileSnapshot = false,
    }) {
        if (this.isCanonicalActiveRestartAttestationPending()) return false;
        const pathExists = await this.isValidPath(this.userDataDir);
        if (!pathExists) return false;

        if (this.nativePostgres) {
            if (!this.browserBridge) {
                throw new Error('wwebjs_browser_bridge_unavailable');
            }
            if (
                this.store.revisionStatus === 'active' &&
                reason !== 'post_quantum_failure_state'
            ) {
                const persisted = await this.performCanonicalCheckpoint(reason);
                if (persisted && emit) {
                    this.client.emit(Events.REMOTE_SESSION_SAVED);
                }
                return persisted;
            }
            this.logNative('checkpoint.started', { reason });
            const maxAttempts = 4;
            for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
                const journal = await this.browserBridge.flush();
                if (
                    attempt === 1 &&
                    !force &&
                    !this.profileDirty &&
                    !journal?.dirty
                ) {
                    return false;
                }
                const canonicalDirtyPlan =
                    this.browserBridge.getCanonicalDirtyPlan?.();
                const browserProjection =
                    await this.browserBridge.exportCanonicalProjection();
                const canonicalProjection =
                    this.reconcileCanonicalProjectionForPersistence(
                        browserProjection,
                    );
                const source =
                    this.store.revisionStatus === 'staging'
                        ? this.store.revisionSource || 'pairing'
                        : 'checkpoint';
                let connectedSnapshotFrozen = false;
                let connectedSnapshotResumed = false;
                try {
                    if (connectedProfileSnapshot) {
                        if (
                            reason !== 'ready' ||
                            this.store.revisionStatus === 'active' ||
                            !['pairing', 'legacy_volume_migration'].includes(
                                this.store.revisionSource,
                            ) ||
                            this.store.isHandoffRevision?.() === true ||
                            typeof this.browserBridge
                                .freezeConnectedProfileSnapshot !==
                                'function' ||
                            typeof this.browserBridge
                                .resumeConnectedProfileSnapshot !== 'function'
                        ) {
                            throw new WhatsAppSessionCompatibilityError(
                                'wwebjs_connected_profile_checkpoint_scope_invalid',
                            );
                        }
                        await this.browserBridge.freezeConnectedProfileSnapshot();
                        connectedSnapshotFrozen = true;
                    }
                    await this.store.checkpointProfile({
                        profilePath: this.userDataDir,
                        canonicalProjection,
                        source,
                        promote: !(
                            reason === 'ready' &&
                            this.canonicalReconnectProjection &&
                            this.store.isHandoffRevision?.() === true
                        ),
                        validateSnapshot: async () => {
                            if (connectedSnapshotFrozen) {
                                connectedSnapshotFrozen = false;
                                await this.browserBridge.resumeConnectedProfileSnapshot();
                                connectedSnapshotResumed = true;
                            }
                            await this.canonicalProjectionSnapshotValidator(
                                canonicalProjection,
                            )();
                        },
                    });
                } catch (error) {
                    if (connectedSnapshotFrozen) {
                        connectedSnapshotFrozen = false;
                        try {
                            await this.browserBridge.resumeConnectedProfileSnapshot();
                            connectedSnapshotResumed = true;
                        } catch (resumeError) {
                            if (
                                resumeError?.code ===
                                CONNECTED_PROFILE_NAVIGATION_SUPERSEDED
                            ) {
                                throw resumeError;
                            }
                            throw new AggregateError(
                                [error, resumeError],
                                'wwebjs_connected_profile_checkpoint_resume_failed',
                                { cause: error },
                            );
                        }
                    }
                    const errorCode = String(
                        error?.code || error?.message || '',
                    );
                    if (
                        errorCode !== PROFILE_CHANGED_DURING_CHECKPOINT ||
                        attempt >= maxAttempts
                    ) {
                        throw error;
                    }
                    // ProfileArtifact re-lists every selected root before it
                    // commits its frozen inventory. A LevelDB rotation causes
                    // a full retry from a fresh journal/projection instead of
                    // persisting the previous partial filesystem view.
                    this.profileDirty = true;
                    this.logNative(
                        'checkpoint.profile_snapshot_retry',
                        {
                            reason,
                            attempt,
                            max_attempts: maxAttempts,
                            mutation_phase: safeFailureCode(
                                error?.details?.phase,
                                'profile_changed',
                            ),
                        },
                        { force: true },
                    );
                    await this.delay(attempt * 100);
                    continue;
                }
                if (connectedProfileSnapshot && !connectedSnapshotResumed) {
                    throw new WhatsAppSessionCompatibilityError(
                        'wwebjs_connected_profile_checkpoint_resume_missing',
                    );
                }
                this.markCanonicalProjectionPersisted(canonicalProjection);
                this.browserBridge.acknowledgeCanonicalDirtyPlan?.(
                    canonicalDirtyPlan,
                );
                this.pendingCanonicalProviderState = undefined;
                const postCheckpointJournal = await this.browserBridge.flush();
                if (postCheckpointJournal?.dirty) {
                    this.profileDirty = true;
                    if (postCheckpointJournal.critical) {
                        this.scheduleCriticalCheckpoint();
                    }
                } else {
                    await this.browserBridge.markClean();
                    this.profileDirty = false;
                }
                if (emit) this.client.emit(Events.REMOTE_SESSION_SAVED);
                return true;
            }
            throw new Error('wwebjs_profile_checkpoint_retry_exhausted');
        }

        let compressedSessionPath;
        try {
            compressedSessionPath = await this.compressSession();
            await this.store.save({
                session: this.sessionName,
                path: compressedSessionPath,
            });
            if (emit) this.client.emit(Events.REMOTE_SESSION_SAVED);
            return true;
        } finally {
            const paths = [
                this.tempDir,
                ...(compressedSessionPath ? [compressedSessionPath] : []),
            ];
            await Promise.allSettled(
                paths.map((p) =>
                    fs.promises.rm(p, {
                        recursive: true,
                        force: true,
                        maxRetries: this.rmMaxRetries,
                    }),
                ),
            );
        }
    }

    async extractNativeSession() {
        await this.removeLocalSession();
        try {
            const restored = await this.store.restoreProfile({
                profilePath: this.userDataDir,
                selector: 'active',
            });
            if (!restored) {
                if (this.store.revisionStatus === 'active') {
                    throw new Error('wwebjs_active_profile_artifact_missing');
                }
                await fs.promises.mkdir(this.userDataDir, {
                    recursive: true,
                });
            }
        } catch (error) {
            await this.removeLocalSession();
            // Once a WWeb revision is active it is the point of no return:
            // the server may already have advanced ratchets/PQ state. Never
            // reactivate the retired native provider merely because the
            // active artifact is unavailable. Staging failures are rolled
            // back by finalizeNativeFailure before any WebSocket is released.
            throw error;
        }
    }

    scheduleCriticalCheckpoint({
        delayMs = this.canonicalFlushDebounceMs,
    } = {}) {
        this.profileDirty = true;
        if (this.providerHandoffCheckpointAdmissionClosed) return;
        if (this.canonicalActivationCheckpointInProgress) return;
        if (this.isCanonicalActiveRestartAttestationPending()) return;
        if (!this.authReady && this.pendingCanonicalAppStateCatchUp) {
            return;
        }
        if (
            (!this.authReady &&
                !this.isCanonicalActivationRecoveryRequired()) ||
            this.shutdownRequested
        ) {
            return;
        }
        if (this.criticalCheckpointTimer) return;
        this.criticalCheckpointTimer = setTimeout(() => {
            this.criticalCheckpointTimer = undefined;
            if (this.providerHandoffCheckpointAdmissionClosed) return;
            const queued = this.checkpointTail.then(() =>
                this.performCanonicalCheckpoint('critical_mutation'),
            );
            this.checkpointTail = queued.catch(() => {});
            void queued.catch((error) => {
                this.logNative(
                    'canonical_checkpoint.critical_failed',
                    {
                        error,
                        error_code: safeFailureCode(
                            error?.code || error?.message,
                            'wwebjs_canonical_checkpoint_critical_failed',
                        ),
                        ...safeAggregateErrorDetails(error),
                    },
                    { force: true },
                );
                if (
                    error?.code ===
                        'wwebjs_canonical_app_state_checkpoint_pending' &&
                    !this.shutdownRequested
                ) {
                    this.scheduleCriticalCheckpoint({
                        delayMs: Math.max(
                            this.canonicalFlushDebounceMs,
                            this.canonicalAppStatePollIntervalMs,
                        ),
                    });
                }
            });
        }, delayMs);
    }

    async performCanonicalCheckpoint(
        reason,
        { allowPreReadyNavigationSuccessor } = {},
    ) {
        if (!this.browserBridge || this.shutdownRequested) return false;
        if (this.isCanonicalActiveRestartAttestationPending()) return false;
        const preReadyNavigationSuccessor = Boolean(
            allowPreReadyNavigationSuccessor &&
            this.isReadyNavigationSuccessorCheckpointAllowed(
                allowPreReadyNavigationSuccessor,
            ),
        );
        // Recheck the lifecycle boundary at execution time. A debounced
        // checkpoint may have been queued before a canonical import/reload
        // started, so the scheduling-time check alone cannot protect the
        // active database revision from a transient or partial projection.
        if (
            !this.authReady &&
            !this.isCanonicalActivationRecoveryRequired() &&
            !preReadyNavigationSuccessor
        ) {
            return false;
        }
        const startedAt = Date.now();
        await this.browserBridge.flush();
        const journalPlan = this.browserBridge.getCanonicalDirtyPlan?.();
        const journalPersistencePlan =
            journalPlan &&
            typeof journalPlan.fullReplace === 'boolean' &&
            typeof journalPlan.device === 'boolean' &&
            Array.isArray(journalPlan.tables)
                ? journalPlan
                : {
                      fullReplace: true,
                      device: true,
                      tables: [],
                  };
        const browserProjection =
            await this.browserBridge.exportCanonicalProjection();
        const persistenceCandidate =
            !this.authReady && this.pendingCanonicalAppStateCatchUp
                ? this.buildCanonicalOfflineCheckpointProjection(
                      browserProjection,
                  )
                : browserProjection;
        const projection =
            this.reconcileCanonicalProjectionForPersistence(
                persistenceCandidate,
            );
        const dirtyPlan = expandCanonicalAppStateDirtyPlan(
            journalPersistencePlan,
            {
                baseline: this.getPersistedCanonicalProjection(),
                browserProjection: persistenceCandidate,
                persistenceProjection: projection,
            },
        );
        const preReadyNavigationSuccessorAtPersistence = Boolean(
            preReadyNavigationSuccessor &&
            this.isReadyNavigationSuccessorCheckpointAllowed(
                allowPreReadyNavigationSuccessor,
            ),
        );
        if (
            !this.authReady &&
            !this.isCanonicalActivationRecoveryRequired() &&
            !preReadyNavigationSuccessorAtPersistence
        ) {
            return false;
        }
        if (this.isCanonicalActiveRestartAttestationPending()) return false;
        await this.store.saveCanonicalProjection({
            projection,
            source: reason,
            dirtyPlan,
        });
        this.browserBridge.acknowledgeCanonicalDirtyPlan?.(journalPlan);
        this.markCanonicalProjectionPersisted(projection);
        this.pendingCanonicalProviderState = undefined;
        const postCheckpointJournal = await this.browserBridge.flush();
        if (postCheckpointJournal?.dirty) {
            this.profileDirty = true;
            if (postCheckpointJournal.critical) {
                this.scheduleCriticalCheckpoint();
            }
        } else {
            await this.browserBridge.markClean?.();
            this.profileDirty = false;
        }
        this.logNative('canonical_checkpoint.completed', {
            reason,
            record_count: projection.record_count,
            size_bytes: projection.size_bytes,
            duration_ms: Date.now() - startedAt,
            profile_snapshot: false,
            full_replace: dirtyPlan.fullReplace,
            device_replaced: dirtyPlan.device,
            table_count: dirtyPlan.tables.length,
            tail_dirty: postCheckpointJournal?.dirty === true,
        });
        return true;
    }

    async handleLeaseLoss(error) {
        const failures = [];
        try {
            this.client._emitConnectionLifecycleEvent(
                Events.DISCONNECTED,
                error.code,
            );
        } catch (emitError) {
            failures.push(emitError);
        }
        failures.push(...(await this.stopNativeFailureWriters()));
        if (failures.length > 0) {
            throw new AggregateError(
                [error, ...failures],
                'wwebjs_lease_loss_cleanup_failed',
                { cause: error },
            );
        }
    }

    async exportProjection() {
        if (!this.nativePostgres) {
            throw new Error('wwebjs_native_postgres_store_required');
        }
        if (this.isCanonicalActiveRestartAttestationPending()) {
            throw new Error(
                'wwebjs_canonical_active_restart_attestation_pending',
            );
        }
        if (!this.browserBridge) {
            throw new Error('wwebjs_browser_bridge_unavailable');
        }
        // The expensive generic IndexedDB projection is intentionally
        // opt-in. Normal READY/checkpoint/shutdown/handoff paths persist the
        // incremental profile artifact plus the canonical crypto projection.
        const maxAttempts = 4;
        for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
            await this.browserBridge.flush();
            const providerProjection =
                await this.browserBridge.exportProjection();
            const browserProjection =
                await this.browserBridge.exportCanonicalProjection();
            const canonicalProjection =
                this.reconcileCanonicalProjectionForPersistence(
                    browserProjection,
                );
            try {
                await this.store.checkpointProfile({
                    profilePath: this.userDataDir,
                    projection: providerProjection,
                    canonicalProjection,
                    source: 'checkpoint',
                    validateSnapshot:
                        this.canonicalProjectionSnapshotValidator(
                            canonicalProjection,
                        ),
                });
            } catch (error) {
                const errorCode = String(error?.code || error?.message || '');
                if (
                    errorCode !== PROFILE_CHANGED_DURING_CHECKPOINT ||
                    attempt >= maxAttempts
                ) {
                    throw error;
                }
                this.profileDirty = true;
                this.logNative(
                    'checkpoint.profile_snapshot_retry',
                    {
                        reason: 'export_projection',
                        attempt,
                        max_attempts: maxAttempts,
                        mutation_phase: safeFailureCode(
                            error?.details?.phase,
                            'profile_changed',
                        ),
                    },
                    { force: true },
                );
                await this.delay(attempt * 100);
                continue;
            }
            this.markCanonicalProjectionPersisted(canonicalProjection);
            return this.store.exportProjection();
        }
        throw new Error('wwebjs_profile_checkpoint_retry_exhausted');
    }

    async importProjection(options) {
        if (!this.nativePostgres) {
            throw new Error('wwebjs_native_postgres_store_required');
        }
        return this.store.importProjection(options);
    }

    async drainProviderHandoffCheckpointTail() {
        const checkpointTail = this.checkpointTail;
        let settled = false;
        void checkpointTail.then(
            () => {
                settled = true;
            },
            () => {
                settled = true;
            },
        );
        await Promise.resolve();
        if (settled) return false;

        let timeout;
        try {
            await Promise.race([
                checkpointTail,
                new Promise((_, reject) => {
                    timeout = setTimeout(() => {
                        const error = new Error(
                            'wwebjs_provider_handoff_checkpoint_drain_timeout',
                        );
                        error.code = error.message;
                        reject(error);
                    }, this.providerHandoffCheckpointDrainTimeoutMs);
                }),
            ]);
        } finally {
            clearTimeout(timeout);
        }
        return true;
    }

    prepareHandoff(targetProvider, expected = {}) {
        let handoffKey;
        try {
            if (!this.nativePostgres) {
                throw new Error('wwebjs_native_postgres_store_required');
            }
            if (this.isCanonicalActiveRestartAttestationPending()) {
                throw new Error(
                    'wwebjs_canonical_active_restart_attestation_pending',
                );
            }
            handoffKey = [
                targetProvider,
                expected.handoffId,
                expected.lifecycleOperationId,
                expected.sourceRevisionId,
            ].join(':');
            if (
                this.providerHandoffKey &&
                this.providerHandoffKey !== handoffKey
            ) {
                throw new Error('wwebjs_provider_handoff_replay_mismatch');
            }
        } catch (error) {
            // Preserve the rejected-Promise contract of the former async
            // method while allowing same-key callers to receive the exact
            // shared operation Promise below.
            return Promise.reject(error);
        }
        if (this.providerHandoffPromise) {
            return this.providerHandoffPromise;
        }
        this.providerHandoffKey = handoffKey;
        // Install the shared promise before authorization can execute. This
        // also closes a synchronous re-entry window in custom store adapters:
        // every same-key caller observes this exact operation, never a second
        // authorization/drain pipeline.
        const operation = Promise.resolve()
            .then(() =>
                this.performProviderHandoff(
                    targetProvider,
                    expected,
                    handoffKey,
                ),
            )
            .finally(() => {
                if (this.providerHandoffPromise === operation) {
                    if (
                        !this.providerHandoffCheckpointAdmissionClosed &&
                        this.providerHandoffKey === handoffKey
                    ) {
                        this.providerHandoffKey = undefined;
                    }
                    this.providerHandoffPromise = undefined;
                }
            });
        this.providerHandoffPromise = operation;
        return operation;
    }

    async performProviderHandoff(targetProvider, expected, handoffKey) {
        const checkpointAdmissionWasClosed =
            this.providerHandoffCheckpointAdmissionClosed;
        if (this.preparedProviderHandoff) {
            const leaseReleased = await this.store.close({
                requireLeaseRelease: true,
            });
            return { ...this.preparedProviderHandoff, leaseReleased };
        }
        let authorizedHandoff;
        try {
            authorizedHandoff = await this.store.assertAuthorizedHandoff(
                targetProvider,
                expected,
            );
        } catch (error) {
            // Authorization happens before any drain/checkpoint side effect.
            // Do not let a rejected request poison a later legitimate target.
            // A retry after a drain timeout inherits a fail-closed admission
            // fence.  A subsequently stale authorization must not reopen it
            // while the original checkpoint writer can still be running.
            if (
                !checkpointAdmissionWasClosed &&
                this.providerHandoffKey === handoffKey
            ) {
                this.providerHandoffCheckpointAdmissionClosed = false;
            }
            throw error;
        }
        // Close checkpoint admission synchronously after authorization and
        // before reading checkpointTail. checkpoint() itself has no await
        // before it appends to the tail, so every writer is now either already
        // represented by the promise we drain or rejected by this fence.
        this.providerHandoffCheckpointAdmissionClosed = true;
        this.shutdownRequested = true;
        this.stopBackupSync();
        this.authReady = false;
        this.client._markConnectionHandoff?.('handoff_preparing');
        // A periodic/profile checkpoint may already be running even though
        // its interval and critical debounce have just been stopped.  Its
        // blob upload is deliberately split from the artifact transaction;
        // starting the handoff snapshot concurrently would let either
        // checkpoint prune the other's not-yet-mapped blobs.  Drain the
        // serialized writer before quiescing or terminating Chromium so the
        // handoff owns the only remaining profile snapshot.
        const checkpointDrainWaited =
            await this.drainProviderHandoffCheckpointTail();
        if (checkpointDrainWaited) {
            const refreshedAuthorization =
                await this.store.assertAuthorizedHandoff(
                    targetProvider,
                    expected,
                );
            const stableFields = [
                'handoffId',
                'sourceRevisionId',
                'targetRevisionId',
                'lifecycleOperationId',
                'targetProvider',
            ];
            if (
                stableFields.some(
                    (field) =>
                        String(refreshedAuthorization?.[field] ?? '') !==
                        String(authorizedHandoff?.[field] ?? ''),
                )
            ) {
                throw new WhatsAppSessionCompatibilityError(
                    'wwebjs_provider_handoff_authorization_changed_during_checkpoint_drain',
                );
            }
            authorizedHandoff = refreshedAuthorization;
        }
        let canonicalProjection;
        let pqServerRollback;
        let pqServerRollbackIntent;
        let pqServerRollbackRecoveryRequired = false;
        let pqServerRollbackAcknowledgementUnknown = false;
        try {
            if (targetProvider === 'whatsmeow') {
                pqServerRollbackIntent =
                    await this.store.beginPostQuantumServerRollbackIntent(
                        authorizedHandoff,
                    );
                try {
                    const rollback =
                        await this.browserBridge?.rollbackPostQuantumForClassicalHandoff?.();
                    if (!rollback) {
                        throw new Error(
                            'wwebjs_pq_rollback_runtime_unavailable',
                        );
                    }
                    pqServerRollbackRecoveryRequired = true;
                    // Persist the acknowledgement immediately. Nothing that
                    // follows (drain, export, profile checkpoint) is allowed
                    // to create a crash window where the server deletion is
                    // known only to Chromium memory.
                    pqServerRollback =
                        await this.store.acknowledgePostQuantumServerRollback(
                            pqServerRollbackIntent,
                            rollback,
                        );
                } catch (error) {
                    pqServerRollbackRecoveryRequired =
                        Boolean(pqServerRollbackIntent) ||
                        error?.serverAcknowledged === true ||
                        error?.acknowledgementUnknown === true;
                    pqServerRollbackAcknowledgementUnknown =
                        error?.acknowledgementUnknown === true;
                    throw error;
                }
            }
            await this.browserBridge?.quiesceNetwork();
            const browserProjection =
                await this.browserBridge?.exportCanonicalProjection({
                    pqServerRollback,
                });
            canonicalProjection =
                this.reconcileCanonicalProjectionForPersistence(
                    browserProjection,
                );
            const handoffAppState =
                normalizeCanonicalAppStateForProviderHandoff(
                    canonicalProjection,
                );
            canonicalProjection = handoffAppState.projection;
            if (handoffAppState.snapshot_resync_collection_count > 0) {
                this.logNative(
                    'handoff.app_state_snapshot_resync_normalized',
                    {
                        snapshot_resync_collection_count:
                            handoffAppState.snapshot_resync_collection_count,
                        removed_version_row_count:
                            handoffAppState.removed_version_row_count,
                        removed_mutation_mac_count:
                            handoffAppState.removed_mutation_mac_count,
                        collection_ids: handoffAppState.collection_ids,
                    },
                    { force: true },
                );
            }
            if (!hasNonzeroDeviceId(canonicalProjection?.device?.jid)) {
                throw new Error('wwebjs_canonical_device_wid_required');
            }
            assertCanonicalTargetProviderCompatibility(
                canonicalProjection,
                targetProvider,
            );
            if (pqServerRollback) {
                // This full canonical replace is the durable, fenced proof of
                // the server ACK. It also removes status/PQ Signal scopes from
                // the future Meow candidate before Chromium is closed.
                await this.store.saveCanonicalProjection({
                    projection: canonicalProjection,
                    source: 'handoff_pq_server_rollback',
                });
            }
        } catch (error) {
            this.logNativeFailure('handoff.preflight_rejected', {
                target_provider: targetProvider,
                error_code: safeFailureCode(
                    error?.code || error?.message,
                    'wwebjs_handoff_preflight_failed',
                ),
            });
            let recoveryError;
            if (pqServerRollbackAcknowledgementUnknown) {
                const failClosedErrors = [error];
                // A timed-out/context-lost delete RPC may still be executing.
                // Never reuse that page for recovery: terminate Chromium and
                // leave the durable intent for conservative startup recovery.
                try {
                    await this.terminateNativeBrowser(this.client.pupBrowser);
                } catch (caughtError) {
                    failClosedErrors.push(caughtError);
                }
                if (failClosedErrors.length === 1) {
                    try {
                        await this.browserBridge?.close?.();
                    } catch (caughtError) {
                        failClosedErrors.push(caughtError);
                    }
                }
                this.client._markConnectionHandoff?.(
                    'handoff_acknowledgement_unknown',
                );
                throw new AggregateError(
                    failClosedErrors,
                    'wwebjs_pq_rollback_server_ack_unknown',
                    { cause: error },
                );
            }
            if (pqServerRollbackRecoveryRequired) {
                try {
                    // Public readiness remains fenced while the source
                    // transport is briefly restored for the official upload.
                    // Close and drain the final PQ upload sinks before making
                    // the network available; recovery itself keeps that fence
                    // closed until its one exclusive upload is validated.
                    await this.browserBridge?.beginPostQuantumRollbackUploadFence?.();
                    await this.browserBridge?.resumeNetwork?.();
                    const pqRecovery =
                        await this.browserBridge?.recoverPostQuantumAfterClassicalHandoffAbort?.();
                    const recoveredBrowserProjection =
                        await this.browserBridge?.exportCanonicalProjection();
                    const recoveredProjection =
                        this.reconcileCanonicalProjectionForPersistence(
                            recoveredBrowserProjection,
                        );
                    await this.store.saveCanonicalProjection({
                        projection: recoveredProjection,
                        source: 'handoff_pq_source_recovery',
                    });
                    await this.store.completePostQuantumServerRollbackRecovery(
                        pqServerRollbackIntent,
                        pqRecovery,
                    );
                } catch (caughtError) {
                    recoveryError = caughtError;
                }
            } else {
                await this.browserBridge?.resumeNetwork?.().catch(() => {});
            }
            if (recoveryError) {
                const failClosedErrors = [error, recoveryError];
                // The recovery transport was resumed. If re-upload or its
                // fenced checkpoint fails, force Chromium offline and closed
                // before surfacing the error. Keep the DB lease owned so no
                // second writer can start from an indeterminate source state.
                try {
                    await this.terminateNativeBrowser(this.client.pupBrowser);
                } catch (caughtError) {
                    failClosedErrors.push(caughtError);
                }
                if (failClosedErrors.length === 2) {
                    try {
                        await this.browserBridge?.close?.();
                    } catch (caughtError) {
                        failClosedErrors.push(caughtError);
                    }
                }
                this.client._markConnectionHandoff?.('handoff_recovery_failed');
                throw new AggregateError(
                    failClosedErrors,
                    'wwebjs_pq_rollback_source_recovery_failed',
                    { cause: error },
                );
            }
            this.shutdownRequested = false;
            this.authReady = true;
            if (this.providerHandoffKey === handoffKey) {
                this.providerHandoffCheckpointAdmissionClosed = false;
            }
            this.startBackupSync();
            await this.client
                ._publishOnlineConnectionStatus?.('handoff_cancelled')
                .catch(() => false);
            throw error;
        }
        const browser = this.client.pupBrowser;
        await this.terminateNativeBrowser(browser);
        await this.browserBridge?.close();
        try {
            const activeSource = this.store.revisionStatus === 'active';
            const stableProfileOptions = activeSource
                ? {
                      ...expected,
                      profilePath: this.userDataDir,
                      canonicalProjection,
                  }
                : expected;
            let handoff;
            try {
                // Chromium is fully stopped at this point. Capture its stable
                // native profile together with the exact canonical projection
                // exported behind the network fence. This keeps the rollback
                // profile and portable Signal tables on the same temporal
                // boundary without ever streaming a live LevelDB.
                handoff = await this.store.prepareHandoff(
                    targetProvider,
                    stableProfileOptions,
                );
            } catch (error) {
                const errorCode = String(error?.code || error?.message || '');
                const observedSize = error?.details?.size_bytes;
                const maxSize = error?.details?.max_bytes;
                const validOversizeFallback = Boolean(
                    activeSource &&
                    errorCode === 'whatsapp_artifact_profile_too_large' &&
                    Number.isSafeInteger(observedSize) &&
                    Number.isSafeInteger(maxSize) &&
                    observedSize > maxSize &&
                    maxSize > 0,
                );
                if (!validOversizeFallback) throw error;

                // Oversized profiles already have a separately verified
                // last-good anchor. Preserve that bounded compatibility path
                // instead of making a safe handoff impossible, but expose the
                // fallback explicitly so performance evidence cannot confuse
                // it with a coherent full-profile checkpoint.
                this.logNative(
                    'handoff.stable_profile_checkpoint_oversize_fallback',
                    {
                        target_provider: targetProvider,
                        rejected_profile_size_bytes: observedSize,
                        profile_max_bytes: maxSize,
                    },
                    { force: true },
                );
                handoff = await this.store.prepareHandoff(targetProvider, {
                    ...expected,
                    canonicalProjection,
                    lastGoodProfileFallback: {
                        version: 1,
                        error_code: errorCode,
                        size_bytes: observedSize,
                        max_bytes: maxSize,
                    },
                });
            }
            this.preparedProviderHandoff = handoff;
            const leaseReleased = await this.store.close({
                requireLeaseRelease: true,
            });
            await this.removeLocalSession();
            return { ...handoff, leaseReleased };
        } catch (error) {
            if (!this.preparedProviderHandoff) {
                await this.store.close().catch(() => {});
            }
            throw error;
        }
    }

    async promote(revisionId) {
        if (!this.nativePostgres) {
            throw new Error('wwebjs_native_postgres_store_required');
        }
        return this.store.promote(revisionId);
    }

    async rollback(errorCode) {
        if (!this.nativePostgres) {
            throw new Error('wwebjs_native_postgres_store_required');
        }
        return this.store.rollback(errorCode);
    }

    async extractRemoteSession() {
        const compressedSessionPath = path.join(
            this.zipDir,
            `${this.sessionName}.zip`,
        );
        const sessionExists = await this.store.sessionExists({
            session: this.sessionName,
        });

        // Remote storage is the source of truth. Local profiles are ephemeral
        // and must never silently override the selected remote revision.
        await this.removeLocalSession();

        if (sessionExists) {
            try {
                await this.extractRevision(
                    this.store.extract.bind(this.store),
                    compressedSessionPath,
                );
            } catch (activeRevisionError) {
                await this.removeLocalSession();
                await fs.promises.rm(compressedSessionPath, { force: true });
                if (typeof this.store.extractPrevious !== 'function') {
                    throw activeRevisionError;
                }

                try {
                    await this.extractRevision(
                        this.store.extractPrevious.bind(this.store),
                        compressedSessionPath,
                    );
                } catch (previousRevisionError) {
                    throw new AggregateError(
                        [activeRevisionError, previousRevisionError],
                        'Unable to restore active or previous remote session revision.',
                    );
                }
            }
        } else {
            await fs.promises.mkdir(this.userDataDir, { recursive: true });
        }
    }

    async extractRevision(extract, compressedSessionPath) {
        await extract({
            session: this.sessionName,
            path: compressedSessionPath,
        });
        await this.unCompressSession(compressedSessionPath);
    }

    async deleteRemoteSession() {
        const sessionExists = await this.store.sessionExists({
            session: this.sessionName,
        });
        if (sessionExists)
            await this.store.delete({ session: this.sessionName });
    }

    stopBackupSync() {
        clearInterval(this.backupSync);
        this.backupSync = undefined;
        clearTimeout(this.criticalCheckpointTimer);
        this.criticalCheckpointTimer = undefined;
    }

    assertNotShuttingDown() {
        if (this.shutdownRequested) {
            throw new Error(
                'RemoteAuth shutdown started before authentication readiness completed.',
            );
        }
    }

    async removeLocalSession() {
        if (!this.userDataDir) return;
        await fs.promises.rm(this.userDataDir, {
            recursive: true,
            force: true,
            maxRetries: this.rmMaxRetries,
        });
    }

    async compressSession() {
        const stageDefaultPath = path.join(this.tempDir, 'Default');
        const userDataDefaultPath = path.join(this.userDataDir, 'Default');

        await fs.emptyDir(stageDefaultPath);
        await this.copyByRequiredDirs(userDataDefaultPath, stageDefaultPath);

        const ZipArchive = await loadZipArchiveConstructor();
        const archive = new ZipArchive();
        const outPath = path.join(this.zipDir, `${this.sessionName}.zip`);
        const out = fs.createWriteStream(outPath);

        await new Promise((resolve, reject) => {
            out.once('close', resolve);
            out.once('error', reject);
            archive.once('error', reject);

            archive.pipe(out);
            archive.directory(this.tempDir, false);
            archive.finalize();
        });
        return outPath;
    }

    async unCompressSession(compressedSessionPath) {
        const stream = fs.createReadStream(compressedSessionPath);
        const extractor = unzipper.Extract({
            path: this.userDataDir,
            concurrency: 10,
        });
        await new Promise((resolve, reject) => {
            stream.once('error', reject);
            extractor.once('error', reject);
            // unzipper's writable `finish` only means that it consumed the
            // archive stream. `close` is the completion boundary for the
            // asynchronous filesystem writes performed by Extract.
            extractor.once('close', resolve);
            stream.pipe(extractor);
        });
        await fs.promises.unlink(compressedSessionPath);
    }

    async copyByRequiredDirs(from, to) {
        for (const d of this.requiredDirs) {
            const src = path.join(from, d);
            if (await this.isValidPath(src)) {
                const dest = path.join(to, path.basename(src));
                await fs.promises.cp(src, dest, {
                    recursive: true,
                    force: true,
                    errorOnExist: false,
                });
            }
        }
    }

    async isValidPath(path) {
        try {
            await fs.promises.access(path);
            return true;
        } catch {
            return false;
        }
    }

    async delay(ms) {
        return new Promise((resolve) => setTimeout(resolve, ms));
    }
}

module.exports = RemoteAuth;