Skip to content

feat(core): use shared JS box image for project containers#281

Open
konard wants to merge 9 commits into
ProverCoderAI:mainfrom
konard:issue-267-99a3d92349cd
Open

feat(core): use shared JS box image for project containers#281
konard wants to merge 9 commits into
ProverCoderAI:mainfrom
konard:issue-267-99a3d92349cd

Conversation

@konard
Copy link
Copy Markdown
Contributor

@konard konard commented May 12, 2026

Summary

Fixes #267.

Switches generated project workspace Dockerfiles from a raw ubuntu:24.04 base to the shared konard/box-js:latest Docker Hub image published by https://github.com/link-foundation/box. The docker-git bootstrap layers, SSH entrypoint, auth bridge, host-Docker-backed runtime contract, and clone/cache orchestration remain owned by docker-git.

Reproduction

Before this change, renderDockerfile(makeTemplateConfig()) emitted:

FROM ubuntu:24.04

and only knew how to rename an existing ubuntu user. That did not satisfy issue #267's requirement to reuse the shared box infrastructure, and it risked duplicate UID-1000 users when a box base already has /home/box.

CI then exposed box-specific follow-up invariants:

  • Non-interactive bash -lc commands sourced /etc/profile.d/zz-prompt.sh, and the prompt script touched /dev/tty without a controlling TTY.
  • konard/box-js inherits HOME=/home/box, WORKDIR=/home/box, and login rc files with absolute /home/box references. After renaming box -> dev, docker exec -u dev bash -lc '...' could still resolve user paths through /home/box, and login shells failed on /home/box/.deno/env.
  • The shared git mirror refresh used +refs/*:refs/*; on public GitHub repositories this enumerated refs/pull/* and timed out the login-context E2E after the cache volume was reused by the PR case.

Changes

  • Add ARG DOCKER_GIT_BASE_IMAGE=konard/box-js:latest and FROM ${DOCKER_GIT_BASE_IMAGE} to generated project Dockerfiles.
  • Keep USER root before docker-git's apt/tool/bootstrap layers so the existing setup remains valid on top of the box image.
  • Rename either box or ubuntu base users to the configured sshUser before falling back to user creation.
  • Normalize inherited image environment after user migration with HOME=/home/<sshUser>, a user-correct PATH, and WORKDIR /home/<sshUser>.
  • Rewrite moved login rc files (.profile, .bashrc, .zshrc, etc.) from /home/box or /home/ubuntu to /home/<sshUser>.
  • Keep /etc/profile.d/bun.sh runtime-relative by writing \$PATH instead of baking the base image build-time PATH.
  • Keep zz-prompt.sh inert for non-interactive shells; interactive shells still install prompt/TTY recovery hooks.
  • Restrict shared mirror refreshes to refs/heads/* and refs/tags/*, so clone-cache reuse does not fetch every GitHub pull-request ref.
  • Mirror renderer changes into packages/app/src/lib for the bundled CLI build.
  • Add regression coverage for the shared base image, base-user migration behavior, HOME/WORKDIR normalization, login rc rewriting, runtime PATH rendering, non-interactive prompt sourcing, and clone-cache ref filtering.
  • Use the Docker Hub JS box because CI confirmed ghcr.io/link-foundation/box:latest currently fails anonymous pulls with HTTP 401, while Docker Hub is publicly pullable. Registry metadata also shows the full konard/box:latest amd64 manifest is about 5.6 GiB compressed, while konard/box-js:latest is about 1.6 GiB compressed and still comes from the same shared box infrastructure.

Mathematical Guarantees

Invariants

  • forall config in TemplateConfig: baseImage(renderDockerfile(config)) = ${DOCKER_GIT_BASE_IMAGE}.
  • forall config in TemplateConfig: sshUser(config) owns /home/sshUser(config) after the user-normalization block when the base image has box, ubuntu, or neither.
  • forall config in TemplateConfig: HOME(renderDockerfile(config)) = /home/sshUser(config) and WORKDIR(renderDockerfile(config)) = /home/sshUser(config).
  • forall p in loginRc(sshUser): not contains(p, "/home/box") and not contains(p, "/home/ubuntu") for inherited base-home references covered by the generated rewrite block.
  • forall shell: nonInteractive(shell) -> source(zz-prompt.sh, shell) produces no prompt mutation and no TTY write.
  • forall r in cloneCacheRefreshRefs: r in refs/heads/* union refs/tags/*; in particular, refs/pull/* is excluded from cache refresh.
  • CORE -> SHELL boundary is preserved: this change modifies pure template rendering; runtime effects remain in generated shell scripts and Docker execution layers.

Preconditions

  • The selected DOCKER_GIT_BASE_IMAGE is Debian/Ubuntu-compatible and supports apt-based root setup.
  • The project container still runs docker-git's generated /entrypoint.sh.

Postconditions

  • Generated project containers inherit the shared link-foundation JS box runtime/tooling base.
  • docker-git-specific SSH/auth/bootstrap behavior remains rendered after the base image selection.
  • Non-interactive e2e commands can run under bash -lc without prompt/TTY side effects and with ~ and login rc paths resolving into the mounted SSH user home.
  • Reused clone-cache mirrors accelerate branch/tag object reuse without expanding the remote ref domain to every GitHub PR ref.

Complexity

  • Dockerfile and prompt rendering remain O(1) time and O(1) additional space.
  • Clone-cache refresh changes from O(|all remote refs|) to O(|heads| + |tags|) remote ref enumeration.

Verification

  • bun run --cwd packages/lib test -- tests/core/templates.test.ts
  • bun run check
  • bun run test
  • bun run build
  • bun run lint
  • bun run lint:effect
  • bun run check:dist-deps-prune
  • git diff --check

Note: this local runner does not have the docker binary installed, so local image build was not run here; Docker/E2E verification is covered by GitHub Actions on PR #281.

konard added 2 commits May 12, 2026 09:49
Adding .gitkeep for PR creation (default mode).
This file will be removed when the task is complete.

Issue: ProverCoderAI#267
@konard konard changed the title [WIP] Есть смысл юзать единные box контейнеры для работы feat(core): use shared box image for project containers May 12, 2026
@konard konard marked this pull request as ready for review May 12, 2026 10:17
@konard konard changed the title feat(core): use shared box image for project containers feat(core): use shared JS box image for project containers May 12, 2026
@konard
Copy link
Copy Markdown
Contributor Author

konard commented May 12, 2026

Working session summary

Done. PR #281 is updated and green: #281

Latest pushed head: bf18af78780766c71e0ded18b9305884305a66a1.

Key final fix:

  • Narrowed shared clone-cache mirror refresh from +refs/*:refs/* to heads/tags only in tasks.ts and the bundled app copy.
  • Added regression coverage in templates.test.ts to ensure refs/pull/* is not fetched during cache refresh.

Verification passed locally:
bun run check, bun run test, bun run build, bun run lint, bun run lint:effect, bun run check:dist-deps-prune, git diff --check.

GitHub checks passed on PR #281, including Docker E2E:
Clone cache, Login context, Runtime volumes + SSH, OpenCode, Browser command, and all static jobs.

Working tree is clean. SOURCE: n/a.


This summary was automatically extracted from the AI working session output.

@konard
Copy link
Copy Markdown
Contributor Author

konard commented May 12, 2026

🤖 Solution Draft Log

This log file contains the complete execution trace of the AI solution draft process.

💰 Cost estimation:

  • Model: GPT-5.5
  • Provider: OpenAI
  • Public pricing estimate: $88.495497

📊 Context and tokens usage:

  • 1.6M / 1.1M (149%) input tokens, 125.0K / 128K (98%) output tokens

Total: (1.6M + 67.2M cached) input tokens, 125.0K output tokens, $88.495497 cost

🤖 Models used:

  • Tool: OpenAI Codex
  • Requested: gpt-5.5
  • Model: GPT-5.5 (gpt-5.5)

📎 Log file uploaded as Repository (2 chunks) (201432KB)


Now working session is ended, feel free to review and add any feedback on the solution draft.

@konard
Copy link
Copy Markdown
Contributor Author

konard commented May 12, 2026

✅ Ready to merge

This pull request is now ready to be merged:

  • All CI checks have passed
  • No merge conflicts
  • No pending changes

Monitored by hive-mind with --auto-restart-until-mergeable flag

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.

Есть смысл юзать единные box контейнеры для работы

1 participant