Project Structure

How the .dokkimi/ folder is organized.

The .dokkimi/ folder

The only requirement is that a .dokkimi/ folder exists at your repo root. You can organize files inside however you want — there are no required subfolder conventions. All **/*.json and **/*.yaml / **/*.yml files inside .dokkimi/ are scanned. You can use JSON or YAML interchangeably for definitions and shared fragments.

A common convention:

.dokkimi/
├── config.yaml            # Project-level config (optional)
├── definitions/           # Runnable definition files
├── shared/                # Shared item fragments (referenced via $ref)
└── init-files/            # Database init scripts (SQL, JS)

Two file types

Dokkimi distinguishes file types by their JSON shape, not by folder or naming convention:

Runnable definition

Has top-level name (string) + items (array):

{
  "name": "my-test-suite",
  "variables": { ... },
  "items": [ ... ],
  "tests": [ ... ]
}

Shared fragment

Any JSON file that does NOT have both name + items. Typically a single item object:

{
  "type": "DATABASE",
  "name": "postgres-db",
  "database": "postgres"
}

Fragments are not runnable on their own — they exist to be referenced via $ref from runnable definitions.

Config file

The .dokkimi/ folder can contain a project-level config file: config.yaml, config.yml, or config.json (first match wins). This file is not a definition — it's loaded separately by name.

dokkimi: 0.1.0
env:
  REGISTRY: ghcr.io/dokkimi
  IMAGE_TAG: v1.2.3
  STRIPE_TEST_KEY: sk_test_abc123
FieldTypeDescription
dokkimistringTarget Dokkimi version. The CLI warns if your installed version is older.
envobjectFlat string → string map of build-time values. Keys must be alphanumeric + underscores.

Build-time interpolation: ${{VAR}}

Any string value in a definition or shared fragment can reference a config env variable with ${{VAR}}. These are resolved at build time by the definition resolver, before the definition is sent to Control Tower.

{
  "type": "SERVICE",
  "name": "my-service",
  "image": "${{REGISTRY}}/my-service:${{IMAGE_TAG}}",
  "port": 3000,
  "healthCheck": "/health"
}

After resolution, the image becomes ghcr.io/dokkimi/my-service:v1.2.3.

${{VAR}} vs {{VAR}} — These are different systems. ${{VAR}} is resolved at build time from the config file. {{VAR}} is resolved at runtime from test variables. If a ${{VAR}} reference doesn't match any key in env, the resolver errors.

.dokignore

You can create a .dokkimi/.dokignore file to exclude files from cloud/CI test runs. It uses the same syntax as .gitignore:

# Ignore experimental definitions
experiments/

# Ignore a specific file
definitions/broken-test.json

# Ignore all files matching a pattern
**/wip-*.json

Paths are relative to the .dokkimi/ directory. Ignored files are still valid for local runs — .dokignore only affects cloud/CI pipelines.