Repository navigation
feat(isolation): validate kit templates under acq-kits/examples/ - #476
Conversation
|
Reviewed the validator change, ADR-0005, and the new test file. Two should-fix findings, one nit. Both findings are pre-existing rather than introduced here, but both live in the function this PR edits, and one gets more likely because of copy-and-rename templates. Everything below was run against the PR's actual Should-fix 1 — two kits may declare the same
|
|
Thanks, both reproduced against this branch (duplicate name: exits 0; empty and missing acq-kits/ exit 0). Taking both: the duplicate check now spans kits and templates together, since copy-and-rename between templates is the same slip, and an empty tree fails with a message that nothing was validated. Tests added for both. Agree the #416 compose-file concern doesn't apply yet; neither #441 nor #442 ships a compose file. |
ef6064d to
41d4ccd
Compare
41d4ccd to
ee1be35
Compare
|
AI-assisted re-review (OpenCode), advisory — needs a human to confirm before it drives a change. Reviewed head Both findings are fixed. I re-ran my original reproductions against this head rather than reading the diff. Should-fix 1 — duplicate
|
|
@wz-gsa just to confirm there is nothing to act on my side from the last review. I'm not sure if your review skill is missing a verdict? |
ee1be35 to
b1cb197
Compare
|
Checked whether this needed a re-review and it does not — the force-push is a rebase, not a content change. Your own files are byte-identical between the old and new head; the whole delta is #436's merged files arriving underneath. My re-review of Not re-running the checks on an unchanged tree — this is waiting on a maintainer, not on me. |
b1cb197 to
57b3d12
Compare
wz-gsa
left a comment
There was a problem hiding this comment.
Approving. Converting my 2026-10-07 re-review into a formal review — it was posted as a comment, which left this at REVIEW_REQUIRED and reading as unreviewed. My fault, not yours.
Still applies at the current head. b1cb1972 → 57b3d128 is a rebase; this PR's own files are byte-identical:
git diff b1cb1972 57b3d128 -- integrations/isolation/acq-kits/validate-kits.py \
scripts/tests/test_validate_kits_examples.py
(empty)
Both findings from my first review are fixed, verified by re-running the original reproductions rather than reading the diff:
Duplicate name: across kits. The set() collapse is gone; name_owners maps name → every declaring directory (validate-kits.py:411-413). My original case now fails, and the error names the owning directories rather than just the colliding name, which is what makes it actionable:
FAIL:
- duplicate kit name 'samename' declared by: a, b
exit=1
Distinct names produce no error. Your extension to span kits and templates catches the likelier slip — a copy-and-rename between containers:
- duplicate kit name 'samename' declared by: a, examples/tpl
Empty tree reported success. validate-kits.py:362-366 now returns 1 for both an empty acq-kits/ and an absent one, and templates-only still validates (test_templates_are_validated_when_no_kit_dirs_exist), so the gate does not over-trigger.
Tests and validators at the head I reviewed: test_validate_kits_examples.py 22 passed, full suite 429 passed, scripts/validate_repo.py all validators passed.
Agreed on the #416 compose-file point — not applicable until a template ships one.
Treat acq-kits/examples/ as a container of copy-and-rename kit templates rather than a kit. validate-kits.py checks each examples/<name>/ like a kit (schema, files[] sources, env names, README) but keeps templates out of the kits.yaml registry cross-check, and skips tool droppings such as __pycache__. ADR 0005 records why scope-layer kits ship as templates and why they live under examples/ (placement B), and acq-kits/README.md gains a Templates section.
57b3d12 to
cfa9bc7
Compare
…#441) ## Summary Adds `integrations/isolation/docs/scope-layers.md`: how global, team, and personal `acq` kits stack through `ACQ_EXTRA_KITS`, a per-field composition table, what belongs in each layer, authoring gotchas, one list of backend differences, and the parser rules to check against your `acq`. Adds the copy-and-rename template `acq-kits/examples/team-kit/`: a valid hybrid/v1 mixin with one live, harmless value per extension point, a host-side `env.sh`, a sample ADR, README, TROUBLESHOOTING, and a `scripts/verify` that asserts the composition live. Second of three stacked PRs for #421: #476, then this one, then the `personal-kit` template. **Reviewer ask: correct the composition table if any field composes differently than described**, especially the rows marked "sbx: composed natively". It was checked against acq v4.0.1 (GSA-TTS/agentic-coding-quickstart `1679530`), which includes the `environment` and `publishedPorts[]` fixes (GSA-TTS/agentic-coding-quickstart#519, GSA-TTS/agentic-coding-quickstart#526) and adds the pinned OpenCode agent kit between the global and team layers. The `volumes[]` and `commands[]` rows describe current behavior while the stacked-kit conflict rule is decided in GSA-TTS/agentic-coding-quickstart#533, which names this PR as its trigger. ## 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 ## Motivation Every team adopting `acq` builds the same team layer between the global kits and each repo's agent config, then a personal layer on top. `ACQ_EXTRA_KITS` supports this, but nothing here said how stacked kits compose, what belongs in each layer, or gave a validated starting point. login.gov Team Data runs such a kit in production; this generalizes what that team learned. Parser and adapter defects the doc works around, stated once under "Check against your acq" and filed upstream: - a trailing `# comment` is kept in top-level fields and in `commands[]`, where it skips the command or changes an argument (GSA-TTS/agentic-coding-quickstart#558); - `environment` values are cut at the first `#`, even inside quotes (GSA-TTS/agentic-coding-quickstart#559); - `acq kit validate` passes commands the translator skips or empties (GSA-TTS/agentic-coding-quickstart#563); - flow-style argv parses as an empty command (GSA-TTS/agentic-coding-quickstart#560); - on msb an empty file fails its drop, and a failed drop stops that kit's `environment` and `commands[]` (GSA-TTS/agentic-coding-quickstart#561). OpenCode 2.x never loads `instructions` files (anomalyco/opencode#51341, fix in anomalyco/opencode#51422, tracked in #482), and the template delivers team conventions that way. Which OpenCode runs depends on the image: the agent kit installs 2.0.22, but an image that bakes 1.x puts it first on `PATH`. Checked live on msb 0.7.7 with acq v4.0.1: acq's own template image for `acq run opencode` (`sandbox-templates:opencode-docker`) runs 1.18.32 and `devenv-opencode:1.0.0` runs 1.18.23, so the conventions load; `sandbox-templates:shell-docker` has no OpenCode of its own and runs only 2.0.22, so they are ignored. `scripts/verify` now fails when 2.x is what runs, and did on `shell-docker`. The doc states this in prose, and the permission sketch follows the global kit's default-allow posture (ask before posting, deny merge/approve, pipeline runs, CI variables, and API writes). Not shipped: an optional `tui.jsonc` with `OPENCODE_TUI_CONFIG`. TUI settings are mostly personal, a personal kit would replace the team file whole, and `verify` could assert only that the variable and file exist. ## Testing - [x] Ran `make validate` locally (all checks pass) - [x] Ran `make test` (if applicable): 448 passed; `scripts/tests/test_validate_kits_*.py`: 95 passed - [x] Tested with at least one real scenario: `examples/team-kit/scripts/verify` on msb 0.7.7 with acq v4.0.1: 20 passed, 0 failed, 1 skipped (the empty TEAM-SPECIFIC section). Not re-run on sbx for this revision (the host's sbx session needed `sbx login`); the doc no longer claims sbx observations. - [x] Examples are concrete and realistic - [x] Commit messages follow [Conventional Commits](https://www.conventionalcommits.org/) format Also run: `validate-kits.py --strict`, `acq kit validate` on the template, `ruff check scripts/`, `ruff format --check scripts/`, `make generate-check`, markdownlint, `shellcheck -s sh env.sh`, and `env.sh` under sh, bash, zsh, and dash. ## 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 (the reference implementation is named, not linked; examples use `example.gov`/`example.org`) - [x] No customer data or proprietary information - [x] Pattern defines `prohibited_content` in output contract (if applicable): not applicable, no SKILL.md pattern ## Quality Checklist - [x] Plain language used (Grade 10 or below preferred) - [x] Examples included - [x] Prerequisites clearly stated ## Validation Results ``` make validate ✓ All validators passed ``` ## Related Issues Relates to #421 (followed by the `personal-kit` template) Depends on #476 (placement B) Relates to GSA-TTS/agentic-coding-quickstart#533 (stacked-kit merge rules for volumes and startup steps) Relates to GSA-TTS/agentic-coding-quickstart#517 (symlinked `files[]` sources on msb) Relates to GSA-TTS/agentic-coding-quickstart#482 (acq's `~/.rc.d` login hook; the personal-kit row relies on it) Relates to #482 (OpenCode 2.x ignores `instructions`) Relates to GSA-TTS/agentic-coding-quickstart#557 (`acq configure` and team kits), GSA-TTS/agentic-coding-quickstart#558, GSA-TTS/agentic-coding-quickstart#559, GSA-TTS/agentic-coding-quickstart#560, GSA-TTS/agentic-coding-quickstart#561, GSA-TTS/agentic-coding-quickstart#562, GSA-TTS/agentic-coding-quickstart#563 (filed from this work) Relates to GSA-TTS/agentic-coding-quickstart#500, GSA-TTS/agentic-coding-quickstart#509, GSA-TTS/agentic-coding-quickstart#519, GSA-TTS/agentic-coding-quickstart#526 ## Additional Context - `scripts/verify` cannot run in this repo's CI (no nested sandboxes); the offline gate is `validate-kits.py`. - The template README links the pattern doc through the repository root with the file path as text: a copied kit cannot follow relative links, and `blob/main/…` links to files added here would fail link-check until merge. ## Reviewer Notes **Reviewers should verify:** - [ ] The composition table matches acq's behavior on msb, and the rows marked "sbx: composed natively" describe sbx correctly - [ ] Backend differences and Check against your acq match what you see on your acq - [ ] Safety checklist items confirmed - [ ] `make validate` passes in CI
Summary
Makes
integrations/isolation/acq-kits/examples/a container of copy-and-rename kit templates:validate-kits.pychecks eachexamples/<name>/like a kit but keeps it out of thekits.yamlregistry.ADR 0005 records why scope-layer kits ship as templates (hybrid/v1 has no parameters) and where they live (placement B).
No template ships here; the first one,
team-kit, and the scope-layers pattern doc follow in a stacked PR.Reviewer ask: is placement (B),
acq-kits/examples/<name>/exempt from the registry, the right home? The alternative (A) isacq-kits/<name>/with akits.yamlentry marked TEMPLATE and no validator change; ADR 0005 lists both. Switching to (A) means dropping this PR and moving the template up one level in the next.Eligibility & Accountability
@GSA-TTS/agentic-coding-teamcode-owner approval; eligibility is attested here, not authenticated). Anyone may open issues without this.AI Assistance Disclosure
Type of Change
Motivation
Every team adopting
acqbuilds the same team scope layer. A template CI keeps schema-valid is more useful than prose alone, but a template is not a kitacqapplies, so it must not sit in the registry of deployable kits. This PR adds the home and the gate; the content lands separately so the placement question can be answered on its own.What lands:
acq-kits/validate-kits.py: skipsexamples/in the kit walk; validates eachexamples/<name>/with the same per-kit checks (schema,files[].sourceresolution, env names, README) under anexamples/prefix; leaves templates out of thekits.yamlcross-check, so a template listed there fails ("registry lists unknown kit"). The walk skips only named tool droppings (__pycache__,.pytest_cache,.ruff_cache,.mypy_cache); any other directory, dot-named or_-prefixed, is validated, because acq can fetch any directory through adir=ref. Two tree-level checks: no two kits or templates may declare the samename:(a copied directory that kept the original name is the likeliest copy-and-rename slip, and the registry cross-check could not see it), and a tree with no kits or templates fails instead of passing with nothing validated.scripts/tests/test_validate_kits_examples.py: 22 tests on generated fixture trees, including duplicate names (kit/kit, template/template, kit/template), empty or missing trees, and dot-named kits and templates; none depend on a real template.integrations/isolation/docs/decisions/0005-kit-templates.md: templates vs a parameterized kit vs doc only, and placement A vs B. Numbered 0005 because feat(isolation): add serviceGateways kit vocabulary #416 and docs(isolation): add ADR 0004 for neutral model-provider discovery #423 claim 0003 and 0004; happy to renumber.acq-kits/README.md: a Templates section, separate from the Available kits table.Testing
make validatelocally (all checks pass)make test(if applicable): 429 passed;scripts/tests/test_validate_kits_*.py: 95 passedAll 10 acq-kits valid.); the stacked PR exercises it with one (All 10 acq-kits + 1 template(s) valid.)Also run:
validate-kits.py --strict,ruff check scripts/,ruff format --check scripts/,make generate-check.Safety Checklist
prohibited_contentin output contract (if applicable): not applicable, no SKILL.md patternQuality Checklist
Validation Results
Related Issues
Relates to #421 (placement option B)
Relates to #416 and #423 (ADR numbering;
validate-kits.pyandacq-kits/README.mdoverlap with #416)Reviewer Notes
Reviewers should verify:
acq-kits/examples/is the preferred optionmake validatepasses in CI