Agent configs — dedicated submodule, minimal user-overrides, umbrella orchestrates sync
Agent configs — submodule at repos/own/infra/agent-configs (2026-07-03)
Decision (locked via grill-me)
Canonical agent configs live in a dedicated public repo, chirag127/agent-configs, added to the umbrella as a submodule at repos/own/infra/agent-configs/. Umbrella's scripts/sync-agent-configs.ps1 + Scheduled Task Oriz-SyncAgentConfigs (logon + daily 09:00) writes them to global paths.
No script inside the submodule. Pure-data. Orchestration in the umbrella. Same shape as agent-skills (submodule = skill data; wiring in umbrella).
What "minimal" means
Only keys we set to non-default values. Zero re-typed defaults, zero provider catalogues from the agent's own runtime.
Kilo went from 744 lines → 60 lines. Cut: the ~500-model provider list (Kilo's own catalogue, not our config). Kept: permissions, model picks, indexing endpoint, MCP block.
Full line counts:
claude/settings.json— 160 lines (every entry a user override)opencode/opencode.json— 18 lines (OmniRoute provider only)kilocode/kilo.jsonc— 60 lines (perms + model + indexing + MCP)
Total canonical: 238 lines across 3 files.
Mapping
| Submodule source | Global target |
|---|---|
repos/own/infra/agent-configs/claude/settings.json |
~/.claude/settings.json |
repos/own/infra/agent-configs/opencode/opencode.json |
~/.config/opencode/opencode.json |
repos/own/infra/agent-configs/kilocode/kilo.jsonc |
~/.config/kilo/kilo.jsonc |
Not in the submodule
Per-machine secrets — live only globally, never synced:
~/.claude/settings.local.json—ANTHROPIC_AUTH_TOKEN,SCREENPIPE_API_KEY. CC merges local over main.- Any file whose target path ends in
.local.*.
Env-referenced secrets — refs like ${env:OMNIROUTE_API_KEY}, ${env:FREELLMAPI_KEY}, ${env:SMITHERY_TOKEN} in submodule files. Sync expands them at write time by reading user env vars, which Oriz-SyncEnv populates from .env (sops-decrypted from .env.enc).
Machine-specific absolute paths — replaced with PATH lookups where possible. Cavemem hooks call cavemem hook run ... (assumes cavemem on PATH via npm-global bin) instead of the machine-specific C:/Users/C5420321/AppData/Roaming/npm/node_modules/.... Workspace-absolute paths (C:/D/oriz/...) are kept because bootstrap guarantees the workspace at that path on every machine.
How sync writes
scripts/sync-agent-configs.ps1 in the umbrella:
- Idempotent, mtime-preserving (writes only on content diff).
- Expands
${env:VAR}refs by default (reversed from prior iteration — refs unresolved at write time cause silent auth failures downstream; expand-then-write surfaces problems immediately via warnings). - Skips writes to any
.local.*file. - Fires: Scheduled Task at AtLogOn + Daily 09:00; manual
pwsh scripts/sync-agent-configs.ps1.
Why this shape
Two questions from the grill locked this:
- Where does canonical live? → dedicated infra submodule (
repos/own/infra/agent-configs) not workspace root. Matchesagent-skillssibling pattern. Rationale: config content is stable, small, and outlives the umbrella's internal reshuffles. - Where does the script live? → umbrella
scripts/(2nd choice picked, override on Recommended). Rationale: Windows-specific scheduling is umbrella-concern; keeps submodule pure-data + OS-neutral. Downside accepted: standalone-clone-of-submodule isn't self-applying.
Failure modes handled
- Live global edited by hand — sync at next logon overwrites. Hand-edits go into workspace or
.local.jsonoverrides. - Submodule pointer stale —
git submodule updatein umbrella catches. Auto-run in bootstrap. ${env:VAR}missing on machine — sync writes warning, leaves ref as literal string. Agent fails at launch with clearer error than an empty auth string.
Bootstrap on new machine
git clone --recurse-submodules https://github.com/chirag127/workspace.git C:\D\orizpwsh scripts/bootstrap-agent-configs.ps1(installs CC/OpenCode/Kilo + registers 3 scheduled tasks)- First logon → all 3 tasks fire → configs materialize at global paths
Anti-patterns
- ❌ Add config script inside submodule — umbrella orchestrates
- ❌ Duplicate config files in workspace
.agents/— that dir now holds only agent-instruction pointers (CLAUDE.md, AGENTS.md, rules/) - ❌ Re-add the 500-model provider list to kilo.jsonc — that's Kilo runtime data, not our config
- ❌ Plaintext secret in submodule — use
${env:VAR}+.env.enc - ❌ Edit global
~/.claude/settings.json— sync overwrites next logon; edit submodule, push, next logon syncs
Cross-refs
canonical-repo-pure-data-orchestrator-in-umbrella— the pattern this instantiatesglobals-derived-from-workspaceagent-fleet-parityenv-to-system-env-daily— sibling taskcc-settings-balanceforks-as-submodules— every fork also a submodule; own-repos-under-umbrella-as-submodules generalises same shape