Skip to content

feat(native): build Compose build services in native up behind HACK_NATIVE_BUILDS - #612

Closed
roodboi wants to merge 13 commits into
claude/native-image-builds-retentionfrom
claude/native-image-builds-up
Closed

roodboi wants to merge 13 commits into
claude/native-image-builds-retentionfrom
claude/native-image-builds-up

Conversation

@roodboi

@roodboi roodboi commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Stacked on #607; review only the top commit. Covers units NB6 (wiring into native up and restart) and NB7 (feature gate and docs) of native Compose build: support.

Native foreground up builds Compose build: services in the native runtime only when HACK_NATIVE_BUILDS=1 is set, along with the existing HACK_NATIVE_SHARED_SOURCE=1. Without it, a build service still refuses before any hook or VM effect. The refusal is now a fixed message that names the variable, instead of the general configuration refusal. Default behavior is otherwise unchanged until the host evidence below exists.

  • Pure admission (src/backends/native-project-builds.ts). It runs before hooks, VM or provider start.
    • Accepted forms: build: <context>, or a mapping of context, dockerfile, target and args.
    • args may be a mapping of literal strings or numbers, or a KEY=VALUE list.
    • Paths follow Compose: the context is relative to the Compose file, the Dockerfile to the context, and the context must stay inside the project. The runtime resolves both again without following symlinks.
    • These refuse: any $ interpolation, list items without = (host-variable inheritance), null values, other build keys (secrets, ssh, cache_*, platforms, network and the rest), remote contexts, and image together with build. Values never appear in messages.
    • Build args are not secrets (Docker parity). A build arg whose value equals a hack env secret of this project and environment refuses before any hook or VM effect. The refusal names only the argument; the comparison is in memory.
  • Active profiles only (Compose up semantics). Only build services in the selected profiles are built and pinned. An inactive build service keeps its build declaration, which the runtime review accepts for inactive services, so restore and restart need no image for it. Selecting its profile in a later fresh up builds it.
  • Build step.
    • It runs after runtime up and the after-runtime review, before image pinning. Each distinct build runs once through runtime build-image (feat(native): build Compose images in the guest engine (runtime build-image) #606), with output streamed to stderr. A final structured runtime error line is held back and returned as the closed error.
    • Every service with that build is pinned to the returned content ID, so review, readiness, receipts and restore treat it as an image service.
    • The request file is private: mode 0600, in a fresh 0700 directory, removed after use. The project root is passed canonical, as the runtime requires.
    • Cancellation sends SIGTERM so the runtime can stop its build client's process group, then SIGKILL after 20 seconds.
  • Rebuilds. HACK_NATIVE_REBUILD=1 asks for a rebuild. Otherwise the runtime reuses a verified image for the same build key.
  • Restore never builds. Restoring an unchanged retained run uses the retained content IDs. A build service without one refuses ("start fresh"). A retained run whose configuration changed selects no retained images, so it builds normally.
  • Restart never builds. hack restart uses the running or retained image for a build service, or refuses before stopping anything.
  • Other changes.
    • Image admission skips admitted build services; their bases are pinned by the runtime build.
    • prepareNativeProjectServices lets only admitted build services omit image.
    • The native candidate guide and the runtime README now describe the gated behavior. The doctor/unsupported_build table row is unchanged (see gaps).

Validation

  • bun run --cwd packages/cli typecheck: pass. ./node_modules/.bin/biome check on all changed files: pass, with no new complexity warnings.
  • Focused tests through the bounded runner (private HOME/TMPDIR, stubbed docker/launchctl/security): 243 pass, 0 fail, across 10 files. Files: native-project-builds, native-compose-backend-features-cli, native-project-start, native-project-restart, native-project-retained-images, native-project-retained-startup, native-config-validate-image-admission, native-project-input, prerelease-plan, native-candidate-authored-artifact. The new tests/native-project-builds.test.ts covers:
    • accepted forms and the full refusal matrix, with no values echoed;
    • gate on and off;
    • dedupe of identical builds, with the request file's contents, mode and removal;
    • retained images winning, restore with a missing image refusing without building, and changed retained configuration building;
    • rebuild policy;
    • streaming with the held-back runtime error;
    • cancellation via SIGTERM to a fake runtime.
  • One assertion changed. The control test native-compose-backend-features-cli expected the general refusal for a basic build. It now expects the new fixed NATIVE_BUILDS_DISABLED_REFUSAL: same code, still one closed line, still no Compose-backend hint.
  • bun run docs:prepare && bun run docs:check: pass. bun run privacy:check: ok. gitleaks: no leaks.
  • I did not run the full Bun suite locally because the host is loaded; hosted CI runs it.

Remaining gaps

  • No real VM evidence yet. End-to-end native up with a real build needs the host evidence listed in feat(native): build Compose images in the guest engine (runtime build-image) #606 (H1–H4) and feat(native): admit build storage, budget build cache and reclaim superseded build images #607. That means a prepared private candidate home with the buildx client, then a cold build, warm reuse, a Dockerfile edit, cancellation mid-build, and restore. None of this has been run.
  • amd64 is still refused. platform: linux/amd64 builds (Rosetta, opt-in per the Nov 5 decision) are not supported here.
  • Doctor not updated. The doctor classification (unsupported_build) still follows the Compose-backend import path, whose basic form excludes args. Making it gate-aware was left out, so doctor does not report args builds as supported.
  • Reclamation is not automatic. It is not yet run after a new graph is ready-observed; runtime reclaim-build-images is explicit.
  • No clean message for a removed retained image. A retained image that was removed from the engine surfaces as the later graph-admission image refusal, not a dedicated message.

Refs HACK-1270

🤖 Generated with Claude Code


Prove it works
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.

…ATIVE_BUILDS

Native foreground up can now build Compose `build:` services in the native
runtime when HACK_NATIVE_BUILDS=1 is set. Without it, a build service keeps
refusing before any hook or VM effect, now with a fixed message that names
the variable.

- Pure admission before hooks or VM start: `build: <context>` or a mapping
  of context, dockerfile, target and literal args (mapping of strings or
  numbers, or KEY=VALUE list). Compose path rules (context relative to the
  Compose file, Dockerfile relative to the context), inside the project.
  Interpolation, host-variable inheritance, null values, other build keys,
  remote contexts and image+build refuse; values are never shown.
- After runtime up, each distinct build runs once through runtime
  build-image with its output streamed to stderr; every service with that
  build is pinned to the returned content ID before image pinning and
  review. The request file is private (0600, removed after use).
  Cancellation sends SIGTERM so the runtime stops its build client group,
  then SIGKILL after a grace period.
- HACK_NATIVE_REBUILD=1 asks for a rebuild. Restore of an unchanged retained
  run uses retained images and never builds (a missing one refuses); hack
  restart never builds and refuses before stopping anything when a build
  service has no running or retained image.

Refs HACK-1270

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@roodboi

roodboi commented Nov 5, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@linear-code

linear-code Bot commented Nov 5, 2026

Copy link
Copy Markdown

HACK-1270

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-07T06:40:51.867936Z 7f42e32 Manual request
🔒 Security Review ✅ Completed 2026-11-07T06:45:01.799579Z 7f42e32 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f51e4262f0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: f51e4262f0

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

roodboi and others added 2 commits November 5, 2026 23:12
…image-builds-up

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Restart now removes a service's build declaration when it adopts the running or
retained content ID, matching startup's build pinning, so an unchanged project's
restart review equals the saved image-only plan instead of tripping the source
compatibility check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@roodboi

roodboi commented Nov 6, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 297df5a0ed

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/backends/native-project-builds.ts Resolved
@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 297df5a0ed

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

…image-builds-up

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@roodboi

roodboi commented Nov 6, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

Admitted build arguments now collect into a null-prototype dictionary, so an
argument named __proto__ is an own property that reaches the runtime request
and the build identity instead of invoking the inherited prototype setter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@roodboi

roodboi commented Nov 6, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1d42589481

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/backends/native-project-builds.ts Resolved
@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 1d42589481

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

…image-builds-up

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@roodboi

roodboi commented Nov 6, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Chef's kiss.

Reviewed commit: ab08fe53c5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: ab08fe53c5

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

roodboi and others added 2 commits November 5, 2026 23:48
…image-builds-up

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… build args

Native up now follows Compose up: only build services in the selected
profiles are built and pinned. An inactive build service keeps its build
declaration, which review accepts for inactive services, so restore and
restart need no image for it; selecting its profile in a later fresh up
builds it then.

Build args are not secrets, so a build arg whose value equals a hack env
secret of the project and environment now refuses before any hook or VM
effect, naming only the argument. The comparison is in memory and no value
is shown.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…image-builds-up

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@roodboi

roodboi commented Nov 6, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Another round soon, please!

Reviewed commit: 8dbafdc631

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

…image-builds-up

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@roodboi

roodboi commented Nov 6, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep it up!

Reviewed commit: 95ad760c05

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

…image-builds-up

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@roodboi

roodboi commented Nov 6, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Another round soon, please!

Reviewed commit: 1ed56b2e5e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 1ed56b2e5e

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

…image-builds-up

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@roodboi

roodboi commented Nov 6, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Nice work!

Reviewed commit: 8ec7460e99

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 8ec7460e99

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@roodboi

roodboi commented Nov 6, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Delightful!

Reviewed commit: 8ec7460e99

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 8ec7460e99

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

…usals (#628)

## What changes

**HACK-1925: build args were refused before the builds path ran.** With
`HACK_NATIVE_BUILDS=1`, the Compose-backend feature gate now admits
exactly the build fields native builds implement: `context`,
`dockerfile`, `target` and `args`. Both sides use one shared constant,
`NATIVE_BUILD_FIELDS`. Native build admission then reviews the values of
those fields. As a result:

- Literal build args build natively.
- A build arg whose value equals a managed `hack env` secret now reaches
the existing refusal. That refusal names the service and the arg, never
prints the value, and does not suggest the Compose backend (a Compose
build would record the value in the image history too).
- These still select the Compose backend: any other build field
(`secrets`, `ssh`, `cache_from`, `platforms`, …) and `image` together
with `build`. The refusal phrase names the native field set in this
case.
- Without native builds, today's basic-form classification and message
are unchanged.
- `hack doctor` applies the same classification, so doctor and `up`
agree.

**HACK-1927: build refusals now name the service.**
- Admission refusals: `cannot build service <name>: …`.
- The builds-disabled refusal (now
`nativeBuildsDisabledRefusal(service)`).
- The secret-arg refusal.
- Runtime failures from `runtime build-image`, wrapped in
`runPendingBuilds`. A refusal with a build source policy code
(`native_build_source`, `_dockerfile`, `_base_image`, `_argument`,
`_reserved_label`, `_image_volumes`) says that it is the native build
source policy and what to change. Other runtime failures name the
service(s) and keep their message. The native codes are kept, and the
code lookup uses only the map's own keys.
- The candidate guide now says the pinned network-tool APKs come from
Alpine v3.19 `main`/`aarch64`, and that v3.20 has files with the same
names but different bytes.

## Validation

- Focused tests (bounded runner, private HOME/TMPDIR, stubbed
`docker`/`launchctl`/`security`):
- `tests/native-project-builds.test.ts`,
`tests/native-compose-backend-features.test.ts`,
`tests/native-compose-backend-features-cli.test.ts`: 64 pass, 0 fail.
- Related suites `native-project-restart`, `native-project-start`,
`compose-startup-budget`, `doctor-json`, `doctor-command`: 157 pass, 0
fail.
- New regression tests (synthetic values only):
- Gate with builds enabled: implemented fields pass; unimplemented
fields and image+build still refuse; disabled behavior is unchanged; the
phrase follows the flag.
  - CLI with `HACK_NATIVE_BUILDS=1`:
    - A build arg passes the gate and reaches native start.
- A build arg equal to a managed secret (set with `setProjectEnvValue`)
refuses with one closed line naming the service and the arg. It does not
show the value and does not mention `HACK_RUNTIME_BACKEND=compose`. The
only runtime call is `check-project-share`.
    - An unimplemented field still gets the Compose-backend line.
  - Service-named admission refusals and the disabled refusal.
- Runtime source-policy refusals, other runtime failures, and an
inherited property name as a native code.
- Checks:
- `bun run --cwd packages/cli typecheck`: the only error is in
`tests/fixtures/atomic-write-foreign-owner-worker.ts`. That file is
unchanged, and the same error appears on the base head 8ec7460.
  - `bun run --cwd packages/cli check`: rc 0.
  - Biome on the changed files: clean.
  - `bun run docs:prepare && bun run docs:check`: pass.
- `gitleaks protect --staged` and `gitleaks detect` over the range: no
leaks.
  - Normal hooks.
- Host check on an M5 VM. Isolated HOME,
`HACK_DAEMON_AUTOSTART_DISABLE=1`, a fresh native home per fixture, and
a bundle made of this branch's compiled CLI plus the base `hack-native`.
The two `hack-native` files are byte-identical; this PR changes no Rust.
- Fixture with a literal non-secret build arg: built in the VM, the
service reached `ready-observed`, then stopped cleanly.
- Fixture whose build arg equals a managed secret: refused with `cannot
build service secretsvc: build arg GREETING equals a hack env secret
value …`. The value is absent from the output, no Compose-backend
suggestion is made, and the runtime stays `uninitialized`.
- Fixture whose Dockerfile uses a non-Docker-Hub base: `cannot build
service deniedsvc: the native build source policy refused it. Dockerfile
line 1: … Use public Docker Hub images in the Dockerfile's FROM and COPY
--from. No image was adopted.`
- The full `bun test` suite was not run locally, as instructed for this
unit. Hosted CI is the full-suite gate.

## Remaining gaps

- The gate runs before managed env is loaded, so it cannot see secret
values. Suppose a project has a Compose-only feature such as an external
network, plus a build arg that carries a secret. It still gets the
generic "use the Compose backend" line. The secret check only runs on
the native builds path.
- Value-level build problems such as a remote context or an absolute
path no longer suggest the Compose backend when builds are enabled.
Native build admission refuses them instead, naming the service.

Refs HACK-1925
Refs HACK-1927

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- codesmith:footer -->
---
<a
href="https://backend.blacksmith.sh/track/run-proof?expires=1796584076&installation_model_id=17053&pr_number=628&ref=codesmith_pr_footer&repository=hack-dance%2Fhack&return_to=https%3A%2F%2Fgithub.com%2Fhack-dance%2Fhack%2Fpull%2F628&variant=prove_it_works&signature=9ee8e41280681ba67bf53893e0353bfe6e1dc0990c6e111c46d3adf7646095db"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/proof-prove-it-works-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/proof-prove-it-works-light.svg"><img
alt="Prove it works"
src="https://pr-comments-assets.blacksmith.sh/codesmith/proof-prove-it-works-dark-3x.png"
width="129" height="28"></picture></a>
<sup><a
href="https://app.blacksmith.sh/hack-dance/codesmith/hack/pr/628?autoLogin=true&ref=codesmith_pr_footer">Open
in [code]smith</a> · Need help on this PR? Tag
<code>@codesmith-bot</code> with what you need.</sup>

<!-- codesmith:autofix:disabled -->
<!-- /codesmith:footer -->

Co-authored-by: Dimitri Kennedy <344842+roodboi@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@roodboi

roodboi commented Nov 7, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: 7f42e328d9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 7f42e328d9

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

roodboi added a commit that referenced this pull request Nov 7, 2026
, #612, #628, #629, #630) (#639)

## What this is

Merge train batch 6 into `next`: the native image builds stack and its
fixes, as one batch. Builds stay off by default: they run only with
`HACK_NATIVE_BUILDS=1`, which native `up`, restart and doctor all check.
Each component's reviewed head is merged with `git merge --no-ff`, in
stack order. Integration conflicts are resolved in the batch's merge
commits, described below. Hosted CI on this branch is the full-suite
gate for the combined result.

| PR | Title | Linear | Head included | Review |
| --- | --- | --- | --- | --- |
| #583 | feat(native): pin a BuildKit client and scan Dockerfile image
references | HACK-1270 | `f21d5a04` | Codex code + security: no
findings; 0 open threads |
| #606 | feat(native): build Compose images in the guest engine (runtime
build-image) | HACK-1270 | `460ddff2` | Codex code + security: no
findings; 0 open threads |
| #607 | feat(native): admit build storage, budget build cache and
reclaim superseded build images | HACK-1270 | `9f33a1d0` | Codex code +
security: no findings; 0 open threads |
| #612 | feat(native): build Compose build services in native up behind
HACK_NATIVE_BUILDS | HACK-1270 | `7f42e328` | Codex clean at `8ec7460e`;
`7f42e328` adds #628's squash (re-review requested) |
| #628 | fix(native): admit native build fields and name services in
build refusals | HACK-1925 | `f07ea583` | Codex code + security clean;
already squashed into #612's branch |
| #629 | fix(native): keep the VM responsive during image builds and
stop a silent guest | HACK-1924 | `a0e3e797` | Codex code + security: no
findings; 0 open threads |
| #630 | fix(native): restore a sourceless graph after its project files
were touched | HACK-1914 | `a93db842` | Codex clean at `009989c7`;
`a93db842` only merges #629 into it (re-review requested) |

## Security properties in the merged code

- **Build arguments:** they reach the BuildKit client only through a
private 0600 bake definition, never its environment. The client
environment is cleared to an allowlist. Names must be plain identifiers,
and BuildKit-interpreted names such as `BUILDKIT_*`, `BUILDX_*` and
`SOURCE_DATE_EPOCH` are refused. A build argument equal to a managed
secret value is refused without echoing the value. Build arguments are
not secrets, matching Docker.
- **Source policy:** a source policy from `build_policy::document`, set
through `EXPERIMENTAL_BUILDKIT_SOURCE_POLICY` in a private file, applies
to every build. It allows only the scanner's digest-pinned base images
and denies other images, `oci-layout`, `http`, `https`, `git` and blob
sources. Pinned bases whose config has `OnBuild` triggers are refused.
- **Dockerfile scanner:**
- remote `ADD` sources are refused, including the JSON form, multiple
sources and variables;
- JSON-form arguments are read as BuildKit reads them, and a
lenient-decode differential fails closed;
- heredocs are recognized as BuildKit's lexer does, including whitespace
after `<<`;
  - a stage named `scratch` is refused;
  - `ARG` names must be plain identifiers;
  - platform arguments must resolve to `linux/arm64`;
  - expanded values are size-bounded.
- **Build output:** forwarded output is sanitized and then redacted,
including Go-quoted and JSON-escaped forms and values split across a
line cut. It is bounded by size.

## Integration changes

- **#606 with #605 / #609:** `resolve_build_base` runs on #605's guarded
registry client, so the resolver and address policy, origin-bound
authentication and the realm rules apply. It uses #609's native platform
selection, so builds stay Docker Hub and linux/arm64 only. The older
Docker Hub-only fetch helpers are dropped.
- **#606 / #607 with #605 / #609 / #615:** the `build-image` and
`reclaim-build-images` commands sit beside the image-policy and
emulation options. The build error helpers take `impl
Into<ErrorMessage>`.
- **#607:** the native-build-retention TLA+ contract is registered
beside the restart-policy, pool-emulation and multi-root contracts. Its
model-coverage row now says an orphaned build client keeps the fence and
per-key lock until it exits (`9f33a1d0`).
- **#612 with batch 5:**
- The builds-enabled classification flows through `classifyAdapted`, the
Compose-backend refusal and doctor.
- With the gate off, native `up` refuses a build with a message that
names `HACK_NATIVE_BUILDS`, so doctor's basic-build advice names it too;
one test expectation changed to match.
- Startup and restart keep the dependency-file selection, host aliases,
emulation policy and the inactive-profile skip alongside the build
services.
- **New (#609 x #612):** a build service whose adaptation selects amd64
emulation is refused before any effect, because native builds are
linux/arm64 only. `prefer-native` passes, and a test covers it.
- **#629:** the socket cleanup after a clean stop is kept inside #629's
new guest stop. #629's two flaky relay tests are fixed on its branch
(`a0e3e797`): each test gets its own fixture root, and EINVAL from
`set_read_timeout` after the peer closes is accepted.
- **`next` merge:** the last merge brings in Kit's CI shard and SIGKILL
harness changes (#624, #627). The commit hook formatted
`tests/native-compose-generation.test.ts` with Biome, a whitespace-only
change to that Kit file.

## Validation on this branch (`6337e0ed`)

- Clean CLI typecheck: pass. Biome on the 20 changed files: no errors.
- `RUSTUP_TOOLCHAIN=1.97.1 bun run check:local`: pass. All-features
clippy `-D warnings` (Zig 0.15.2): pass.
- Cargo `--lib`: 1346 pass. `--features native-config-plan`
`provider::graph`: 673 pass. Contracts: `project_contract` 66,
`compose_fields_contract` 10, `interpolation_budget_contract` 1,
`local_contract` 14.
- `bun run test:models` (TLA+ 1.7.4): exit 0, 172 controls verified.
- Focused bun tests, bounded runner, the changed test files: 242 pass, 0
fail.
- `docs:prepare` + `docs:check`, `privacy:check`, gitleaks over
`origin/next..HEAD`: pass.

Host evidence: 11 of 11 builds passed on an M5 host with the relay
(#629). Still open: the source-policy host check (a pinned build
succeeds, and a base trigger that pulls an unpinned image or fetches
https fails with "denied by policy") and the bake `--allow fs.read` /
metadata shape on the pinned buildx 0.34.1. Both are listed in #606.

After this merges, each component PR is closed with a link to the merge
commit.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- codesmith:footer -->
---
<a
href="https://backend.blacksmith.sh/track/run-proof?expires=1796625833&installation_model_id=17053&pr_number=639&ref=codesmith_pr_footer&repository=hack-dance%2Fhack&return_to=https%3A%2F%2Fgithub.com%2Fhack-dance%2Fhack%2Fpull%2F639&variant=see_it_in_action&signature=c3ba624f6f34813ba26773c5b4c3caf941bd59515e8c3016c92df8f0e2a6048f"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/proof-see-it-in-action-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/proof-see-it-in-action-light.svg"><img
alt="See it in action"
src="https://pr-comments-assets.blacksmith.sh/codesmith/proof-see-it-in-action-dark-3x.png"
width="132" height="28"></picture></a>
<sup><a
href="https://app.blacksmith.sh/hack-dance/codesmith/hack/pr/639?autoLogin=true&ref=codesmith_pr_footer">Open
in [code]smith</a> · Need help on this PR? Tag
<code>@codesmith-bot</code> with what you need.</sup>

<!-- codesmith:autofix:disabled -->
<!-- /codesmith:footer -->

---------

Co-authored-by: Dimitri Kennedy <344842+roodboi@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@roodboi

roodboi commented Nov 7, 2026

Copy link
Copy Markdown
Contributor Author

Merged into next through the train batch PR #639 (squash commit e59fcc2). This PR's reviewed head 7f42e328d9b3f95060a71a5db0d22778cb0c5c2f was included. #639 describes the integration resolutions and the batch security fixes: Go-style image config key reading, non-ASCII key refusal, the build base size bound (unpacked size tracked in HACK-1945), build-base descriptor validation and case-insensitive stage names. Closing as merged by batch; the branch is kept.

🤖 Addressed by Claude Code

@roodboi roodboi closed this Nov 7, 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