Repository navigation
feat(usai-provider): render opencode.jsonc from the neutral models aggregate (ADR 0003 Layer 3, first harness) #426
Description
Summary
Layer 3 of ADR 0003 (integrations/isolation/docs/decisions/0003-neutral-model-provider-discovery.md, PR #423), first harness. Depends on #425 (the models orchestrator kit producing /var/lib/acq/models/catalog.json).
Scope
usai-provider's startup phase (after the models kit in kit order) reads:
/var/lib/acq/models/catalog.json(the neutral aggregate from feat(isolation): new models orchestrator kit — discover, cache/TTL, aggregate neutral catalog (ADR 0004 Layer 2) #425), and- The config kit's cross-harness defaults (model-role priority — separate issue; can be stubbed/deferred to a follow-up if the config kit isn't ready yet, defaulting to today's hardcoded
ROLE_PRIORITYbehavior),
and renders opencode.jsonc's model block itself — replacing the current path where the kit ships a hand-maintained, manually-synced static block (refreshed only when a maintainer runs scripts/sync-usai-models.mjs on the host and cuts a release).
This is the harness kit owning its own configuration lifecycle end-to-end — it is the only thing that knows how to turn a neutral model list into opencode.jsonc's exact JSONC shape (comments, indentation, the // BEGIN/END GENERATED markers). No central kit renders on usai-provider's behalf.
Migration notes
merge-global-config.mjs(the existing copy-on-first-boot/merge-without-clobbering script) is unaffected in its core algorithm — only the SOURCE of the model block changes (from a static committed file to the freshly-rendered output of this new render step).- This is a good point to extract
merge-global-config.mjs's ~150-190 shared-algorithm lines into the Tier-0-style shared library referenced in ADR 0003's Context (the already-confirmed duplication withgoose-server'smerge-config.mjs) — worth doing here rather than as a separate issue, since this issue is already touching the merge path. Judgment call for whoever picks this up; split out as a separate issue if it's cleaner. scripts/sync-usai-models.mjsbecomes redundant for the day-to-day refresh path once this lands (the models kit + this render step replace it). Do not delete it in this issue — it may still be useful as a manual/CI dry-run tool — but note its reduced role in the kit's README.
Explicitly out of scope for this issue
- goose-server's equivalent renderer (separate issue, second harness — should be easy given this issue proves the pattern).
- The config kit itself (separate issue; stub/default if not ready).
Verification
- Golden-file tests: fixture neutral aggregate + fixture config defaults → expected rendered
opencode.jsoncmodel block, byte-exact (mirrors the existing byte-exact lockstep test pattern already used foremitters/opencode.mjs). shellcheck/scan_unsafe_shell.pyon any new script,validate-kits.py --strict.- Live
RUN_ACQ=1 scripts/verify: boot a sandbox withusai-provider(+ the models kit from feat(isolation): new models orchestrator kit — discover, cache/TTL, aggregate neutral catalog (ADR 0004 Layer 2) #425), confirmopencode.jsoncreflects the aggregate's model list, confirmopencode modelsinside the sandbox sees the rendered models.
Activity