From 74d5e5a89935fcf18ce76e581211f50f3dd97e29 Mon Sep 17 00:00:00 2001 From: claude-ceo-assistant Date: Fri, 8 May 2026 03:38:13 +0000 Subject: [PATCH] test(dockerfile): rewrite tui-resolution invariants for post-a49f4c6 design Two contract tests guarded properties of the now-retired @hermes/ink materialization dance (--prefix node_modules/@hermes/ink + omit=dev + nested react cleanup + await-import smoke). The Dockerfile was restructured in a49f4c6 ("fix: prevent tui rebuilding assets") to instead: 1. Copy the full ui-tui/packages/hermes-ink/ tree (not just manifests) 2. Set ENV npm_config_install_links=false to force symlink resolution despite Debian's bundled npm 9.x defaulting to install-links=true The new mechanism solves the same workspace-resolution problem with fewer build steps (no rebuild on container start). Update the tests to guard the new invariants, both designed to catch a regression that would break @hermes/ink at runtime: - test_dockerfile_installs_tui_dependencies now asserts the full packages/hermes-ink/ COPY (catches manifest-only revert) - new test_dockerfile_forces_npm_install_links_false_for_workspace_resolution asserts the env var (catches accidental removal that re-introduces the npm 9 install-as-copy bug) Co-Authored-By: Claude Opus 4.7 (1M context) --- tests/tools/test_dockerfile_pid1_reaping.py | 39 ++++++++++++++------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/tests/tools/test_dockerfile_pid1_reaping.py b/tests/tools/test_dockerfile_pid1_reaping.py index 52532a78..8d5e38f2 100644 --- a/tests/tools/test_dockerfile_pid1_reaping.py +++ b/tests/tools/test_dockerfile_pid1_reaping.py @@ -106,8 +106,16 @@ def test_dockerfile_entrypoint_routes_through_the_init(dockerfile_text): def test_dockerfile_installs_tui_dependencies(dockerfile_text): + """The Dockerfile must install ui-tui's npm dependencies during build, + and must copy the workspace package tree (not just manifests) so npm + can resolve the @hermes/ink ``file:`` dep without falling back to the + bare manifest. See PR #16690 + a49f4c6 for the design. + """ assert "ui-tui/package.json" in dockerfile_text - assert "ui-tui/packages/hermes-ink/package-lock.json" in dockerfile_text + # ui-tui/packages/hermes-ink/ is a `file:` workspace; copying the FULL + # tree (not just its manifests) is what lets npm resolve it correctly. + # Catches the regression where someone reverts to manifest-only copies. + assert "COPY ui-tui/packages/hermes-ink/ ui-tui/packages/hermes-ink/" in dockerfile_text assert any( "ui-tui" in step and "npm" in step and (" install" in step or " ci" in step) for step in _run_steps(dockerfile_text) @@ -121,17 +129,24 @@ def test_dockerfile_builds_tui_assets(dockerfile_text): ) -def test_dockerfile_materializes_local_tui_ink_package(dockerfile_text): - assert any( - "ui-tui" in step - and "node_modules/@hermes/ink" in step - and "packages/hermes-ink" in step - and "rm -rf packages/hermes-ink/node_modules" in step - and "npm install --omit=dev" in step - and "--prefix node_modules/@hermes/ink" in step - and "rm -rf node_modules/@hermes/ink/node_modules/react" in step - and "await import('@hermes/ink')" in step - for step in _run_steps(dockerfile_text) +def test_dockerfile_forces_npm_install_links_false_for_workspace_resolution(dockerfile_text): + """The Dockerfile must force npm to install ``file:`` deps as symlinks + rather than copies. Debian's bundled npm 9.x defaults to install-links=true + (deps installed as copies), which produces a hidden + node_modules/.package-lock.json that permanently disagrees with the root + lockfile (which is generated by npm 10+ using symlinks). The disagreement + trips the TUI launcher's _tui_need_npm_install() check on every startup + and triggers an EACCES-failing runtime `npm install`. + + Replaces the older `--prefix node_modules/@hermes/ink` materialization + pattern (PR #16690) — that approach was retired in a49f4c6 in favor of + install-links=false because the materialization step was rebuilding TUI + assets unnecessarily. + """ + assert "npm_config_install_links=false" in dockerfile_text, ( + "ENV npm_config_install_links=false missing — without it, Debian npm 9.x " + "installs file: deps as copies, breaking @hermes/ink workspace resolution. " + "See PR #16690 + a49f4c6." )