packages/kilo-docs/pages/contributing/architecture/config-schema.md
The JSON Schema referenced by "$schema": "https://app.kilo.ai/config.json" in kilo.json files is served by the cloud repo. It is a runtime overlay of the upstream opencode schema with Kilo-specific additions on top.
https://app.kilo.ai/config.json.apps/web/src/app/config.json/route.ts fetches https://opencode.ai/config.json, runs merge() on it, and returns the result.merge() overlays three sections from apps/web/src/app/config.json/extras.ts:
top — top-level keys like commit_message, remote_control, nullable model / small_modelagents — Kilo primary agents (ask, debug, orchestrator)experimental — codebase_search, openTelemetryThe source of truth is the zod schema in packages/opencode/src/config/config.ts. The cloud overlay must match it.
kilocode_change marker in config.ts.bun --bun packages/opencode/script/schema.ts /tmp/kilo.json, then jq '.properties.<new_key>' /tmp/kilo.json.apps/web/src/app/config.json/extras.ts in the cloud repo.
top; under experimental → experimental; new primary agent → agents; anywhere else → add a new bucket and extend merge() in route.ts.apps/web/src/tests/cli-config-schema.test.ts.If step 3 is skipped, users with $schema: https://app.kilo.ai/config.json will see "unknown property" warnings for the new key.
The cloud route caches the upstream fetch for 1 hour (next: { revalidate: 3600 }) and emits s-maxage=3600, stale-while-revalidate=3600, so the response is served from the Cloudflare + Vercel edge cache for all but one request per hour per region.