Skip to main content

Manage project

A Wren project is the unit of authoring, version control, and deployment for MDL. This recipe covers the lifecycle — initialization, validation, build, profile management, multi-environment workflow, and migration.

What you'll end up with

  • A clean understanding of which files live in the project vs. globally in ~/.wren/
  • The lifecycle commands wired into your editor / CI
  • Multiple profiles set up for dev / staging / prod against the same project
  • A safe pattern for switching environments without touching secrets

Project lifecycle

wren context init # scaffold a new project in cwd
wren context validate # check YAML structure (no DB required)
wren context build # compile YAML to target/mdl.json
wren context upgrade # upgrade to the latest schema_version
wren context set-profile pg # bind a connection profile to the project
wren memory index # index schema + knowledge/ for recall

A typical first-time setup:

mkdir my_project && cd my_project
wren context init
# (edit models/, relationships.yml, knowledge/ — usually agent-driven)
wren context validate
wren context build
wren profile add pg-dev --from-file dev.yml --activate
wren context set-profile pg-dev
wren memory index
wren --sql "SELECT 1"

After editing models, rebuild and re-index:

wren context build
wren memory index

wren_project.yml at the project root

schema_version: 5
name: my_project
version: "1.0"
catalog: wren
schema: public
data_source: postgres
profile: pg-dev
FieldPurpose
schema_versionProject layout version (current: 5 — the layout below). Owned by the CLI — bump with wren context upgrade. The knowledge/ base tracks its own version in knowledge/knowledge.yml, independent of this one.
nameProject identifier.
versionYour own project version (free-form).
catalog / schemaWren AI namespace, not your database catalog/schema. Defaults: wren / public.
data_sourceData source type — postgres, bigquery, etc. Set by wren context set-profile.
profileThe bound connection profile. Set by wren context set-profile.

The same field names catalog and schema appear inside each model's table_reference to point at the database. Do not confuse the two — see the MDL schema reference for the full distinction.

Project layout

wren context init scaffolds the current layout (v5): per-model and per-view folders, cubes/ for pre-aggregated semantic objects, a first-class knowledge/ base, and (added later) GenBI apps/.

Everything below lives in the project (version-controlled), except target/ (build output) and .wren/ (project-local runtime state), which are gitignore-able. Connection credentials and global CLI state live separately under ~/.wren/ (see Where profiles live).

my_project/
├── wren_project.yml # project manifest (fields above)

├── models/<name>/ # MDL — one folder per model
│ ├── metadata.yml # columns, primary_key, table_reference, …
│ └── ref_sql.sql # (optional) SQL-defined model body
├── views/<name>/ # MDL — one folder per view
│ ├── metadata.yml # view definition
│ └── sql.yml # (optional) statement in a separate file
├── relationships.yml # MDL — all relationships between models
├── cubes/<name>/ # (optional) pre-aggregation cubes
│ └── metadata.yml # base_object, measures, dimensions, …

├── knowledge/ # knowledge base (committed)
│ ├── rules/ # business rules — read by `wren context instructions`
│ ├── glossary/ # business-term definitions
│ ├── metrics/ # named metric definitions
│ ├── caveats/ # data caveats / gotchas
│ ├── sql/ # NL→SQL pairs — source of truth for memory
│ └── knowledge.yml # knowledge-axis schema_version (decoupled from MDL)

├── AGENTS.md # AI agent workflow guidance for this project

├── apps/<name>/ # (optional) generated GenBI apps — see the GenBI guide
│ ├── index.html # app entry point
│ └── mdl.json # compiled MDL copied into the app

├── target/
│ └── mdl.json # compiled MDL — `wren context build`
└── .wren/ # project-local runtime state (gitignore-able)
├── memory/ # LanceDB semantic index over knowledge/sql/ — `wren memory index`
└── apps.yml # GenBI app index — written by `wren genbi register`

knowledge/ carries what the database schema cannot — business rules, glossary terms, named metrics, caveats, and the NL→SQL pairs under knowledge/sql/ (written by wren memory store). It tracks its own schema_version in knowledge.yml, decoupled from the MDL layout version because knowledge and the data model evolve on different cadences. knowledge/rules/ supersedes the older single-file instructions.md, and knowledge/sql/ supersedes queries.yml; both legacy files are still read for back-compat but are no longer scaffolded.

The memory extra builds a semantic (embedding) index under .wren/memory/; without it, recall falls back to reading knowledge/sql/*.md directly — so knowledge/sql/, not the index, is the source of truth.

apps/<name>/ and .wren/apps.yml are added by the GenBI workflow; .wren/apps.yml is machine-written via wren genbi register/remove — never edit it by hand.

Profile management

Profiles separate connection credentials from project definitions. The same MDL project can connect to multiple databases by switching profiles.

wren profile list # list all profiles (* marks active)
wren profile add pg-prod --ui # create via browser form
wren profile switch pg-prod # change the globally active profile
wren profile debug # show resolved config (secrets masked)
wren profile rm old-db # remove a profile

Where profiles live

~/.wren/profiles.yml # global, all profiles + active pointer
~/.wren/config.yml # global CLI preferences, default_project

The file is written with 0600 permissions. Secrets use ${ENV_VAR} interpolation — see Secrets and .env files below.

Profile vs project at a glance

ProfileProject
WhatConnection credentialsMDL model definitions
Where~/.wren/profiles.yml (global)<project>/wren_project.yml + models/
ScopeShared across all projectsPer-project — version controlled
SecretsContains themNone — safe to commit

Multi-environment workflow

A single MDL project can be bound to different profiles for different environments.

Pattern 1: switch profile globally

wren profile switch pg-dev # work against dev
wren profile switch pg-prod # switch to prod for one query
wren profile switch pg-dev # back to dev

Pattern 2: bind a profile per project

cd ~/projects/sales
wren context set-profile pg-prod # writes profile + data_source into wren_project.yml

After binding, every command in this project uses pg-prod regardless of the globally active profile. Useful when you have multiple projects open at once.

Pattern 3: per-shell override

export WREN_PROJECT_HOME=~/projects/sales
wren --connection-file ./connection.yml --sql "SELECT 1"

Useful for CI jobs that need to point at a specific database without touching ~/.wren/profiles.yml.

Secrets and .env files

Any profile value can reference ${VAR_NAME} placeholders. Resolution order (first match wins):

  1. os.environ — variables exported in your shell
  2. $CWD/.env — directory you run wren from
  3. <project>/.env — co-located with wren_project.yml
  4. ~/.wren/.env — user-global fallback
# ~/.wren/profiles.yml
profiles:
pg-prod:
datasource: postgres
host: db.example.com
port: '5432'
database: wren
user: ${POSTGRES_USER}
password: ${POSTGRES_PASSWORD}
# .env (in project root, gitignored)
POSTGRES_USER=paul
POSTGRES_PASSWORD=s3cr3t

Rules:

  • Names must be UPPERCASE ([A-Z_][A-Z0-9_]*)
  • $$ escapes a literal dollar sign
  • Missing vars fail early with a clear error — no cryptic driver errors

AI coding agents should never ask for credentials in chat. The agent writes a profile referencing ${POSTGRES_PASSWORD} and instructs you to fill the value in .env via your editor.

Migrate from an existing manifest

wren context init accepts two import flags, one per external manifest format. Both produce the same wren project layout, ready for validate / build. They are mutually exclusive.

SourceCommandWhen to use
Wren mdl.json (camelCase)wren context init --from-mdl /path/to/mdl.json --path my_projectYou have an older mdl.json from a previous Wren setup.
OSI semantic_model.yamlwren context init --from-osi /path/to/semantic_model.yaml --data-source postgres --path my_projectYou have an Open Semantic Interchange file and want to leave the OSI flow to use Wren-only features (cubes, views, RLAC).

After either import:

wren context validate --path my_project
wren context build --path my_project

If the target directory already has project files, use --force to overwrite.

For --from-osi, see the dedicated OSI guide — it covers the alternative of keeping OSI as the source of truth (wren context build --from-osi) instead of migrating once.

Upgrade an existing project

When a new layout schema_version ships, upgrade with:

wren context upgrade # bumps to the latest schema_version
wren context upgrade --to 5 # bump to a specific version
wren context upgrade --dry-run # preview without writing

After upgrade, re-validate and re-build:

wren context validate
wren context build

Some versions add content beyond the automatic restamp — e.g. v5 introduces knowledge/ and makes it the home for business rules and NL→SQL memory, so there are extra steps to move instructions.md and an existing LanceDB index across. Per-version steps live in the Migration reference.

When to come back here

  • Adding a new environment (staging / preview / customer X)
  • Onboarding a new teammate (point them at ~/.wren/profiles.yml setup)
  • A schema_version bump shows up in a release
  • Migrating from another semantic layer manifest

See also