import type { GitvaultMirrorCredential, GitvaultMirrorDestination } from "./gitvault-mirror-config.js"; export interface GitvaultMirrorObjectMeta { size_bytes: string; } /** * gitvault-byo-primary-bucket task 3.1 — allocation-time bucket probe * (design D6): does this destination honor create-only `if-none-match` * writes, is bucket versioning off, and is a write actually permitted? Every * property is checked independently so a refusal names EXACTLY which one * failed, never a bundled "something is wrong". `detail` carries the * underlying HTTP/network fact for the property that failed — never a * credential, never bytes. */ export interface GitvaultBucketProbeResult { write_permitted: boolean; create_only_honored: boolean; versioning_off: boolean; detail?: string; } /** * Storage-agnostic mirror backend. Every method addresses a KEY relative to * the mirror's own root — the writer is responsible for using the exact same * key the gateway's objects listing names (§3 layout), so the mirror is a * byte-for-byte replica of `source//` under the destination. */ export interface GitvaultMirrorBackend { /** A human-readable description of where this backend writes (for status/errors — never a credential). */ describe(): string; /** `null` when the key is absent. */ head(key: string): Promise; /** Read the full bytes, or `null` when absent. */ get(key: string): Promise; /** * Write bytes, create-only where the destination supports it (D7: "where * the destination honors if-none-match, recommended not required"). Returns * `created: false` when the key already existed — the caller decides * whether that is a benign dedup (matching size, matching hash) or a real * conflict. */ putCreateOnly(key: string, bytes: Uint8Array): Promise<{ created: boolean; }>; /** Every key under `prefix` (default: every key in the mirror), sorted. */ list(prefix?: string): Promise; /** * gitvault-byo-primary-bucket task 3.1 — the allocation-time bucket-policy * probe (design D6): create-only `if-none-match` honored, versioning off, * write permitted. Never throws on a failed property — it REPORTS the * three independent facts; the caller ({@link probeGitvaultByoDestination} * in `gitvault-byo-probe.js`) decides whether to refuse and names which * property failed. A backend implementation MAY throw for a genuinely * unexpected transport failure (network/DNS) rather than reporting a * property as false — the caller treats a thrown probe identically to a * failed one. */ probeWritePolicy(): Promise; } /** * A local (or network-mounted) directory, laid out identically to the bucket * (`/source//head/`, etc. — but the backend is * repo-scoped, so `root` IS already `/source/`). Writes * are atomic (temp file + rename); create-only is REAL create-only via * `wx` (`O_CREAT|O_EXCL`) — never a silent overwrite of a differently-keyed * torn write. */ export declare class DirectoryMirrorBackend implements GitvaultMirrorBackend { private readonly root; constructor(root: string); describe(): string; private resolve; head(key: string): Promise; get(key: string): Promise; putCreateOnly(key: string, bytes: Uint8Array): Promise<{ created: boolean; }>; list(prefix?: string): Promise; /** * A local (or network-mounted) directory trivially satisfies every * property: there is no versioning concept, and create-only is REAL * create-only (see the class doc). `write_permitted` is still actually * EXERCISED (not assumed) — a read-only mount or missing permission fails * it honestly rather than reporting a directory backend as always-write. */ probeWritePolicy(): Promise; } interface Sigv4Credentials { access_key_id: string; secret_access_key: string; session_token?: string; } /** Resolve a NAMED PROFILE (`~/.aws/credentials` + `~/.aws/config`) or the AMBIENT environment chain — see the module doc's documented scope limit. */ export declare function resolveMirrorCredentials(credential: GitvaultMirrorCredential): Sigv4Credentials; export declare class S3MirrorBackend implements GitvaultMirrorBackend { private readonly bucket; private readonly prefix; private readonly region; private readonly credential; private readonly endpoint?; constructor(bucket: string, prefix: string, region: string, credential: GitvaultMirrorCredential, endpoint?: string | undefined); describe(): string; private fullKey; private creds; head(key: string): Promise; get(key: string): Promise; putCreateOnly(key: string, bytes: Uint8Array): Promise<{ created: boolean; }>; list(prefix?: string): Promise; /** * gitvault-byo-primary-bucket task 3.1 (design D6). Deliberately does NOT * reuse {@link putCreateOnly}'s own read-and-compare fallback for a bucket * that rejects the `if-none-match` header (400/501): that fallback is a * best-effort DEGRADATION for ordinary writes, and the whole point of the * probe is to report the STRICT signal — does this bucket actually * enforce atomic create-only writes — so a bucket that cannot even * understand the condition is correctly reported as NOT honoring it, * never silently upgraded to "fine, we'll compare after the fact". * * Runs two independent PUTs at the SAME probe key (create-only, `p1` then * `p2` bytes): the first proves `write_permitted`; the second, at the * SAME key, proves `create_only_honored` — a bucket that lets the second * PUT succeed is silently overwriting, exactly the hazard §3's * "versioning disabled + mandatory if-none-match" profile exists to rule * out. `versioning_off` is a SEPARATE bucket-level `GET ?versioning` call * — a bucket whose versioning state cannot even be READ (e.g. missing * `s3:GetBucketVersioning`) is conservatively reported as NOT off, per the * fail-closed doctrine (D6): "no vault half-exists" beats "probably fine". * "Suspended" versioning is treated as compliant — the hazard the profile * guards against (a create-only PUT silently becoming a new object * version instead of a real conflict) applies only to `Enabled`. */ probeWritePolicy(): Promise; private probeVersioningOff; } /** Open the backend for one vault's mirror config — repo-scoped: the directory backend's root and the S3 prefix both already carry `source/`. */ export declare function openGitvaultMirrorBackend(destination: GitvaultMirrorDestination, repoId: string, credential?: GitvaultMirrorCredential): GitvaultMirrorBackend; /** * gitvault-byo-primary-bucket task 3.1 — open a backend at the DESTINATION * ROOT, with no `source/` scoping. Two callers need this shape, * both because `repo_id` is not (yet) in scope: the allocation-time probe * (a fresh destination has no repo_id until allocation MINTS one — the * probe writes/reads a `_byo-probe/` key at the destination's own * root, never colliding with any vault's `source//` prefix), and * BYO payload writes (task 3.2), whose server-issued `key` already carries * the full `source//...` path — this is the SAME opener * {@link discoverMirroredRepoIds} already used inline for mirror discovery, * factored out here so it has one implementation instead of two. */ export declare function openGitvaultDestinationBackend(destination: GitvaultMirrorDestination, credential?: GitvaultMirrorCredential): GitvaultMirrorBackend; /** * List every `repo_id` mirrored under a destination's root (`source//…`), * WITHOUT repo-scoping the backend first — the discovery step `recover * ` needs before it can even open the repo-scoped backend {@link * openGitvaultMirrorBackend} expects. Used only to resolve which vault a bare * destination URL (no `--repo`) names. */ export declare function discoverMirroredRepoIds(destination: GitvaultMirrorDestination, credential?: GitvaultMirrorCredential): Promise; /** Best-effort recursive delete of an empty (or now-empty) mirror root — used by `mirror remove --purge` semantics if ever added; NOT called by plain `mirror remove` (design: config removal never touches the customer's bytes). Exported for tests. */ export declare function _rmMirrorRoot(destination: GitvaultMirrorDestination, repoId: string): void; export {}; //# sourceMappingURL=gitvault-mirror-backend.d.ts.map