Skip to content

feat(hub): real docker base freshness + two-phase bake-then-create#173

Closed
madarco wants to merge 1 commit into
mainfrom
feat/create-bake-phase
Closed

feat(hub): real docker base freshness + two-phase bake-then-create#173
madarco wants to merge 1 commit into
mainfrom
feat/create-bake-phase

Conversation

@madarco

@madarco madarco commented Jul 8, 2026

Copy link
Copy Markdown
Owner

Problem

When a create needs the docker base image baked (first run, or stale build-context fingerprint), the bake happened silently inside the create job. The hub hardcoded docker freshness to fresh, so no UI could warn — the tray's progress card parked at 80% and its 2-minute job poll gave up, reading as a hang.

Changes (one rule on every surface, matching the CLI)

  • Docker auto-bakes, never prompts (the CLI's self-heal rule) — the fix is visibility: a note in the create form plus an explicit two-phase flow (prepare job streamed as "Building base image…", then the create job).
  • Cloud providers keep the CLI wizard's stale prompt — the web create modal now offers Rebuild & Create / Use Existing Image / Cancel on a stale cloud base.

Monorepo

  • packages/sandbox-docker: new evaluateDockerBaseFreshness() — read-only mirror of ensureImage's rebuild predicate (one docker image inspect + context hashing); pure classifier unit-tested.
  • Hub backend: GET /providers?freshness=1 reports docker unprepared/stale truthfully; configured stays true. Hub spawn passes AGENTBOX_DOCKER_CONTEXT so the bundled hub fingerprints the same staged context as the workers.
  • Hub web: create modal bake note + auto prepare→create chain (both job logs streamed); Settings badge shows "needs bake" for docker unprepared.
  • CLI unchanged (docker still self-heals silently there); evaluateBaseFreshness untouched.

The tray-side counterpart is in madarco/agentbox-tray db02c27.

Verified

  • Live e2e: stale docker → tray/hub freshness reported the fingerprint delta → prepare job ran (real docker build streamed under "Building base image…") → chained create with zero [image] lines → box Up; freshness flipped to fresh after.
  • sandbox-docker tests (280) + CLI freshness/wizard tests (24) pass; hub standalone typechecks/builds.

https://claude.ai/code/session_01JKGc7YWFuXVJvXKNHYnHeB


Note

Medium Risk
Changes the hub create path timing and UX (prepare→create chain must stay open) and depends on freshness matching actual ensureImage behavior; docker create still self-heals, but a mismatch would mislead users or skip announced bakes.

Overview
Docker base freshness is no longer faked as always fresh. evaluateDockerBaseFreshness / classifyDockerBaseFreshness in @agentbox/sandbox-docker mirror ensureImage's rebuild rules (read-only: one docker image inspect + context hash). Hub GET /providers?freshness=1 uses that for docker too while keeping configured: true. The hub child process gets AGENTBOX_DOCKER_CONTEXT so fingerprints match create/prepare workers.

The hub create modal becomes a two-phase flow when a bake is needed. It loads freshness from ?freshness=1, shows amber warnings, and on submit runs POST …/prepare first (or attaches to an in-flight jobId), streams "Building base image…", then chains createBoxAction on bake done. Docker always auto-bakes; stale cloud bases get Rebuild & create / Use existing / Cancel like the CLI. Settings shows a needs bake badge for docker unprepared.

Docs and ProviderOption comments are updated; classifier behavior is covered by new unit tests.

Reviewed by Cursor Bugbot for commit 13de8bc. Configure here.

… the create modal

The docker provider's base-image freshness was hardcoded 'fresh' in the hub
(docker self-heals inside create), so a first-run or stale-base create hid a
multi-minute docker build inside the create job with no warning.

- packages/sandbox-docker: new evaluateDockerBaseFreshness() — a cheap,
  read-only mirror of ensureImage's rebuild predicate (one docker image
  inspect + context hashing), with the pure classifier unit-tested.
- hub backend: GET /providers?freshness=1 now reports docker
  unprepared/stale truthfully (configured stays true — freshness is a
  heads-up, never a gate). The hub spawn passes AGENTBOX_DOCKER_CONTEXT so
  the bundled hub can fingerprint the same staged context as the workers.
- hub web: create modal shows a bake note under the provider picker;
  docker auto-chains a prepare job ('Building base image…', streamed) into
  the create on end:done; a stale cloud base offers Rebuild & Create /
  Use Existing Image / Cancel (mirrors the CLI wizard). Settings badge
  shows 'needs bake' for docker unprepared.

The CLI is unchanged: docker still self-heals silently there.

Claude-Session: https://claude.ai/code/session_01JKGc7YWFuXVJvXKNHYnHeB
@vercel

vercel Bot commented Jul 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agentbox-web Ready Ready Preview, Comment Jul 8, 2026 10:12am

Request Review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 13de8bc. Configure here.

!!providerFreshness &&
(!!providerFreshness.jobId ||
providerFreshness.baseStatus === 'unprepared' ||
providerFreshness.baseStatus === 'stale');

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Freshness gate ignores store jobId

Medium Severity

bakeNeeded only consults the async ?freshness=1 map, so until that request finishes providerFreshness is undefined and create goes straight to startCreate. The store’s providers already carry an in-flight jobId from getData(), but that value is never merged in, so a quick submit can start a create while a base bake is still running and skip the intended prepare→create chain (and the cloud stale rebuild prompt).

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 13de8bc. Configure here.

@madarco

madarco commented Jul 8, 2026

Copy link
Copy Markdown
Owner Author

Closing: this branch's commit (13de8bc) is already integrated into nightly (via merge ca92afd0), so there's nothing left to merge. GitHub won't retarget the base to nightly either — "no new commits between base branch 'nightly' and head branch 'feat/create-bake-phase'". Per the nightly integration flow (fast-forward nightly to the feature tip, then close the main PR rather than merging to main), closing here — the changes are live on nightly.

https://claude.ai/code/session_01JKGc7YWFuXVJvXKNHYnHeB

@madarco madarco closed this Jul 8, 2026
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.

1 participant