from __future__ import annotations

import copy
import json
import os
import shlex
import subprocess
from pathlib import Path
from unittest import mock

import pytest

from ops import gcp_leoclean_nosend_package as package
from ops import install_gcp_leoclean_nosend_release as installer
from ops import leoclean_nosend_service_control as control
from tests.test_gcp_leoclean_nosend_package import (
    build_push_receipt_fixture,
    docker_inspection_fixture,
    image_input_fixture,
    write_json,
)

# Representative production-shaped values from systemd's synthesized
# properties for a system service with LoadState=not-found. These are manager
# defaults, not evidence that a unit fragment, command, environment, runtime
# directory, or process exists.
PRODUCTION_SHAPED_NOT_FOUND_SECURITY = {
    "RuntimeDirectory": "",
    "RuntimeDirectoryMode": "0755",
    "RuntimeDirectoryPreserve": "no",
    "UMask": "0022",
    "NoNewPrivileges": "no",
    "CapabilityBoundingSet": (
        "cap_chown cap_dac_override cap_dac_read_search cap_fowner cap_fsetid cap_kill "
        "cap_setgid cap_setuid cap_setpcap cap_linux_immutable cap_net_bind_service "
        "cap_net_broadcast cap_net_admin cap_net_raw cap_ipc_lock cap_ipc_owner "
        "cap_sys_module cap_sys_rawio cap_sys_chroot cap_sys_ptrace cap_sys_pacct "
        "cap_sys_admin cap_sys_boot cap_sys_nice cap_sys_resource cap_sys_time "
        "cap_sys_tty_config cap_mknod cap_lease cap_audit_write cap_audit_control "
        "cap_setfcap cap_mac_override cap_mac_admin cap_syslog cap_wake_alarm "
        "cap_block_suspend cap_audit_read cap_perfmon cap_bpf cap_checkpoint_restore"
    ),
    "AmbientCapabilities": "",
    "PrivateDevices": "no",
    "PrivateTmp": "no",
    "ProtectSystem": "no",
    "ProtectHome": "no",
    "ProtectKernelTunables": "no",
    "ProtectKernelModules": "no",
    "ProtectKernelLogs": "no",
    "ProtectControlGroups": "no",
    "LockPersonality": "no",
    "RestrictSUIDSGID": "no",
    "RestrictRealtime": "no",
    "RestrictAddressFamilies": "",
    "SystemCallArchitectures": "",
}


def source_binding() -> dict[str, object]:
    stable: dict[str, object] = {
        "revision": "a" * 40,
        "files": [
            {"path": path, "sha256": package.sha256_file(installer.CONTRACT_ROOT / path)}
            for path in sorted(installer.SOURCE_PATHS)
        ],
    }
    return {**stable, "sha256": package.canonical_sha256(stable)}


def release_bundle(tmp_path: Path, digest_character: str) -> tuple[Path, dict[str, object], dict[str, object]]:
    fixture_root = tmp_path / f"input-{digest_character}"
    fixture_root.mkdir(mode=0o755)
    # Production image creation rejects any dirty reviewed source closure.
    # This synthetic fixture tests an uncommitted installer candidate without
    # weakening the production check itself.
    with mock.patch.object(package, "_verify_git_source_closure"):
        image_input = image_input_fixture(fixture_root)
    reference = f"{package.IMAGE_REPOSITORY}@sha256:{digest_character * 64}"
    config_digest = "sha256:" + chr(ord(digest_character) + 1) * 64
    image_inspection = docker_inspection_fixture(
        image_input,
        reference,
        config_digest=config_digest,
    )
    inspection = package.build_image_inspection(image_input, reference, image_inspection)
    release = package.build_release_descriptor(
        image_input,
        inspection,
        build_push_receipt_fixture(image_input, reference, config_digest=config_digest),
    )
    bundle = tmp_path / f"bundle-{digest_character}"
    bundle.mkdir(mode=0o755)
    write_json(bundle / "release.json", release, mode=0o644)
    (bundle / package.SERVICE).write_text(package.render_systemd_unit(release), encoding="utf-8")
    (bundle / package.SERVICE).chmod(0o644)
    return bundle, release, image_inspection


class FakeHost:
    def __init__(self, paths: installer.InstallPaths) -> None:
        self.paths = paths
        self.images: dict[str, dict[str, object]] = {}
        self.releases: dict[bytes, dict[str, object]] = {}
        self.active = False
        self.main_pid = 0
        self.n_restarts = 0
        self.invocation = ""
        self.container: dict[str, object] | None = None
        self.current_release: dict[str, object] | None = None
        self.loaded_release: dict[str, object] | None = None
        self.generation = 0
        self.start_calls = 0
        self.restart_calls = 0
        self.stop_calls = 0
        self.fail_dropin_release: str | None = None
        self.race_release: str | None = None
        self.race_kind: str | None = None
        self.race_applied = False
        self.property_overrides: dict[str, str] = {}
        self.omitted_properties: set[str] = set()
        self.not_found_omitted_properties: set[str] = set()
        self.not_found_security_defaults: dict[str, str] = {}
        self.unstable_readbacks = False
        self.show_count = 0
        self.calls: list[list[str]] = []

    def add_release(self, release: dict[str, object], image_inspection: dict[str, object]) -> None:
        image = release["image"]
        assert isinstance(image, dict)
        self.images[str(image["reference"])] = copy.deepcopy(image_inspection)
        self.releases[package.render_systemd_unit(release).encode()] = release

    def _release_from_unit(self) -> dict[str, object]:
        value = self.releases.get(self.paths.unit.read_bytes())
        assert value is not None
        return value

    def _effective_fields(self) -> dict[str, list[str]]:
        assert self.loaded_release is not None
        return installer._rendered_service_fields(self.loaded_release)

    @staticmethod
    def _effective_exec(value: str) -> str:
        argv = shlex.split(value)
        return (
            f"{{ path={argv[0]} ; argv[]={value} ; ignore_errors=no ; "
            "start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }"
        )

    def _write_process_environment(self) -> None:
        directory = self.paths.proc_root / str(self.main_pid)
        directory.mkdir(parents=True, exist_ok=True)
        (directory / "environ").write_bytes(f"PATH={package.SERVICE_PATH}\0INVOCATION_ID={self.invocation}\0".encode())
        fields = self._effective_fields()
        command = shlex.split(fields["ExecStart"][0])
        (directory / "exe").symlink_to(command[0])
        (directory / "cmdline").write_bytes(b"\0".join(item.encode() for item in command) + b"\0")
        (directory / "cgroup").write_text(f"0::/system.slice/{package.SERVICE}\n", encoding="utf-8")

    def _start(self, action: str = "restart") -> None:
        release = self.loaded_release
        assert release is not None
        image = release["image"]
        inspection = release["inspection"]
        assert isinstance(image, dict) and isinstance(inspection, dict)
        runtime = inspection["runtime_config"]
        assert isinstance(runtime, dict)
        self.generation += 1
        if action == "start":
            self.start_calls += 1
        else:
            self.restart_calls += 1
        self.active = True
        self.main_pid = 1000 + self.generation
        self.invocation = f"{self.generation:032x}"
        container_id = f"{self.generation:064x}"
        labels = dict(image["labels"])
        labels.update(
            {
                "livingip.release.sha256": release["release_sha256"],
                "livingip.container.role": "leoclean-gcp-nosend",
            }
        )
        self.container = {
            "Id": container_id,
            "Name": f"/{package.CONTAINER_NAME}",
            "Image": image["config_digest"],
            "Path": runtime["entrypoint"][0],
            "Args": [*runtime["entrypoint"][1:], *runtime["cmd"]],
            "Config": {
                "Image": image["reference"],
                "Env": runtime["environment"],
                "Labels": labels,
            },
            "State": {
                "Status": "running",
                "Running": True,
                "Pid": 2000 + self.generation,
                "Health": {"Status": "healthy"},
            },
            "HostConfig": {
                "ReadonlyRootfs": True,
                "NetworkMode": "bridge",
                "PidsLimit": 512,
                "CapDrop": ["ALL"],
                "CapAdd": ["CHOWN", "SETGID", "SETPCAP", "SETUID"],
                "SecurityOpt": ["no-new-privileges:true"],
            },
        }
        self.paths.cidfile.parent.mkdir(parents=True, exist_ok=True, mode=0o700)
        self.paths.cidfile.parent.chmod(0o700)
        self.paths.cidfile.write_text(container_id, encoding="ascii")
        self.paths.cidfile.chmod(0o600)
        self.current_release = release
        self._write_process_environment()

    def _stop(self) -> None:
        self.stop_calls += 1
        self.active = False
        self.main_pid = 0
        self.invocation = ""
        self.container = None
        self.current_release = None
        self.paths.cidfile.unlink(missing_ok=True)
        try:
            self.paths.cidfile.parent.rmdir()
        except FileNotFoundError:
            pass

    def _show(self, arguments: list[str]) -> subprocess.CompletedProcess[bytes]:
        self.show_count += 1
        loaded = self.loaded_release is not None
        release_sha = self.current_release.get("release_sha256") if self.current_release else None
        dropin = bool(self.active and release_sha == self.fail_dropin_release)
        value: dict[str, str] = {
            "LoadState": "loaded" if loaded else "not-found",
            "ActiveState": "active" if self.active else "inactive",
            "SubState": "running" if self.active else "dead",
            "MainPID": str(self.main_pid),
            "NRestarts": str(self.n_restarts),
            "InvocationID": self.invocation,
            "FragmentPath": str(self.paths.unit) if loaded else "",
            "DropInPaths": f"{self.paths.unit}.d/override.conf" if dropin else "",
            "EnvironmentFiles": "",
            "Environment": f"PATH={package.SERVICE_PATH}" if loaded else "",
            "ControlGroup": f"/system.slice/{package.SERVICE}" if self.active else "",
        }
        fields = self._effective_fields() if loaded else {}
        for property_name in installer.SERVICE_EXEC_PROPERTIES:
            value[property_name] = self._effective_exec(fields[property_name][0]) if loaded else ""
        for property_name in installer.SERVICE_SECURITY_PROPERTIES:
            value[property_name] = (
                fields[property_name][0] if loaded else self.not_found_security_defaults.get(property_name, "")
            )
        value.update(self.property_overrides)
        if self.unstable_readbacks:
            value["NRestarts"] = str(self.n_restarts + self.show_count % 2)
        payload = "".join(
            f"{name}={value[name]}\n"
            for name in installer.SERVICE_PROPERTIES
            if name not in self.omitted_properties and (loaded or name not in self.not_found_omitted_properties)
        ).encode()
        return subprocess.CompletedProcess(arguments, 0, stdout=payload, stderr=b"")

    def __call__(self, arguments: list[str]) -> subprocess.CompletedProcess[bytes]:
        self.calls.append(arguments)
        if arguments[0] == installer.SYSTEMCTL:
            action = arguments[1]
            if action == "show":
                return self._show(arguments)
            if action == "daemon-reload":
                self.loaded_release = self._release_from_unit() if self.paths.unit.exists() else None
                return subprocess.CompletedProcess(arguments, 0, stdout=b"", stderr=b"")
            if action == "reset-failed":
                self.n_restarts = 0
                return subprocess.CompletedProcess(arguments, 0, stdout=b"", stderr=b"")
            if action == "restart":
                self._start()
                return subprocess.CompletedProcess(arguments, 0, stdout=b"", stderr=b"")
            if action == "start":
                self._start("start")
                return subprocess.CompletedProcess(arguments, 0, stdout=b"", stderr=b"")
            if action == "stop":
                self._stop()
                return subprocess.CompletedProcess(arguments, 0, stdout=b"", stderr=b"")
            raise AssertionError(arguments)

        assert arguments[:3] == [
            package.DOCKER_BINARY,
            f"--host={package.DOCKER_HOST}",
            f"--config={self.paths.docker_config}",
        ]
        operation = arguments[3:]
        if operation[:2] == ["image", "inspect"]:
            image = self.images.get(operation[2])
            if image is None:
                return subprocess.CompletedProcess(arguments, 1, stdout=b"", stderr=b"not found")
            return subprocess.CompletedProcess(arguments, 0, stdout=json.dumps([image]).encode(), stderr=b"")
        if operation[:2] == ["container", "inspect"]:
            if self.container is None or operation[2] not in {package.CONTAINER_NAME, self.container["Id"]}:
                error = f"Error: No such container: {operation[2]}\n".encode()
                return subprocess.CompletedProcess(arguments, 1, stdout=b"", stderr=error)
            observed = copy.deepcopy(self.container)
            release_sha = self.current_release.get("release_sha256") if self.current_release else None
            if operation[2] != package.CONTAINER_NAME and release_sha == self.race_release and not self.race_applied:
                self.race_applied = True
                if self.race_kind == "container_pid":
                    observed["State"]["Pid"] += 1
                elif self.race_kind == "service_restart":
                    self.main_pid += 1
                    self.n_restarts += 1
                    self.invocation = "f" * 32
                    self._write_process_environment()
            return subprocess.CompletedProcess(arguments, 0, stdout=json.dumps([observed]).encode(), stderr=b"")
        raise AssertionError(arguments)


def install_paths(tmp_path: Path) -> installer.InstallPaths:
    root = tmp_path / "root"
    root.mkdir(mode=0o700)
    return installer.InstallPaths.under(root, proc_root=root / "proc")


def test_dry_run_validates_bundle_without_creating_install_paths(tmp_path: Path) -> None:
    bundle, release, _image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)

    result = installer.install_release(
        bundle,
        paths=paths,
        source_binding=source_binding(),
        execute_restart=False,
    )

    assert result["mode"] == "dry_run"
    assert result["release"]["release_sha256"] == release["release_sha256"]
    assert not paths.unit.exists()
    assert not paths.state_dir.exists()


def test_dry_run_rejects_unbound_installer_source_without_creating_paths(tmp_path: Path) -> None:
    bundle, _release, _image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    binding = source_binding()
    binding["sha256"] = "f" * 64

    with pytest.raises(installer.InstallError, match="source binding"):
        installer.install_release(
            bundle,
            paths=paths,
            source_binding=binding,
            execute_restart=False,
        )

    assert not paths.unit.exists()
    assert not paths.state_dir.exists()


def test_alternate_repo_root_cannot_bind_the_executing_installer(tmp_path: Path) -> None:
    with pytest.raises(installer.InstallError, match="not the contract root"):
        installer.reviewed_source_binding(tmp_path)

    with pytest.raises(installer.InstallError, match="invalid arguments"):
        installer.parse_args(["--bundle", str(tmp_path), "--repo-root", str(tmp_path)])


def test_explicit_rollback_cli_is_dry_run_unless_execute_flag_is_separate() -> None:
    release_sha256 = "a" * 64

    dry_run = installer.parse_args(["--rollback-release", release_sha256])
    execute = installer.parse_args(["--rollback-release", release_sha256, "--execute-rollback"])

    assert dry_run.execute_rollback is False
    assert execute.execute_rollback is True
    with pytest.raises(installer.InstallError, match="invalid arguments"):
        installer.parse_args(["--execute-rollback"])
    with pytest.raises(installer.InstallError, match="invalid arguments"):
        installer.parse_args(["--bundle", "/tmp/release", "--rollback-release", release_sha256])


def test_rehashed_alternate_source_bytes_cannot_bypass_actual_source_binding(tmp_path: Path) -> None:
    bundle, _release, _image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    binding = source_binding()
    files = copy.deepcopy(binding["files"])
    assert isinstance(files, list) and isinstance(files[0], dict)
    files[0]["sha256"] = "f" * 64
    stable = {"revision": binding["revision"], "files": files}
    forged = {**stable, "sha256": package.canonical_sha256(stable)}

    with pytest.raises(installer.InstallError, match="executing installer source differed"):
        installer.install_release(
            bundle,
            paths=paths,
            source_binding=forged,
            execute_restart=False,
        )


def test_disposable_root_install_is_digest_bound_idempotent_and_exact(tmp_path: Path) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)

    result = installer.install_release(
        bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    receipt = json.loads(paths.receipt.read_text(encoding="utf-8"))

    assert result["status"] == "pass"
    assert result["schema"] == installer.INSTALL_EXECUTION_RESULT_SCHEMA
    assert result["outcome"] == "installed"
    assert result["transition"] == {
        "outcome": "installed",
        "prior_posture": "absent",
        "prior_n_restarts": 0,
        "final_posture": "active",
        "service_action": "restart",
        "managed_files_replaced": True,
    }
    assert result["release_sha256"] == release["release_sha256"]
    assert result["persisted_receipt"] == {
        "schema": installer.INSTALL_RECEIPT_SCHEMA,
        "sha256": package.sha256_file(paths.receipt),
    }
    assert receipt["schema"] == installer.INSTALL_RECEIPT_SCHEMA
    assert receipt["outcome"] == "installed"
    assert host.restart_calls == 1
    assert paths.unit.read_text(encoding="utf-8") == package.render_systemd_unit(release)
    assert paths.unit.stat().st_mode & 0o777 == 0o644
    assert paths.helper.stat().st_mode & 0o777 == 0o755
    assert paths.release.stat().st_mode & 0o777 == 0o600
    assert paths.receipt.stat().st_mode & 0o777 == 0o600
    assert paths.rollback_state.stat().st_mode & 0o777 == 0o600
    rollback_state = json.loads(paths.rollback_state.read_text(encoding="utf-8"))
    assert rollback_state["schema"] == installer.ROLLBACK_STATE_SCHEMA
    assert rollback_state["current_release_sha256"] == release["release_sha256"]
    assert receipt["rollback"]["state_sha256"] == package.sha256_file(paths.rollback_state)
    assert not list(paths.docker_config.iterdir())
    assert not list(paths.unit.parent.glob(f".{paths.unit.name}.*.tmp"))

    managed_before = {
        role: path.read_bytes()
        for role, (path, _mode) in installer._managed_files(paths).items()
    }
    identity_before = (host.main_pid, host.n_restarts, host.invocation)
    calls_before = len(host.calls)
    repeated = installer.install_release(
        bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )

    assert repeated["outcome"] == "verified_noop"
    assert repeated["schema"] == installer.INSTALL_EXECUTION_RESULT_SCHEMA
    assert repeated["persisted_receipt"] == {
        "schema": installer.INSTALL_RECEIPT_SCHEMA,
        "sha256": package.sha256_file(paths.receipt),
    }
    assert repeated["transition"] == {
        "outcome": "verified_noop",
        "prior_posture": "active",
        "prior_n_restarts": 0,
        "final_posture": "active",
        "service_action": "none",
        "managed_files_replaced": False,
    }
    assert host.restart_calls == 1
    assert host.start_calls == 0
    assert (host.main_pid, host.n_restarts, host.invocation) == identity_before
    assert {
        role: path.read_bytes()
        for role, (path, _mode) in installer._managed_files(paths).items()
    } == managed_before
    assert not any(
        call[0] == installer.SYSTEMCTL and call[1] in {"start", "restart", "stop", "daemon-reload"}
        for call in host.calls[calls_before:]
    )


def test_first_install_accepts_production_shaped_systemd_not_found_defaults(tmp_path: Path) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    host.not_found_security_defaults = dict(PRODUCTION_SHAPED_NOT_FOUND_SECURITY)

    receipt = installer.install_release(
        bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )

    assert receipt["status"] == "pass"
    assert receipt["release_sha256"] == release["release_sha256"]
    assert host.restart_calls == 1

    repeated = installer.install_release(
        bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )

    assert repeated["outcome"] == "verified_noop"
    assert host.restart_calls == 1


def test_exact_inactive_release_converges_with_one_controlled_start_and_preserves_history(
    tmp_path: Path,
) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    installer.install_release(
        bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    host._stop()
    managed_before = {
        role: path.read_bytes()
        for role, (path, _mode) in installer._managed_files(paths).items()
    }
    calls_before = len(host.calls)
    restart_calls = host.restart_calls
    stop_calls = host.stop_calls

    result = installer.install_release(
        bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )

    assert result["outcome"] == "controlled_start"
    assert result["schema"] == installer.INSTALL_EXECUTION_RESULT_SCHEMA
    assert result["transition"] == {
        "outcome": "controlled_start",
        "prior_posture": "inactive",
        "prior_n_restarts": 0,
        "final_posture": "active",
        "service_action": "start",
        "managed_files_replaced": False,
    }
    assert host.active
    assert host.start_calls == 1
    assert host.restart_calls == restart_calls
    assert host.stop_calls == stop_calls
    assert {
        role: path.read_bytes()
        for role, (path, _mode) in installer._managed_files(paths).items()
    } == managed_before
    assert [
        call[1]
        for call in host.calls[calls_before:]
        if call[0] == installer.SYSTEMCTL and call[1] in {"start", "restart", "stop", "daemon-reload"}
    ] == ["start"]


@pytest.mark.parametrize(
    "role",
    ["unit", "helper", "release", "receipt", "rollback_state"],
)
def test_each_missing_managed_file_is_rejected_as_partial_before_mutation(
    tmp_path: Path,
    role: str,
) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    installer.install_release(
        bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    managed_path = installer._managed_files(paths)[role][0]
    managed_path.unlink()
    calls_before = len(host.calls)

    with pytest.raises(installer.InstallError, match="managed install state was partial"):
        installer.install_release(
            bundle,
            paths=paths,
            source_binding=source_binding(),
            runner=host,
            sleeper=lambda _seconds: None,
            execute_restart=True,
        )

    assert not any(
        call[0] == installer.SYSTEMCTL and call[1] in {"start", "restart", "stop", "daemon-reload"}
        for call in host.calls[calls_before:]
    )


@pytest.mark.parametrize(
    "mutation",
    [
        "outer_extra",
        "rollback_extra",
        "previous_release_integer",
        "previous_active_integer",
        "automatic_integer",
        "service_restart_drift",
        "rollback_posture_drift",
        "load_state_drift",
        "main_pid_drift",
        "verification_forged",
        "authority_forged",
        "invocation_integer",
        "container_integer",
        "cmdline_integer",
        "environment_nonstring",
    ],
)
def test_current_install_receipt_is_exact_and_bound_to_rollback_state(
    tmp_path: Path,
    mutation: str,
) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    installer.install_release(
        bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    receipt = json.loads(paths.receipt.read_text(encoding="utf-8"))
    if mutation == "outer_extra":
        receipt["unexpected"] = "field"
    elif mutation == "rollback_extra":
        receipt["rollback"]["unexpected"] = "field"
    elif mutation == "previous_release_integer":
        receipt["rollback"]["previous_release_present"] = 0
    elif mutation == "previous_active_integer":
        receipt["rollback"]["previous_service_active"] = 0
    elif mutation == "automatic_integer":
        receipt["rollback"]["automatic_on_failure"] = 1
    elif mutation == "service_restart_drift":
        receipt["service_before"]["n_restarts"] += 1
    elif mutation == "rollback_posture_drift":
        receipt["rollback"]["previous_service_posture"] = "active"
    elif mutation == "load_state_drift":
        receipt["service_before"]["load_state"] = "loaded"
    elif mutation == "main_pid_drift":
        receipt["service_before"]["main_pid"] = 12345
    elif mutation == "verification_forged":
        receipt["verification"] = {"status": "forged"}
    elif mutation == "authority_forged":
        receipt["authority"] = {"cloud_or_database_authority_changed": True}
    elif mutation == "invocation_integer":
        receipt["verification"]["invocation_id"] = int("1" * 32)
    elif mutation == "container_integer":
        receipt["verification"]["container_id"] = int("2" * 64)
    elif mutation == "cmdline_integer":
        receipt["verification"]["supervising_process"]["cmdline_sha256"] = int("3" * 64)
    else:
        receipt["verification"]["validated_process_environment_fields"] = [{}]
    paths.receipt.write_text(json.dumps(receipt, sort_keys=True) + "\n", encoding="utf-8")
    paths.receipt.chmod(0o600)
    stop_calls = host.stop_calls

    with pytest.raises(installer.InstallError, match="installed receipt"):
        installer.install_release(
            bundle,
            paths=paths,
            source_binding=source_binding(),
            runner=host,
            sleeper=lambda _seconds: None,
            execute_restart=True,
        )
    with pytest.raises(installer.InstallError, match="installed receipt"):
        installer._validate_managed_snapshots(
            installer._current_managed_snapshots(paths),
            paths=paths,
        )

    assert host.stop_calls == stop_calls


def test_legacy_v2_install_receipt_remains_readable_without_rewrite(tmp_path: Path) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    installer.install_release(
        bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    legacy = json.loads(paths.receipt.read_text(encoding="utf-8"))
    legacy["schema"] = installer.LEGACY_INSTALL_RECEIPT_SCHEMA
    legacy["result"] = "installed"
    legacy.pop("outcome")
    legacy.pop("transition")
    paths.receipt.write_text(json.dumps(legacy, indent=2, sort_keys=True) + "\n", encoding="utf-8")
    paths.receipt.chmod(0o600)
    receipt_before = paths.receipt.read_bytes()

    result = installer.install_release(
        bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )

    assert result["outcome"] == "verified_noop"
    assert paths.receipt.read_bytes() == receipt_before


@pytest.mark.parametrize("failure_mode", ["start_command", "post_start_verification"])
def test_exact_inactive_start_failure_restores_inactive_without_rewriting_history(
    tmp_path: Path,
    failure_mode: str,
) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    installer.install_release(
        bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    host._stop()
    managed_before = {
        role: path.read_bytes()
        for role, (path, _mode) in installer._managed_files(paths).items()
    }
    if failure_mode == "post_start_verification":
        host.fail_dropin_release = str(release["release_sha256"])

    def runner(arguments: list[str]) -> subprocess.CompletedProcess[bytes]:
        completed = host(arguments)
        if failure_mode == "start_command" and arguments[:2] == [installer.SYSTEMCTL, "start"]:
            return subprocess.CompletedProcess(arguments, 1, stdout=b"", stderr=b"injected")
        return completed

    with pytest.raises(installer.VerificationError) as caught:
        installer.install_release(
            bundle,
            paths=paths,
            source_binding=source_binding(),
            runner=runner,
            sleeper=lambda _seconds: None,
            execute_restart=True,
        )

    assert caught.value.rollback_executed is True
    assert caught.value.restored_posture == "inactive"
    assert caught.value.prior_posture_preserved is True
    assert not host.active
    assert host.container is None
    assert host.start_calls == 1
    assert {
        role: path.read_bytes()
        for role, (path, _mode) in installer._managed_files(paths).items()
    } == managed_before


@pytest.mark.parametrize("cleanup_failure", ["stop_command", "restart_counter_drift"])
def test_exact_inactive_cleanup_failure_never_claims_prior_posture_preserved(
    tmp_path: Path,
    cleanup_failure: str,
) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    installer.install_release(
        bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    host._stop()
    host.fail_dropin_release = str(release["release_sha256"])
    managed_before = {
        role: path.read_bytes()
        for role, (path, _mode) in installer._managed_files(paths).items()
    }

    def runner(arguments: list[str]) -> subprocess.CompletedProcess[bytes]:
        completed = host(arguments)
        if arguments[:2] == [installer.SYSTEMCTL, "stop"]:
            if cleanup_failure == "stop_command":
                return subprocess.CompletedProcess(arguments, 1, stdout=b"", stderr=b"injected")
            host.n_restarts += 1
        return completed

    with pytest.raises(installer.InstallError, match="cleanup was incomplete") as caught:
        installer.install_release(
            bundle,
            paths=paths,
            source_binding=source_binding(),
            runner=runner,
            sleeper=lambda _seconds: None,
            execute_restart=True,
        )

    assert getattr(caught.value, "prior_posture_preserved", None) is not True
    assert not host.active
    assert {
        role: path.read_bytes()
        for role, (path, _mode) in installer._managed_files(paths).items()
    } == managed_before


@pytest.mark.parametrize("prior_posture", ["active", "inactive"])
def test_exact_release_rejects_receipt_replacement_race(
    tmp_path: Path,
    prior_posture: str,
) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    installer.install_release(
        bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    if prior_posture == "inactive":
        host._stop()
    replaced = False
    service_show_calls = 0

    def replace_receipt() -> None:
        nonlocal replaced
        if replaced:
            return
        replaced = True
        paths.receipt.unlink()
        paths.receipt.write_text('{"schema":"forged"}\n', encoding="utf-8")
        paths.receipt.chmod(0o600)

    def runner(arguments: list[str]) -> subprocess.CompletedProcess[bytes]:
        nonlocal service_show_calls
        completed = host(arguments)
        if prior_posture == "active" and arguments[:2] == [installer.SYSTEMCTL, "show"]:
            service_show_calls += 1
            if service_show_calls == 3:
                replace_receipt()
        if prior_posture == "inactive" and arguments[:2] == [installer.SYSTEMCTL, "start"]:
            replace_receipt()
        return completed

    with pytest.raises(installer.InstallError, match="file identity drifted"):
        installer.install_release(
            bundle,
            paths=paths,
            source_binding=source_binding(),
            runner=runner,
            sleeper=lambda _seconds: None,
            execute_restart=True,
        )

    assert replaced
    assert host.active is (prior_posture == "active")


def test_first_install_waits_for_complete_cid_and_healthy_container(tmp_path: Path) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    container_inspections = 0
    completed_cid = False

    def runner(arguments: list[str]) -> subprocess.CompletedProcess[bytes]:
        nonlocal container_inspections
        result = host(arguments)
        if arguments[:2] == [installer.SYSTEMCTL, "restart"]:
            assert host.container is not None
            paths.cidfile.write_text(str(host.container["Id"])[:12], encoding="ascii")
            paths.cidfile.chmod(0o600)
        operation = arguments[3:]
        if operation == ["container", "inspect", package.CONTAINER_NAME] and result.returncode == 0:
            container_inspections += 1
            if container_inspections == 1:
                observed = json.loads(result.stdout)
                observed[0]["State"]["Health"]["Status"] = "starting"
                return subprocess.CompletedProcess(
                    arguments,
                    0,
                    stdout=json.dumps(observed).encode(),
                    stderr=b"",
                )
        return result

    def sleeper(_seconds: float) -> None:
        nonlocal completed_cid
        if host.active and not completed_cid:
            assert host.container is not None
            paths.cidfile.write_text(str(host.container["Id"]), encoding="ascii")
            paths.cidfile.chmod(0o600)
            completed_cid = True

    receipt = installer.install_release(
        bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=runner,
        sleeper=sleeper,
        execute_restart=True,
    )

    assert receipt["status"] == "pass"
    assert completed_cid
    assert container_inspections == 2
    assert host.stop_calls == 0


def test_first_install_defers_process_identity_until_release_cid_exists(tmp_path: Path) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    delayed_container_id: str | None = None
    process_identity_restored = False

    def runner(arguments: list[str]) -> subprocess.CompletedProcess[bytes]:
        nonlocal delayed_container_id
        result = host(arguments)
        if arguments[:2] == [installer.SYSTEMCTL, "restart"]:
            assert host.container is not None
            delayed_container_id = str(host.container["Id"])
            paths.cidfile.unlink()
            process_root = paths.proc_root / str(host.main_pid)
            (process_root / "environ").unlink()
            (process_root / "exe").unlink()
            (process_root / "cmdline").unlink()
            (process_root / "cgroup").unlink()
        return result

    def sleeper(_seconds: float) -> None:
        nonlocal process_identity_restored
        if host.active and delayed_container_id is not None and not process_identity_restored:
            host._write_process_environment()
            paths.cidfile.write_text(delayed_container_id, encoding="ascii")
            paths.cidfile.chmod(0o600)
            process_identity_restored = True

    receipt = installer.install_release(
        bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=runner,
        sleeper=sleeper,
        execute_restart=True,
    )

    assert receipt["status"] == "pass"
    assert process_identity_restored
    assert host.stop_calls == 0


def test_process_environment_failure_has_bounded_stage_and_reason(tmp_path: Path) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    installer.install_release(
        bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    process_root = paths.proc_root / str(host.main_pid)
    (process_root / "environ").write_bytes(b"PATH=/unexpected\0")

    with pytest.raises(installer.VerificationError) as caught:
        installer.verify_running_release(
            release,
            runner=host,
            paths=paths,
            sleeper=lambda _seconds: None,
        )

    assert caught.value.failure_stage == "process_environment"
    assert caught.value.failure_reason == "process_environment_mismatch"


@pytest.mark.parametrize(
    ("path", "replacement", "failure_stage", "failure_reason"),
    [
        (("Id",), "f" * 64, "container_identity", "container_id_mismatch"),
        (("Name",), "/unexpected", "container_identity", "container_name_mismatch"),
        (
            ("Image",),
            f"sha256:{'f' * 64}",
            "container_image_identity",
            "container_image_id_mismatch",
        ),
        (
            ("Config", "Image"),
            "example.invalid/unexpected@sha256:" + "f" * 64,
            "container_image_identity",
            "container_image_reference_mismatch",
        ),
        (
            ("Config", "Env"),
            ["PATH=/unexpected"],
            "container_environment",
            "container_environment_mismatch",
        ),
        (("Config", "Labels"), [], "container_labels", "container_labels_invalid"),
        (
            ("Config", "Labels", "livingip.release.sha256"),
            "f" * 64,
            "container_labels",
            "container_release_label_mismatch",
        ),
        (
            ("Config", "Labels", "livingip.container.role"),
            "unexpected",
            "container_labels",
            "container_role_label_mismatch",
        ),
        (("Config",), None, "container_inspection", "container_config_invalid"),
        (("State",), None, "container_inspection", "container_state_invalid"),
        (("HostConfig",), None, "container_inspection", "container_host_config_invalid"),
        (
            ("HostConfig", "ReadonlyRootfs"),
            False,
            "container_security",
            "container_readonly_rootfs_mismatch",
        ),
        (
            ("HostConfig", "NetworkMode"),
            "host",
            "container_security",
            "container_network_mode_mismatch",
        ),
        (
            ("HostConfig", "PidsLimit"),
            513,
            "container_security",
            "container_pids_limit_mismatch",
        ),
        (
            ("HostConfig", "CapDrop"),
            [],
            "container_security",
            "container_cap_drop_mismatch",
        ),
        (
            ("HostConfig", "CapAdd"),
            [],
            "container_security",
            "container_cap_add_mismatch",
        ),
        (
            ("HostConfig", "SecurityOpt"),
            ["no-new-privileges=true"],
            "container_security",
            "container_security_options_mismatch",
        ),
        (("Path",), "/unexpected", "container_command", "container_path_mismatch"),
        (("Args",), ["unexpected"], "container_command", "container_args_mismatch"),
        (
            ("State", "Running"),
            "true",
            "container_state",
            "container_running_flag_invalid",
        ),
        (("State", "Pid"), "2001", "container_state", "container_pid_invalid"),
        (("State", "Health"), None, "container_health", "container_health_missing"),
        (
            ("State", "Health", "Status"),
            "unhealthy",
            "container_health",
            "container_health_status_invalid",
        ),
    ],
)
def test_container_contract_failures_have_field_specific_bounded_codes(
    tmp_path: Path,
    path: tuple[str, ...],
    replacement: object,
    failure_stage: str,
    failure_reason: str,
) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    installer.install_release(
        bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    assert host.container is not None
    target = host.container
    for key in path[:-1]:
        nested = target[key]
        assert isinstance(nested, dict)
        target = nested
    target[path[-1]] = copy.deepcopy(replacement)

    with pytest.raises(installer.VerificationError) as caught:
        installer.verify_running_release(
            release,
            runner=host,
            paths=paths,
            sleeper=lambda _seconds: None,
        )

    assert caught.value.failure_stage == failure_stage
    assert caught.value.failure_reason == failure_reason


def test_container_cap_add_accepts_docker_28_canonical_names(tmp_path: Path) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    installer.install_release(
        bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    assert host.container is not None
    host.container["HostConfig"]["CapAdd"] = [
        "CAP_CHOWN",
        "CAP_SETGID",
        "CAP_SETPCAP",
        "CAP_SETUID",
    ]

    verification = installer.verify_running_release(
        release,
        runner=host,
        paths=paths,
        sleeper=lambda _seconds: None,
    )

    assert verification["container_id"] == host.container["Id"]


def test_container_cap_add_rejects_mixed_duplicate_names(tmp_path: Path) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    installer.install_release(
        bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    assert host.container is not None
    host.container["HostConfig"]["CapAdd"] = [
        "CHOWN",
        "CAP_CHOWN",
        "SETGID",
        "SETPCAP",
        "SETUID",
    ]

    with pytest.raises(installer.VerificationError) as caught:
        installer.verify_running_release(
            release,
            runner=host,
            paths=paths,
            sleeper=lambda _seconds: None,
        )

    assert caught.value.failure_stage == "container_security"
    assert caught.value.failure_reason == "container_cap_add_mismatch"


def test_container_inspection_shape_has_bounded_code(tmp_path: Path) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    installer.install_release(
        bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )

    def runner(arguments: list[str]) -> subprocess.CompletedProcess[bytes]:
        result = host(arguments)
        if arguments[3:] == ["container", "inspect", package.CONTAINER_NAME] and result.returncode == 0:
            return subprocess.CompletedProcess(arguments, 0, stdout=b"{}", stderr=b"")
        return result

    with pytest.raises(installer.VerificationError) as caught:
        installer.verify_running_release(
            release,
            runner=runner,
            paths=paths,
            sleeper=lambda _seconds: None,
        )

    assert caught.value.failure_stage == "container_inspection"
    assert caught.value.failure_reason == "container_inspection_invalid"


def test_container_exit_before_health_has_bounded_code(tmp_path: Path) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    installer.install_release(
        bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    assert host.container is not None
    state = host.container["State"]
    assert isinstance(state, dict)
    state.update({"Running": False, "Pid": 0, "Status": "exited"})

    with pytest.raises(installer.VerificationError) as caught:
        installer.verify_running_release(
            release,
            runner=host,
            paths=paths,
            sleeper=lambda _seconds: None,
        )

    assert caught.value.failure_stage == "container_state"
    assert caught.value.failure_reason == "container_exited_early"


def test_container_security_mismatch_rolls_back_without_exposing_observed_value(tmp_path: Path) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)

    def runner(arguments: list[str]) -> subprocess.CompletedProcess[bytes]:
        result = host(arguments)
        if arguments[3:] == ["container", "inspect", package.CONTAINER_NAME] and result.returncode == 0:
            observed = json.loads(result.stdout)
            observed[0]["HostConfig"]["SecurityOpt"] = ["unexpected-sensitive-value"]
            return subprocess.CompletedProcess(
                arguments,
                0,
                stdout=json.dumps(observed).encode(),
                stderr=b"",
            )
        return result

    with pytest.raises(installer.VerificationError) as caught:
        installer.install_release(
            bundle,
            paths=paths,
            source_binding=source_binding(),
            runner=runner,
            sleeper=lambda _seconds: None,
            execute_restart=True,
        )

    assert caught.value.failure_stage == "container_security"
    assert caught.value.failure_reason == "container_security_options_mismatch"
    assert "unexpected-sensitive-value" not in str(caught.value)
    assert host.stop_calls == 1
    assert not host.active
    assert host.container is None
    assert not paths.cidfile.exists()
    assert not paths.unit.exists()
    assert not paths.helper.exists()
    assert not paths.state_dir.exists()


def test_first_install_health_timeout_rolls_back_to_absent(tmp_path: Path) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)

    def runner(arguments: list[str]) -> subprocess.CompletedProcess[bytes]:
        result = host(arguments)
        if arguments[3:] == ["container", "inspect", package.CONTAINER_NAME] and result.returncode == 0:
            observed = json.loads(result.stdout)
            observed[0]["State"]["Health"]["Status"] = "starting"
            return subprocess.CompletedProcess(
                arguments,
                0,
                stdout=json.dumps(observed).encode(),
                stderr=b"",
            )
        return result

    with pytest.raises(installer.InstallError, match="did not become healthy"):
        installer.install_release(
            bundle,
            paths=paths,
            source_binding=source_binding(),
            runner=runner,
            sleeper=lambda _seconds: None,
            execute_restart=True,
        )

    assert host.stop_calls == 1
    assert not host.active
    assert host.container is None
    assert not paths.cidfile.exists()
    assert not paths.unit.exists()
    assert not paths.helper.exists()
    assert not paths.state_dir.exists()


def test_verification_rebinds_stable_container_to_unchanged_cidfile(tmp_path: Path) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    installer.install_release(
        bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    changed = False

    def runner(arguments: list[str]) -> subprocess.CompletedProcess[bytes]:
        nonlocal changed
        result = host(arguments)
        operation = arguments[3:]
        if operation[:2] == ["container", "inspect"] and operation[2] != package.CONTAINER_NAME and not changed:
            paths.cidfile.write_text("f" * 64, encoding="ascii")
            paths.cidfile.chmod(0o600)
            changed = True
        return result

    with pytest.raises(installer.InstallError, match="changed during verification"):
        installer.verify_running_release(
            release,
            runner=runner,
            paths=paths,
            sleeper=lambda _seconds: None,
        )

    assert changed


def test_systemd_252_omitted_environment_files_property_is_normalized(tmp_path: Path) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    host.not_found_security_defaults = dict(PRODUCTION_SHAPED_NOT_FOUND_SECURITY)
    host.omitted_properties.add("EnvironmentFiles")

    receipt = installer.install_release(
        bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )

    assert receipt["status"] == "pass"
    assert receipt["release_sha256"] == release["release_sha256"]
    assert host.restart_calls == 1


def test_systemd_252_omitted_not_found_commands_are_normalized(tmp_path: Path) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    host.not_found_security_defaults = dict(PRODUCTION_SHAPED_NOT_FOUND_SECURITY)
    host.not_found_omitted_properties.update({"EnvironmentFiles", *installer.SERVICE_EXEC_PROPERTIES})

    receipt = installer.install_release(
        bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )

    assert receipt["status"] == "pass"
    assert receipt["release_sha256"] == release["release_sha256"]
    assert host.restart_calls == 1


def test_systemd_252_omission_does_not_hide_a_later_dropin(tmp_path: Path) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    host.not_found_security_defaults = dict(PRODUCTION_SHAPED_NOT_FOUND_SECURITY)
    host.omitted_properties.add("EnvironmentFiles")
    host.fail_dropin_release = str(release["release_sha256"])

    with pytest.raises(installer.InstallError, match="later drop-in"):
        installer.install_release(
            bundle,
            paths=paths,
            source_binding=source_binding(),
            runner=host,
            sleeper=lambda _seconds: None,
            execute_restart=True,
        )

    assert host.restart_calls == 1
    assert not host.active
    assert host.container is None
    assert not paths.unit.exists()
    assert not paths.state_dir.exists()


@pytest.mark.parametrize(
    "property_name",
    tuple(name for name in installer.SERVICE_PROPERTIES if name != "EnvironmentFiles"),
)
def test_systemd_252_compatibility_still_requires_other_properties(
    tmp_path: Path,
    property_name: str,
) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    host.not_found_security_defaults = dict(PRODUCTION_SHAPED_NOT_FOUND_SECURITY)
    host.omitted_properties.update({"EnvironmentFiles", property_name})

    with pytest.raises(installer.InstallError, match="property output was incomplete"):
        installer.install_release(
            bundle,
            paths=paths,
            source_binding=source_binding(),
            runner=host,
            sleeper=lambda _seconds: None,
            execute_restart=True,
        )

    assert host.restart_calls == 0
    assert not paths.unit.exists()
    assert not paths.state_dir.exists()


@pytest.mark.parametrize("property_name", installer.ABSENT_SERVICE_IDENTITY_PROPERTIES)
def test_first_install_rejects_identity_bearing_not_found_property(
    tmp_path: Path,
    property_name: str,
) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    host.not_found_security_defaults = dict(PRODUCTION_SHAPED_NOT_FOUND_SECURITY)
    host.property_overrides[property_name] = "unexpected-authority"

    with pytest.raises(installer.InstallError, match="exactly absent"):
        installer.install_release(
            bundle,
            paths=paths,
            source_binding=source_binding(),
            runner=host,
            sleeper=lambda _seconds: None,
            execute_restart=True,
        )

    assert host.restart_calls == 0
    assert not paths.unit.exists()
    assert not paths.state_dir.exists()


def test_execute_transaction_uses_exclusive_owner_only_lock(tmp_path: Path) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)

    with installer._install_lock(paths):
        observed = paths.lock.stat(follow_symlinks=False)
        assert observed.st_uid == os.geteuid()
        assert observed.st_mode & 0o777 == 0o600
        with pytest.raises(installer.InstallError, match="holds the lock"):
            installer.install_release(
                bundle,
                paths=paths,
                source_binding=source_binding(),
                runner=host,
                sleeper=lambda _seconds: None,
                execute_restart=True,
            )

    assert not host.calls
    assert not paths.unit.exists()


def test_upgrade_stops_verified_prior_release_before_unit_replacement(tmp_path: Path) -> None:
    first_bundle, first_release, first_image = release_bundle(tmp_path, "2")
    second_bundle, second_release, second_image = release_bundle(tmp_path, "4")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(first_release, first_image)
    host.add_release(second_release, second_image)

    installer.install_release(
        first_bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    start = len(host.calls)
    result = installer.install_release(
        second_bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    receipt = json.loads(paths.receipt.read_text(encoding="utf-8"))

    actions = [call[1] for call in host.calls[start:] if call[0] == installer.SYSTEMCTL]
    assert actions.index("stop") < actions.index("daemon-reload") < actions.index("restart")
    assert result["release_sha256"] == second_release["release_sha256"]
    assert result["outcome"] == "replaced"
    assert result["transition"] == {
        "outcome": "replaced",
        "prior_posture": "active",
        "prior_n_restarts": 0,
        "final_posture": "active",
        "service_action": "restart",
        "managed_files_replaced": True,
    }
    assert receipt["rollback"]["previous_service_posture"] == "active"
    assert host.current_release == second_release
    assert host.stop_calls == 1


def test_inactive_prior_release_is_replaced_without_claiming_active_posture(tmp_path: Path) -> None:
    first_bundle, first_release, first_image = release_bundle(tmp_path, "2")
    second_bundle, second_release, second_image = release_bundle(tmp_path, "4")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(first_release, first_image)
    host.add_release(second_release, second_image)
    installer.install_release(
        first_bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    host._stop()
    stop_calls = host.stop_calls

    result = installer.install_release(
        second_bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    receipt = json.loads(paths.receipt.read_text(encoding="utf-8"))

    assert result["outcome"] == "replaced"
    assert result["transition"]["prior_posture"] == "inactive"
    assert result["transition"]["prior_n_restarts"] == 0
    assert receipt["rollback"]["previous_release_present"] is True
    assert receipt["rollback"]["previous_service_active"] is False
    assert receipt["rollback"]["previous_service_posture"] == "inactive"
    assert host.stop_calls == stop_calls
    assert host.active


def test_active_prior_verification_failure_reports_unchanged_recovery_posture(
    tmp_path: Path,
) -> None:
    first_bundle, first_release, first_image = release_bundle(tmp_path, "2")
    second_bundle, second_release, second_image = release_bundle(tmp_path, "4")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(first_release, first_image)
    host.add_release(second_release, second_image)
    installer.install_release(
        first_bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    process_root = paths.proc_root / str(host.main_pid)
    (process_root / "environ").write_bytes(b"PATH=/unexpected\0")
    stop_calls = host.stop_calls

    with pytest.raises(installer.VerificationError) as caught:
        installer.install_release(
            second_bundle,
            paths=paths,
            source_binding=source_binding(),
            runner=host,
            sleeper=lambda _seconds: None,
            execute_restart=True,
        )

    assert caught.value.rollback_executed is False
    assert caught.value.restored_posture == "active"
    assert caught.value.prior_posture_preserved is True
    assert host.stop_calls == stop_calls
    assert host.active


def test_stale_loaded_unit_is_rejected_before_trusting_old_exec_stop(tmp_path: Path) -> None:
    first_bundle, first_release, first_image = release_bundle(tmp_path, "2")
    second_bundle, second_release, second_image = release_bundle(tmp_path, "4")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(first_release, first_image)
    host.add_release(second_release, second_image)
    installer.install_release(
        first_bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    host.loaded_release = second_release

    with pytest.raises(installer.InstallError, match="effective service command differed"):
        installer.install_release(
            second_bundle,
            paths=paths,
            source_binding=source_binding(),
            runner=host,
            sleeper=lambda _seconds: None,
            execute_restart=True,
        )

    assert host.active
    assert host.current_release == first_release
    assert host.stop_calls == 0
    assert host.restart_calls == 1


def test_effective_security_drift_is_rejected_before_old_service_stop(tmp_path: Path) -> None:
    first_bundle, first_release, first_image = release_bundle(tmp_path, "2")
    second_bundle, second_release, second_image = release_bundle(tmp_path, "4")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(first_release, first_image)
    host.add_release(second_release, second_image)
    installer.install_release(
        first_bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    host.property_overrides["NoNewPrivileges"] = "no"

    with pytest.raises(installer.InstallError, match="effective service security differed"):
        installer.install_release(
            second_bundle,
            paths=paths,
            source_binding=source_binding(),
            runner=host,
            sleeper=lambda _seconds: None,
            execute_restart=True,
        )

    assert host.stop_calls == 0
    assert host.restart_calls == 1


@pytest.mark.parametrize(
    ("field", "error"),
    [
        ("exe", "supervising executable differed"),
        ("cmdline", "supervising command line differed"),
        ("cgroup", "cgroup differed from systemd"),
    ],
)
def test_supervising_process_drift_is_rejected_before_old_service_stop(
    tmp_path: Path,
    field: str,
    error: str,
) -> None:
    first_bundle, first_release, first_image = release_bundle(tmp_path, "2")
    second_bundle, second_release, second_image = release_bundle(tmp_path, "4")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(first_release, first_image)
    host.add_release(second_release, second_image)
    installer.install_release(
        first_bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    process_root = paths.proc_root / str(host.main_pid)
    if field == "exe":
        executable = process_root / "exe"
        executable.unlink()
        executable.symlink_to("/bin/false")
    elif field == "cmdline":
        (process_root / "cmdline").write_bytes(b"/usr/bin/false\0")
    else:
        (process_root / "cgroup").write_text("0::/system.slice/other.service\n", encoding="utf-8")

    with pytest.raises(installer.InstallError, match=error):
        installer.install_release(
            second_bundle,
            paths=paths,
            source_binding=source_binding(),
            runner=host,
            sleeper=lambda _seconds: None,
            execute_restart=True,
        )

    assert host.stop_calls == 0
    assert host.restart_calls == 1


def test_prior_managed_file_mode_drift_fails_before_service_mutation(tmp_path: Path) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    installer.install_release(
        bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    paths.receipt.chmod(0o644)

    with pytest.raises(installer.InstallError, match="file posture drifted"):
        installer.install_release(
            bundle,
            paths=paths,
            source_binding=source_binding(),
            runner=host,
            sleeper=lambda _seconds: None,
            execute_restart=True,
        )

    assert host.active
    assert host.stop_calls == 0
    assert host.restart_calls == 1


def test_transitional_prior_service_posture_is_rejected_before_mutation(tmp_path: Path) -> None:
    first_bundle, first_release, first_image = release_bundle(tmp_path, "2")
    second_bundle, second_release, second_image = release_bundle(tmp_path, "4")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(first_release, first_image)
    host.add_release(second_release, second_image)
    installer.install_release(
        first_bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    host.property_overrides.update({"ActiveState": "deactivating", "SubState": "stop-sigterm"})

    with pytest.raises(installer.InstallError, match="transitional or failed"):
        installer.install_release(
            second_bundle,
            paths=paths,
            source_binding=source_binding(),
            runner=host,
            sleeper=lambda _seconds: None,
            execute_restart=True,
        )

    assert host.stop_calls == 0
    assert host.restart_calls == 1


def test_failed_prior_service_posture_is_rejected_before_mutation(tmp_path: Path) -> None:
    first_bundle, first_release, first_image = release_bundle(tmp_path, "2")
    second_bundle, second_release, second_image = release_bundle(tmp_path, "4")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(first_release, first_image)
    host.add_release(second_release, second_image)
    installer.install_release(
        first_bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    host.property_overrides.update(
        {
            "ActiveState": "failed",
            "SubState": "failed",
            "MainPID": "0",
            "InvocationID": "",
            "ControlGroup": "",
        }
    )

    with pytest.raises(installer.InstallError, match="transitional or failed"):
        installer.install_release(
            second_bundle,
            paths=paths,
            source_binding=source_binding(),
            runner=host,
            sleeper=lambda _seconds: None,
            execute_restart=True,
        )

    assert host.stop_calls == 0
    assert host.restart_calls == 1


def test_changing_prior_service_posture_fails_two_readback_gate(tmp_path: Path) -> None:
    first_bundle, first_release, first_image = release_bundle(tmp_path, "2")
    second_bundle, second_release, second_image = release_bundle(tmp_path, "4")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(first_release, first_image)
    host.add_release(second_release, second_image)
    installer.install_release(
        first_bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    host.show_count = 0
    host.unstable_readbacks = True

    with pytest.raises(installer.InstallError, match="changed between readbacks"):
        installer.install_release(
            second_bundle,
            paths=paths,
            source_binding=source_binding(),
            runner=host,
            sleeper=lambda _seconds: None,
            execute_restart=True,
        )

    assert host.stop_calls == 0
    assert host.restart_calls == 1


def test_wrong_local_image_is_rejected_without_service_restart(tmp_path: Path) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    image["Id"] = "sha256:" + "9" * 64
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)

    with pytest.raises(installer.VerificationError, match=r"finalized (release|inspection)") as caught:
        installer.install_release(
            bundle,
            paths=paths,
            source_binding=source_binding(),
            runner=host,
            sleeper=lambda _seconds: None,
            execute_restart=True,
        )

    assert caught.value.rollback_executed is False
    assert caught.value.restored_posture == "absent"
    assert caught.value.prior_posture_preserved is True
    assert host.restart_calls == 0
    assert not paths.unit.exists()
    assert not paths.state_dir.exists()


def test_preflight_reports_incomplete_directory_cleanup(tmp_path: Path) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    image["Id"] = "sha256:" + "9" * 64
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    original_call = host.__call__

    def runner(arguments: list[str]) -> subprocess.CompletedProcess[bytes]:
        result = original_call(arguments)
        if arguments[3:5] == ["image", "inspect"]:
            (paths.state_dir / "unexpected").write_text("preserve", encoding="utf-8")
        return result

    with pytest.raises(installer.InstallError, match="cleanup was incomplete"):
        installer.install_release(
            bundle,
            paths=paths,
            source_binding=source_binding(),
            runner=runner,
            sleeper=lambda _seconds: None,
            execute_restart=True,
        )

    assert host.restart_calls == 0
    assert (paths.state_dir / "unexpected").read_text(encoding="utf-8") == "preserve"


def test_post_rename_race_refuses_to_mutate_replaced_pathname(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    original_fsync = installer._fsync_directory
    raced = False

    def replace_after_helper_rename(directory: Path) -> None:
        nonlocal raced
        if directory == paths.helper.parent and paths.helper.exists() and not raced:
            raced = True
            paths.helper.unlink()
            paths.helper.write_bytes(b"independent replacement\n")
            paths.helper.chmod(0o755)
            raise OSError("injected post-rename durability failure")
        original_fsync(directory)

    monkeypatch.setattr(installer, "_fsync_directory", replace_after_helper_rename)
    with pytest.raises(installer.InstallError, match="automatic rollback was incomplete"):
        installer.install_release(
            bundle,
            paths=paths,
            source_binding=source_binding(),
            runner=host,
            sleeper=lambda _seconds: None,
            execute_restart=True,
        )

    assert raced
    assert paths.helper.read_bytes() == b"independent replacement\n"
    assert host.restart_calls == 0


@pytest.mark.parametrize("race_kind", ["container_pid", "service_restart"])
def test_pid_or_restart_race_fails_and_cleans_first_install(tmp_path: Path, race_kind: str) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    host.race_release = str(release["release_sha256"])
    host.race_kind = race_kind

    with pytest.raises(installer.InstallError, match="changed during verification"):
        installer.install_release(
            bundle,
            paths=paths,
            source_binding=source_binding(),
            runner=host,
            sleeper=lambda _seconds: None,
            execute_restart=True,
        )

    assert not host.active
    assert host.container is None
    assert not paths.unit.exists()
    assert not paths.helper.exists()
    assert not paths.state_dir.exists()


def test_restart_command_failure_after_side_effect_stops_candidate_and_cleans_install(tmp_path: Path) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    failed_restart = False

    def runner(arguments: list[str]) -> subprocess.CompletedProcess[bytes]:
        nonlocal failed_restart
        result = host(arguments)
        if arguments[:2] == [installer.SYSTEMCTL, "restart"] and not failed_restart:
            failed_restart = True
            return subprocess.CompletedProcess(arguments, 1, stdout=b"", stderr=b"restart failed")
        return result

    with pytest.raises(installer.InstallError, match="systemd restart failed"):
        installer.install_release(
            bundle,
            paths=paths,
            source_binding=source_binding(),
            runner=runner,
            sleeper=lambda _seconds: None,
            execute_restart=True,
        )

    assert failed_restart
    assert not host.active
    assert host.stop_calls == 1
    assert not paths.unit.exists()
    assert not paths.state_dir.exists()


def test_candidate_stop_failure_preserves_recovery_artifacts(tmp_path: Path) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    host.race_release = str(release["release_sha256"])
    host.race_kind = "service_restart"

    def runner(arguments: list[str]) -> subprocess.CompletedProcess[bytes]:
        if arguments[:2] == [installer.SYSTEMCTL, "stop"]:
            return subprocess.CompletedProcess(arguments, 1, stdout=b"", stderr=b"stop failed")
        return host(arguments)

    with pytest.raises(installer.InstallError, match="automatic rollback was incomplete"):
        installer.install_release(
            bundle,
            paths=paths,
            source_binding=source_binding(),
            runner=runner,
            sleeper=lambda _seconds: None,
            execute_restart=True,
        )

    assert paths.unit.is_file()
    assert paths.helper.is_file()
    assert paths.state_dir.is_dir()
    assert host.active
    assert host.container is not None


def test_successful_stop_command_with_candidate_residue_preserves_recovery_artifacts(tmp_path: Path) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    host.race_release = str(release["release_sha256"])
    host.race_kind = "service_restart"

    def runner(arguments: list[str]) -> subprocess.CompletedProcess[bytes]:
        if arguments[:2] == [installer.SYSTEMCTL, "stop"]:
            return subprocess.CompletedProcess(arguments, 0, stdout=b"", stderr=b"")
        return host(arguments)

    with pytest.raises(installer.InstallError, match="automatic rollback was incomplete"):
        installer.install_release(
            bundle,
            paths=paths,
            source_binding=source_binding(),
            runner=runner,
            sleeper=lambda _seconds: None,
            execute_restart=True,
        )

    assert paths.unit.is_file()
    assert paths.helper.is_file()
    assert paths.state_dir.is_dir()
    assert paths.cidfile.is_file()
    assert host.active
    assert host.container is not None


def test_later_dropin_failure_restores_previous_release_and_running_service(tmp_path: Path) -> None:
    first_bundle, first_release, first_image = release_bundle(tmp_path, "2")
    second_bundle, second_release, second_image = release_bundle(tmp_path, "4")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(first_release, first_image)
    host.add_release(second_release, second_image)

    installer.install_release(
        first_bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    first_unit = paths.unit.read_bytes()
    first_state = paths.release.read_bytes()
    first_receipt = paths.receipt.read_bytes()
    host.fail_dropin_release = str(second_release["release_sha256"])

    with pytest.raises(installer.InstallError, match="later drop-in"):
        installer.install_release(
            second_bundle,
            paths=paths,
            source_binding=source_binding(),
            runner=host,
            sleeper=lambda _seconds: None,
            execute_restart=True,
        )

    assert paths.unit.read_bytes() == first_unit
    assert paths.release.read_bytes() == first_state
    assert paths.receipt.read_bytes() == first_receipt
    assert host.active
    assert host.current_release == first_release
    assert host.stop_calls == 2
    assert host.restart_calls == 3
    assert not list(paths.state_dir.glob(".*.tmp"))


def test_failed_upgrade_restores_exact_inactive_prior_posture(tmp_path: Path) -> None:
    first_bundle, first_release, first_image = release_bundle(tmp_path, "2")
    second_bundle, second_release, second_image = release_bundle(tmp_path, "4")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(first_release, first_image)
    host.add_release(second_release, second_image)
    installer.install_release(
        first_bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    host._stop()
    stop_calls = host.stop_calls
    restart_calls = host.restart_calls
    prior_n_restarts = host.n_restarts
    first_unit = paths.unit.read_bytes()
    host.fail_dropin_release = str(second_release["release_sha256"])

    with pytest.raises(installer.InstallError, match="effective later drop-in"):
        installer.install_release(
            second_bundle,
            paths=paths,
            source_binding=source_binding(),
            runner=host,
            sleeper=lambda _seconds: None,
            execute_restart=True,
        )

    assert not host.active
    assert host.loaded_release == first_release
    assert host.n_restarts == prior_n_restarts
    assert host.stop_calls == stop_calls + 1
    assert host.restart_calls == restart_calls + 1
    assert paths.unit.read_bytes() == first_unit


def test_effective_process_environment_override_is_rejected_and_rolled_back(tmp_path: Path) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    original_start = host._start

    def start_with_override() -> None:
        original_start()
        environment = paths.proc_root / str(host.main_pid) / "environ"
        environment.write_bytes(f"PATH={package.SERVICE_PATH}\0DOCKER_HOST=tcp://unsafe.invalid:2375\0".encode())

    host._start = start_with_override  # type: ignore[method-assign]

    with pytest.raises(installer.InstallError, match="forbidden environment"):
        installer.install_release(
            bundle,
            paths=paths,
            source_binding=source_binding(),
            runner=host,
            sleeper=lambda _seconds: None,
            execute_restart=True,
        )

    assert not host.active
    assert not paths.state_dir.exists()


def test_explicit_rollback_is_dry_run_by_default_and_removes_first_install(tmp_path: Path) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    installer.install_release(
        bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    before_calls = list(host.calls)
    before_stops = host.stop_calls
    before_restarts = host.restart_calls

    plan = installer.rollback_release(
        str(release["release_sha256"]),
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
    )

    assert plan["mode"] == "dry_run"
    assert plan["installed_release_sha256"] == release["release_sha256"]
    assert plan["target_release_sha256"] is None
    assert plan["target_service_posture"] == "absent"
    assert host.stop_calls == before_stops
    assert host.restart_calls == before_restarts
    assert host.calls != before_calls
    assert host.active

    with pytest.raises(installer.InstallError, match="did not match the expected release hash"):
        installer.rollback_release(
            "f" * 64,
            paths=paths,
            source_binding=source_binding(),
            runner=host,
            sleeper=lambda _seconds: None,
            execute_rollback=True,
        )
    assert host.stop_calls == before_stops

    result = installer.rollback_release(
        str(release["release_sha256"]),
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_rollback=True,
    )

    assert result == {
        "schema": installer.ROLLBACK_RESULT_SCHEMA,
        "status": "pass",
        "mode": "executed",
        "rolled_back_release_sha256": release["release_sha256"],
        "restored_release_sha256": None,
        "restored_service_posture": "absent",
        "verification": None,
        "authority": {
            "image_pulled": False,
            "cloud_or_database_authority_changed": False,
            "transport_authority_changed": False,
        },
    }
    assert not host.active
    assert host.loaded_release is None
    assert not paths.unit.exists()
    assert not paths.helper.exists()
    assert not paths.state_dir.exists()


def test_explicit_rollback_restores_exact_previous_active_release_and_history(tmp_path: Path) -> None:
    first_bundle, first_release, first_image = release_bundle(tmp_path, "2")
    second_bundle, second_release, second_image = release_bundle(tmp_path, "4")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(first_release, first_image)
    host.add_release(second_release, second_image)
    installer.install_release(
        first_bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    first_files = {role: path.read_bytes() for role, (path, _mode) in installer._managed_files(paths).items()}
    installer.install_release(
        second_bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )

    result = installer.rollback_release(
        str(second_release["release_sha256"]),
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_rollback=True,
    )

    assert result["restored_release_sha256"] == first_release["release_sha256"]
    assert result["restored_service_posture"] == "active"
    assert host.current_release == first_release
    assert {role: path.read_bytes() for role, (path, _mode) in installer._managed_files(paths).items()} == first_files

    nested = installer.rollback_release(
        str(first_release["release_sha256"]),
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_rollback=True,
    )
    assert nested["restored_service_posture"] == "absent"
    assert not paths.state_dir.exists()


def test_explicit_rollback_restores_previous_inactive_posture(tmp_path: Path) -> None:
    first_bundle, first_release, first_image = release_bundle(tmp_path, "2")
    second_bundle, second_release, second_image = release_bundle(tmp_path, "4")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(first_release, first_image)
    host.add_release(second_release, second_image)
    installer.install_release(
        first_bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    host._stop()
    installer.install_release(
        second_bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    restarts = host.restart_calls

    result = installer.rollback_release(
        str(second_release["release_sha256"]),
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_rollback=True,
    )

    assert result["restored_release_sha256"] == first_release["release_sha256"]
    assert result["restored_service_posture"] == "inactive"
    assert not host.active
    assert host.loaded_release == first_release
    assert host.restart_calls == restarts


def test_failed_explicit_rollback_recovers_current_release(tmp_path: Path) -> None:
    first_bundle, first_release, first_image = release_bundle(tmp_path, "2")
    second_bundle, second_release, second_image = release_bundle(tmp_path, "4")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(first_release, first_image)
    host.add_release(second_release, second_image)
    installer.install_release(
        first_bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    installer.install_release(
        second_bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    second_files = {role: path.read_bytes() for role, (path, _mode) in installer._managed_files(paths).items()}
    fail_next_reload = True

    def runner(arguments: list[str]) -> subprocess.CompletedProcess[bytes]:
        nonlocal fail_next_reload
        if arguments[:2] == [installer.SYSTEMCTL, "daemon-reload"] and fail_next_reload:
            fail_next_reload = False
            return subprocess.CompletedProcess(arguments, 1, stdout=b"", stderr=b"injected")
        return host(arguments)

    with pytest.raises(installer.InstallError, match="systemd daemon-reload failed"):
        installer.rollback_release(
            str(second_release["release_sha256"]),
            paths=paths,
            source_binding=source_binding(),
            runner=runner,
            sleeper=lambda _seconds: None,
            execute_rollback=True,
        )

    assert host.active
    assert host.current_release == second_release
    assert {role: path.read_bytes() for role, (path, _mode) in installer._managed_files(paths).items()} == second_files


def test_explicit_rollback_rejects_receipt_drift_before_service_stop(tmp_path: Path) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    installer.install_release(
        bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    receipt = json.loads(paths.receipt.read_text(encoding="utf-8"))
    receipt["release_sha256"] = "f" * 64
    paths.receipt.write_text(json.dumps(receipt), encoding="utf-8")
    paths.receipt.chmod(0o600)
    stop_calls = host.stop_calls

    with pytest.raises(installer.InstallError, match=r"(installed|snapshot install) receipt was invalid"):
        installer.rollback_release(
            str(release["release_sha256"]),
            paths=paths,
            source_binding=source_binding(),
            runner=host,
            sleeper=lambda _seconds: None,
            execute_rollback=True,
        )

    assert host.stop_calls == stop_calls
    assert host.active


def test_explicit_rollback_rejects_path_inode_drift_before_service_stop(tmp_path: Path) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    installer.install_release(
        bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    prepared = installer._prepare_explicit_rollback(
        str(release["release_sha256"]),
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
    )
    unit = paths.unit.read_bytes()
    paths.unit.unlink()
    paths.unit.write_bytes(unit)
    paths.unit.chmod(0o644)
    stop_calls = host.stop_calls

    with pytest.raises(installer.InstallError, match="file identity drifted"):
        installer._execute_explicit_rollback(
            str(release["release_sha256"]),
            prepared,
            paths=paths,
            runner=host,
            sleeper=lambda _seconds: None,
        )

    assert host.stop_calls == stop_calls
    assert host.active


def test_explicit_rollback_rejects_pid_drift_before_service_stop(tmp_path: Path) -> None:
    bundle, release, image = release_bundle(tmp_path, "2")
    paths = install_paths(tmp_path)
    host = FakeHost(paths)
    host.add_release(release, image)
    installer.install_release(
        bundle,
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
        execute_restart=True,
    )
    prepared = installer._prepare_explicit_rollback(
        str(release["release_sha256"]),
        paths=paths,
        source_binding=source_binding(),
        runner=host,
        sleeper=lambda _seconds: None,
    )
    host.main_pid += 1
    host._write_process_environment()
    stop_calls = host.stop_calls

    with pytest.raises(installer.InstallError, match=r"changed during verification|drifted before rollback stop"):
        installer._execute_explicit_rollback(
            str(release["release_sha256"]),
            prepared,
            paths=paths,
            runner=host,
            sleeper=lambda _seconds: None,
        )

    assert host.stop_calls == stop_calls
    assert host.active


def test_control_helper_stops_only_trusted_full_container_id(tmp_path: Path) -> None:
    cid_parent = tmp_path / "runtime"
    cid_parent.mkdir(mode=0o700)
    cidfile = cid_parent / "container.cid"
    container_id = "c" * 64
    cidfile.write_text(container_id, encoding="ascii")
    cidfile.chmod(0o600)
    release_sha = "d" * 64
    image_reference = f"{package.IMAGE_REPOSITORY}@sha256:{'e' * 64}"
    container: dict[str, object] | None = {
        "Id": container_id,
        "Name": f"/{package.CONTAINER_NAME}",
        "Image": "sha256:" + "f" * 64,
        "Config": {
            "Image": image_reference,
            "Labels": {
                "livingip.release.sha256": release_sha,
                "livingip.container.role": "leoclean-gcp-nosend",
            },
        },
        "State": {"Running": True},
    }
    calls: list[list[str]] = []

    def runner(arguments: list[str]) -> subprocess.CompletedProcess[bytes]:
        nonlocal container
        calls.append(arguments)
        operation = arguments[3:]
        if operation[:2] == ["container", "inspect"]:
            if container is None or operation[2] not in {package.CONTAINER_NAME, container_id}:
                error = f"Error: No such container: {operation[2]}\n".encode()
                return subprocess.CompletedProcess(arguments, 1, stdout=b"", stderr=error)
            return subprocess.CompletedProcess(arguments, 0, stdout=json.dumps([container]).encode(), stderr=b"")
        if operation[:2] == ["container", "stop"]:
            assert operation == ["container", "stop", "--time=30", container_id]
            container = None
            return subprocess.CompletedProcess(arguments, 0, stdout=b"", stderr=b"")
        raise AssertionError(arguments)

    result = control.control_container(
        "stop",
        release_sha,
        image_reference,
        "sha256:" + "f" * 64,
        runner=runner,
        sleeper=lambda _seconds: None,
        cidfile=cidfile,
    )

    assert result == {"action": "stop", "status": "pass", "container": "stopped"}
    assert not cidfile.exists()
    stop_calls = [call[3:] for call in calls if call[3:5] == ["container", "stop"]]
    assert stop_calls == [["container", "stop", "--time=30", container_id]]


@pytest.mark.parametrize("running", [True, False])
def test_control_helper_waits_for_complete_cid_before_exact_cleanup(
    tmp_path: Path,
    running: bool,
) -> None:
    cid_parent = tmp_path / "runtime"
    cid_parent.mkdir(mode=0o700)
    cidfile = cid_parent / "container.cid"
    container_id = "c" * 64
    cidfile.write_text(container_id[:12], encoding="ascii")
    cidfile.chmod(0o600)
    release_sha = "d" * 64
    image_reference = f"{package.IMAGE_REPOSITORY}@sha256:{'e' * 64}"
    pending_container: dict[str, object] = {
        "Id": container_id,
        "Name": f"/{package.CONTAINER_NAME}",
        "Image": "sha256:" + "f" * 64,
        "Config": {
            "Image": image_reference,
            "Labels": {
                "livingip.release.sha256": release_sha,
                "livingip.container.role": "leoclean-gcp-nosend",
            },
        },
        "State": {
            "Status": "running" if running else "created",
            "Running": running,
        },
    }
    container: dict[str, object] | None = None
    calls: list[list[str]] = []

    def runner(arguments: list[str]) -> subprocess.CompletedProcess[bytes]:
        nonlocal container
        calls.append(arguments)
        operation = arguments[3:]
        if operation[:2] == ["container", "inspect"]:
            if container is None:
                error = f"Error: No such container: {operation[2]}\n".encode()
                return subprocess.CompletedProcess(arguments, 1, stdout=b"", stderr=error)
            return subprocess.CompletedProcess(arguments, 0, stdout=json.dumps([container]).encode(), stderr=b"")
        expected_mutation = (
            ["container", "stop", "--time=30", container_id] if running else ["container", "rm", container_id]
        )
        if operation == expected_mutation:
            container = None
            return subprocess.CompletedProcess(arguments, 0, stdout=b"", stderr=b"")
        raise AssertionError(arguments)

    completed = False

    def sleeper(_seconds: float) -> None:
        nonlocal completed, container
        if not completed:
            cidfile.write_text(container_id, encoding="ascii")
            cidfile.chmod(0o600)
            container = pending_container
            completed = True

    result = control.control_container(
        "stop",
        release_sha,
        image_reference,
        "sha256:" + "f" * 64,
        runner=runner,
        sleeper=sleeper,
        cidfile=cidfile,
    )

    assert result == {"action": "stop", "status": "pass", "container": "stopped"}
    assert completed
    assert not cidfile.exists()
    mutations = [call[3:] for call in calls if call[3:5] in (["container", "stop"], ["container", "rm"])]
    assert mutations == [
        ["container", "stop", "--time=30", container_id] if running else ["container", "rm", container_id]
    ]


def test_control_helper_reconciles_created_to_running_race_by_full_id(tmp_path: Path) -> None:
    cid_parent = tmp_path / "runtime"
    cid_parent.mkdir(mode=0o700)
    cidfile = cid_parent / "container.cid"
    container_id = "c" * 64
    cidfile.write_text(container_id, encoding="ascii")
    cidfile.chmod(0o600)
    release_sha = "d" * 64
    image_reference = f"{package.IMAGE_REPOSITORY}@sha256:{'e' * 64}"
    container: dict[str, object] | None = {
        "Id": container_id,
        "Name": f"/{package.CONTAINER_NAME}",
        "Image": "sha256:" + "f" * 64,
        "Config": {
            "Image": image_reference,
            "Labels": {
                "livingip.release.sha256": release_sha,
                "livingip.container.role": "leoclean-gcp-nosend",
            },
        },
        "State": {"Status": "created", "Running": False},
    }
    calls: list[list[str]] = []

    def runner(arguments: list[str]) -> subprocess.CompletedProcess[bytes]:
        nonlocal container
        calls.append(arguments)
        operation = arguments[3:]
        if operation[:2] == ["container", "inspect"]:
            if container is None:
                error = f"Error: No such container: {operation[2]}\n".encode()
                return subprocess.CompletedProcess(arguments, 1, stdout=b"", stderr=error)
            return subprocess.CompletedProcess(arguments, 0, stdout=json.dumps([container]).encode(), stderr=b"")
        if operation == ["container", "rm", container_id]:
            assert container is not None
            container["State"] = {"Status": "running", "Running": True}
            return subprocess.CompletedProcess(arguments, 1, stdout=b"", stderr=b"started during removal")
        if operation == ["container", "stop", "--time=30", container_id]:
            container = None
            return subprocess.CompletedProcess(arguments, 0, stdout=b"", stderr=b"")
        raise AssertionError(arguments)

    result = control.control_container(
        "stop",
        release_sha,
        image_reference,
        "sha256:" + "f" * 64,
        runner=runner,
        sleeper=lambda _seconds: None,
        cidfile=cidfile,
    )

    assert result == {"action": "stop", "status": "pass", "container": "stopped"}
    assert not cidfile.exists()
    mutations = [call[3:] for call in calls if call[3:5] in (["container", "stop"], ["container", "rm"])]
    assert mutations == [
        ["container", "rm", container_id],
        ["container", "stop", "--time=30", container_id],
    ]


def test_control_helper_partial_cid_timeout_retains_authority_and_does_not_mutate(tmp_path: Path) -> None:
    cid_parent = tmp_path / "runtime"
    cid_parent.mkdir(mode=0o700)
    cidfile = cid_parent / "container.cid"
    cidfile.write_text("c" * 12, encoding="ascii")
    cidfile.chmod(0o600)
    calls: list[list[str]] = []

    def runner(arguments: list[str]) -> subprocess.CompletedProcess[bytes]:
        calls.append(arguments)
        operation = arguments[3:]
        assert operation == ["container", "inspect", package.CONTAINER_NAME]
        error = f"Error: No such container: {package.CONTAINER_NAME}\n".encode()
        return subprocess.CompletedProcess(arguments, 1, stdout=b"", stderr=error)

    with pytest.raises(control.ControlError, match="did not become complete"):
        control.control_container(
            "stop",
            "d" * 64,
            f"{package.IMAGE_REPOSITORY}@sha256:{'e' * 64}",
            "sha256:" + "f" * 64,
            runner=runner,
            sleeper=lambda _seconds: None,
            cidfile=cidfile,
        )

    assert cidfile.read_text(encoding="ascii") == "c" * 12
    assert all(call[3:5] not in (["container", "stop"], ["container", "rm"]) for call in calls)


def test_control_helper_refuses_config_digest_mismatch_without_stopping(tmp_path: Path) -> None:
    cid_parent = tmp_path / "runtime"
    cid_parent.mkdir(mode=0o700)
    cidfile = cid_parent / "container.cid"
    container_id = "c" * 64
    cidfile.write_text(container_id, encoding="ascii")
    cidfile.chmod(0o600)
    release_sha = "d" * 64
    image_reference = f"{package.IMAGE_REPOSITORY}@sha256:{'e' * 64}"
    container = {
        "Id": container_id,
        "Name": f"/{package.CONTAINER_NAME}",
        "Image": "sha256:" + "1" * 64,
        "Config": {
            "Image": image_reference,
            "Labels": {
                "livingip.release.sha256": release_sha,
                "livingip.container.role": "leoclean-gcp-nosend",
            },
        },
        "State": {"Running": True},
    }
    calls: list[list[str]] = []

    def runner(arguments: list[str]) -> subprocess.CompletedProcess[bytes]:
        calls.append(arguments)
        return subprocess.CompletedProcess(arguments, 0, stdout=json.dumps([container]).encode(), stderr=b"")

    with pytest.raises(control.ControlError, match="identity did not match"):
        control.control_container(
            "stop",
            release_sha,
            image_reference,
            "sha256:" + "2" * 64,
            runner=runner,
            sleeper=lambda _seconds: None,
            cidfile=cidfile,
        )

    assert cidfile.exists()
    assert all(call[3:5] != ["container", "stop"] for call in calls)


def test_control_helper_retains_cid_when_name_rebinds_after_trusted_id_disappears(tmp_path: Path) -> None:
    cid_parent = tmp_path / "runtime"
    cid_parent.mkdir(mode=0o700)
    cidfile = cid_parent / "container.cid"
    container_id = "c" * 64
    rebound_id = "b" * 64
    cidfile.write_text(container_id, encoding="ascii")
    cidfile.chmod(0o600)
    release_sha = "d" * 64
    image_reference = f"{package.IMAGE_REPOSITORY}@sha256:{'e' * 64}"
    config_digest = "sha256:" + "f" * 64
    trusted = {
        "Id": container_id,
        "Name": f"/{package.CONTAINER_NAME}",
        "Image": config_digest,
        "Config": {
            "Image": image_reference,
            "Labels": {
                "livingip.release.sha256": release_sha,
                "livingip.container.role": "leoclean-gcp-nosend",
            },
        },
        "State": {"Running": True},
    }
    stopped = False
    rebound = False
    calls: list[list[str]] = []

    def runner(arguments: list[str]) -> subprocess.CompletedProcess[bytes]:
        nonlocal stopped, rebound
        calls.append(arguments)
        operation = arguments[3:]
        if operation[:2] == ["container", "stop"]:
            stopped = True
            return subprocess.CompletedProcess(arguments, 0, stdout=b"", stderr=b"")
        if operation[:2] == ["container", "inspect"]:
            reference = operation[2]
            if reference == container_id and stopped:
                rebound = True
                error = f"Error: No such container: {reference}\n".encode()
                return subprocess.CompletedProcess(arguments, 1, stdout=b"", stderr=error)
            if reference == package.CONTAINER_NAME and rebound:
                replacement = {"Id": rebound_id, "Name": f"/{package.CONTAINER_NAME}"}
                return subprocess.CompletedProcess(
                    arguments,
                    0,
                    stdout=json.dumps([replacement]).encode(),
                    stderr=b"",
                )
            return subprocess.CompletedProcess(arguments, 0, stdout=json.dumps([trusted]).encode(), stderr=b"")
        raise AssertionError(arguments)

    with pytest.raises(control.ControlError, match="name was rebound"):
        control.control_container(
            "stop",
            release_sha,
            image_reference,
            config_digest,
            runner=runner,
            sleeper=lambda _seconds: None,
            cidfile=cidfile,
        )

    assert stopped and rebound
    assert cidfile.read_text(encoding="ascii") == container_id
    assert [call[3:5] for call in calls].count(["container", "stop"]) == 1


def test_control_helper_refuses_untrusted_name_collision_without_mutation(tmp_path: Path) -> None:
    cid_parent = tmp_path / "runtime"
    cid_parent.mkdir(mode=0o700)
    calls: list[list[str]] = []

    def runner(arguments: list[str]) -> subprocess.CompletedProcess[bytes]:
        calls.append(arguments)
        operation = arguments[3:]
        if operation == ["container", "inspect", package.CONTAINER_NAME]:
            return subprocess.CompletedProcess(
                arguments,
                0,
                stdout=json.dumps([{"Id": "f" * 64, "Name": f"/{package.CONTAINER_NAME}"}]).encode(),
                stderr=b"",
            )
        raise AssertionError(arguments)

    with pytest.raises(control.ControlError, match="without a trusted ID"):
        control.control_container(
            "prestart",
            "d" * 64,
            f"{package.IMAGE_REPOSITORY}@sha256:{'e' * 64}",
            "sha256:" + "f" * 64,
            runner=runner,
            sleeper=lambda _seconds: None,
            cidfile=cid_parent / "container.cid",
        )

    assert all(call[3:5] != ["container", "stop"] for call in calls)


def test_control_helper_does_not_treat_daemon_failure_as_container_absence(tmp_path: Path) -> None:
    cid_parent = tmp_path / "runtime"
    cid_parent.mkdir(mode=0o700)
    cidfile = cid_parent / "container.cid"

    def runner(arguments: list[str]) -> subprocess.CompletedProcess[bytes]:
        return subprocess.CompletedProcess(
            arguments,
            1,
            stdout=b"",
            stderr=b"Cannot connect to the Docker daemon\n",
        )

    with pytest.raises(control.ControlError, match="absence could not be proven"):
        control.control_container(
            "prestart",
            "d" * 64,
            f"{package.IMAGE_REPOSITORY}@sha256:{'e' * 64}",
            "sha256:" + "f" * 64,
            runner=runner,
            sleeper=lambda _seconds: None,
            cidfile=cidfile,
        )

    assert not cidfile.exists()


def test_release_bundle_symlink_is_rejected(tmp_path: Path) -> None:
    bundle, _release, _image = release_bundle(tmp_path, "2")
    alias = tmp_path / "bundle-alias"
    alias.symlink_to(bundle, target_is_directory=True)

    with pytest.raises(installer.InstallError, match="missing or unsafe"):
        installer.validate_release_bundle(alias)


def test_service_unit_binds_local_docker_authority_and_private_cidfile(tmp_path: Path) -> None:
    _bundle, release, _image = release_bundle(tmp_path, "2")
    unit = package.render_systemd_unit(release)

    assert f"--host={control.DOCKER_HOST}" in unit
    assert f"--config={control.DOCKER_CONFIG}" in unit
    assert f"--cidfile={control.CIDFILE}" in unit
    assert str(release["image"]["config_digest"]) in unit
    assert "UMask=0077" in unit
    assert "docker rm" not in unit
    assert "--force" not in unit
