Skip to content

Proposal: team-kit and personal-kit templates plus a "scope layers" pattern doc for acq mixin kits #421

Closed

Description

@basiliskus

Problem

Every team adopting acq ends up building the same thing: a team scope layer between the global kits acq applies for everyone and each repo's own agent config, and then a personal layer each teammate stacks on top. ACQ_EXTRA_KITS already supports this (whitespace-separated, ordered), but nothing in this repo says so, spells out how the fields of stacked kits compose, shows what belongs in each layer, or gives a validated starting point. login.gov Team Data has run a team kit since June (data-warehouse-ag acq-kits/team-data/) and a personal-kit example next to it, and we re-learned a list of failure modes along the way that other teams will hit again: whole-file overlays clobbering ~/.bashrc, binary payloads breaking file delivery, create-time installs through the proxy failing the whole create, secret rotation breaking existing sandboxes when the placeholder changes, and environment last-wins shadowing between kits.

The hybrid/v1 vocabulary this needs already exists here; environment and volumes were added for our team kit. What is missing is the pattern and a skeleton that CI keeps schema-valid.

Proposal

Add, under integrations/isolation/:

  1. A pattern doc, docs/scope-layers.md: the layer model (global kits, then team kit, then personal kit, all applied by acq in ACQ_EXTRA_KITS order; the repo's own workspace config such as AGENTS.md or .opencode/ sits above them but is read by the agent, not applied by acq); the kit-vs-image-vs-host-side-secret decision rule (config in kits, toolchains in the image, credentials via acq secret); a "what belongs / what does not" table per layer; and the authoring gotchas above.
  2. A per-field composition table in that doc, stating how stacked kits combine field by field. Our expected rules, to be confirmed against acq's kit-translate code before the PR: environment last-wins (documented in usai-provider ADR-0002), volumes union by path, caps.network.allow union, files[] last-wins by path, commands[] append in order. Correct us now if a field composes differently.
  3. An ADR, docs/decisions/0003-kit-templates.md: templates rather than a parameterized generic kit, and the placement decision below.
  4. Two copy-and-rename templates, team-kit and personal-kit: minimal hybrid/v1 mixins where every extension point (caps.network.allow, files[], commands[], environment) carries one live, harmless value the schema actually checks and scripts/verify asserts, with comments saying what to replace. Each has a README (rename both the directory and the kebab-case name:), TROUBLESHOOTING, and a scripts/verify that stacks the pinned usai-provider kit plus the template (personal-kit also stacks team-kit) in a throwaway sandbox and asserts the composition rules from the table, not just that the sandbox came up.

These are templates, not deployable kits. hybrid/v1 has no parameters, so a kit applied by acq cannot carry placeholder team values; a "generic team kit" would be applied verbatim with empty extension points. The value is the pattern plus a skeleton that stays valid as the schema evolves.

Design points

Placement is your call; two options. (A) Live under acq-kits/<name>/ with a kits.yaml entry whose parity note says TEMPLATE, not applied by acq. Zero validator changes, and prime-agent already sits in the registry as a skeleton (#369), so there is precedent. (B) Live under acq-kits/examples/<name>/, schema- and files[]-validated by validate-kits.py but exempt from the registry cross-check. Cleaner separation; the cost is teaching the validator to treat examples/ as a container of templates rather than as a kit (today it would fail on the missing spec.yaml). Either way acq-kits/README.md gets a separate Templates section rather than rows in the Available kits table. We lean (B) but will implement whichever you prefer.

Backend-neutral, acq-first prose. Everything is written in the neutral vocabulary and every command in the docs is an acq command. No backend shortcuts or extras, so parity is identical on sbx and msb.

Patterns, not fossilized workarounds. Where a gotcha is really an acq defect (for example a spec-parser limitation), the doc links the quickstart issue or marks it "as of acq vX" rather than teaching it as a permanent rule.

What stays out. Our egress list, the Nix/devenv coupling, agent-specific config beyond a single OpenCode example of the config-tier mechanism (OPENCODE_CONFIG pointing at a team file), and any workaround specific to our repos. No internal URLs; the reference implementation is named, not linked, unless you prefer otherwise.

Delivery. Two stacked PRs, roughly 1,200 to 1,400 lines in total. PR 1: the doc, the ADR, the placement/validator change, the README Templates section, and the team-kit template, the one with a working precedent that exercises everything the doc describes. PR 2: the personal-kit template plus its short doc section; its verify proves the three-kit stack (usai-provider, team, personal). Happy to collapse into one PR if you prefer less review overhead.

Prior art

The devenv base image (#394, #395) followed the same route: generalized from our team's setup, with team-specific content left in the team kit. This proposal contributes the other half of that split, the team layer itself as a pattern. Our side of the decision is recorded in data-warehouse-ag as an ADR (proposed, pending this issue).

We would author both PRs and validate the templates against our team kit on both backends.

Activity

  1. self-assigned this
    on Sep 25, 2026
  2. basiliskus commented on Sep 28, 2026

    @basiliskus
    ContributorAuthor

    Both PRs from this proposal are up: #441 (pattern doc, ADR, team-kit template, validator change) and #442 (personal-kit template, stacked on #441).

    On the placement question, we went with option (B): templates live under integrations/isolation/acq-kits/examples/<name>/. validate-kits.py validates each one like a kit (schema, files[].source resolution, env names, README) but keeps them out of the kits.yaml registry, and fails if a template is listed there. The reasoning is in isolation ADR 0005, which is marked "proposed" until you weigh in.

    We chose (B) because the templates are deliberately not deployable (hybrid/v1 has no parameters, so each carries harmless placeholder values), and (B) makes that separation structural instead of a note in the registry. If you prefer (A), switching is cheap: move the two directories up a level, add kits.yaml entries marked TEMPLATE, and drop the validator change and its tests.

    The composition rules in the doc were checked against acq main@187aa57 and asserted live by each template's scripts/verify on msb and sbx. Corrections to the composition table are especially welcome in review.

  3. basiliskus commented on Oct 15, 2026

    @basiliskus
    ContributorAuthor

    Both PRs from this proposal have merged: #441 (scope-layers pattern doc, ADR 0005, team-kit template, validator change) and #442 (personal-kit template). Placement went with option (B), templates under integrations/isolation/acq-kits/examples/. Closing as done. One loose end: ADR 0005 is still marked proposed; since both PRs merged with it as written, should it be flipped to accepted? Happy to open the one-line PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions