Skip to content

Docker: one multi-target image (dev + user), guarded pins, published to Docker Hub #5229

Closed

Description

@Trecek

Supersedes #66, whose spec predates the tracked verification image and the installed-copy prototype.

Maintainer setup — do this first

  • Share the org secret DOCKERHUB_TOKEN with TalonT-Org/AutoSkillit. AutoSkillit can already read the org secret DOCKERHUB_USERNAME but not DOCKERHUB_TOKEN; helper_agents can read both (checked 2026-10-03 with gh api repos/TalonT-Org/<repo>/actions/organization-secrets). The token must be a Docker Hub access token, not the account password.
  • Create the Docker Hub repository trecek/autoskillit with public visibility. trecek is the namespace helper_agents publishes to; AutoSkillit is a public repository.

No Anthropic, Claude, OpenAI or MiniMax credential is needed for this ticket.

Why

AutoSkillit has two Docker definitions and neither is published:

Their toolchain pins disagree: uv 0.9.21 vs 0.12.13, Node 22 vs 24.21.0, Rust 1.90 vs 1.98.1, Task 3.43.3 vs 3.53.1 (tracked pins). Only the Claude Code and Codex pins are checked against outside authorities (guard).

This ticket establishes the image and its publication only. End-to-end tests that use it are separate tickets.

Scope

  1. One multi-target Dockerfile at scripts/docker/Dockerfile:
    • toolchain stage holding every pin (Claude Code, Codex, uv, Node, Rust, Task, pre-commit, ripgrep, jq, gh).
    • dev target: today's verification image, behavior unchanged.
    • user target: the prototype, but uv tool install from the archived source already in the build context instead of a GitHub URL, so an unpushed commit builds the same way as a release. This works without git metadata: the version is static (pyproject) and a wheel built from git archive HEAD contains the bundled recipes and skills. The private api-simulator dependency is dev-only (dev extras, git source), so user needs no GitHub token.
    • Avoid the prototype's split UV_TOOL_DIR=/opt/uv-tools / UV_TOOL_BIN_DIR=/opt/uv-bin layout, or confirm it: in a clean container autoskillit doctor reports installation_record_invalid (ERROR) and stale_entry_points against it.
  2. One pin set, fully guarded. Make the toolchain stage's ARGs the single authority, and extend tests/infra/test_verification_container.py so every other place that installs or requires the same tool must match it: Claude Code (backend minimum version and the conformance-probes matrix, already guarded), Codex (Taskfile preconditions, already guarded), uv and Task (CI setup steps), and ripgrep — CI installs 14.1.0 (tests.yml) while the tracked Dockerfile pins 15.2.0. CI's Rust floats on stable (tests.yml) and no CI step pins Node; either pin them in CI or record the Dockerfile as their only authority.
  3. Move every hardcoded path to the old Dockerfile: tests/infra/test_verification_container.py:16, tests/arch/test_shell_capture_conformance_registry.py:66, tests/_test_filter.py:192, docs/decisions/0008-shell-capture-snapshot-authority.md:76, tests/infra/test_typecheck_gate.py:168, and the verification README (line 16, plus the codex_shell_baseline.py path at line 47).
  4. Track the container manager (autoskillit-container from the prototype: update, start, stop, shell, status, sync-auth) beside the Dockerfile. update pulls a published tag instead of building. Credentials are copied into the home volume at run time, never into an image layer.
  5. Publishing workflow .github/workflows/docker-image.yml, modeled on TalonT-Org/helper_agents/.github/workflows/container_build.yml (docker/setup-buildx-action, docker/login-action with DOCKERHUB_USERNAME/DOCKERHUB_TOKEN, GitHub Actions layer cache):
    • Build context: a directory produced by git archive "$GITHUB_SHA" | tar -x (docker/build-push-action takes a path or URL, not a tar stream).
    • Tags: <version> and sha-<short> plus a moving develop for each develop version bump; stable and latest on release.
    • After push: run the pushed image and assert autoskillit --version, claude --version and codex --version match the pins.

Out of scope

  • Any end-to-end test, and fixing what autoskillit doctor reports inside the image (separate E2E tickets).
  • Live verification in the remediation and implementation pipelines.

Acceptance criteria

  • git archive <sha> | docker build --target user builds a committed but unpushed SHA, and the image's autoskillit --version equals pyproject.toml's version.
  • --target dev still runs task test-local-gate as the verification README describes.
  • The pin guard fails when a pinned tool's version differs between the Dockerfile and any CI step, Taskfile precondition or code constant that installs or requires that tool.
  • A develop version bump publishes trecek/autoskillit:<version>, :sha-<short> and :develop, pullable without logging in.
  • No credential appears in any image layer (docker history --no-trunc shows none).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions