Repository navigation
feat(kits)!: adopt pinned agent and capability kits - #474
Conversation
|
Support for option 3. The login.gov data team kit already lives in this model: since patterns#395 we consume the generic devenv image and install team tools through kit startup steps, so an agent-less base plus an agent kit is the next step rather than a change of course. Some points from that experience, mostly aimed at the open questions. Agent install: pin by content, derive the image from the kit. The cost of installing the agent at create is once per sandbox (acq already skips on Activation: acq should not run it. Create-time vs run-time needs a stated rule, and Supervision: two models are now in flight. This ADR asks whether devenv's process supervision replaces ad hoc loops; #472 runs services outside the sandbox as gateways; goose-server runs an in-guest supervisor via usai-provider: split facts from rendering. The provider facts (endpoint, key env var, model catalog) are one thing; the config format is each agent's. One agent-aware kit that emits every agent's format is the coupling this ADR removes from acq, relocated into a kit. Have usai-provider export the facts and each agent kit render them. Related: acq should never merge agent config files; the team kit relies on OpenCode's own project-layer deep-merge for its permission gate, and that semantic belongs to the agent. Bring-your-own image contract must say where the Nix store lives. The team kit's Egress merge: union only, and visible. "Later wins" is right for env and files and wrong for network. A personal kit widening egress without a trace is the concrete AC-6 case the ADR gestures at. Team impact if adopted is small: |
|
Great feedback, thank you.
I've pretty much already settled on leveraging podman-compose for the host side since it's cross-platform between Mac/Linux/Windows, already incorporates dependencies, health-checks, restart policies, etc. (I briefly considered also using devenv for the host side, but then realized that while it works in Mac and Linux, it does not work in Windows.) |
Records the review outcomes for the questions the ADR left open: a content-pinned agent install contract; human-owned activation with an explicit ACQ_ env opt-in for non-interactive use; a create-time vs run-time rule plus a max-merged resources: field; the native devenv process manager as the general in-guest supervisor (host side uses podman-compose); provider facts exported by usai-provider and rendered by each agent kit; a /nix-anchored bring-your-own-image contract; union-only visible egress; a personal kit plus a neutral ~/.rc.d hook with documented use-cases; built-in-bundle-only agent kit inference; an optional OCI engine kit; declared privileged capabilities under passwordless sudo; SecretSpec confined to in-sandbox usage; and the stability contract to preserve during migration. Leaves three follow-ups open: merge semantics beyond egress, the exact minimum image contract, and migration sequencing. Refs: #473, #474
|
Pushed commits to this branch. They renumber the ADR to 0030 (0028 and 0029 are claimed by other in-flight work), add a Devenv Baseline and Upstream Impact section recording that the patterns devenv image currently ships devenv 1.11.2 on A scoped follow-up for updating the devenv image itself based on research into 2.x is tracked at GSA-TTS/agentic-coding-patterns#418. |
|
Update pushed: What changed:
Verification:
Also updated the PR summary with a fully qualified |
Reviewer orientationAI-assisted (OpenCode). Independently re-verified at head Deliberately dormant — not oversightsTwo things a reviewer will reasonably flag as incomplete are intentional, because the producing artifacts are not in the pinned patterns release:
OCI is live but opt-in, default-offv1.10.0 contains the Unset means byte-identical behavior to today. ADR-0030's open questions are tracked, not unresolved
Review focus
Verification (my independent re-run at
|
|
Reviewed at Thanks for the orientation comment — it made this reviewable, and it held up: I checked all five of your numbered claims and four verify cleanly. Two findings, both in the same family: a gate that fails open rather than closed. Neither is live at the current pin, which is why I'd take them as follow-ups rather than a block, but the second one activates on the next pin bump and that is exactly when you want it loud.
Your five claims, verified:
Below the bar:
Validation. Ran: full suite Not run, and worth naming explicitly given the size of this change. I did not run the new and modified tests against the merge-base Also not run: Verdict: comment, not request-changes. Nothing here is live-broken at the current pin, your dormancy analysis is accurate, and the merge trap you flagged is genuinely resolved. I would want finding 2 fixed before the pin bump that lands Before merging I would want a human to run Assisted-by: OpenCode [gpt_5_5_default_v2] change-review |
|
Closing the base-comparison gap I flagged in my previous comment, since an open question like that reads as doubt and it should not sit there unresolved. I copied the three new test files plus That includes both So those tests assert the normalization itself, not merely the absence of a value. My concern was wrong and I withdraw it. On the 9 that do pass at base: they are mostly The other two gaps from that comment stand unchanged: Verdict unchanged: comment, not request-changes. Assisted-by: OpenCode [gpt_5_5_default_v2] change-review |
Co-authored-by: OpenCode [gpt-5.5] <bret.mogilefsky@gsa.gov>
Co-authored-by: OpenCode [gpt-5.5] <bret.mogilefsky@gsa.gov>
…uestions Refs: #533 Co-authored-by: OpenCode [gpt-5.5] <bret.mogilefsky@gsa.gov>
Co-authored-by: OpenCode [gpt-5.5] <bret.mogilefsky@gsa.gov>
#500's generic opt-in catalog (ADR-0031) supersedes the OCI-specific gate. The oci-engine kit will be added to ACQ_OPTIN_KIT_NAMES in the follow-up tracked by #505. The msb adapter auto-install path is unchanged by this commit; retiring that path remains part of the follow-up. Co-authored-by: OpenCode [gpt-5.5] <bret.mogilefsky@gsa.gov>
…back Co-authored-by: OpenCode [gpt-5.5] <bret.mogilefsky@gsa.gov>
Replace markdownlint-cli2 with markdownlint-cli because the current cli2 dependency graph depends on braces 3.0.3, which has no fixed release for GHSA-vfj7-8cjw-p6xm. Keep the same markdown rules and exclusions through markdownlint config and ignore files, and install the pinned linter dependencies before the pre-commit workflow invokes the local hook. Refs: #505 Co-authored-by: OpenCode [gpt-5.5] <bret.mogilefsky@gsa.gov>
verify-backends exports a hermetic XDG_CONFIG_HOME so a run cannot read the user's real acq config. _acq_config_file resolves under that, so acq never finds a config file and EVERY verify run looks like a first run to maybe_first_run_configure, which blocks on an interactive confirm. The symptom is a verifier that appears to hang: run_acq captures output by default, so the create step emits nothing and never returns while acq waits on stdin. create_time_kit_picker is a second gate with the same cause. Export ACQ_NO_PROMPT=1 alongside the other hermetic-state settings. That forces the non-interactive path for both config widgets (and for acq configure, which then reports "configuration unchanged" and makes no writes), so the configured defaults apply — which is what a verifier wants. Secret VALUE reads are gated on [ -t 0 ] rather than on the prompt helper, so seeding is unaffected. The underlying gap is on main: the first-run prompt arrived with #500 and the verifier was never taught to opt out. Fixed here because this is the PR whose own ADR-0030 live verification gate is blocked by it. Co-authored-by: OpenCode [claude-opus-5] <bret.mogilefsky@gsa.gov>
Step 2 of seed_usai_secret decides whether to create the global sbx custom secret by grepping the whole `sbx secret ls` listing for USAI_API_KEY. That also matches a SANDBOX-SCOPED row, including one left behind for a sandbox that no longer exists. When such a row is present the global row is never created, step 3's `acq secret has -g usai` returns 1, and every sbx check skips with "verifier did not seed sandbox-scoped USAi key". Observed live against sbx v0.46.0 with a stale row: CUSTOM SECRETS SCOPE TARGETS ENV PLACEHOLDER nonexistent api.gsa.usai.gov USAI_API_KEY sbx-cs-naRspB5KyWAPCxB1 The bare grep matches that row, so the seed is skipped and the run reports 1 passed / 2 skipped instead of exercising the kit contract. Match only a row whose SCOPE column is "(global)", which is the scope step 3 asks about. A genuine pre-existing global row still no-ops as before. Co-authored-by: OpenCode [claude-opus-5] <bret.mogilefsky@gsa.gov>
191d501 to
4c5812a
Compare
92ce87f to
058c1af
Compare
|
Release-note / release-please warning for merge: Please preserve the breaking-change and migration details in the squash commit body. release-please reads the Conventional Commit on Suggested squash commit message: |
|
I reverified on the host just in case... All tests pass. Merging! |
## Summary Corrective PR after #474 was squash-merged with release notes that describe the full collapsed stack, but the final branch contents only included the lower #474 layer. This lands the implementation that the merged #474 commit message already announces as breaking: - add `oci-engine` to the opt-in kit catalog; - retire MSB adapter-owned OCI/podman auto-install and unconditional device grants; - pin `PATTERNS_KIT_REF` to agentic-coding-patterns v1.12.0 (`56d1f5f49ef928f50e61aa64a93d618b3d21c415`); - remove the native MSB OpenCode npm fallback so OpenCode is supplied by the pinned `opencode` agent kit. ## Why This Is Separate The merge commit for #474 already contains the correct release-please `BREAKING CHANGE:` footers and migration notes, but the code still had the old v1.10.0 patterns pin plus the old adapter-owned OCI/OpenCode paths. This PR makes shipped behavior match the already-merged release notes before the release PR is merged. ## Verification - `bash -n acq acq.backends/*.sh scripts/test-acq-lib.sh scripts/test-acq-bats scripts/fix-exec-bits test/bats/helper.bash scripts/verify-backends` passed. - `./scripts/fix-exec-bits --check` passed. - `git diff --check` passed. - `npm run lint:md` passed. - `npm audit --prefix .github/linters --audit-level=high` passed. - ShellCheck batch passed. - Focused Bats passed: `TMPDIR="$PWD/tmp" ./scripts/test-acq-bats test/bats/36-agent-catalog.bats test/bats/50-kit-list-completeness.bats test/bats/72-msb-agent-user.bats test/bats/95-kit-ref-persistence.bats test/bats/135-configure.bats test/bats/140-opencode-migration-gate.bats` (`109 ok`). ## Rollback Revert this PR to restore the implementation currently on `main`; note that doing so would again make the code disagree with the already-merged #474 breaking-change release notes. ## Security Impact Positive security impact consistent with #474's release notes: OCI device exposure is opt-in through the `oci-engine` kit, and OpenCode installation comes from the pinned patterns release instead of native npm fallback. AI-assisted. Human review required.
🤖 I have created a release *beep* *boop* --- ## [4.0.0](v3.1.0...v4.0.0) (2026-10-06) ### ⚠ BREAKING CHANGES * **kits:** acq no longer installs podman/OCI tooling by default. Users who need docker, docker compose, or rootless podman when the base image doesn't provide it must opt into the oci-engine kit with `acq configure`, `--kit`, or `ACQ_EXTRA_KITS`. * **kits:** acq no longer performs native OpenCode npm fallback installation. OpenCode is supplied by the pinned opencode agent kit from agentic-coding-patterns v1.12.0, currently delivering OpenCode v2.0.22. If the kit is unavailable or invalid, acq fails closed instead of installing opencode-ai from npm. * **kits:** existing acq sandboxes with adapter-installed podman are not migrated in place. Recreate affected sandboxes or add the oci-engine kit before relying on OCI behavior after stop/start. ### Features * **acq:** choose the host port per sandbox, and let --publish pin it ([#526](#526)) ([410f332](410f332)) * **acq:** export ACQ_WORKSPACE and ACQ_CLONE into the guest on both backends ([#457](#457)) ([e0b9a3b](e0b9a3b)) * **acq:** interactive `acq configure` UI for extra kits + token-scoping defaults ([#500](#500)) ([13d9d3a](13d9d3a)) * **kits:** adopt pinned agent and capability kits ([#474](#474)) ([6a67063](6a67063)) * **secrets:** add Windows-native DPAPI secret backend ([#464](#464)) ([907f404](907f404)) * **windows:** add acq preview install path ([#463](#463)) ([d6d76f4](d6d76f4)) ### Bug Fixes * **acq:** use sandbox workspace for github scoping ([#476](#476)) ([1610835](1610835)) * **ci:** bump js-yaml to 4.3.2 to clear a high-severity CPU-DoS advisory ([#454](#454)) ([3217b49](3217b49)) * **ci:** bump smol-toml to 1.7.1 to clear an infinite-loop DoS advisory ([#459](#459)) ([c2291bf](c2291bf)) * **ci:** centralize markdownlint coverage ([#548](#548)) ([a27c31e](a27c31e)) * **ci:** pin markdownlint-cli2 once, clear GHSA-253c, unify file selection ([#527](#527)) ([e712685](e712685)) * **ci:** unblock unrelated PRs from the bash32 required-check deadlock ([#513](#513)) ([187aa57](187aa57)) * **install:** keep curl | sh stdin intact and tap msb formula first ([#462](#462)) ([c808d74](c808d74)) * **install:** trust the microsandbox-acq dependency before brew install ([#534](#534)) ([ffac0fa](ffac0fa)) * **kits:** land collapsed kit stack implementation ([#549](#549)) ([bcd5b9c](bcd5b9c)) * **msb:** allow Playwright browser downloads ([#477](#477)) ([0c399c5](0c399c5)) * **msb:** block unsafe 0.7 migration versions ([#510](#510)) ([3634046](3634046)) * **msb:** carry every origin URL, keep the scratch private, fail closed on a copy miss ([#488](#488)) ([babcd49](babcd49)) * **msb:** carry the source checkout's git identity into the --clone scratch ([#443](#443)) ([320d784](320d784)) * **msb:** follow the host resolvers and disable DNS rebind protection in the guest ([#444](#444)) ([d2f4bdc](d2f4bdc)) * **msb:** point the --clone scratch's origin at the source checkout's remote ([#455](#455)) ([7f48b94](7f48b94)) * **msb:** refresh ssh authorization for port publish ([#446](#446)) ([72a6bd5](72a6bd5)) * **msb:** session parity for exec/attach/shell (cwd, terminal identity, login shell) ([#427](#427)) ([6261eda](6261eda)) * **msb:** skip the recursive home chown when the image baked the agent user ([#432](#432)) ([d8f66a4](d8f66a4)) * **msb:** thread the merged kit env onto kit lifecycle commands ([#519](#519)) ([2248a92](2248a92)) * **msb:** translate kit wildcard network rules ([#451](#451)) ([e22bbc3](e22bbc3)) * **msb:** verify post-hoc port forward listener ([#530](#530)) ([8ca50e1](8ca50e1)) * **msb:** warn on broadened kit wildcard rules ([#460](#460)) ([6ded3ce](6ded3ce)) * **msb:** warn when ssh-agent route is missing ([#448](#448)) ([3a767a4](3a767a4)) * **sbx:** emit valid setup.install shape for the git-identity mixin ([#492](#492)) ([8e6160c](8e6160c)) * **sbx:** raise the version floor to 0.39.0, where sbx create --env first exists ([#491](#491)) ([30f9ecf](30f9ecf)) * **sbx:** wait for startup barrier before attach ([#512](#512)) ([33c83c5](33c83c5)) * **secret:** reject multiline test secret values ([#447](#447)) ([f2da950](f2da950)) * **secrets:** propagate rotation across backends ([#509](#509)) ([9641958](9641958)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Bret Mogilefsky <bret.mogilefsky@gsa.gov>
…#480) ## Summary Move the devenv image's `NIXPKGS_REV` to `nixos-26.05` (`0d9e9b832d03ac387417e16ce1febf73b2e631e1`), which ships devenv 2.1.2, and bump `VERSION` to `2.0.0` because the devenv major is part of the image contract. The README records that contract and what a 2.x CLI changes for repos still locked to 1.x modules. Existing consumers keep the immutable `1.0.0` tag. ## Eligibility & Accountability - [x] I am a **federal employee or contractor** (PRs merge with `@GSA-TTS/agentic-coding-team` code-owner approval; eligibility is attested here, not authenticated). *Anyone may open issues without this.* - [x] **I understand this change and can explain it in my own words** — I am the author of record and accountable for it. - [x] By opening this PR, I **attest I have the right to release this work** under the repository's [CC0-1.0](../LICENSE) dedication. ## AI Assistance Disclosure - [x] AI tools were used in this contribution - [x] I verified all AI-generated content: no fabricated/hallucinated APIs, dependencies, citations, or placeholder content; any AI-suggested dependency was confirmed to exist. - [x] Any inherited/reused third-party material retains its original license and is identified (not represented as public domain). ## Type of Change - [x] New tool/editor integration (`integrations/`) - [x] Documentation update - [x] Infrastructure/tooling change ## Motivation Toolchain currency for the generic devenv image (item 1 of #418): devenv 2.x is absent from `nixos-25.05` and `nixos-25.11` and first appears in `nixos-26.05`. This PR is only the pin bump plus consumer documentation; size/startup measurement, the `devenv container` generation model, and persistence docs from that issue are left for follow-ups. This satisfies the substrate requirement in GSA-TTS/agentic-coding-quickstart#474 (ADR-0030: a channel carrying the intended devenv major, with the major recorded in the image contract), so it should land before GSA-TTS/agentic-coding-quickstart#474 claims that requirement is met. The dependency is conceptual: that PR pins no devenv image tag, so nothing enforces the order. `nixos-26.05` is the only channel that is both devenv 2.x and release-pinned: 2.2 and later exist only in `nixpkgs-unstable` (currently 2.4.0), and devenv 2.2 stopped building for `x86_64-darwin` (devenv v2.2 release notes). ## Testing - [x] Ran `make validate` locally (all checks pass) - [x] Tested with at least one real scenario - [x] Commit messages follow [Conventional Commits](https://www.conventionalcommits.org/) format (see [CONTRIBUTING.md](../CONTRIBUTING.md#commit-message-format)) Build: `workflow_dispatch` of `devenv-image.yml` on this branch succeeded on all four legs (shell/opencode × amd64/arm64); the manifest job skipped as designed off `main`. Run: https://github.com/GSA-TTS/agentic-coding-patterns/actions/runs/37489740805 Image smoke test (arm64 `devenv-opencode` digest from that run, in an msb sandbox created through `acq` with a real kit stack): `devenv version` → `devenv 2.1.2 (aarch64-linux)`; installer Nix 2.24.9 and direnv 2.37.1 present; non-interactive `bash -c 'devenv version'` works; `agent:agent` owns `/nix`, `/nix/store` (1775) and `/nix/var/nix/db`. A minimal devenv 2.x project built in the sandbox: its outputs are registered in the shared store DB (schema 10) as seen by the installer's `nix path-info`, `nix store verify` passes, and no group/world-writable outputs are produced (the single-user-store regression fixed upstream in cachix/devenv#2757 is absent). Locked GitHub inputs, cache.nixos.org and cachix fetches all succeeded through the kit-provided CA via devenv's bundled Nix. Consumer compatibility (devenv 2.1.2 from the same nixpkgs rev, run against scratch copies of two team repos that stay locked to 1.x modules): a Python/venv/tasks repo passes unchanged; a Ruby/Postgres/`git-hooks` repo fails until the `git-hooks` input is declared in `devenv.yaml`, then passes including `devenv up -d` Postgres. `devenv shell` under 2.x rewrites `devenv.lock` (drops implicit `git-hooks`/`pre-commit-hooks`/`flake-compat` nodes) and a 1.x CLI adds them back at current HEAD; `.devenv/` is reusable across majors. These behaviors are what the README section documents. ## Safety Checklist - [x] No secrets, API keys, tokens, or passwords included - [x] No PII (names, emails, SSNs, addresses) - [x] No CUI (Controlled Unclassified Information) - [x] No internal URLs, hostnames, or system paths - [x] No customer data or proprietary information ## Quality Checklist - [x] Plain language used (Grade 10 or below preferred) ## Validation Results ``` make validate ✓ All validators passed ``` ## Related Issues Relates to #418 ## Additional Context The feature-branch build wrote to the shared `devenv-*:cache-{amd64,arm64}` registry cache tags, so the next `main` build after merge rebuilds more layers than usual. Known follow-ups not in this PR: a post-build smoke-test job in `devenv-image.yml` (fixture with `git-hooks`, `direnv exec . true`, store-permission check); `devenv processes down` can time out and SIGKILL the process group without stopping a service's children (observed with Postgres under the 2.1.2 CLI); the `devenv update` path (2.x modules, `prek` default, native process manager) could not be exercised behind a GitHub-API-rate-limited proxy because the bundled Nix's libgit2 fallback fails with `authentication required but no callback set`. ## Reviewer Notes **Reviewers should verify:** - [ ] `NIXPKGS_REV` resolves to a `nixos-26.05` commit and the Dockerfile comment matches - [ ] `VERSION` is `2.0.0` and not previously published - [ ] README 2.x consumer notes match the migration guide's documented breaking changes - [ ] No sensitive information included - [ ] `make validate` passes in CI
Context
AI-assisted implementation for the ADR-0030 migration: move from adapter-owned agent/tool installation toward a generic devenv-enabled base image plus explicit, pinned capability/agent kits from
agentic-coding-patterns.This PR now includes the work that was previously stacked above it:
oci-engineas an opt-in catalog kit and retirement of adapter-owned MSB OCI auto-install.Discussion issue: #473
Related patterns release: GSA-TTS/agentic-coding-patterns v1.12.0 (
56d1f5f49ef928f50e61aa64a93d618b3d21c415)Closes: #478, #479, #480, #481, #482, #483, #484, #485, #505
#475 remains a separate resource-sizing track and is intentionally not closed by this PR.
BREAKING CHANGE
This PR changes default MSB provisioning behavior.
MSB no longer auto-installs podman/OCI tooling by default.
Users who need
docker run,docker compose, or rootless podman inside MSB sandboxes must opt into theoci-enginekit.MSB no longer performs native OpenCode npm fallback installation.
OpenCode is supplied by the pinned
opencodeagent kit fromagentic-coding-patternsv1.12.0. If the kit is unavailable or invalid, acq fails closed instead of silently installingopencode-aifrom npm.Existing MSB sandboxes with adapter-installed podman are not migrated in place.
Recreate affected sandboxes or add the
oci-enginekit before relying on OCI behavior after stop/start.Migration
For OCI/podman inside MSB sandboxes, choose one of:
and select
oci-engine, or pass the pinned kit for a one-off sandbox:For OpenCode, no separate user action is intended for new sandboxes: the built-in
opencodeagent kit is selected by acq from the pinned patterns bundle.Existing sandboxes should be recreated when their provisioned state must match the new defaults.
Summary
PATTERNS_KIT_REFto agentic-coding-patterns v1.12.0 (56d1f5f49ef928f50e61aa64a93d618b3d21c415).opencodekit.provider-facts/usai.envwhen present.oci-engine./home/agent/.rc.d/*.shshell-snippet contract and bridge it for MSB/SBX.Verification
Latest local verification after rebasing over #548 and collapsing the stack:
bash -n acq acq.backends/*.sh scripts/test-acq-lib.sh scripts/test-acq-bats scripts/fix-exec-bits test/bats/helper.bash scripts/verify-backends./scripts/fix-exec-bits --checkgit diff --checknpm run lint:mdTMPDIR="$PWD/tmp" ./scripts/test-acq-bats test/bats/30-dispatch-routing.bats(55 ok)test/bats/36-agent-catalog.batstest/bats/50-kit-list-completeness.batstest/bats/55-version.batstest/bats/72-msb-agent-user.batstest/bats/80-kit-subcommands.batstest/bats/85-kit-provenance.batstest/bats/95-kit-ref-persistence.batstest/bats/135-configure.batstest/bats/140-opencode-migration-gate.bats15 passed,0 failed,1 skipped10 passed,0 failed,1 skippedCI is the source of truth for full offline suite coverage on the collapsed PR.
Rollback
Revert this PR to restore the previous MSB adapter-owned podman auto-install path and native OpenCode npm fallback. Existing sandboxes are not migrated by rollback; recreate affected sandboxes if their provisioned state must match the restored adapter behavior.
Security Impact
Positive security impact with user-visible migration cost:
No secrets are introduced. Secret values are not placed on argv, in docs, or in test fixtures.
Review Focus
opencodekit is unavailable or malformed.scripts/verify-backendscapture behavior and exec-bit self-healing.