RelationalAI Deployment (Path to Prod)
Covers the path from a built RelationalAI model to production: the rai models CLI (schema deployment + lifecycle) and Snowflake CoWork (Cortex) agents. Built on the relationalai package (PyRel).
Early access. Deploy mode and semantic model management — the rai models deploy + branch/collaborate/merge/teardown lifecycle — are early-access features (documented in the RAI docs' early-access section); the API, messages, and defaults may still change. Op-log recording (the basis for branch/pull/merge) is off by default today, expected to default on soon. Verified against relationalai 1.20.1; see Prerequisites to turn it on. (The Cortex-agent path carries its own GA/PREVIEW markers — see references/cortex-agents.md.)
Summary
What: Everything between a built model and production, by either of two paths. You've built and validated a model; this skill ships it. Schema deployment — deploy into a Snowflake schema and manage its lifecycle: track every change in the op log, fork experiments into branches, collaborate through a shared model, promote vetted changes back with merge, and tear models down safely. Cortex agent — package the model as a Snowflake CoWork agent users query in natural language.
When to use:
- Deploying a model to a Snowflake schema (
rai models deploy) and understanding what the op log records
- Branching a deployed model for isolated experiments (
rai models branch)
- Collaborating with other developers on one model (shared model,
rai models pull)
- Promoting a branch back to its parent (
rai models merge) or removing a model (rai models teardown)
- Deploying a model as a Snowflake CoWork (Cortex) agent
- Choosing a path to prod (schema deployment vs. Cortex agent)
When NOT to use:
- First-time install,
rai connect, or raiconfig.yaml auth/engine tuning — see rai-setup
- Building or evolving the model itself (concepts, rules, queries) — see
rai-ontology, rai-pyrel
- Diagnosing engine performance or failed transactions — see
rai-health
Overview: Start with Choose a path to prod to pick the deployment target. For schema deployment, read Quick Reference for the command surface, then Deploy for the foundation; the lifecycle commands build on a single idea — the op log — so read that first, then load the reference matching the task (branching, collaboration, merge/teardown). Always check Prerequisites before the lifecycle commands — they refuse cleanly if op-log recording is off. For the Cortex-agent path, go straight to references/cortex-agents.md.
Choose a path to prod
A built model reaches production by one of these paths. Pick the target, then follow the matching guidance:
- Deploy into a Snowflake schema — the model's resources and outputs live in a schema you deploy, version, and evolve with
rai models. This is the default path and the foundation for branching and collaboration. Covered below; lifecycle detail in the reference files.
- Deploy as a Snowflake CoWork (Cortex) agent — package the model as a Cortex agent users query in natural language. Use when the deliverable is a conversational agent rather than a deployed schema. → references/cortex-agents.md; reference implementation in examples/deploy.py.
The two are not exclusive: you deploy a model to a schema first, then optionally expose it as a Cortex agent.
Prerequisites
relationalai ≥ 1.20.1 (rai --version) — this skill targets the 1.20 rai models surface.
A reachable Snowflake connection (rai connect passes) and a fully qualified deployment.schema (DB.SCHEMA) — model management co-locates its metadata schema with the model's database. (Bare or unset, it falls back to the connection's database, then the app name — which fails.) For install/auth, see rai-setup.
A model to deploy — a .py model file or package, with model.path set in raiconfig.yaml (or pass --path). Its outputs need a refresh schedule (deployment.schedules + deployment.outputs.schedule) or deploy refuses with "Unscheduled Outputs".
Rules-based reasoning models only (current limitation), with PyRel queries kept out of the model definition — the model file is loaded whole at deploy time.
For branch / pull / merge: op-log recording must be ON. It is off by default (opt-in while rolling out). Turn it on in raiconfig.yaml:
oplog:
enabled: true # required for branch / pull / merge
backend: snowflake # default; 'jsonl' is for local tests/demos only
Without it, branch, pull, and merge refuse with Oplog recording is disabled (config.oplog.enabled = false). deploy and teardown still work (deploy installs the model but records no history).
Quick Reference
The current model is the schema named by deployment.schema in raiconfig.yaml. Every lifecycle command targets it; switch changes it.
| Command |
Purpose |
Key options |
rai models init [NAME] |
Scaffold a starter project |
--name |
rai models deploy |
Install model + record diff to op log |
--path --name --force --wait |
rai models list |
List models (schema, parent, type, HEAD, owner) |
--limit |
rai models switch NAME |
Set the current model (deployment.schema) |
-y/--yes |
rai models branch NAME |
Zero-copy fork into a new schema |
--static |
rai models pull |
Reconcile shared changes into shared_model.py |
--path --force --from-parent |
rai models merge |
Promote branch to parent, retire branch |
--path --delete --force |
rai models teardown |
Drop the current model/branch + schema + op log |
--force --allow-unmerged --allow-children |
deploy --schema overrides deployment.schema for that deploy (working since 1.18; earlier releases ignored it — RAI-51584). As of 1.20, pull / merge / teardown act on the current model only (no --name); use switch to target a different one.
Deploy (the foundation)
rai models deploy does two things: it installs the model's resources and outputs into the target schema, and — when op-log recording is on — it records the diff versus the previously deployed version as operations in the schema's op log.
rai connect # validate config + connectivity first
rai models deploy --wait # --wait blocks until the first refresh completes
When changes are recorded, PyRel reports the count: Recorded 3 change(s) to the snowflake oplog. An empty diff is a no-op (No oplog changes to record). If you deployed owned source changes, PyRel warns you to commit them to version control.
The op log is the model's history — an ordered record of how it changed from one deploy to the next, and the foundation for everything below: deploy appends to the current model's log, branch forks it, merge appends a branch's changes onto its parent's, and collaboration uses it to keep developers in sync. You never edit it directly.
If another developer (or session) deployed since your last pull, the deploy is refused: Remote oplog is ahead (remote seq N, local seq M). Run 'rai models pull' first. Pull, then deploy again.
See references/deploy-and-oplog.md for backends, install-only behavior when the op log is off, and shared_model.py generation.
The deployed lifecycle
Once a model is deployed and op-log recording is on, four flows manage it. Load the reference file for the task:
- Branch — fork the current model into a new schema to experiment in isolation; the parent is untouched. Live branches track the parent; static branches freeze at the fork. → references/branching.md
- Collaborate — several developers work one model. You own your source (synced through version control); PyRel reconciles everyone's shared changes through the op log into a generated
shared_model.py. → references/collaboration.md
- Merge — promote a branch's vetted changes back into its parent and retire the branch. → references/merge-and-teardown.md
- Teardown — drop a model or branch and all its data, with guards against losing unmerged work. → references/merge-and-teardown.md
Reference files
Load only the file matching the task:
| File |
Load when |
| references/deploy-and-oplog.md |
Deploying; the op log, backends, opt-in, install-only mode; refresh schedules, output materialization, REFRESH_STATUS monitoring |
| references/branching.md |
branch, switch, list; live vs. static; --from-parent; single-level limit |
| references/collaboration.md |
Multi-developer work; owned vs. shared; shared_model.py; pull; build_shared |
| references/merge-and-teardown.md |
merge (preconditions, --delete/--force); teardown (dry-run, guards) |
| references/cortex-agents.md |
Deploying the model as a Snowflake CoWork (Cortex) agent — deployment script, DeploymentConfig, tool registry, query catalog, deploy-mode reads (serving precomputed results), grants, debugging |
Examples
Reference implementations for the Cortex-agent path (see references/cortex-agents.md for the full walkthrough):
| Pattern |
Description |
File |
| Cortex deployment script |
Complete lifecycle CLI (preflight / deploy / update / status / chat / teardown) — primary reference |
examples/deploy.py |
| Cortex debug script |
Describe the deployed agent, call each sproc directly, trace a chat turn |
examples/debug.py |
| Model modules |
Core, computed, and query modules for the zero-arg init_tools() pattern |
examples/model/ |
Common Pitfalls
| Mistake |
Cause |
Fix |
branch/pull/merge refuse: "Oplog recording is disabled" |
Op-log recording is off by default (opt-in while rolling out) |
Set oplog.enabled: true in raiconfig.yaml. deploy/teardown work without it |
deploy fails: "Database '...' does not exist or not authorized" |
deploy creates the target schema but not its database |
Create the database first — deploy runs CREATE SCHEMA IF NOT EXISTS <db>.<schema>. If the deploy role lacks CREATE SCHEMA, pre-create the schema (and its _META meta schema, when op-log recording is on) and grant USAGE; deploy confirms it exists and proceeds |
deploy (op-log on) fails: "Insufficient privileges to operate on application 'RELATIONALAI'" |
deployment.schema is bare or unset and the connection has no database — model management falls back to the app name and tries to create its metadata schema inside the app |
Use a fully qualified deployment.schema (DB.SCHEMA), or set database: on the connection (not a grant or account-enablement issue) |
Bare rai models merge fails: "Model file path is required" |
Merge diffs your source to confirm the branch is fully deployed |
Pass --path <model>, or set model.path in config |
merge refuses: "branch has not observed the parent's latest changes" |
Branch isn't rebased on the parent's latest |
On the branch: rai models pull then rai models deploy, then merge |
merge --force doesn't get past a precondition |
--force only affects --delete (drops a branch that has children) |
Rebase the branch (pull + deploy) to satisfy the merge preconditions |
| "Cannot branch from '...': it is itself a branch" |
Branching is single-level in early access |
Branch from the base model instead |
pull/deploy refuse to overwrite shared_model.py |
Fail-closed guard on a hand-edited generated file |
Re-run with --force (backs up to a timestamped .bak); normally let PyRel maintain it |
teardown dropped nothing |
teardown is a dry run by default |
Add --force; use --allow-unmerged / --allow-children only when you intend to lose that work |
Related Skills
rai-setup — install, rai connect, and raiconfig.yaml (do this first)
rai-ontology — build and evolve the model you deploy
rai-pyrel — PyRel syntax and data loading
rai-health — diagnose engine performance, failed transactions, and CDC health
1---2name: rai-deployment3description: Take a built RelationalAI model to production — deploy it into a Snowflake schema and version it through the op log (branch, collaborate, merge, and tear down with the `rai models` CLI), or deploy it as a Snowflake CoWork (Cortex) agent. The one path-to-prod skill across deployment targets. Use when deploying a model, managing its deployed lifecycle, or operationalizing it as a Cortex agent — not for first-time install/connect (see rai-setup), building the model (see rai-ontology, rai-pyrel), or interpreting reasoner output.4---56# RelationalAI Deployment (Path to Prod)7<!-- v1-SENSITIVE -->89Covers the path from a built RelationalAI model to production: the `rai models` CLI (schema deployment + lifecycle) and Snowflake CoWork (Cortex) agents. Built on the [relationalai package](https://pypi.org/project/relationalai) (PyRel).1011> **Early access.** Deploy mode and semantic model management — the `rai models` deploy + branch/collaborate/merge/teardown lifecycle — are **early-access** features (documented in the RAI docs' early-access section); the API, messages, and defaults may still change. Op-log recording (the basis for `branch`/`pull`/`merge`) is **off by default** today, expected to default on soon. Verified against relationalai 1.20.1; see **Prerequisites** to turn it on. (The Cortex-agent path carries its own GA/PREVIEW markers — see [references/cortex-agents.md](references/cortex-agents.md).)1213## Summary1415**What:** Everything between a built model and production, by either of two paths. You've built and validated a model; this skill ships it. **Schema deployment** — deploy into a Snowflake schema and manage its lifecycle: track every change in the op log, fork experiments into branches, collaborate through a shared model, promote vetted changes back with merge, and tear models down safely. **Cortex agent** — package the model as a Snowflake CoWork agent users query in natural language.1617**When to use:**18- Deploying a model to a Snowflake schema (`rai models deploy`) and understanding what the op log records19- Branching a deployed model for isolated experiments (`rai models branch`)20- Collaborating with other developers on one model (shared model, `rai models pull`)21- Promoting a branch back to its parent (`rai models merge`) or removing a model (`rai models teardown`)22- Deploying a model as a Snowflake CoWork (Cortex) agent23- Choosing a path to prod (schema deployment vs. Cortex agent)2425**When NOT to use:**26- First-time install, `rai connect`, or `raiconfig.yaml` auth/engine tuning — see `rai-setup`27- Building or evolving the model itself (concepts, rules, queries) — see `rai-ontology`, `rai-pyrel`28- Diagnosing engine performance or failed transactions — see `rai-health`2930**Overview:** Start with **Choose a path to prod** to pick the deployment target. For **schema deployment**, read **Quick Reference** for the command surface, then **Deploy** for the foundation; the lifecycle commands build on a single idea — the **op log** — so read that first, then load the reference matching the task (branching, collaboration, merge/teardown). **Always check Prerequisites before the lifecycle commands** — they refuse cleanly if op-log recording is off. For the **Cortex-agent path**, go straight to [references/cortex-agents.md](references/cortex-agents.md).3132---3334## Choose a path to prod3536A built model reaches production by one of these paths. Pick the target, then follow the matching guidance:3738- **Deploy into a Snowflake schema** — the model's resources and outputs live in a schema you deploy, version, and evolve with `rai models`. This is the default path and the foundation for branching and collaboration. Covered below; lifecycle detail in the reference files.39- **Deploy as a Snowflake CoWork (Cortex) agent** — package the model as a Cortex agent users query in natural language. Use when the deliverable is a conversational agent rather than a deployed schema. → [references/cortex-agents.md](references/cortex-agents.md); reference implementation in [examples/deploy.py](examples/deploy.py).4041The two are not exclusive: you deploy a model to a schema first, then optionally expose it as a Cortex agent.4243---4445## Prerequisites4647- **relationalai ≥ 1.20.1** (`rai --version`) — this skill targets the 1.20 `rai models` surface.48- A reachable Snowflake connection (`rai connect` passes) and a **fully qualified `deployment.schema` (`DB.SCHEMA`)** — model management co-locates its metadata schema with the model's database. (Bare or unset, it falls back to the connection's `database`, then the app name — which fails.) For install/auth, see `rai-setup`.49- A model to deploy — a `.py` model file or package, with `model.path` set in `raiconfig.yaml` (or pass `--path`). Its outputs need a refresh schedule (`deployment.schedules` + `deployment.outputs.schedule`) or deploy refuses with "Unscheduled Outputs".50- **Rules-based reasoning models only** (current limitation), with PyRel queries kept out of the model definition — the model file is loaded whole at deploy time.51- **For `branch` / `pull` / `merge`: op-log recording must be ON.** It is **off by default** (opt-in while rolling out). Turn it on in `raiconfig.yaml`:5253 ```yaml54 oplog:55 enabled: true # required for branch / pull / merge56 backend: snowflake # default; 'jsonl' is for local tests/demos only57 ```5859 Without it, `branch`, `pull`, and `merge` refuse with `Oplog recording is disabled (config.oplog.enabled = false).` `deploy` and `teardown` still work (deploy installs the model but records no history).6061---6263## Quick Reference6465The **current model** is the schema named by `deployment.schema` in `raiconfig.yaml`. Every lifecycle command targets it; `switch` changes it.6667| Command | Purpose | Key options |68|---|---|---|69| `rai models init [NAME]` | Scaffold a starter project | `--name` |70| `rai models deploy` | Install model + record diff to op log | `--path` `--name` `--force` `--wait` |71| `rai models list` | List models (schema, parent, type, HEAD, owner) | `--limit` |72| `rai models switch NAME` | Set the current model (`deployment.schema`) | `-y/--yes` |73| `rai models branch NAME` | Zero-copy fork into a new schema | `--static` |74| `rai models pull` | Reconcile shared changes into `shared_model.py` | `--path` `--force` `--from-parent` |75| `rai models merge` | Promote branch to parent, retire branch | `--path` `--delete` `--force` |76| `rai models teardown` | Drop the current model/branch + schema + op log | `--force` `--allow-unmerged` `--allow-children` |7778`deploy --schema` overrides `deployment.schema` for that deploy (working since 1.18; earlier releases ignored it — RAI-51584). As of 1.20, `pull` / `merge` / `teardown` act on the **current model only** (no `--name`); use `switch` to target a different one.7980---8182## Deploy (the foundation)8384`rai models deploy` does two things: it installs the model's resources and outputs into the target schema, and — when op-log recording is on — it records the *diff* versus the previously deployed version as operations in the schema's **op log**.8586```sh87rai connect # validate config + connectivity first88rai models deploy --wait # --wait blocks until the first refresh completes89```9091When changes are recorded, PyRel reports the count: `Recorded 3 change(s) to the snowflake oplog.` An empty diff is a no-op (`No oplog changes to record`). If you deployed owned source changes, PyRel warns you to commit them to version control.9293**The op log is the model's history** — an ordered record of how it changed from one deploy to the next, and the foundation for everything below: `deploy` appends to the current model's log, `branch` forks it, `merge` appends a branch's changes onto its parent's, and collaboration uses it to keep developers in sync. You never edit it directly.9495If another developer (or session) deployed since your last pull, the deploy is refused: `Remote oplog is ahead (remote seq N, local seq M). Run 'rai models pull' first.` Pull, then deploy again.9697See [references/deploy-and-oplog.md](references/deploy-and-oplog.md) for backends, install-only behavior when the op log is off, and `shared_model.py` generation.9899---100101## The deployed lifecycle102103Once a model is deployed and op-log recording is on, four flows manage it. Load the reference file for the task:1041051. **Branch** — fork the current model into a new schema to experiment in isolation; the parent is untouched. Live branches track the parent; static branches freeze at the fork. → [references/branching.md](references/branching.md)1062. **Collaborate** — several developers work one model. You own your source (synced through version control); PyRel reconciles everyone's *shared* changes through the op log into a generated `shared_model.py`. → [references/collaboration.md](references/collaboration.md)1073. **Merge** — promote a branch's vetted changes back into its parent and retire the branch. → [references/merge-and-teardown.md](references/merge-and-teardown.md)1084. **Teardown** — drop a model or branch and all its data, with guards against losing unmerged work. → [references/merge-and-teardown.md](references/merge-and-teardown.md)109110## Reference files111112Load only the file matching the task:113114| File | Load when |115|---|---|116| [references/deploy-and-oplog.md](references/deploy-and-oplog.md) | Deploying; the op log, backends, opt-in, install-only mode; refresh schedules, output materialization, `REFRESH_STATUS` monitoring |117| [references/branching.md](references/branching.md) | `branch`, `switch`, `list`; live vs. static; `--from-parent`; single-level limit |118| [references/collaboration.md](references/collaboration.md) | Multi-developer work; owned vs. shared; `shared_model.py`; `pull`; `build_shared` |119| [references/merge-and-teardown.md](references/merge-and-teardown.md) | `merge` (preconditions, `--delete`/`--force`); `teardown` (dry-run, guards) |120| [references/cortex-agents.md](references/cortex-agents.md) | Deploying the model as a Snowflake CoWork (Cortex) agent — deployment script, `DeploymentConfig`, tool registry, query catalog, deploy-mode reads (serving precomputed results), grants, debugging |121122---123124## Examples125126Reference implementations for the Cortex-agent path (see [references/cortex-agents.md](references/cortex-agents.md) for the full walkthrough):127128| Pattern | Description | File |129|---|---|---|130| Cortex deployment script | Complete lifecycle CLI (preflight / deploy / update / status / chat / teardown) — primary reference | [examples/deploy.py](examples/deploy.py) |131| Cortex debug script | Describe the deployed agent, call each sproc directly, trace a chat turn | [examples/debug.py](examples/debug.py) |132| Model modules | Core, computed, and query modules for the zero-arg `init_tools()` pattern | [examples/model/](examples/model/) |133134---135136## Common Pitfalls137138| Mistake | Cause | Fix |139|---|---|---|140| `branch`/`pull`/`merge` refuse: "Oplog recording is disabled" | Op-log recording is **off by default** (opt-in while rolling out) | Set `oplog.enabled: true` in `raiconfig.yaml`. `deploy`/`teardown` work without it |141| `deploy` fails: "Database '...' does not exist or not authorized" | `deploy` creates the target **schema** but not its database | Create the database first — `deploy` runs `CREATE SCHEMA IF NOT EXISTS <db>.<schema>`. If the deploy role lacks `CREATE SCHEMA`, pre-create the schema (and its `_META` meta schema, when op-log recording is on) and grant `USAGE`; deploy confirms it exists and proceeds |142| `deploy` (op-log on) fails: "Insufficient privileges to operate on application 'RELATIONALAI'" | `deployment.schema` is bare or unset and the connection has no `database` — model management falls back to the app name and tries to create its metadata schema inside the app | Use a fully qualified `deployment.schema` (`DB.SCHEMA`), or set `database:` on the connection (not a grant or account-enablement issue) |143| Bare `rai models merge` fails: "Model file path is required" | Merge diffs your source to confirm the branch is fully deployed | Pass `--path <model>`, or set `model.path` in config |144| `merge` refuses: "branch has not observed the parent's latest changes" | Branch isn't rebased on the parent's latest | On the branch: `rai models pull` then `rai models deploy`, then merge |145| `merge --force` doesn't get past a precondition | `--force` only affects `--delete` (drops a branch that has children) | Rebase the branch (pull + deploy) to satisfy the merge preconditions |146| "Cannot branch from '...': it is itself a branch" | Branching is single-level in early access | Branch from the base model instead |147| `pull`/`deploy` refuse to overwrite `shared_model.py` | Fail-closed guard on a hand-edited generated file | Re-run with `--force` (backs up to a timestamped `.bak`); normally let PyRel maintain it |148| `teardown` dropped nothing | `teardown` is a dry run by default | Add `--force`; use `--allow-unmerged` / `--allow-children` only when you intend to lose that work |149150---151152## Related Skills153- `rai-setup` — install, `rai connect`, and `raiconfig.yaml` (do this first)154- `rai-ontology` — build and evolve the model you deploy155- `rai-pyrel` — PyRel syntax and data loading156- `rai-health` — diagnose engine performance, failed transactions, and CDC health