Skip to content

fix: align Cascade agent runtime images with common review tools#1380

Merged
aaight merged 2 commits into
devfrom
fix/align-agent-runtime-images
May 18, 2026
Merged

fix: align Cascade agent runtime images with common review tools#1380
aaight merged 2 commits into
devfrom
fix/align-agent-runtime-images

Conversation

@aaight
Copy link
Copy Markdown
Collaborator

@aaight aaight commented May 18, 2026

Summary

Aligns the worker image with the baseline native-session toolchain agents actually reach for, so per-project .cascade/setup.sh hooks no longer have to install Python or Playwright on the hot path. Closes the friction clusters tracked under MNG-1055:

  • Python shim — MNG-887/897/926/934/947/957/973/1010/1024/1033/1039/1044 (12 papercuts about python missing from PATH)
  • Playwright Chromium — MNG-998 / MNG-1048 (review workspace missing the browser binary)

Linear issue

https://linear.app/issue/MNG-1055

What changed

Area Change
Dockerfile.worker Adds Debian-owned python3 + python-is-python3 (one apt-managed shim, no ln -s drift). Adds pinned @playwright/test@1.49.1 + Chromium via playwright install --with-deps chromium. Sets ENV PLAYWRIGHT_BROWSERS_PATH=/ms-playwright and chmod -R a+rX /ms-playwright so the non-root node user can read the cache. A small image-build sanity check (python --version && python -c 'import json') catches future package-name regressions.
src/backends/shared/envFilter.ts Adds PLAYWRIGHT_BROWSERS_PATH to SHARED_ALLOWED_ENV_EXACT so the env propagates to Claude Code / Codex / OpenCode subprocesses. The broader PLAYWRIGHT_* prefix is intentionally not allowlisted — only the exact var.
src/backends/shared/nativeToolPrompts.ts Adds a "Guaranteed runtime tools" section so agents are told what is pre-installed (Python shim, jq/rg/fd/git/tmux/cascade-tools, Playwright Chromium via $PLAYWRIGHT_BROWSERS_PATH) instead of working around it.
tests/docker/worker-runtime-tools/run-test.sh New, single source of truth for the runtime smoke (Python shim + python -c 'import json' + Playwright Chromium launch). Used by CI and both deploy workflows — failure blocks :latest, :dev, and SHA-tag pushes.
.github/workflows/{ci,deploy,deploy-dev}.yml Wires the smoke script into docker-build-check (PR CI) and gates the worker image push in both deploy workflows behind the same check, so a regression never reaches production.
Tests Pin PLAYWRIGHT_BROWSERS_PATH survival across filterProcessEnv and buildEngineEnv (every engine allowlist shape), and pin the prompt guarantees (Python shim, baseline shell tools, $PLAYWRIGHT_BROWSERS_PATH reference) without disturbing the existing CASCADE Tools section.
Docs Engine-backends doc gets a new "Worker-image runtime baseline (MNG-1055)" section. README's deployment table mentions the baseline. Getting Started prerequisites updates the ~6 GB hint to ~8 GB and links to the engine-backends section. CHANGELOG entry under ### Changed.

Notable design decisions

  • One Playwright pin in the image, not multi-version. Target repos that need a materially different Chromium revision install their own copy in .cascade/setup.sh — keeping the image small enough to ship.
  • Env-filter is the load-bearing piece for native-tool engines. Just setting PLAYWRIGHT_BROWSERS_PATH in Docker is insufficient — the native-tool engines sanitize subprocess env via SHARED_ALLOWED_ENV_EXACT before spawning. The plan called out this defense-in-depth posture explicitly; the test pins it.
  • Single smoke script, three CI consumers. Avoids the copy-shell-snippets-across-workflows trap. The script is the only place that knows the exact checks.

Test plan

  • npx vitest run --project unit-backends tests/unit/backends/shared-envFilter.test.ts tests/unit/backends/shared-envBuilder.test.ts tests/unit/backends/shared-nativeToolPrompts.test.ts (53 → 106 tests, all green)
  • Full npm test (9,725 passed / 28 skipped)
  • npm run typecheck (clean)
  • npm run lint (no new warnings in changed files)
  • CI docker-build-check exercises tests/docker/worker-runtime-tools/run-test.sh against the freshly built image. (Cannot run Docker from the sandbox; the script is bash-syntax-validated and the CI step is wired.)

Risks & mitigations

  • Image size grows — Chromium + system deps add several hundred MB. Mitigated by installing only Chromium (no Firefox / WebKit). Getting Started doc updated.
  • Playwright version drift — Target repos pinning a different @playwright/test major may still need their own browser install. Documented in the engine-backends section; the baseline serves the median review/Playwright-launch case.
  • Env filter could be tightened later and accidentally drop the new entry — Pinned by both shared-envFilter.test.ts and shared-envBuilder.test.ts (the latter is the regression net for the case where someone tightens an engine-specific allowlist without touching the shared one).

🕵️ claude-code · claude-opus-4-7 · run details

@codecov
Copy link
Copy Markdown

codecov Bot commented May 18, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
Collaborator

@nhopeatall nhopeatall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Requesting changes because the new global Playwright browser path makes the documented version-drift fallback fail for project setup scripts.

Code Issues

Should Fix

  • Dockerfile.worker:99 — The image exports PLAYWRIGHT_BROWSERS_PATH=/ms-playwright globally and only grants read/execute permissions on that root-owned cache. setupRepository runs .cascade/setup.sh later as the node user and runCommand inherits process.env, so a target repo pinned to a different Playwright revision that runs npx playwright install chromium in setup will try to create the missing browser revision under /ms-playwright and fail with a permission error. That contradicts the PR/docs fallback that projects needing a materially different Chromium revision can install their own copy in .cascade/setup.sh. Make the cache writable by the runtime user or provide an automatic/project-facing override for project-local Playwright installs before merging.

🕵️ codex · gpt-5.5 · run details

Comment thread Dockerfile.worker Outdated
RUN npm install -g @playwright/test@1.49.1 \
&& PLAYWRIGHT_BROWSERS_PATH=/ms-playwright \
npx --yes playwright@1.49.1 install --with-deps chromium \
&& chmod -R a+rX /ms-playwright
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The image exports PLAYWRIGHT_BROWSERS_PATH=/ms-playwright globally, then grants only read/execute on that root-owned cache. .cascade/setup.sh runs later as the node user and inherits this env, so a project pinned to a different Playwright revision that runs npx playwright install chromium will try to create the missing browser revision under /ms-playwright and hit a permission error. That is the fallback described in the PR/docs for version drift. Please either make this cache writable by the runtime user or provide an automatic/project-facing override for project-local Playwright installs.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 5b6fb7b. The shared Playwright cache is now owned/writable by the runtime node user, so project setup scripts inheriting PLAYWRIGHT_BROWSERS_PATH can install a missing pinned Chromium revision there. I also added a smoke-test assertion that the node user can write to the cache and updated the docs/prompt/changelog wording.

@zbigniewsobiecki
Copy link
Copy Markdown
Member

@aaight address code review concerns

@aaight
Copy link
Copy Markdown
Collaborator Author

aaight commented May 18, 2026

@zbigniewsobiecki addressed the code review concern in 5b6fb7b. The Playwright cache remains shared at PLAYWRIGHT_BROWSERS_PATH, but it is now owned/writable by the runtime node user so project .cascade/setup.sh scripts can install missing pinned Chromium revisions instead of failing on permissions. Added smoke coverage for node-user write access and updated the related docs/prompt/changelog text.

🕵️ codex · gpt-5.5 · run details

Copy link
Copy Markdown
Collaborator

@nhopeatall nhopeatall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - the updated worker image baseline matches MNG-1055, the previous writable-cache issue is covered by the node-user ownership and smoke assertion, env propagation remains exact-match only, and the focused backend tests pass locally (106 tests).

🕵️ codex · gpt-5.5 · run details

@aaight aaight merged commit 8ea8e42 into dev May 18, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants