Skip to content

Release v1.3.0: pre-accepted agent prompts and golden build fixes - #10

Merged
foobarto merged 5 commits into
mainfrom
release/v1.3.0
Aug 16, 2026
Merged

Release v1.3.0: pre-accepted agent prompts and golden build fixes#10
foobarto merged 5 commits into
mainfrom
release/v1.3.0

Conversation

@foobarto

Copy link
Copy Markdown
Owner

Pre-accepts the AI CLIs' first-run prompts, and fixes the golden build that made
devbox build unusable on the default image.

Agent first-run prompts

Starting a Devbox for a folder is already the trust decision, and the VM — not a
dialog inside the agent — is the boundary. Asking again trains people to click
through prompts, which devalues them everywhere they do matter. Every run now
seeds, for the mounted directory only:

prompt state written
Claude onboarding hasCompletedOnboarding
Claude folder trust projects."DIR".hasTrustDialogAccepted
Claude custom API key customApiKeyResponses.approved (last 20 chars of the key)
Codex folder trust [projects."DIR"] trust_level = "trusted"
Codex sign-in picker api-key-mode auth.json holding the existing dummy routing marker

The key approval comes from whatever ANTHROPIC_API_KEY the guest login shell
actually resolves, so --api-keys and a custom proxy-env are covered, not just
the --proxy marker. Both CLIs' config homes are resolved rather than assumed,
since CLAUDE_CONFIG_DIR and CODEX_HOME relocate them.

Never $HOME, never --mount paths. Answers already on record are kept, and a
real Codex auth.json from --with-creds is never overwritten. Seeding failures
warn rather than fail a box that is otherwise up.

Trade-off: a repository's own .claude/settings.json and hooks now run
unprompted. Documented in docs/agent-capabilities-security.md, including how it
interacts with the persistent session store.

Golden build fixes

devbox build --image ubuntu-24.04 — the default — built a complete golden and
then deleted it, every time. Verification probed bwrap and pasta in one command
and treated any failure as fatal, but Ubuntu 24.04 ships passt
0.0~git20240220, which predates pasta --splice-only, and noble has no
backport. The check could never pass.

  • Probe the two separately. bwrap stays fatal and now prints the command to
    reproduce a failure; a missing --splice-only warns and keeps the golden.
  • Build passt 2026_07_28.f8df3f1 from upstream git when the distro's is older,
    so the capability is real rather than reported missing. Pinned by tag and
    asserted against the commit it must resolve to, because passt.top publishes its
    prebuilt binaries with no checksums or signatures.
  • Install the bwrap AppArmor profile whenever the profile and parser exist,
    instead of testing apparmor_restrict_unprivileged_userns during provisioning.
    That sysctl is applied by the apparmor package's own units and races the
    package upgrade in the same apt run — observed producing two goldens from one
    YAML where only one got the profile.

e2e harness

run_session capped every session at 600s while a first golden build is allowed
90 minutes, so the suite silently required a pre-existing golden and, on a fresh
machine, orphaned a half-provisioned one. It now builds the golden up front
(idempotent) and its per-session cap is 900s, overridable with
DEVBOX_E2E_SESSION_TIMEOUT.

Verification

110 bats + 38 python tests, make lint clean. Full make e2e run on a separate
machine against this branch, including new guest-side assertions that trust is
seeded for the project directory and not for $HOME or --mount paths:

[e2e] ensure the ubuntu-24.04 golden exists (untimed; may take many minutes)
[devbox] Golden devbox-golden-ubuntu-24-04 already exists (use --force to rebuild).
[e2e] reject manifest consent without creating a VM
[e2e] manifest approval, image, package, start, mount, copy, SSH signing, and OAuth proxy
[e2e] agent first-run prompts are pre-accepted for the mounted directory only
trust-seeding OK
[e2e] -a copies non-secret agent config without copying OAuth credentials
[e2e] API keys and --with-creds on the same retained, disposable VM
[e2e] --no-auth removes every Devbox-managed auth profile
[e2e] PASS

devbox build on that machine now ends Golden ready with
ok pasta /usr/local/bin/pasta and no splice warning; the same command
previously ended removing unusable devbox-golden-ubuntu-24-04.

Caveat

The AppArmor profile now loads on any Debian/Ubuntu image carrying
apparmor-profiles, including ones where unprivileged userns was never
restricted, where it newly confines bwrap. It should be inert by design, but only
the Ubuntu path has been exercised.

`devbox build --image ubuntu-24.04` — the default image — deleted every golden
it built. Verification probed bwrap and pasta in one command and treated any
failure as fatal, but Ubuntu 24.04 carries passt 0.0~git20240220, which predates
`pasta --splice-only`, and noble has no backport. The capability is genuinely
absent and cannot be installed from the archive, so the check could never pass
and the build could never succeed.

Probe the two separately. bwrap is the isolation primitive and every supported
image can provide it, so an unusable bwrap still fails the build — now with the
command to reproduce it. A passt without `--splice-only` warns and keeps the
golden: only Stado's proxy-only guest networking is affected, and the rest of
the toolchain is already verified.

Also drop the apparmor_restrict_unprivileged_userns test from the guard that
installs the bwrap AppArmor profile. That sysctl is applied by the apparmor
package's own units, so its value during provisioning races the package upgrade
in the same apt run — observed building two goldens from one YAML where only
one got the profile. The one that missed it failed the bwrap probe later, and
that was indistinguishable from an unsupported kernel. Installing the profile is
harmless when the restriction is off and required when it is on, so key it only
on the profile and parser existing, and let a parser failure leave the file on
disk for apparmor.service rather than aborting provisioning under set -e.
Rather than reporting `pasta --splice-only` as unavailable on images whose
archive predates it, provide it. Ubuntu 24.04 carries passt 0.0~git20240220 and
noble has no backport, so Stado's proxy-only sandbox networking was simply
absent there.

Provisioning now builds passt 2026_07_28.f8df3f1 from the upstream git when the
distro's pasta lacks the option, and leaves a new-enough one alone. From source
at a pinned tag, verified against the commit that tag must resolve to, because
passt.top's prebuilt binaries are published without checksums or signatures.
passt is plain C needing nothing beyond the build-essential already installed.

A build failure still only warns: the golden's whole AI toolchain is otherwise
verified, and deleting it over one degraded capability is the regression this
branch exists to fix. The verification message now names the build as the cause
and gives the rebuild command.
`run_session` capped every Devbox session at 600s while a first-time golden
build is allowed 90 minutes, so the suite implicitly required a golden to
already exist. On a fresh machine it timed out mid-build, reported "devbox
session timed out", and left a half-provisioned golden running — the orphan
case bin/devbox's own comments warn about.

Build the golden up front, before any timed session; it is idempotent, so an
existing verified golden is reused. Raise the per-session cap to 900s and make
it overridable with DEVBOX_E2E_SESSION_TIMEOUT for slow machines.
Starting a devbox for a directory is already the trust decision: the operator
named the folder, and the VM boundary — not a dialog inside the agent — is what
contains the result. Asking again trained people to click through prompts, which
devalues them everywhere they do matter.

Seed the five gates for the mounted project directory on every run:

  claude  hasCompletedOnboarding, projects."DIR".hasTrustDialogAccepted, and
          the custom-API-key approval, which Claude Code stores as the last 20
          characters of the key.
  codex   [projects."DIR"] trust_level = "trusted", and an api-key-mode
          auth.json so the sign-in picker is skipped. Its value is the same
          dummy routing marker already exported as OPENAI_API_KEY, not a
          credential.

The key approval is taken from whatever the guest login shell really resolves,
so --api-keys and a custom proxy-env template are covered, not just the
--proxy marker. Both CLIs' config homes are resolved rather than assumed, since
CLAUDE_CONFIG_DIR and CODEX_HOME relocate them.

Scoped to the single mounted directory: never $HOME, and never the read-only
paths added with --mount. Answers already on record are left alone, and a real
auth.json copied in with --with-creds is never overwritten. Seeding failures
warn rather than fail a box that is otherwise up.

The trade — a repository's own .claude/settings.json and hooks now run
unprompted — is documented in docs/agent-capabilities-security.md alongside the
session-store persistence it interacts with.
Pre-accepted agent first-run prompts, plus the golden-build fixes that made
`devbox build` usable on the default image again.
Copilot AI lite review requested due to automatic review settings August 16, 2026 11:41
@foobarto
foobarto merged commit 7c58f7a into main Aug 16, 2026
1 check passed
@foobarto
foobarto deleted the release/v1.3.0 branch August 16, 2026 11:41

Copilot AI 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.

Pull request overview

This PR releases v1.3.0 by (1) pre-seeding Claude Code and Codex “first-run / trust” prompt state for the mounted project directory, and (2) fixing golden-image provisioning/verification so devbox build --image ubuntu-24.04 no longer deletes a freshly-built golden due to an unmeetable pasta --splice-only requirement. It also updates the e2e harness to build the golden up front and increases/overrides the per-session timeout.

Changes:

  • Add guest-side trust seeding for Claude/Codex config (scoped to the mounted project dir) and document the security trade-off.
  • Fix golden provisioning/verification by separating bwrap vs pasta probes, warning (not failing) on missing --splice-only, and building a pinned passt when needed.
  • Update e2e to build the golden before timed sessions and add assertions around trust-seeding scope.

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated no comments.

Show a summary per file
File Description
VERSION Bumps version to 1.3.0.
bin/devbox Implements trust seeding; adjusts golden provisioning (AppArmor profile install + pinned passt build) and verification behavior.
test/e2e.sh Builds golden up front; session timeout becomes configurable; adds guest assertions for trust seeding scope.
test/devbox.bats Adds unit coverage for the new golden verification/provisioning logic and trust-seeding helpers.
README.md Documents pre-accepted agent first-run prompts and associated trade-off.
docs/index.html Updates displayed current version to v1.3.0.
docs/agent-capabilities-security.md Documents the always-on pre-accepted prompt behavior and security implications.
CHANGELOG.md Adds v1.3.0 release notes covering the new behavior and fixes.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

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.

2 participants