Skip to main content

KCL Schema Developer

Overview

Who this is for: engineers writing or updating KCL schemas in https://github.com/sparqd/platform-stacks/tree/main/kcl/.

What is KCL? · How schemas work · Why we use it


Control plane orientation

The dev control plane is at https://cplane.dev.cogrion.com.

Before writing schemas, get familiar with two areas of the UI.

KCL Modules

In the left sidebar under Authoring, click KCL Modules.

Open a module (e.g. delta-spark) to see the Versions table:

ColumnWhat it shows
VersionSemver label for this registration (e.g. 0.0.3)
RefThe branch name or git tag that gets cloned at deploy time
ChangelogFree-text note entered when registering
StatusActive once the ui/*.k files compiled successfully

To add a version, click + Register Version (top right of the Versions table).

Note If the module does not exist yet, a platform developer must create it first. See KCL Platform Developer Guide.

Workspaces

In the left sidebar under Account, click My Workspaces.

Click a workspace to open its detail page. The inner nav on the left has:

Nav itemWhat you do here
OverviewSee workspace identity, status, and agent connection
ResourcesView app stacks currently deployed
SettingsAssign a KCL schema version and trigger infra operations

On the Settings page:

KCL SCHEMA — shows the currently assigned schema version. Click Assign schema to open the assignment dialog and pick your module and version.

OPERATIONS — three buttons to act on the workspace after assigning a version:

ButtonWhat it does
Sync AppsSync composite application stacks from the workspace template
Provision InfraRun the infra provisioning workflow (use when workspace is pending or failed)
Sync InfraRe-apply the current infra configuration without reprovisioning

How to

1. Get the repo

git clone github.com/sparqd/platform-stacks
cd platform-stacks
git checkout -b developer/<your-name>/my-feature

2. Edit a schema

All schemas live under platform-stacks/kcl/. Pick the component you're working on:

kcl/infra/ storages, karpenter, compute-profiles
kcl/observability/ observability, openbao, kafka, spark-operator
kcl/data/ trino, hive-metastore, spark-history-server, mlflow, ranger
kcl/apps/ airflow, superset, jupyterhub, datahub, ...
kcl/flavors/ delta-spark.k ← top-level entrypoint

3. Test locally — no cluster needed

cd platform-stacks/kcl
kcl flavors/delta-spark.k -Y values/example.yaml | uvx --with pyyaml python kcl-preview

kcl-preview renders a Pulumi-style plan summary — no raw YAML:

Previewing apply (delta-spark)
platform: my-platform provider: aws region: ap-southeast-1

Type Name Plan

+ ├── k8s:manifest Namespace/cogrion-system apply
+ ├── aws:sdk storages-warehouse S3.createBucket
+ ├── aws:sdk storages-workspace S3.createBucket
+ └── aws:sdk storages-log-archive S3.createBucket

Steps:
aws:sdk 3
k8s:manifest 1

+ 4 to apply

If flow is missing or malformed, the agent fails with a parse error — fix the schema and re-run.

To see the raw YAML output instead:

kcl flavors/delta-spark.k -Y values/example.yaml

To iterate:

  1. Edit values/example.yaml — update platformId, provider, region, etc.
  2. Re-run with kcl-preview — the step list reflects your change
  3. Edit the relevant .k file — add or modify steps
  4. Re-run — new steps appear in the plan

Copy-paste starter for values/example.yaml:

# values/example.yaml — local test values
# Edit these to match your workspace before running kcl-preview
kcl_options:
- key: flavor
value: delta-spark # delta-spark | spark-only | trino-only
- key: platformId
value: my-platform # ← replace with your platform ID
- key: provider
value: aws # aws | alicloud
- key: region
value: ap-southeast-1 # ← replace with your target region

To validate a UI schema file:

kcl ui/delta-spark-workspace.k

Expected output — a section object with kind, title, and fields:

section:
kind: workspace
title: Workspace Settings
fields:
- key: flavor
label: Flavor
type: select
...

4. Register your branch in the control plane

  1. Open https://cplane.dev.cogrion.com
  2. In the left sidebar under Authoring, click KCL Modules
  3. Click the module (e.g. delta-spark)
  4. Click + Register Version
  5. Enter your branch name in the Ref field:
    developer/<your-name>/my-feature
  6. Click Save

The server compiles all ui/*.k files from the branch and stores the UI schemas. If there is a compile error it will be shown inline — fix, push, then save again to re-compile.

5. Assign the version and deploy

  1. In the left sidebar under Account, click My Workspaces and open your workspace
  2. In the inner nav, click Settings
  3. Under KCL SCHEMA, click Assign schema
  4. Select the module and your branch version, then click Assign
  5. Under OPERATIONS, click Provision Infra
  6. Watch each step execute in the Events tab

Iteration loop: if a step fails or produces wrong resources — fix the schema, push, re-register the same branch ref (server re-compiles from latest commit), then click Provision Infra again. Repeat until the plan matches what kcl-preview showed locally.

To observe the rollout on the cluster in parallel:

kubectl get pods -n <workspace-namespace> -w

If a step fails or produces wrong resources — fix the schema, push, then return to step 4 in Register your branch to re-compile, then trigger another deploy.

6. Open a PR

Schema changes are reviewed like any code change. Open a PR against main.

7. Tag a release

After merge:

git tag kcl/v0.2.0
git push origin kcl/v0.2.0

Then register the tag in the control plane UI (see KCL Platform Developer Guide).


Writing UI schema files

Every flavor entrypoint has a matching ui/<flavor>-<kind>.k file that describes the fields shown in the workspace settings UI. These are compiled at version registration time and stored in the KclUiSchema table.

Contract

UI schema files must import ui/schema.k and emit a single UiSection object:

import .schema as s

section = s.UiSection {
kind = "workspace"
title = "Workspace Settings"
fields = [
s.FieldDef { key = "flavor", label = "Flavor", type = "select", required = True, default = "delta-spark", options = ["delta-spark", "spark-only", "trino-only"] }
s.FieldDef { key = "provider", label = "Cloud Provider", type = "select", required = True, options = ["aws", "alicloud"] }
s.FieldDef { key = "region", label = "Region", type = "string", required = True, description = "e.g. ap-southeast-1" }
]
}

kind values

kindWhere it appears
workspaceTop-level workspace settings (shown first)
trinoTrino-specific settings section
airflowAirflow-specific settings section

Field types

typeRenders as
stringText input
selectDropdown (requires options)
booleanToggle switch
numberNumeric input

Adding a new setting

  1. Add the field to ui/<flavor>-<kind>.k
  2. Add it to the WorkspaceSpec schema in flavors/<flavor>-values.k
  3. Use it in flavors/<flavor>.k to produce the right deployment steps
  4. Push the branch, register a new schema version — ui/*.k files are compiled and stored automatically

Migration order

Migration follows the dependency order in delta-spark.yaml. A component is migrated only after all its dependencies are on the KCL path.

Current status: infra/storages.k — written, testing in progress.

#ComponentTierFileDepends on
1storagesinfrainfra/storages.k
2karpenterinfrainfra/karpenter.k
3compute-profileinfrainfra/compute_profiles.kkarpenter
4observabilityobservabilityobservability/observability.kstorages, compute-profile
5openbaoobservabilityobservability/openbao.kobservability
6kafkaobservabilityobservability/kafka.kobservability
7spark-operatorobservabilityobservability/spark_operator.kobservability
8airflowappsapps/airflow.kobservability
9datahubappsapps/datahub.kkafka
10hive-metastoredatadata/hive_metastore.kobservability
11jupyterhubappsapps/jupyterhub.kspark-operator
12mlflowappsapps/mlflow.kobservability
13rangerdatadata/ranger.kobservability
14trinodatadata/trino.khive-metastore
15spark-history-serverdatadata/spark_history_server.kstorages
16supersetappsapps/superset.ktrino
17spark-teamdatadata/spark_team.kspark-operator
18celeborndatadata/celeborn.kspark-operator
19trino-clusterdatadata/trino_cluster.ktrino
20cubeappsapps/cube.ktrino-cluster
21workspace-file-managementappsapps/workspace_file_management.kjupyterhub
22dashboard-access-managementappsapps/dashboard_access_management.ksuperset
23ontology-backendappsapps/ontology_backend.kcube
24text-to-sqlappsapps/text_to_sql.kontology-backend
25agent-based-ml-platformappsapps/agent_based_ml_platform.kmlflow, jupyterhub
26workflow-backendappsapps/workflow_backend.kairflow, trino
27pipeline-backendappsapps/pipeline_backend.kworkflow-backend
28bffappsapps/bff.kranger, superset, dashboard-access-management, workspace-file-management
29delta-spark-product-capabilitiesappsapps/delta_spark_product_capabilities.kranger, superset, bff
30chatbot-backendappsapps/chatbot_backend.kbff

What is KCL

KCL (Kusion Configuration Language) is a typed configuration language. A KCL file is a schema: it defines what fields exist, what types they accept, and what output it produces.

In this platform, each component schema (storages.k, trino.k, etc.) takes workspace values as input and outputs flow — a structured list of deployment steps the agent executes.

Three-tier module architecture

Tier 1 — Shared infrastructure (cross-flavor, cross-provider)
kcl/infra/ storages, karpenter, compute-profiles
kcl/observability/ observability, openbao, kafka, spark-operator

Tier 2 — Open-source components (individually ownable)
kcl/data/ trino, hive-metastore, spark-history-server, mlflow, ranger
kcl/apps/ airflow, superset, jupyterhub, datahub, ...

Tier 3 — Product flavors (compositions)
kcl/flavors/delta-spark.k

A flavor imports from Tier 1 and 2 and wires them into a complete deployment graph. All tiers share a single kcl.mod and are released together as a git tag with the kcl/ prefix (e.g. kcl/v0.1.0).


How schemas work

The values/example.yaml uses KCL's settings file format — values are read by option() in the entrypoint:

kcl_options:
- key: flavor
value: delta-spark
- key: platformId
value: test-platform
- key: provider
value: aws
- key: region
value: ap-southeast-1

The agent clones <module.repository> at <version.ref> at deploy time, runs the KCL entrypoint with the workspace values, extracts flow, and executes each step in order.


Why KCL

The previous system (StackCompose → StackTemplate → AgentCommand) had two compounding problems:

  • YAML duplication — AWS and AliCloud deployments were separate files that diverged silently over time with no shared type system.
  • No schema ownership — any team member could modify a bundle without a code review gate. No versioning of the configuration shape, only Helm chart tags.

KCL solves both: type errors are caught at compile time, and module versions are git tags — upgrading a workspace is an explicit, reviewable action.


Key rules

  • One .k file per component — mirrors one stack in delta-spark.yaml
  • Multicloud schemas use a provider: "aws" | "alicloud" union field — one schema covers both providers
  • Default values go in the schema; workspace-specific overrides go in the operator's values file
  • Only flavors/delta-spark.k imports from other tiers — component schemas do not import each other