/** * Is this error the S3/STS "access denied" class? Expected when a scoped * member/guest credential touches a key outside its granted ACL prefixes * (the server's `SCOPE_EXCEEDS_PARENT` surfaces as a 403 AccessDenied / * Forbidden). */ export declare function isAccessDenied(err: unknown): boolean; /** * Is this error the S3/presign "object does not exist" class? Distinct from * {@link isAccessDenied}: a 403/Forbidden is "can't read this key"; NotFound * is "the key is gone". `object-io.ts` `notFoundError` (presigned GET 404 * and GET `FILES_PRESIGN_NOT_FOUND`) uses `name === "NotFound"`. */ export declare function isNotFound(err: unknown): boolean; /** Host resource snapshot used to decide the default transfer fan-out. */ export interface HostLoadProbe { /** Logical CPU count (0 when unknown). */ cores: number; /** 1-minute load average (0 on platforms without it, e.g. Windows). */ load1: number; /** * Memory *available to applications* as a fraction of total (0..1). This is * NOT `os.freemem() / os.totalmem()`: on macOS and Linux the OS keeps most * "free" RAM as reclaimable file cache, so raw free-page counts report a * near-full machine as memory-starved. `readAvailableMemoryFraction` * measures available memory per-platform instead. */ availableMemFraction: number; } /** Read the current host load. Pure I/O; callers inject a probe in tests. */ export declare function readHostLoad(): HostLoadProbe; /** * True when the host is already under meaningful CPU or memory load from other * processes. `cores === 0` (unknown) disables the CPU signal rather than * dividing by zero; `load1 === 0` (Windows has no load average) likewise leaves * the CPU signal inert, so those hosts fall back to the memory signal only. */ export declare function machineAlreadyBusy(probe: HostLoadProbe): boolean; /** * Concurrency for the per-file transfer pool (uploads + downloads). * * An explicit, valid `HQ_SYNC_TRANSFER_CONCURRENCY` always wins. Otherwise the * default adapts to the host: 64-way normally, 32-way when the machine is * already busy (see `machineAlreadyBusy`). Callers capture the probe at pass * entry — BEFORE the walk/hash pass — and inject it, so the reading reflects * other processes rather than sync's own load; tests inject a synthetic probe. */ export type TransferPriority = "chore" | "realtime"; export declare function resolveTransferConcurrency(probe?: HostLoadProbe, priority?: TransferPriority): number; /** * A run-scoped permit pool for payload transfers. * * Most syncs have one engine, whose local executor uses * {@link resolveTransferConcurrency}. Company fanout intentionally starts * several independent engines at once, though, so the runner gives each one * the same semaphore when `HQ_SYNC_MAX_CONCURRENCY` is configured. That makes * the documented bandwidth-governor ceiling apply to the whole run rather * than once per company. */ export declare class TransferSemaphore { private available; private readonly waiters; constructor(capacity: number); withPermit(fn: () => Promise): Promise; } /** * Total in-flight upload-body bytes the upload pool may hold at once. Because * `uploadFile` buffers whole files, this — not the worker count — is what * bounds sync's peak memory. Sized from AVAILABLE memory (the pass-entry * probe's `availableMemFraction`), so a memory-tight host gets a small budget * that cannot exhaust what is left while an idle host is capped at 1 GiB. No * hard floor: a tiny budget is safe because the pool always admits one item * when nothing is in flight, so a single oversized file still uploads. Override * for tuning/tests with `HQ_SYNC_UPLOAD_BYTE_BUDGET_MB` (absolute, fractional * MB accepted). */ export declare function resolveUploadByteBudget(availableMemFraction?: number, totalMemBytes?: number): number; /** * Resolve active company from .hq/config.json. */ export declare function resolveActiveCompany(hqRoot: string): string | undefined; /** * Returns true when the remote object appears to have moved since the * journal entry's last-recorded sync. When both sides expose content lineage, * compare the remote published SHA-256 to the journal's local baseline before * considering the ETag. ETags remain version/concurrency tokens and are the * back-compat fallback for legacy objects and list-only results. */ export declare function hasRemoteChanged(remote: { lastModified: Date; etag: string; contentHash?: string; }, entry: { syncedAt: string; remoteEtag?: string; hash?: string; }): boolean; //# sourceMappingURL=sync-core.d.ts.map