Skip to content
zit Artifact [44248444b0]
Login

Artifact [44248444b0]

Artifact 44248444b07145496b44fc1ba0c39637b64c486f79ef195f3db42e717a2cc60e:


//! RED coverage for Task 10's transactional `zit import-git` command.
//!
//! This file deliberately names the smallest testable production seam that does
//! not execute a shell command or contact a remote:
//!
//!   `git_import_cli.run(gpa, io, request, streams, dependencies) -> cli.Exit`
//!
//! `dependencies` supplies a `ChildFactory`/`ChildSession` and filesystem hooks.
//! A `ChildSession` must expose its stdout reader plus `terminate`, `drainStderr`,
//! and `reap`; each lifecycle operation is observable in the supplied fake. The
//! real CLI dispatch will construct OS-backed dependencies. The filesystem hook
//! is only needed to deterministically fail publication flush/close/sync/rename
//! boundaries; ordinary scenarios exercise a real `std.testing.tmpDir`.
//!
//! The opt-in suite intentionally remains RED until Task 10 provides command
//! preflight, real-pipe lifecycle, and publication-boundary fault seams. It is
//! not part of `zig build test`.

const std = @import("std");
const builtin = @import("builtin");
const cli = @import("cli.zig");
const fast_export = @import("zit").git_fast_export;
const import_cli = @import("git_import_cli.zig");
const checkout = @import("zit").checkout;
const helper_options = @import("git_import_cli_options");

const valid_export =
    "feature done\n" ++
    "blob\n" ++
    "mark :1\n" ++
    "data 5\n" ++
    "hello\n" ++
    "commit refs/heads/main\n" ++
    "mark :2\n" ++
    "author A <[email protected]> 0 +0000\n" ++
    "committer A <[email protected]> 0 +0000\n" ++
    "data 4\n" ++
    "init\n" ++
    "M 100644 :1 README\n" ++
    "\n" ++
    "done\n";

const valid_export_with_remote_ref =
    "feature done\n" ++
    "blob\n" ++
    "mark :1\n" ++
    "data 5\n" ++
    "hello\n" ++
    "commit refs/heads/main\n" ++
    "mark :2\n" ++
    "author A <[email protected]> 0 +0000\n" ++
    "committer A <[email protected]> 0 +0000\n" ++
    "data 4\n" ++
    "init\n" ++
    "M 100644 :1 README\n" ++
    "\n" ++
    "reset refs/remotes/origin/main\n" ++
    "from :2\n" ++
    "\n" ++
    "done\n";

const valid_export_with_oids =
    "feature done\n" ++
    "blob\n" ++
    "mark :1\n" ++
    "original-oid 100b93820ade4c16225673b4ca62bb3ade63c313\n" ++
    "data 5\n" ++
    "hello\n" ++
    "commit refs/heads/main\n" ++
    "mark :2\n" ++
    "original-oid ed9b38a10070b504cecfacd892507af78fcb24a4\n" ++
    "author A <[email protected]> 0 +0000\n" ++
    "committer A <[email protected]> 0 +0000\n" ++
    "data 4\n" ++
    "init\n" ++
    "M 100644 :1 README\n" ++
    "\n" ++
    "done\n";

const malformed_export =
    "feature done\n" ++
    "commit refs/heads/main\n" ++
    "mark :not-a-number\n";

const marked_tag_export =
    "feature done\n" ++
    "blob\n" ++
    "mark :1\n" ++
    "data 5\n" ++
    "hello\n" ++
    "commit refs/heads/main\n" ++
    "mark :2\n" ++
    "author A <[email protected]> 0 +0000\n" ++
    "committer A <[email protected]> 0 +0000\n" ++
    "data 4\n" ++
    "init\n" ++
    "M 100644 :1 README.md\n" ++
    "\n" ++
    "tag v1\n" ++
    "mark :3\n" ++
    "from :2\n" ++
    "tagger A <[email protected]> 0 +0000\n" ++
    "data 0\n" ++
    "\n" ++
    "done\n";

const Result = struct {
    code: cli.Exit,
    out: []const u8,
    err: []const u8,
    lifecycle: import_cli.ChildLifecycle,
};

/// The wished test adapter. Task 10's production implementation owns no fake
/// process: it consumes this narrow interface, while the CLI passes the
/// OS-backed implementation and this file passes a scripted one.
const LifecycleFault = enum { terminate, drain_stderr, reap };

const ScriptedGit = struct {
    fast_export: []const u8,
    export_exit: u8 = 0,
    stderr: []const u8 = "",
    launched: usize = 0,
    terminated: usize = 0,
    stderr_drained: usize = 0,
    reaped: usize = 0,
    lifecycle_fault: ?LifecycleFault = null,
    limits: import_cli.ImportLimits = .{},

    fn dependencies(self: *ScriptedGit, publication: import_cli.PublicationHooks) import_cli.Dependencies {
        return .{
            .git = .{
                .context = self,
                .vtable = &.{
                    .start_export = startExport,
                    .terminate = terminate,
                    .drain_stderr = drainStderr,
                    .reap = reap,
                },
            },
            .publication = publication,
            .limits = self.limits,
        };
    }

    fn startExport(context: *anyopaque, _: []const u8) !import_cli.ExportPipes {
        const self: *ScriptedGit = @ptrCast(@alignCast(context));
        self.launched += 1;
        return .{
            .stdout = .fixed(self.fast_export),
            .stderr = .fixed(self.stderr),
            .exit_code = self.export_exit,
        };
    }

    fn terminate(context: *anyopaque) !void {
        const self: *ScriptedGit = @ptrCast(@alignCast(context));
        self.terminated += 1;
        if (self.lifecycle_fault == .terminate) return error.InjectedLifecycleFailure;
    }

    fn drainStderr(context: *anyopaque) !void {
        const self: *ScriptedGit = @ptrCast(@alignCast(context));
        self.stderr_drained += 1;
        if (self.lifecycle_fault == .drain_stderr) return error.InjectedLifecycleFailure;
    }

    fn reap(context: *anyopaque) !void {
        const self: *ScriptedGit = @ptrCast(@alignCast(context));
        self.reaped += 1;
        if (self.lifecycle_fault == .reap) return error.InjectedLifecycleFailure;
    }
};

fn runFixture(
    tmp: std.testing.TmpDir,
    source: []const u8,
    destination: []const u8,
    quiet: bool,
    git: *ScriptedGit,
    publication: import_cli.PublicationHooks,
) Result {
    const Capture = struct {
        var out_storage: [4096]u8 = undefined;
        var err_storage: [4096]u8 = undefined;
    };
    var out = std.Io.Writer.fixed(&Capture.out_storage);
    var err = std.Io.Writer.fixed(&Capture.err_storage);
    const streams: cli.Streams = .{ .out = &out, .err = &err };

    const code = import_cli.run(
        std.testing.allocator,
        std.testing.io,
        .{
            .source = source,
            .destination_parent = tmp.dir,
            .destination_name = destination,
            .submanifest_k = 5,
            .attribution = .committer,
            .default_branch = null,
            .quiet = quiet,
        },
        streams,
        git.dependencies(publication),
    );

    return .{
        .code = code,
        .out = out.buffered(),
        .err = err.buffered(),
        .lifecycle = .{
            .launched = git.launched,
            .terminated = git.terminated,
            .stderr_drained = git.stderr_drained,
            .reaped = git.reaped,
        },
    };
}
fn retainedBytesForExport(bytes: []const u8) !u64 {
    var reader = fast_export.Reader.init(std.testing.allocator, .fixed(bytes), .{
        .max_line = 1024 * 1024,
        .max_data = 1024 * 1024 * 1024,
        .max_path = 4096,
    });
    defer reader.deinit();

    var retained_bytes: u64 = 0;
    while (try reader.next()) |lease| {
        const charge = blk: {
            var event = lease;
            defer event.deinit();
            break :blk try import_cli.retainedByteCharge(event.value);
        };
        retained_bytes = try std.math.add(u64, retained_bytes, charge);
    }
    return retained_bytes;
}

fn exists(io: std.Io, dir: std.Io.Dir, path: []const u8) bool {
    var file = dir.openFile(io, path, .{}) catch return false;
    file.close(io);
    return true;
}

fn directoryExists(io: std.Io, dir: std.Io.Dir, path: []const u8) bool {
    var child = dir.openDir(io, path, .{}) catch return false;
    child.close(io);
    return true;
}

fn expectNoPublication(io: std.Io, tmp: std.testing.TmpDir, destination: []const u8) !void {
    try std.testing.expect(!directoryExists(io, tmp.dir, destination));
    try std.testing.expect(!exists(io, tmp.dir, ".zit-import-map.jsonl"));
    var entries = tmp.dir.iterate();
    while (try entries.next(io)) |entry| {
        try std.testing.expect(!std.mem.startsWith(u8, entry.name, ".zit-import-tmp-"));
    }
}

test "import-git publishes .zit refs and map together only after a complete export" {
    var tmp = std.testing.tmpDir(.{});
    defer tmp.cleanup();

    var git: ScriptedGit = .{ .fast_export = valid_export, .stderr = "Enumerating objects\n" };
    const result = runFixture(
        tmp,
        "fixture.git",
        "imported",
        false,
        &git,
        .real_filesystem,
    );

    try std.testing.expectEqual(cli.Exit.ok, result.code);
    try std.testing.expectEqualStrings("imported\n", result.out);
    try std.testing.expect(std.mem.indexOf(u8, result.err, "import-git:") != null);
    var destination = try tmp.dir.openDir(std.testing.io, "imported", .{});
    defer destination.close(std.testing.io);
    try std.testing.expect(exists(std.testing.io, destination, ".zit"));
    try std.testing.expect(directoryExists(std.testing.io, destination, "refs"));
    try std.testing.expect(exists(std.testing.io, destination, ".zit-import-map.jsonl"));
    var checkout_buf: [checkout.max_ck_payload + 1]u8 = undefined;
    const imported_checkout = (try checkout.read(std.testing.io, destination, &checkout_buf)).?;
    try std.testing.expectEqualStrings("", imported_checkout.version);
    try std.testing.expectEqualStrings("main", imported_checkout.branch);
    try std.testing.expectEqual(@as(usize, 1), result.lifecycle.launched);
    try std.testing.expectEqual(@as(usize, 0), result.lifecycle.terminated);
    try std.testing.expectEqual(@as(usize, 1), result.lifecycle.stderr_drained);
    try std.testing.expectEqual(@as(usize, 1), result.lifecycle.reaped);
}

test "import-git finalizes remote refs emitted with all refs" {
    var tmp = std.testing.tmpDir(.{});
    defer tmp.cleanup();

    var git: ScriptedGit = .{ .fast_export = valid_export_with_remote_ref };
    const result = runFixture(tmp, "fixture.git", "with-remote", false, &git, .real_filesystem);

    try std.testing.expectEqual(cli.Exit.ok, result.code);
    var destination = try tmp.dir.openDir(std.testing.io, "with-remote", .{});
    defer destination.close(std.testing.io);
    try std.testing.expect(exists(std.testing.io, destination, "refs/sym-heads/main"));
    try std.testing.expect(exists(std.testing.io, destination, "refs/sym-refs/remotes/origin/main"));
}

test "import-git refuses an existing destination before Git starts" {
    var tmp = std.testing.tmpDir(.{});
    defer tmp.cleanup();
    try tmp.dir.createDir(std.testing.io, "already-there", .default_dir);

    var git: ScriptedGit = .{ .fast_export = valid_export };
    const result = runFixture(tmp, "fixture.git", "already-there", false, &git, .real_filesystem);

    try std.testing.expectEqual(cli.Exit.failure, result.code);
    try std.testing.expectEqualStrings("", result.out);
    try std.testing.expect(std.mem.indexOf(u8, result.err, "already exists") != null);
    try std.testing.expectEqual(@as(usize, 0), result.lifecycle.launched);
    try std.testing.expectEqual(@as(usize, 0), result.lifecycle.terminated);
    try std.testing.expectEqual(@as(usize, 0), result.lifecycle.stderr_drained);
    try std.testing.expectEqual(@as(usize, 0), result.lifecycle.reaped);
}

test "import-git aborts malformed export by terminating draining and reaping once" {
    var tmp = std.testing.tmpDir(.{});
    defer tmp.cleanup();

    var git: ScriptedGit = .{ .fast_export = malformed_export, .stderr = "fatal fixture diagnostic\n" };
    const result = runFixture(tmp, "fixture.git", "broken", false, &git, .real_filesystem);

    try std.testing.expectEqual(cli.Exit.failure, result.code);
    try std.testing.expectEqualStrings("", result.out);
    try std.testing.expect(std.mem.indexOf(u8, result.err, "fatal fixture diagnostic") != null);
    try std.testing.expectEqual(@as(usize, 1), result.lifecycle.launched);
    try std.testing.expectEqual(@as(usize, 1), result.lifecycle.terminated);
    try std.testing.expectEqual(@as(usize, 1), result.lifecycle.stderr_drained);
    try std.testing.expectEqual(@as(usize, 1), result.lifecycle.reaped);
    try expectNoPublication(std.testing.io, tmp, "broken");
}

test "import-git removes all temporary output when storage creation fails" {
    var tmp = std.testing.tmpDir(.{});
    defer tmp.cleanup();

    var git: ScriptedGit = .{ .fast_export = valid_export };
    const result = runFixture(
        tmp,
        "fixture.git",
        "storage-failed",
        false,
        &git,
        .{ .fail_at = .create_store },
    );

    try std.testing.expectEqual(cli.Exit.failure, result.code);
    try std.testing.expectEqualStrings("", result.out);
    try std.testing.expectEqual(@as(usize, 1), result.lifecycle.launched);
    try std.testing.expectEqual(@as(usize, 1), result.lifecycle.reaped);
    try expectNoPublication(std.testing.io, tmp, "storage-failed");
}

test "import-git removes all temporary output when publication flush or rename fails" {
    const failures = [_]import_cli.PublicationHooks.FailurePoint{ .flush_store, .sync_map, .rename_no_replace };
    for (failures) |failure| {
        var tmp = std.testing.tmpDir(.{});
        defer tmp.cleanup();
        var git: ScriptedGit = .{ .fast_export = valid_export };
        const result = runFixture(
            tmp,
            "fixture.git",
            "publication-failed",
            false,
            &git,
            .{ .fail_at = failure },
        );

        try std.testing.expectEqual(cli.Exit.failure, result.code);
        try std.testing.expectEqualStrings("", result.out);
        try std.testing.expectEqual(@as(usize, 1), result.lifecycle.reaped);
        try expectNoPublication(std.testing.io, tmp, "publication-failed");
    }
}

test "import-git writes only a machine-readable destination to stdout and progress to stderr" {
    var tmp = std.testing.tmpDir(.{});
    defer tmp.cleanup();
    var git: ScriptedGit = .{ .fast_export = valid_export, .stderr = "git progress\n" };
    const result = runFixture(tmp, "fixture.git", "machine", false, &git, .real_filesystem);

    try std.testing.expectEqual(cli.Exit.ok, result.code);
    try std.testing.expectEqualStrings("machine\n", result.out);
    try std.testing.expect(std.mem.indexOf(u8, result.err, "git progress") != null);
    try std.testing.expect(std.mem.indexOf(u8, result.out, "progress") == null);
}

test "import-git --quiet suppresses progress but not diagnostics" {
    var quiet_tmp = std.testing.tmpDir(.{});
    defer quiet_tmp.cleanup();
    var quiet_git: ScriptedGit = .{ .fast_export = valid_export, .stderr = "git progress\n" };
    const quiet = runFixture(quiet_tmp, "fixture.git", "quiet", true, &quiet_git, .real_filesystem);
    try std.testing.expectEqual(cli.Exit.ok, quiet.code);
    try std.testing.expectEqualStrings("quiet\n", quiet.out);
    try std.testing.expectEqualStrings("", quiet.err);

    var error_tmp = std.testing.tmpDir(.{});
    defer error_tmp.cleanup();
    var error_git: ScriptedGit = .{ .fast_export = malformed_export, .stderr = "fatal fixture diagnostic\n" };
    const failed = runFixture(error_tmp, "fixture.git", "quiet-error", true, &error_git, .real_filesystem);
    try std.testing.expectEqual(cli.Exit.failure, failed.code);
    try std.testing.expectEqualStrings("", failed.out);
    try std.testing.expect(std.mem.indexOf(u8, failed.err, "fatal fixture diagnostic") != null);
}

// The remaining tests specify the Task 10 seam not yet present in
// `git_import_cli`: CommandScript records every preflight/export invocation,
// supplies bounded stdout/stderr streams, and exposes deterministic
// cancellation and publication-boundary faults. Production dispatch constructs
// the OS adapter; tests use no shell or network.
fn scripted(
    tmp: std.testing.TmpDir,
    script: *import_cli.CommandScript,
    destination: []const u8,
    quiet: bool,
    fault: import_cli.PublicationHooks,
) import_cli.ScriptResult {
    return import_cli.runScripted(
        std.testing.allocator,
        std.testing.io,
        .{
            .source = "fixture.git",
            .destination_parent = tmp.dir,
            .destination_name = destination,
            .submanifest_k = 5,
            .attribution = .committer,
            .default_branch = null,
            .quiet = quiet,
        },
        script,
        fault,
    );
}

const ProcessResult = struct {
    code: cli.Exit,
    out: []const u8,
    err: []const u8,
    exit_code: u8,
    reaped: bool,
    reap_calls: usize,
    child_gone: bool,
    stderr_bytes_drained: usize,
    retained_diagnostic_len: usize,
};

/// Drives the real ProductionGit session against the build-wired helper. The
/// only substitution is argv; spawning, pipe adapters, concurrent diagnostic
/// drain, terminate, join, and wait are the production implementation.
fn runProductionPipe(
    tmp: std.testing.TmpDir,
    destination: []const u8,
    mode: []const u8,
) !ProcessResult {
    var threaded = std.Io.Threaded.init(std.testing.allocator, .{});
    defer threaded.deinit();
    const io = threaded.io();
    var session = import_cli.ProductionGit.initForTest(
        std.testing.allocator,
        io,
        &.{ helper_options.git_import_pipe_helper, mode },
    );
    const Capture = struct {
        var out_storage: [4096]u8 = undefined;
        var err_storage: [4096]u8 = undefined;
    };
    var out = std.Io.Writer.fixed(&Capture.out_storage);
    var err = std.Io.Writer.fixed(&Capture.err_storage);
    const code = import_cli.run(
        std.testing.allocator,
        io,
        .{
            .source = "fixture.git",
            .destination_parent = tmp.dir,
            .destination_name = destination,
        },
        .{ .out = &out, .err = &err },
        session.dependencies(.real_filesystem),
    );
    return .{
        .code = code,
        .out = out.buffered(),
        .err = err.buffered(),
        .exit_code = session.exit_code,
        .reaped = session.reaped,
        .child_gone = session.child == null,
        .stderr_bytes_drained = session.stderr_bytes_drained,
        .reap_calls = session.reap_calls,
        .retained_diagnostic_len = session.stderr_ring_len,
    };
}
fn runGit(io: std.Io, argv: []const []const u8) !void {
    const result = try std.process.run(std.testing.allocator, io, .{ .argv = argv });
    defer std.testing.allocator.free(result.stdout);
    defer std.testing.allocator.free(result.stderr);
    switch (result.term) {
        .exited => |code| if (code == 0) return,
        else => {},
    }
    return error.GitSetupFailed;
}

fn writeFixtureFile(io: std.Io, dir: std.Io.Dir, path: []const u8, bytes: []const u8) !void {
    var file = try dir.createFile(io, path, .{ .read = true, .truncate = true });
    defer file.close(io);
    try file.writeStreamingAll(io, bytes);
}

fn runProductionPreflight(
    tmp: std.testing.TmpDir,
    source: []const u8,
    destination: []const u8,
) cli.Exit {
    const Capture = struct {
        var out_storage: [1024]u8 = undefined;
        var err_storage: [1024]u8 = undefined;
    };
    var out = std.Io.Writer.fixed(&Capture.out_storage);
    var err = std.Io.Writer.fixed(&Capture.err_storage);
    var session = import_cli.ProductionGit.init(std.testing.allocator, std.testing.io);
    defer session.deinit();
    return import_cli.run(
        std.testing.allocator,
        std.testing.io,
        .{
            .source = source,
            .destination_parent = tmp.dir,
            .destination_name = destination,
        },
        .{ .out = &out, .err = &err },
        session.dependencies(.real_filesystem),
    );
}

test "import-git parser leaves k unset for analysis and is a real dispatched verb" {
    // Absent means "analyze", not "5": the parser must not manufacture a pin
    // the runner would then be unable to distinguish from an operator's.
    const defaulted = try cli.parseImportGitArgs(&.{ "fixture.git", "dest" });
    try std.testing.expectEqual(@as(?u4, null), defaulted.submanifest_k);
    try std.testing.expectEqual(cli.Verb.import_git, cli.verbOf("import-git"));
    try std.testing.expect(!cli.isPlanned("import-git"));

    const parsed = try cli.parseImportGitArgs(&.{
        "--submanifest-k",  "7",
        "--attribution",    "author",
        "--default-branch", "main",
        "--quiet",          "fixture.git",
        "dest",
    });
    try std.testing.expectEqual(@as(?u4, 7), parsed.submanifest_k);
    try std.testing.expectEqual(.author, parsed.attribution);
    try std.testing.expectEqualStrings("main", parsed.default_branch.?);
    try std.testing.expect(parsed.quiet);
    const min_k = try cli.parseImportGitArgs(&.{ "--submanifest-k", "1", "fixture.git", "dest" });
    try std.testing.expectEqual(@as(?u4, 1), min_k.submanifest_k);
    const max_k = try cli.parseImportGitArgs(&.{ "--submanifest-k", "12", "fixture.git", "dest" });
    try std.testing.expectEqual(@as(?u4, 12), max_k.submanifest_k);
    for ([_][]const u8{ "0", "13", "14", "15" }) |value| {
        try std.testing.expectError(
            cli.ImportGitParseError.InvalidSubmanifestK,
            cli.parseImportGitArgs(&.{ "--submanifest-k", value, "fixture.git", "dest" }),
        );
    }
}

test "import-git parser exposes the export payload budget as an operator flag" {
    // Every ceiling an honest source can reach must be raisable without a
    // recompile. This one budget carries both the cumulative payload limit and
    // the derived per-commit file-command ceiling, so it is the only knob the
    // verb needs.
    const defaulted = try cli.parseImportGitArgs(&.{ "fixture.git", "dest" });
    try std.testing.expectEqual(@as(?u64, null), defaulted.max_export_payload_bytes);

    const raised = try cli.parseImportGitArgs(&.{
        "--max-export-payload-bytes", "68719476736",
        "fixture.git",                "dest",
    });
    try std.testing.expectEqual(@as(?u64, 68719476736), raised.max_export_payload_bytes);

    // Zero derives a per-commit ceiling of zero: a budget no import can ever
    // satisfy is a typo, not a policy.
    try std.testing.expectError(
        cli.ImportGitParseError.InvalidExportPayloadBytes,
        cli.parseImportGitArgs(&.{ "--max-export-payload-bytes", "0", "fixture.git", "dest" }),
    );
    try std.testing.expectError(
        cli.ImportGitParseError.InvalidExportPayloadBytes,
        cli.parseImportGitArgs(&.{ "--max-export-payload-bytes", "many", "fixture.git", "dest" }),
    );
    try std.testing.expectError(
        cli.ImportGitParseError.MissingOptionValue,
        cli.parseImportGitArgs(&.{ "fixture.git", "dest", "--max-export-payload-bytes" }),
    );
    try std.testing.expectError(
        cli.ImportGitParseError.RepeatedOption,
        cli.parseImportGitArgs(&.{
            "--max-export-payload-bytes", "1024",
            "--max-export-payload-bytes", "2048",
            "fixture.git",                "dest",
        }),
    );
}

/// Whether `token` appears anywhere in `argv`. Positional indices would encode
/// the argv's shape, which is not what this asserts.
fn argvHas(argv: []const []const u8, token: []const u8) bool {
    for (argv) |candidate| {
        if (std.mem.eql(u8, candidate, token)) return true;
    }
    return false;
}

test "import-git strips signatures by default and aborts only under --refuse-signed" {
    // Fossil has no signature card, so refusing by default withheld the import
    // without saving anything. The default must therefore strip.
    const defaulted = try cli.parseImportGitArgs(&.{ "fixture.git", "dest" });
    try std.testing.expect(!defaulted.refuse_signed);
    const stripping = import_cli.exportArgv("fixture.git", defaulted.refuse_signed);
    try std.testing.expect(argvHas(&stripping, "--signed-commits=strip"));
    try std.testing.expect(argvHas(&stripping, "--signed-tags=strip"));
    try std.testing.expect(!argvHas(&stripping, "--signed-commits=abort"));
    try std.testing.expect(!argvHas(&stripping, "--signed-tags=abort"));

    // The opt-out restores the refusal, and nothing else about the argv moves.
    const opted_out = try cli.parseImportGitArgs(&.{ "--refuse-signed", "fixture.git", "dest" });
    try std.testing.expect(opted_out.refuse_signed);
    const aborting = import_cli.exportArgv("fixture.git", opted_out.refuse_signed);
    try std.testing.expect(argvHas(&aborting, "--signed-commits=abort"));
    try std.testing.expect(argvHas(&aborting, "--signed-tags=abort"));
    try std.testing.expectEqual(stripping.len, aborting.len);
    for (stripping, aborting) |strip_token, abort_token| {
        if (std.mem.startsWith(u8, strip_token, "--signed-")) continue;
        try std.testing.expectEqualStrings(strip_token, abort_token);
    }

    // Same error shape as every other boolean flag: repeated is a usage error,
    // and the retired spelling is simply unknown.
    try std.testing.expectError(
        cli.ImportGitParseError.RepeatedOption,
        cli.parseImportGitArgs(&.{ "--refuse-signed", "--refuse-signed", "fixture.git", "dest" }),
    );
    try std.testing.expectError(
        cli.ImportGitParseError.UnknownOption,
        cli.parseImportGitArgs(&.{ "--drop-signatures", "fixture.git", "dest" }),
    );
}

test "import-git help exits zero and malformed argument forms exit usage without process launch" {
    const help = import_cli.dispatchForTest(&.{"--help"});
    try std.testing.expectEqual(cli.Exit.ok, help.code);
    try std.testing.expectEqualStrings("", help.err);
    try std.testing.expect(std.mem.indexOf(u8, help.out, "zit import-git SOURCE DEST") != null);

    const accepted_max = import_cli.dispatchForTest(&.{ "--submanifest-k", "12", "fixture.git", "dest" });
    try std.testing.expectEqual(cli.Exit.failure, accepted_max.code);
    try std.testing.expectEqual(@as(usize, 0), accepted_max.lifecycle.launched);
    try std.testing.expectEqualStrings("test dispatch requires scripted dependencies\n", accepted_max.err);

    for ([_][]const []const u8{
        &.{ "--submanifest-k", "0", "fixture.git", "dest" },
        &.{ "--submanifest-k", "13", "fixture.git", "dest" },
        &.{ "--submanifest-k", "14", "fixture.git", "dest" },
        &.{ "--submanifest-k", "15", "fixture.git", "dest" },
        &.{ "--attribution", "committerish", "fixture.git", "dest" },
        &.{"fixture.git"},
        &.{ "fixture.git", "dest", "extra" },
    }) |args| {
        const usage = import_cli.dispatchForTest(args);
        try std.testing.expectEqual(cli.Exit.usage, usage.code);
        try std.testing.expectEqual(@as(usize, 0), usage.lifecycle.launched);
        try std.testing.expectEqualStrings("", usage.out);
        try std.testing.expect(usage.err.len != 0);
    }
}

test "import-git rejects missing Git non-repository shallow and partial sources before export" {
    const preflight_failures = [_]import_cli.CommandScript.Preflight{
        .git_missing,
        .not_repository,
        .missing_objects,
        .shallow,
        .partial_promisor,
    };
    for (preflight_failures) |preflight| {
        var tmp = std.testing.tmpDir(.{});
        defer tmp.cleanup();
        var script = import_cli.CommandScript.init(.{ .preflight = preflight });
        const result = scripted(tmp, &script, "rejected", false, .real_filesystem);
        try std.testing.expectEqual(cli.Exit.failure, result.code);
        try std.testing.expectEqual(@as(usize, 0), script.export_starts);
        try std.testing.expect(script.preflight_starts != 0);
        try std.testing.expectEqual(@as(usize, 0), result.lifecycle.terminated);
        try std.testing.expectEqual(@as(usize, 1), result.lifecycle.reaped);
        try expectNoPublication(std.testing.io, tmp, "rejected");
    }
}
test "import-git production preflight rejects absent non-repository missing-object shallow and partial sources" {
    var tmp = std.testing.tmpDir(.{});
    defer tmp.cleanup();
    var root_buf: [128]u8 = undefined;
    const root = try std.fmt.bufPrint(&root_buf, ".zig-cache/tmp/{s}", .{tmp.sub_path});
    var source_buf: [160]u8 = undefined;
    const source = try std.fmt.bufPrint(&source_buf, "{s}/source", .{root});

    // A non-existent -C path and an existing non-repository both execute real
    // ProductionGit query children and fail before an export can launch.
    try std.testing.expectEqual(cli.Exit.failure, runProductionPreflight(tmp, source, "missing-git"));
    try tmp.dir.createDir(std.testing.io, "not-repository", .default_dir);
    var nonrepo_buf: [160]u8 = undefined;
    const nonrepo = try std.fmt.bufPrint(&nonrepo_buf, "{s}/not-repository", .{root});
    try std.testing.expectEqual(cli.Exit.failure, runProductionPreflight(tmp, nonrepo, "not-repository-dest"));
    try expectNoPublication(std.testing.io, tmp, "missing-git");
    try expectNoPublication(std.testing.io, tmp, "not-repository-dest");

    try runGit(std.testing.io, &.{ "git", "init", source });
    try runGit(std.testing.io, &.{ "git", "-C", source, "config", "user.name", "Zit Test" });
    try runGit(std.testing.io, &.{ "git", "-C", source, "config", "user.email", "[email protected]" });
    try runGit(std.testing.io, &.{ "git", "-C", source, "commit", "--allow-empty", "-m", "init" });

    try runGit(std.testing.io, &.{ "git", "-C", source, "config", "extensions.partialClone", "origin" });
    try std.testing.expectEqual(cli.Exit.failure, runProductionPreflight(tmp, source, "partial"));
    try runGit(std.testing.io, &.{ "git", "-C", source, "config", "--unset", "extensions.partialClone" });

    try writeFixtureFile(std.testing.io, tmp.dir, "source/.git/shallow", "0000000000000000000000000000000000000000\n");
    try std.testing.expectEqual(cli.Exit.failure, runProductionPreflight(tmp, source, "shallow"));
    try tmp.dir.deleteFile(std.testing.io, "source/.git/shallow");

    try tmp.dir.deleteTree(std.testing.io, "source/.git/objects");
    try std.testing.expectEqual(cli.Exit.failure, runProductionPreflight(tmp, source, "missing-objects"));
    try expectNoPublication(std.testing.io, tmp, "partial");
    try expectNoPublication(std.testing.io, tmp, "shallow");
    try expectNoPublication(std.testing.io, tmp, "missing-objects");
}

test "import-git records detached HEAD and refuses it unless default branch is explicit" {
    var tmp = std.testing.tmpDir(.{});
    defer tmp.cleanup();
    var script = import_cli.CommandScript.init(.{ .preflight = .detached_head, .fast_export = valid_export });
    const rejected = scripted(tmp, &script, "detached", false, .real_filesystem);
    try std.testing.expectEqual(cli.Exit.failure, rejected.code);
    try std.testing.expectEqual(@as(usize, 0), script.export_starts);
    try expectNoPublication(std.testing.io, tmp, "detached");

    script.default_branch = "main";
    const accepted = scripted(tmp, &script, "detached-with-branch", false, .real_filesystem);
    try std.testing.expectEqual(cli.Exit.ok, accepted.code);
    try std.testing.expect(script.detached_head_recorded);
}

test "import-git starts fast-export with the exact safe argv and disabled prompt and lazy fetch" {
    var tmp = std.testing.tmpDir(.{});
    defer tmp.cleanup();
    var script = import_cli.CommandScript.init(.{ .preflight = .branch_head, .fast_export = valid_export });
    const result = scripted(tmp, &script, "argv", false, .real_filesystem);
    try std.testing.expectEqual(cli.Exit.ok, result.code);
    try std.testing.expectEqualStrings(
        "git -C fixture.git fast-export --all --show-original-ids --mark-tags --signed-commits=strip --signed-tags=strip --use-done-feature",
        script.exportCommandLine(),
    );
    try std.testing.expectEqualStrings("0", script.environment.get("GIT_TERMINAL_PROMPT").?);
    try std.testing.expectEqualStrings("1", script.environment.get("GIT_NO_LAZY_FETCH").?);
}

test "import-git drains real OS-pipe backpressure concurrently while stdout remains active" {
    var tmp = std.testing.tmpDir(.{});
    defer tmp.cleanup();
    const result = try runProductionPipe(tmp, "flood", "success");

    try std.testing.expectEqual(cli.Exit.ok, result.code);
    try std.testing.expectEqual(@as(usize, 8 * 1024 * 1024), result.stderr_bytes_drained);
    try std.testing.expectEqual(@as(usize, 4096), result.retained_diagnostic_len);
    try std.testing.expect(result.err.len < 4096);
    try std.testing.expect(std.mem.indexOf(u8, result.err, "imported 'fixture.git'") != null);
    try std.testing.expectEqual(@as(u8, 0), result.exit_code);
    try std.testing.expect(result.reaped);
    try std.testing.expect(result.child_gone);
}

test "import-git cancellation terminates a real child then joins and reaps its actual status once" {
    var tmp = std.testing.tmpDir(.{});
    defer tmp.cleanup();
    const result = try runProductionPipe(tmp, "cancelled", "hold");

    try std.testing.expectEqual(cli.Exit.failure, result.code);
    try std.testing.expect(result.exit_code != 0);
    try std.testing.expect(result.err.len < 4096);
    try std.testing.expect(std.mem.indexOf(u8, result.err, "Malformed") != null);
    try std.testing.expect(std.mem.indexOf(u8, result.err, "GitExportFailed") == null);
    try std.testing.expect(result.reaped);
    try std.testing.expect(result.child_gone);
    try expectNoPublication(std.testing.io, tmp, "cancelled");
}

test "import-git non-Darwin/Linux fallback drains stable stderr ownership then reaps once" {
    if (builtin.os.tag == .macos or builtin.os.tag == .linux) return;
    var tmp = std.testing.tmpDir(.{});
    defer tmp.cleanup();
    const result = try runProductionPipe(tmp, "fallback-cancelled", "hold");

    try std.testing.expectEqual(cli.Exit.failure, result.code);
    try std.testing.expect(result.stderr_bytes_drained != 0);
    try std.testing.expect(result.reaped);
    try std.testing.expectEqual(@as(usize, 1), result.reap_calls);
    try std.testing.expect(result.child_gone);
    try expectNoPublication(std.testing.io, tmp, "fallback-cancelled");
}

test "import-git rejects a nonzero completed export after draining and reaping it once" {
    var tmp = std.testing.tmpDir(.{});
    defer tmp.cleanup();
    const result = try runProductionPipe(tmp, "nonzero-export", "nonzero");

    try std.testing.expectEqual(cli.Exit.failure, result.code);
    try std.testing.expectEqual(@as(u8, 23), result.exit_code);
    try std.testing.expect(result.reaped);
    try std.testing.expect(result.child_gone);
    try expectNoPublication(std.testing.io, tmp, "nonzero-export");
}
test "import-git prefers a nonzero truncated export status over its parser EOF" {
    var tmp = std.testing.tmpDir(.{});
    defer tmp.cleanup();
    const result = try runProductionPipe(tmp, "signed-like-export", "truncated-nonzero");

    try std.testing.expectEqual(cli.Exit.failure, result.code);
    try std.testing.expectEqual(@as(u8, 23), result.exit_code);
    try std.testing.expect(std.mem.indexOf(u8, result.err, "GitExportFailed") != null);
    try std.testing.expect(std.mem.indexOf(u8, result.err, "fatal: signed commit rejected") != null);
    try std.testing.expect(std.mem.indexOf(u8, result.err, "UnexpectedEof") == null);
    try std.testing.expect(result.reaped);
    try std.testing.expect(result.child_gone);
    try expectNoPublication(std.testing.io, tmp, "signed-like-export");
}

test "import-git verifies the frozen .zit and import map before the atomic rename" {
    var tmp = std.testing.tmpDir(.{});
    defer tmp.cleanup();
    var script = import_cli.CommandScript.init(.{ .preflight = .branch_head, .fast_export = valid_export });
    const result = scripted(tmp, &script, "verified", false, .real_filesystem);
    try std.testing.expectEqual(cli.Exit.ok, result.code);
    try std.testing.expect(script.publication.store_reopened_for_verify);
    try std.testing.expect(script.publication.map_reopened_for_verify);
    try std.testing.expect(script.publication.verify_before_publish);
}

test "import-git competing destination at commit point never clobbers it and removes its temporary sibling" {
    var tmp = std.testing.tmpDir(.{});
    defer tmp.cleanup();
    var script = import_cli.CommandScript.init(.{
        .preflight = .branch_head,
        .fast_export = valid_export,
        .competing_destination_at_publish = true,
    });
    const result = scripted(tmp, &script, "raced", false, .real_filesystem);
    try std.testing.expectEqual(cli.Exit.failure, result.code);
    try std.testing.expect(script.competitor_destination_intact);
    try std.testing.expectEqual(@as(usize, 1), result.lifecycle.reaped);
    try std.testing.expect(!script.temporary_sibling_left);
}

test "import-git never publishes or deletes a replaced staging sibling" {
    const replacements = [_]import_cli.CommandScript.StagingReplacement{ .directory, .symlink };
    for (replacements) |replacement| {
        for (0..8) |_| {
            var tmp = std.testing.tmpDir(.{});
            defer tmp.cleanup();
            try tmp.dir.createDir(std.testing.io, "outside", .default_dir);
            try writeFixtureFile(std.testing.io, tmp.dir, "outside/replacement-sentinel", "survives\n");

            var script = import_cli.CommandScript.init(.{
                .preflight = .branch_head,
                .fast_export = valid_export,
                .replace_staging_at_publish = replacement,
            });
            const result = scripted(tmp, &script, "raced-staging", false, .real_filesystem);

            try std.testing.expectEqual(cli.Exit.failure, result.code);
            try std.testing.expect(std.mem.indexOf(u8, result.err, "StagingEntryReplaced") != null);
            try std.testing.expect(script.staging_replacement_observed);
            try std.testing.expectEqual(@as(usize, 0), result.lifecycle.terminated);
            try std.testing.expectEqual(@as(usize, 1), result.lifecycle.stderr_drained);
            try std.testing.expectEqual(@as(usize, 1), result.lifecycle.reaped);
            try std.testing.expect(!directoryExists(std.testing.io, tmp.dir, "raced-staging"));
            try std.testing.expect(!exists(std.testing.io, tmp.dir, ".zit-import-map.jsonl"));

            const staging_name = script.stagingReplacementName();
            try std.testing.expect(staging_name.len != 0);
            var outside = try tmp.dir.openDir(std.testing.io, "outside", .{ .follow_symlinks = false });
            defer outside.close(std.testing.io);
            try std.testing.expect(exists(std.testing.io, outside, "replacement-sentinel"));
            switch (replacement) {
                .directory => {
                    var preserved = try tmp.dir.openDir(std.testing.io, staging_name, .{ .follow_symlinks = false });
                    defer preserved.close(std.testing.io);
                    try std.testing.expect(exists(std.testing.io, preserved, "replacement-sentinel"));
                },
                .symlink => {
                    var target: [32]u8 = undefined;
                    const len = try tmp.dir.readLink(std.testing.io, staging_name, &target);
                    try std.testing.expectEqualStrings("outside", target[0..len]);
                },
            }
        }
    }
}

test "import-git default ceilings clear the retired 200k per-commit file wall" {
    const limits: import_cli.ImportLimits = .{};
    const ceiling = fast_export.fileCommandCeiling(.{
        .max_line = 0,
        .max_data = 0,
        .max_path = 0,
        .max_total_data = limits.max_export_payload_bytes,
    });
    // The retired ceiling was 200,000 because that is the benchmark corpus
    // width. The derived one must clear it by orders of magnitude, so no
    // ordinary monorepo root commit can reach it, and it must move only with
    // the byte budget.
    try std.testing.expect(ceiling > 100 * 200_000);
    try std.testing.expectEqual(
        limits.max_export_payload_bytes / fast_export.min_retained_bytes_per_file_command,
        ceiling,
    );
    try std.testing.expect(limits.max_export_events >= 400_000);
    try std.testing.expect(limits.max_export_payload_bytes >= 64 * 1024 * 1024);
    try std.testing.expect(limits.max_retained_entries >= 6 * 400_000);
    try std.testing.expect(limits.max_retained_bytes >= 64 * 1024 * 1024);
}

test "import-git reader limits reject before event and data parsing allocations" {
    const event_limited = "feature done\nblob\nmark :1\ndata 1\nx\n";
    var event_reader = fast_export.Reader.init(std.testing.allocator, .fixed(event_limited), .{
        .max_line = 1024,
        .max_data = 1024,
        .max_path = 1024,
        .max_events = 0,
        .max_total_data = 1024,
    });
    defer event_reader.deinit();
    try std.testing.expectError(error.EventLimitExceeded, event_reader.next());

    const data_limited = "feature done\nblob\nmark :1\ndata 1\nx\n";
    var data_reader = fast_export.Reader.init(std.testing.allocator, .fixed(data_limited), .{
        .max_line = 1024,
        .max_data = 1024,
        .max_path = 1024,
        .max_events = 1,
        .max_total_data = 0,
    });
    defer data_reader.deinit();
    try std.testing.expectError(error.DataLimitExceeded, data_reader.next());
}
test "import-git enforces total import ceilings before publication" {
    // The payload budget now carries two ceilings, so the accepted value sits
    // at the tighter of them: exactly one command's worth of minimum retention,
    // which is also comfortably above the stream's nine payload bytes.
    const one_command_budget = fast_export.min_retained_bytes_per_file_command;
    const accepted_limits: import_cli.ImportLimits = .{
        .max_export_events = 3,
        .max_export_payload_bytes = one_command_budget,
        .max_retained_entries = 7,
        .max_retained_bytes = 1024,
    };
    const RejectedLimit = struct {
        limits: import_cli.ImportLimits,
        error_name: []const u8,
    };
    const rejected_limits = [_]RejectedLimit{
        .{
            .limits = .{
                .max_export_events = accepted_limits.max_export_events - 1,
                .max_export_payload_bytes = accepted_limits.max_export_payload_bytes,
                .max_retained_entries = accepted_limits.max_retained_entries,
            },
            .error_name = "ExportEventLimitExceeded",
        },
        .{
            // One byte below the stream's own payload. The blob's five bytes
            // admit; the commit message's four push the total past it, before
            // any file command is parsed.
            .limits = .{
                .max_export_events = accepted_limits.max_export_events,
                .max_export_payload_bytes = 8,
                .max_retained_entries = accepted_limits.max_retained_entries,
            },
            .error_name = "ExportPayloadLimitExceeded",
        },
        .{
            .limits = .{
                .max_export_events = accepted_limits.max_export_events,
                .max_export_payload_bytes = accepted_limits.max_export_payload_bytes,
                .max_retained_entries = accepted_limits.max_retained_entries - 1,
            },
            .error_name = "ImporterRetainedEntryLimitExceeded",
        },
        .{
            .limits = .{
                .max_export_events = accepted_limits.max_export_events,
                .max_export_payload_bytes = accepted_limits.max_export_payload_bytes,
                .max_retained_entries = accepted_limits.max_retained_entries,
                .max_retained_bytes = 0,
            },
            .error_name = "ImporterRetainedByteLimitExceeded",
        },
    };
    {
        var tmp = std.testing.tmpDir(.{});
        defer tmp.cleanup();
        var script = import_cli.CommandScript.init(.{
            .preflight = .branch_head,
            .fast_export = valid_export_with_oids,
            .limits = accepted_limits,
        });
        const result = scripted(tmp, &script, "at-limit", false, .real_filesystem);
        try std.testing.expectEqual(cli.Exit.ok, result.code);
        try std.testing.expectEqual(@as(usize, 0), result.lifecycle.terminated);
        try std.testing.expectEqual(@as(usize, 1), result.lifecycle.stderr_drained);
        try std.testing.expectEqual(@as(usize, 1), result.lifecycle.reaped);
    }

    for (rejected_limits, 0..) |rejected, index| {
        var tmp = std.testing.tmpDir(.{});
        defer tmp.cleanup();
        var script = import_cli.CommandScript.init(.{
            .preflight = .branch_head,
            .fast_export = valid_export_with_oids,
            .limits = rejected.limits,
        });
        var destination: [32]u8 = undefined;
        const destination_name = try std.fmt.bufPrint(&destination, "limit-{d}", .{index});
        const result = scripted(tmp, &script, destination_name, false, .real_filesystem);

        try std.testing.expectEqual(cli.Exit.failure, result.code);
        try std.testing.expect(std.mem.indexOf(u8, result.err, rejected.error_name) != null);
        try std.testing.expectEqual(@as(usize, 1), result.lifecycle.terminated);
        try std.testing.expectEqual(@as(usize, 1), result.lifecycle.stderr_drained);
        try std.testing.expectEqual(@as(usize, 1), result.lifecycle.reaped);
        try expectNoPublication(std.testing.io, tmp, destination_name);
    }
    {
        // One byte below one command's minimum retention derives a ceiling of
        // zero, so the stream's single `M` command is refused. The failure must
        // name the observed count, the ceiling, the derivation, and the flag
        // that raises it — the error name alone is not actionable.
        var tmp = std.testing.tmpDir(.{});
        defer tmp.cleanup();
        var script = import_cli.CommandScript.init(.{
            .preflight = .branch_head,
            .fast_export = valid_export_with_oids,
            .limits = .{
                .max_export_events = accepted_limits.max_export_events,
                .max_export_payload_bytes = one_command_budget - 1,
                .max_retained_entries = accepted_limits.max_retained_entries,
                .max_retained_bytes = accepted_limits.max_retained_bytes,
            },
        });
        const result = scripted(tmp, &script, "command-ceiling", false, .real_filesystem);
        try std.testing.expectEqual(cli.Exit.failure, result.code);

        var expected: [512]u8 = undefined;
        const diagnostic = try std.fmt.bufPrint(
            &expected,
            "import-git: import failed: ExportFileCommandLimitExceeded\n" ++
                "import-git: a commit exceeded the per-commit file-command ceiling: " ++
                "observed at least 1, ceiling 0, derived from the {d}-byte export payload " ++
                "budget at {d} minimum retained bytes per command; re-run with " ++
                "--max-export-payload-bytes above {d}\n",
            .{ one_command_budget - 1, one_command_budget, one_command_budget - 1 },
        );
        try std.testing.expect(std.mem.indexOf(u8, result.err, diagnostic) != null);
        try expectNoPublication(std.testing.io, tmp, "command-ceiling");
    }
    {
        var tmp = std.testing.tmpDir(.{});
        defer tmp.cleanup();
        var script = import_cli.CommandScript.init(.{
            .preflight = .branch_head,
            .fast_export = "feature done\nprogress first\nprogress second\n",
            .limits = .{ .max_export_events = 1 },
        });
        const result = scripted(tmp, &script, "progress-limit", false, .real_filesystem);
        try std.testing.expectEqual(cli.Exit.failure, result.code);
        try std.testing.expect(std.mem.indexOf(u8, result.err, "ExportEventLimitExceeded") != null);
        try std.testing.expectEqual(@as(usize, 1), result.lifecycle.terminated);
        try std.testing.expectEqual(@as(usize, 1), result.lifecycle.stderr_drained);
        try std.testing.expectEqual(@as(usize, 1), result.lifecycle.reaped);
        try expectNoPublication(std.testing.io, tmp, "progress-limit");
    }
}

test "import-git aborts every pre-rename writable-boundary failure without a partial destination" {
    const failures = [_]import_cli.PublicationHooks.FailurePoint{
        .before_flush_store,              .after_flush_store,
        .before_sync_store,               .after_sync_store,
        .before_close_store,              .after_close_store,
        .before_flush_map,                .after_flush_map,
        .before_sync_map,                 .after_sync_map,
        .before_close_map,                .after_close_map,
        .before_sync_temporary_directory, .after_sync_temporary_directory,
        .before_rename_no_replace,
    };
    for (failures) |failure| {
        var tmp = std.testing.tmpDir(.{});
        defer tmp.cleanup();
        var script = import_cli.CommandScript.init(.{ .preflight = .branch_head, .fast_export = valid_export });
        const result = scripted(tmp, &script, "boundary-failed", false, .{ .fail_at = failure });
        try std.testing.expectEqual(cli.Exit.failure, result.code);
        try std.testing.expectEqual(@as(usize, 1), result.lifecycle.reaped);
        try expectNoPublication(std.testing.io, tmp, "boundary-failed");
    }
}

test "import-git reports parent sync durability uncertainty after publish while retaining the verified destination" {
    var tmp = std.testing.tmpDir(.{});
    defer tmp.cleanup();
    var script = import_cli.CommandScript.init(.{ .preflight = .branch_head, .fast_export = valid_export });
    const result = scripted(tmp, &script, "durability-uncertain", false, .{ .fail_at = .sync_parent_after_publish });
    try std.testing.expectEqual(cli.Exit.failure, result.code);
    try std.testing.expect(result.published_durability_uncertain);
    var destination = try tmp.dir.openDir(std.testing.io, "durability-uncertain", .{});
    defer destination.close(std.testing.io);
    try std.testing.expect(exists(std.testing.io, destination, ".zit"));
    try std.testing.expect(exists(std.testing.io, destination, ".zit-import-map.jsonl"));
}

test "import-git start session failure after stderr thread closes pipes and reaps exactly once" {
    var session = import_cli.ProductionGit.initForTest(
        std.testing.allocator,
        std.testing.io,
        &.{ helper_options.git_import_pipe_helper, "hold" },
    );
    defer session.deinit();
    session.test_startup_failure = .after_stderr_thread;

    const dependencies = session.dependencies(.real_filesystem);
    try std.testing.expectError(
        error.InjectedStartFailure,
        dependencies.git.vtable.start_export(dependencies.git.context, "fixture.git"),
    );
    try std.testing.expect(session.child == null);
    try std.testing.expect(session.stderr_thread == null);
    try std.testing.expect(session.stderr_file == null);
    try std.testing.expect(session.reaped);
    try std.testing.expectEqual(@as(usize, 1), session.reap_calls);
}

test "import-git rejects a replacement destination after rename without deleting it" {
    var tmp = std.testing.tmpDir(.{});
    defer tmp.cleanup();

    var script = import_cli.CommandScript.init(.{
        .preflight = .branch_head,
        .fast_export = valid_export,
        .replace_destination_after_rename = true,
    });
    const result = scripted(tmp, &script, "replacement-after-rename", false, .real_filesystem);

    try std.testing.expectEqual(cli.Exit.failure, result.code);
    try std.testing.expect(std.mem.indexOf(u8, result.err, "PublishedDestinationReplaced") != null);
    try std.testing.expect(script.competitor_destination_intact);
    var replacement = try tmp.dir.openDir(std.testing.io, "replacement-after-rename", .{
        .follow_symlinks = false,
    });
    defer replacement.close(std.testing.io);
    try std.testing.expect(exists(std.testing.io, replacement, "replacement-sentinel"));
    try std.testing.expect(!script.temporary_sibling_left);
}

test "import-git reaps after termination failure and reports the lifecycle error" {
    var tmp = std.testing.tmpDir(.{});
    defer tmp.cleanup();

    var git: ScriptedGit = .{
        .fast_export = malformed_export,
        .lifecycle_fault = .terminate,
    };
    const result = runFixture(tmp, "fixture.git", "termination-failure", false, &git, .real_filesystem);

    try std.testing.expectEqual(cli.Exit.failure, result.code);
    try std.testing.expect(std.mem.indexOf(u8, result.err, "InjectedLifecycleFailure") != null);
    try std.testing.expectEqual(@as(usize, 1), result.lifecycle.terminated);
    try std.testing.expectEqual(@as(usize, 1), result.lifecycle.stderr_drained);
    try std.testing.expectEqual(@as(usize, 1), result.lifecycle.reaped);
    try expectNoPublication(std.testing.io, tmp, "termination-failure");
}

test "import-git accounts the peeled target retained for marked tags at the exact byte boundary" {
    const exact_limit = try retainedBytesForExport(marked_tag_export);
    var exact_tmp = std.testing.tmpDir(.{});
    defer exact_tmp.cleanup();
    var exact_git: ScriptedGit = .{
        .fast_export = marked_tag_export,
        .limits = .{ .max_retained_bytes = exact_limit },
    };
    const exact = runFixture(exact_tmp, "fixture.git", "marked-tag-exact", false, &exact_git, .real_filesystem);
    try std.testing.expectEqual(cli.Exit.ok, exact.code);

    var exceeded_tmp = std.testing.tmpDir(.{});
    defer exceeded_tmp.cleanup();
    var exceeded_git: ScriptedGit = .{
        .fast_export = marked_tag_export,
        .limits = .{ .max_retained_bytes = exact_limit - 1 },
    };
    const exceeded = runFixture(exceeded_tmp, "fixture.git", "marked-tag-exceeded", false, &exceeded_git, .real_filesystem);
    try std.testing.expectEqual(cli.Exit.failure, exceeded.code);
    try std.testing.expect(std.mem.indexOf(u8, exceeded.err, "ImporterRetainedByteLimitExceeded") != null);
    try expectNoPublication(std.testing.io, exceeded_tmp, "marked-tag-exceeded");
}