From d3425473a3144119dbc69b21dd99a05ef0cf4caa Mon Sep 17 00:00:00 2001 From: Minh Trinh Date: Thu, 16 Jul 2026 17:04:27 -0700 Subject: [PATCH 1/4] Bake CloakBrowser instead of vanilla Chromium in the cloud slice pre-bake Cloud slices are x86_64, so this mirrors default-workspace-template's own deferred_install.sh swap: apt-only playwright install-deps for shared libs, then a pinned, SHA256-verified CloakBrowser release unpacked to /opt/cloakbrowser. Two done-markers now (playwright_deps, cloakbrowser) so a loaded slice's deferred-install still no-ops correctly. Co-Authored-By: Claude Sonnet 5 --- .../imbue/mngr_imbue_cloud/bake/pool_bake.py | 7 +- .../mngr_imbue_cloud/bake/pool_bake_test.py | 2 +- .../providers/slice_provider.py | 98 ++++++++++++------- .../providers/slice_provider_test.py | 16 +-- 4 files changed, 78 insertions(+), 45 deletions(-) diff --git a/libs/mngr_imbue_cloud/imbue/mngr_imbue_cloud/bake/pool_bake.py b/libs/mngr_imbue_cloud/imbue/mngr_imbue_cloud/bake/pool_bake.py index 44d5c5b0a4..a76f7185fc 100644 --- a/libs/mngr_imbue_cloud/imbue/mngr_imbue_cloud/bake/pool_bake.py +++ b/libs/mngr_imbue_cloud/imbue/mngr_imbue_cloud/bake/pool_bake.py @@ -76,9 +76,10 @@ # Exit code GNU ``timeout`` returns when it kills the wrapped command on timeout. _COMMAND_TIMEOUT_EXIT_CODE: Final[int] = 124 -# The DEFAULT_WORKSPACE_TEMPLATE ``deferred-install`` service writes this marker on success; the bake waits -# for it (see ``wait_for_deferred_install``) before stopping the services agent. -_DEFERRED_INSTALL_MARKER: Final[str] = "/var/lib/minds/deferred-install/done.playwright" +# The DEFAULT_WORKSPACE_TEMPLATE ``deferred-install`` service writes this marker on success (the final one -- +# CloakBrowser itself, after the apt-deps marker); the bake waits for it (see +# ``wait_for_deferred_install``) before stopping the services agent. +_DEFERRED_INSTALL_MARKER: Final[str] = "/var/lib/minds/deferred-install/done.cloakbrowser" # Cap on how long the bake blocks for the deferred install (heavy apt + browser # download) to finish; on timeout the bake proceeds and the install retries on lease. _DEFERRED_INSTALL_WAIT_TIMEOUT_SECONDS: Final[int] = 900 diff --git a/libs/mngr_imbue_cloud/imbue/mngr_imbue_cloud/bake/pool_bake_test.py b/libs/mngr_imbue_cloud/imbue/mngr_imbue_cloud/bake/pool_bake_test.py index ed0bbf0f30..b1544335f8 100644 --- a/libs/mngr_imbue_cloud/imbue/mngr_imbue_cloud/bake/pool_bake_test.py +++ b/libs/mngr_imbue_cloud/imbue/mngr_imbue_cloud/bake/pool_bake_test.py @@ -80,7 +80,7 @@ def test_wait_for_deferred_install_polls_for_marker_or_finished_process() -> Non assert [label for label, _cmd in runner.calls] == ["deferred-install-wait"] command = runner.calls[0][1] # The poll checks the success marker and uses a bracketed pgrep pattern (self-match guard). - assert "done.playwright" in command + assert "done.cloakbrowser" in command assert "[d]eferred_install.sh" in command assert "timeout 5" in command diff --git a/libs/mngr_imbue_cloud/imbue/mngr_imbue_cloud/providers/slice_provider.py b/libs/mngr_imbue_cloud/imbue/mngr_imbue_cloud/providers/slice_provider.py index 46fd613e31..b9b6bea32b 100644 --- a/libs/mngr_imbue_cloud/imbue/mngr_imbue_cloud/providers/slice_provider.py +++ b/libs/mngr_imbue_cloud/imbue/mngr_imbue_cloud/providers/slice_provider.py @@ -60,22 +60,35 @@ # DEFAULT_WORKSPACE_TEMPLATE image tar -- the box boot disk is shared, so fail early rather than fill it. _ESTIMATED_DEFAULT_WORKSPACE_TEMPLATE_IMAGE_BYTES: Final[int] = 15 * 1024**3 # Generous cap for the seeding slice's base DEFAULT_WORKSPACE_TEMPLATE image build (the inner create budget -# is 45 min; the build is the long pole, the Playwright derive + save the rest). +# is 45 min; the build is the long pole, the CloakBrowser derive + save the rest). _SEED_BASE_BUILD_TIMEOUT_SECONDS: Final[float] = 1800.0 -# The Playwright-derived image RUNs a chromium download + apt; retry transient -# failures a few times before hard-failing the seed. -_PLAYWRIGHT_BUILD_ATTEMPTS: Final[int] = 3 -_PLAYWRIGHT_BUILD_TIMEOUT_SECONDS: Final[float] = 900.0 -_PLAYWRIGHT_CTX_DIR: Final[str] = "/tmp/default-workspace-template-playwright-ctx" +# The CloakBrowser-derived image RUNs an apt install + a pinned binary download; retry +# transient failures a few times before hard-failing the seed. +_CLOAKBROWSER_BUILD_ATTEMPTS: Final[int] = 3 +_CLOAKBROWSER_BUILD_TIMEOUT_SECONDS: Final[float] = 900.0 +_CLOAKBROWSER_CTX_DIR: Final[str] = "/tmp/default-workspace-template-cloakbrowser-ctx" +# Pinned CloakBrowser release -- keep in sync with default-workspace-template's +# scripts/deferred_install.sh (_CLOAKBROWSER_VERSION / _CLOAKBROWSER_SHA256_X64). +# Cloud slices are x86_64 bare metal only (see DEFAULT_IMAGE_URL_X86_64), so this +# bakes the x64 asset only -- no arch branching needed here. +_CLOAKBROWSER_VERSION: Final[str] = "chromium-v146.0.7680.177.4" +_CLOAKBROWSER_RELEASE_URL: Final[str] = ( + f"https://github.com/CloakHQ/CloakBrowser/releases/download/{_CLOAKBROWSER_VERSION}" +) +_CLOAKBROWSER_SHA256_X64: Final[str] = "5af027faafb1fef9933eb784c094b764706de22a372a2cee84bc117fc4ab537f" +_CLOAKBROWSER_INSTALL_DIR: Final[str] = "/opt/cloakbrowser" _BUILDER_PRUNE_TIMEOUT_SECONDS: Final[float] = 120.0 # The DEFAULT_WORKSPACE_TEMPLATE Dockerfile relocates the built workspace here (off the /mngr volume mount) -# before first boot; the Playwright derive runs ``uv run`` from it. This is a DEFAULT_WORKSPACE_TEMPLATE image +# before first boot; the CloakBrowser derive runs ``uv run`` from it. This is a DEFAULT_WORKSPACE_TEMPLATE image # contract -- if DEFAULT_WORKSPACE_TEMPLATE moves it, the derive's guard fails fast with a clear message. _DEFAULT_WORKSPACE_TEMPLATE_BUILD_CODE_DIR: Final[str] = "/docker_build_code" -# Where the DEFAULT_WORKSPACE_TEMPLATE deferred-install service writes its success marker; baking it into -# the seeded image makes ``[program:deferred-install]`` a no-op on every loaded slice. +# Where the DEFAULT_WORKSPACE_TEMPLATE deferred-install service writes its success markers; baking both +# into the seeded image makes ``[program:deferred-install]`` a no-op on every loaded slice. +# Two markers, matching default-workspace-template's scripts/deferred_install.sh split: +# apt libs, then the CloakBrowser binary itself (the one deferred_install_ready() gates on). _DEFERRED_INSTALL_MARKER_DIR: Final[str] = "/var/lib/minds/deferred-install" -_DEFERRED_INSTALL_MARKER: Final[str] = f"{_DEFERRED_INSTALL_MARKER_DIR}/done.playwright" +_DEFERRED_INSTALL_DEPS_MARKER: Final[str] = f"{_DEFERRED_INSTALL_MARKER_DIR}/done.playwright_deps" +_DEFERRED_INSTALL_MARKER: Final[str] = f"{_DEFERRED_INSTALL_MARKER_DIR}/done.cloakbrowser" class SliceVpsDockerProviderConfig(VpsProviderConfig): @@ -444,7 +457,7 @@ def _seed_box_image( image_tag: str, build_args: Sequence[str] | None, ) -> None: - """Build the DEFAULT_WORKSPACE_TEMPLATE image (+ baked Playwright) and seed the box tar; this slice runs that image too.""" + """Build the DEFAULT_WORKSPACE_TEMPLATE image (+ baked CloakBrowser) and seed the box tar; this slice runs that image too.""" logger.info("Building + seeding box tar {} (first slice on this box for this tag)", image_tag) parsed = self._parse_build_args(build_args) # Build the base DEFAULT_WORKSPACE_TEMPLATE image via the same shared helper the realizer's build path @@ -461,7 +474,7 @@ def _seed_box_image( builder=self.config.builder, build_timeout_seconds=_SEED_BASE_BUILD_TIMEOUT_SECONDS, ) - self._build_playwright_derived_image(outer=outer, base_image=base_image, target_tag=image_tag) + self._build_cloakbrowser_derived_image(outer=outer, base_image=base_image, target_tag=image_tag) cache.check_free_disk(_ESTIMATED_DEFAULT_WORKSPACE_TEMPLATE_IMAGE_BYTES) with self._transfer_key_authorized(cache, outer) as transfer_key: cache.save_image_from_slice(image_tag, vm_ssh_port=vm_ssh_port, transfer_key=transfer_key) @@ -471,58 +484,73 @@ def _seed_box_image( @retry( retry=retry_if_exception_type(MngrError), - stop=stop_after_attempt(_PLAYWRIGHT_BUILD_ATTEMPTS), + stop=stop_after_attempt(_CLOAKBROWSER_BUILD_ATTEMPTS), wait=wait_exponential(multiplier=1, min=1, max=10), reraise=True, ) - def _build_playwright_derived_image(self, *, outer: OuterHostInterface, base_image: str, target_tag: str) -> None: - """Build target_tag as base_image + a baked Playwright/Chromium layer (and the done marker). + def _build_cloakbrowser_derived_image(self, *, outer: OuterHostInterface, base_image: str, target_tag: str) -> None: + """Build target_tag as base_image + a baked CloakBrowser layer (and the done markers). - Playwright is deliberately not in the DEFAULT_WORKSPACE_TEMPLATE Dockerfile (it is shared with the + CloakBrowser is deliberately not in the DEFAULT_WORKSPACE_TEMPLATE Dockerfile (it is shared with the desktop Lima path); baking it cloud-side here keeps the desktop path - unchanged while letting every loaded slice skip the deferred install. The - browser cache lands in /root/.cache/ms-playwright -- outside the /mngr volume - and untouched by default-workspace-template-seed, so it survives into every container. + unchanged while letting every loaded slice skip the deferred install. It + lands at /opt/cloakbrowser -- outside the /mngr volume and untouched by + default-workspace-template-seed, so it survives into every container. The RUN first guards that the DEFAULT_WORKSPACE_TEMPLATE build-code dir exists, so a future DEFAULT_WORKSPACE_TEMPLATE image that relocates it fails fast with a clear message instead of a confusing ``cd``-not-found build failure buried in retries. - Playwright is invoked as ``python -m playwright`` (not the ``playwright`` - console script) on purpose: the DEFAULT_WORKSPACE_TEMPLATE Dockerfile builds the uv venv at - ``/mngr/code`` and then ``mv``\\s the workspace to ``/docker_build_code``. A uv - venv is path-bound -- its console-script shebangs hardcode - ``/mngr/code/.venv/bin/python``, which does not exist here, so ``uv run - playwright`` would fail with ``Failed to spawn: playwright``. ``python -m`` - goes through the venv's interpreter symlink (location-independent), so it works - from the relocated path. (DEFAULT_WORKSPACE_TEMPLATE's own deferred-install runs the console script, - but only at runtime after default-workspace-template-seed restores the workspace to ``/mngr/code``.) + Playwright's own apt-only ``install-deps`` step is invoked as ``python -m + playwright`` (not the ``playwright`` console script) on purpose: the + DEFAULT_WORKSPACE_TEMPLATE Dockerfile builds the uv venv at ``/mngr/code`` and then ``mv``\\s the + workspace to ``/docker_build_code``. A uv venv is path-bound -- its + console-script shebangs hardcode ``/mngr/code/.venv/bin/python``, which does + not exist here, so ``uv run playwright`` would fail with ``Failed to spawn: + playwright``. ``python -m`` goes through the venv's interpreter symlink + (location-independent), so it works from the relocated path. + (DEFAULT_WORKSPACE_TEMPLATE's own deferred-install runs the console script, but only at runtime + after default-workspace-template-seed restores the workspace to ``/mngr/code``.) CloakBrowser + itself is a plain pinned-release curl + sha256 + tar, no venv involved. """ guard = ( f"test -d {_DEFAULT_WORKSPACE_TEMPLATE_BUILD_CODE_DIR} || " f"{{ echo 'DEFAULT_WORKSPACE_TEMPLATE build-code dir {_DEFAULT_WORKSPACE_TEMPLATE_BUILD_CODE_DIR} missing; DEFAULT_WORKSPACE_TEMPLATE image layout changed -- " "update _DEFAULT_WORKSPACE_TEMPLATE_BUILD_CODE_DIR' >&2; exit 1; }" ) + # Cloud slices are x86_64 bare metal only -- one asset, no arch branching + # (contrast default-workspace-template's own deferred_install.sh, which also covers desktop arm64). + asset = "cloakbrowser-linux-x64.tar.gz" + install_cloakbrowser = ( + f"curl -fsSL -o /tmp/{asset} {_CLOAKBROWSER_RELEASE_URL}/{asset} " + f"&& echo '{_CLOAKBROWSER_SHA256_X64} /tmp/{asset}' | sha256sum -c - " + f"&& mkdir -p {_CLOAKBROWSER_INSTALL_DIR} " + f"&& tar xzf /tmp/{asset} -C {_CLOAKBROWSER_INSTALL_DIR} " + f"&& chmod +x {_CLOAKBROWSER_INSTALL_DIR}/chrome " + f"&& rm /tmp/{asset}" + ) dockerfile = ( f"FROM {base_image}\n" f"RUN {guard} " - f"&& cd {_DEFAULT_WORKSPACE_TEMPLATE_BUILD_CODE_DIR} && uv run python -m playwright install --with-deps chromium " - f"&& mkdir -p {_DEFERRED_INSTALL_MARKER_DIR} && touch {_DEFERRED_INSTALL_MARKER}\n" + f"&& cd {_DEFAULT_WORKSPACE_TEMPLATE_BUILD_CODE_DIR} && uv run python -m playwright install-deps chromium " + f"&& mkdir -p {_DEFERRED_INSTALL_MARKER_DIR} && touch {_DEFERRED_INSTALL_DEPS_MARKER} " + f"&& {install_cloakbrowser} " + f"&& touch {_DEFERRED_INSTALL_MARKER}\n" ) encoded_dockerfile = base64.b64encode(dockerfile.encode()).decode() stage_command = ( - f"rm -rf {_PLAYWRIGHT_CTX_DIR} && mkdir -p {_PLAYWRIGHT_CTX_DIR} && " - f"echo {shlex.quote(encoded_dockerfile)} | base64 -d > {_PLAYWRIGHT_CTX_DIR}/Dockerfile" + f"rm -rf {_CLOAKBROWSER_CTX_DIR} && mkdir -p {_CLOAKBROWSER_CTX_DIR} && " + f"echo {shlex.quote(encoded_dockerfile)} | base64 -d > {_CLOAKBROWSER_CTX_DIR}/Dockerfile" ) stage_result = outer.execute_idempotent_command(stage_command, timeout_seconds=30.0) if not stage_result.success: raise BoxImageCacheError( - f"failed to stage the Playwright Dockerfile on the slice: {stage_result.stderr.strip()}" + f"failed to stage the CloakBrowser Dockerfile on the slice: {stage_result.stderr.strip()}" ) run_docker( outer, - ["build", "-t", target_tag, "-f", f"{_PLAYWRIGHT_CTX_DIR}/Dockerfile", _PLAYWRIGHT_CTX_DIR], - timeout_seconds=_PLAYWRIGHT_BUILD_TIMEOUT_SECONDS, + ["build", "-t", target_tag, "-f", f"{_CLOAKBROWSER_CTX_DIR}/Dockerfile", _CLOAKBROWSER_CTX_DIR], + timeout_seconds=_CLOAKBROWSER_BUILD_TIMEOUT_SECONDS, ) @contextmanager diff --git a/libs/mngr_imbue_cloud/imbue/mngr_imbue_cloud/providers/slice_provider_test.py b/libs/mngr_imbue_cloud/imbue/mngr_imbue_cloud/providers/slice_provider_test.py index 748dc15925..32c9f7f146 100644 --- a/libs/mngr_imbue_cloud/imbue/mngr_imbue_cloud/providers/slice_provider_test.py +++ b/libs/mngr_imbue_cloud/imbue/mngr_imbue_cloud/providers/slice_provider_test.py @@ -16,9 +16,10 @@ from imbue.mngr.primitives import HostId from imbue.mngr_imbue_cloud.errors import BoxImageCacheError from imbue.mngr_imbue_cloud.providers.slice_provider import SliceVpsDockerProvider +from imbue.mngr_imbue_cloud.providers.slice_provider import _CLOAKBROWSER_CTX_DIR from imbue.mngr_imbue_cloud.providers.slice_provider import _DEFAULT_WORKSPACE_TEMPLATE_BUILD_CODE_DIR +from imbue.mngr_imbue_cloud.providers.slice_provider import _DEFERRED_INSTALL_DEPS_MARKER from imbue.mngr_imbue_cloud.providers.slice_provider import _DEFERRED_INSTALL_MARKER -from imbue.mngr_imbue_cloud.providers.slice_provider import _PLAYWRIGHT_CTX_DIR from imbue.mngr_imbue_cloud.slices.box_image_cache import BoxImageCacheInterface from imbue.mngr_imbue_cloud.slices.mock_box_image_cache_test import MockBoxImageCache @@ -134,14 +135,14 @@ def execute_idempotent_command( return CommandResult(stdout="", stderr="", success=True) -def test_build_playwright_derived_image_renders_marker_and_build_command() -> None: +def test_build_cloakbrowser_derived_image_renders_marker_and_build_command() -> None: provider = SliceVpsDockerProvider.model_construct() outer = _RecordingOuter() - provider._build_playwright_derived_image( + provider._build_cloakbrowser_derived_image( outer=cast(OuterHostInterface, outer), base_image="mngr-build-xyz", target_tag=_TAG ) # The staged context Dockerfile is shipped base64-encoded; decode it and assert the - # baked-Playwright + deferred-install-marker contract every loaded slice relies on. + # baked-CloakBrowser + deferred-install-marker contract every loaded slice relies on. stage_command = next(c for c in outer.recorded if "base64 -d" in c) encoded = stage_command.split("echo ")[1].split(" | base64 -d")[0].strip().strip("'") dockerfile = base64.b64decode(encoded).decode() @@ -149,8 +150,11 @@ def test_build_playwright_derived_image_renders_marker_and_build_command() -> No # Must invoke playwright via ``python -m`` (not the ``playwright`` console script): the DEFAULT_WORKSPACE_TEMPLATE # venv is built at /mngr/code and ``mv``\\d to /docker_build_code, so the script's hardcoded # shebang is broken here -- only the interpreter (reached via ``python -m``) is relocatable. - assert "uv run python -m playwright install --with-deps chromium" in dockerfile + assert "uv run python -m playwright install-deps chromium" in dockerfile + assert _DEFERRED_INSTALL_DEPS_MARKER in dockerfile assert _DEFERRED_INSTALL_MARKER in dockerfile + assert "cloakbrowser-linux-x64.tar.gz" in dockerfile + assert "sha256sum -c -" in dockerfile # Guards the DEFAULT_WORKSPACE_TEMPLATE build-code path so a relocated layout fails fast with a clear message. assert f"test -d {_DEFAULT_WORKSPACE_TEMPLATE_BUILD_CODE_DIR}" in dockerfile # The RUN body must be valid shell -- catches f-string brace-escaping bugs in the guard. @@ -159,7 +163,7 @@ def test_build_playwright_derived_image_renders_marker_and_build_command() -> No assert syntax_check.returncode == 0, syntax_check.stderr build_command = next(c for c in outer.recorded if "docker build" in c) assert _TAG in build_command - assert f"{_PLAYWRIGHT_CTX_DIR}/Dockerfile" in build_command + assert f"{_CLOAKBROWSER_CTX_DIR}/Dockerfile" in build_command def test_transfer_key_authorize_and_deauthorize_render_expected_commands() -> None: From 978062532f1f1ecf5f5c61392892f9e760d65941 Mon Sep 17 00:00:00 2001 From: Minh Trinh Date: Fri, 17 Jul 2026 11:43:34 -0700 Subject: [PATCH 2/4] Point to the CloakBrowser reference doc directly from the pinned constants Co-Authored-By: Claude Sonnet 5 --- .../imbue/mngr_imbue_cloud/providers/slice_provider.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libs/mngr_imbue_cloud/imbue/mngr_imbue_cloud/providers/slice_provider.py b/libs/mngr_imbue_cloud/imbue/mngr_imbue_cloud/providers/slice_provider.py index b9b6bea32b..267617cece 100644 --- a/libs/mngr_imbue_cloud/imbue/mngr_imbue_cloud/providers/slice_provider.py +++ b/libs/mngr_imbue_cloud/imbue/mngr_imbue_cloud/providers/slice_provider.py @@ -71,6 +71,14 @@ # scripts/deferred_install.sh (_CLOAKBROWSER_VERSION / _CLOAKBROWSER_SHA256_X64). # Cloud slices are x86_64 bare metal only (see DEFAULT_IMAGE_URL_X86_64), so this # bakes the x64 asset only -- no arch branching needed here. +# +# Full context (where CloakBrowser came from, why it replaced Fortress/vanilla +# Chromium, exact variable-by-variable ownership incl. the Playwright-vs- +# browser-use `executable_path` distinction, and step-by-step version-bump / +# engine-swap instructions) lives in default-workspace-template, not here: +# libs/browser/CHROMIUM_ENGINE_DESCRIPTION_AND_FUTURE_GUIDELINES.md +# These constants are that doc's row 7 -- a manually-kept-in-sync mirror. +# Bump one, bump the other. _CLOAKBROWSER_VERSION: Final[str] = "chromium-v146.0.7680.177.4" _CLOAKBROWSER_RELEASE_URL: Final[str] = ( f"https://github.com/CloakHQ/CloakBrowser/releases/download/{_CLOAKBROWSER_VERSION}" From 1f1f8e47a144042c03bc041a3384cf907322eb56 Mon Sep 17 00:00:00 2001 From: Minh Trinh Date: Fri, 17 Jul 2026 11:47:03 -0700 Subject: [PATCH 3/4] Add mngr_imbue_cloud changelog entry for the CloakBrowser cloud pre-bake swap Co-Authored-By: Claude Sonnet 5 --- libs/mngr_imbue_cloud/changelog/cloakbrowser-cloud-prebake.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 libs/mngr_imbue_cloud/changelog/cloakbrowser-cloud-prebake.md diff --git a/libs/mngr_imbue_cloud/changelog/cloakbrowser-cloud-prebake.md b/libs/mngr_imbue_cloud/changelog/cloakbrowser-cloud-prebake.md new file mode 100644 index 0000000000..fd4a95ff77 --- /dev/null +++ b/libs/mngr_imbue_cloud/changelog/cloakbrowser-cloud-prebake.md @@ -0,0 +1 @@ +Cloud slice pre-baking now bakes CloakBrowser (a stealth-patched Chromium fork) instead of vanilla Playwright-managed Chromium into the box image, matching the engine swap in default-workspace-template's browser fleet. The deferred-install marker split in two (`done.playwright_deps`, `done.cloakbrowser`) so loaded slices still skip the real install correctly. From 51cc91f2c5ff1b47a12e60d5c68e4de9b510aba6 Mon Sep 17 00:00:00 2001 From: Minh Trinh Date: Fri, 17 Jul 2026 11:56:57 -0700 Subject: [PATCH 4/4] Ruff-format slice_provider.py Co-Authored-By: Claude Sonnet 5 --- .../imbue/mngr_imbue_cloud/providers/slice_provider.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libs/mngr_imbue_cloud/imbue/mngr_imbue_cloud/providers/slice_provider.py b/libs/mngr_imbue_cloud/imbue/mngr_imbue_cloud/providers/slice_provider.py index 267617cece..6273dd01c4 100644 --- a/libs/mngr_imbue_cloud/imbue/mngr_imbue_cloud/providers/slice_provider.py +++ b/libs/mngr_imbue_cloud/imbue/mngr_imbue_cloud/providers/slice_provider.py @@ -496,7 +496,9 @@ def _seed_box_image( wait=wait_exponential(multiplier=1, min=1, max=10), reraise=True, ) - def _build_cloakbrowser_derived_image(self, *, outer: OuterHostInterface, base_image: str, target_tag: str) -> None: + def _build_cloakbrowser_derived_image( + self, *, outer: OuterHostInterface, base_image: str, target_tag: str + ) -> None: """Build target_tag as base_image + a baked CloakBrowser layer (and the done markers). CloakBrowser is deliberately not in the DEFAULT_WORKSPACE_TEMPLATE Dockerfile (it is shared with the