Writes cpln CLI commands and workflows for Control Plane. Use when the user asks about cpln login, cpln apply, cpln workload, CLI or CI/CD deploys, container debugging with cpln exec/logs, or any cpln resource command.
Scanned 8/31/2026
Install via CLI
openskills install controlplane-com/ai-plugin---
name: cpln
description: "Writes cpln CLI commands and workflows for Control Plane. Use when the user asks about cpln login, cpln apply, cpln workload, CLI or CI/CD deploys, container debugging with cpln exec/logs, or any cpln resource command."
---
# cpln CLI
**MCP first; the CLI is the fallback** — use it when the MCP server is unavailable or unauthenticated, for the CLI-only operations below, and for interactive debugging or scripted GitOps. **In CI/CD the CLI is the primary interface** — pipelines authenticate with a service-account key in `CPLN_TOKEN`, build and push images (`cpln image build --push`, or `--remote` on a runner with no Docker daemon), and apply resources (`cpln apply --ready`). Platform rules (resource model, secrets, destructive ops, production defaults, scale-to-zero, firewall) live in `rules/cpln-guardrails.md`; this skill is the CLI mechanics.
**Never write a `cpln` command from memory.** Verify every verb and flag with `cpln <command> --help` before quoting it. If a command isn't in the resource command map below, assume it isn't real.
## CLI-only operations
No MCP equivalent — the CLI's primary job:
| Command | Purpose |
|---|---|
| `cpln image build` | Build a container image — locally with Docker, or on Control Plane with `--remote` (no daemon) — and push to the org registry |
| `cpln image copy` | Copy an image between orgs |
| `cpln port-forward` | Forward local ports to a running workload |
| `cpln convert` | Convert Kubernetes manifests to Control Plane specs (Compose is `cpln stack`) |
| `cpln cp` | Copy files in or out of a running container |
| `cpln apply` | Scripted GitOps — declarative create-or-update from files |
One-shot and interactive container commands, TTY sessions (`workload connect`, `exec -it`), and streamed logs (`cpln logs --tail`) are also CLI-only; MCP's `get_workload_logs` covers bounded log fetches. Everything else — discovery and CRUD — prefer the MCP tools (generic `mcp__cpln__list_resources` / `get_resource` / `delete_resource` with a `kind`, typed `create_*`/`update_*` for mutations).
When no MCP tool covers a resource, field, or sub-endpoint, use the `cpln` CLI for that piece (ground the command in this skill and `--help`) or tell the user what is missing. The raw-API escape hatch (`cpln_api_request`) is disabled by default — it bypasses the typed tools' pre-call validation.
## Setup & auth
```bash
cpln login # interactive (opens a browser); creates the "default" profile
cpln profile update default --org ORG --gvc GVC # set defaults ("update" creates the profile if missing)
```
**CI/CD needs no profile.** With `CPLN_TOKEN` set (service-account key, from `cpln serviceaccount add-key`), the CLI runs a profile-less session against `api.cpln.io`. Add `CPLN_ORG` / `CPLN_GVC` for defaults and `CPLN_SKIP_UPDATE_CHECK=1` to silence update checks. Resolution everywhere is **flag, then env var, then profile**: `--org` beats `CPLN_ORG` beats the profile default — same for `--gvc`/`CPLN_GVC`, `--profile`/`CPLN_PROFILE`, `--endpoint`/`CPLN_ENDPOINT`, `--token`/`CPLN_TOKEN`. Profiles live in `~/.config/cpln` (override with `CPLN_HOME`).
**Never pass `--token`** — it leaks into logs and shell history; use `CPLN_TOKEN` or a profile. Inspect context with `cpln profile get` — **there is no `cpln whoami`.** **`cpln profile token` (prints the profile's live access JWT) is break-glass** — it exposes a live credential: never suggest it or run it on your own; use it only when the user explicitly asks. **Secret data commands are off-limits entirely** — never run or suggest `cpln secret reveal`, `cpln secret create-*`, `cpln secret edit`, or `cpln secret delete`; the user manages secret values and lifecycle themselves. Explain any profile state changes so operators can revert them.
## Command structure & shared flags
```
cpln <resource> <action> [REF] [--flags]
```
Standalone (break the pattern): `cpln apply`, `delete`, `logs`, `port-forward`, `cp`, `convert`, `login`. Aliases: `workload`=`w`, `identity`=`id`, `serviceaccount`=`sa`, `location`=`loc`, `stack`=`compose`. Shell completion: `cpln misc install-completion` (bash/zsh/fish).
Flags on nearly every command — never list per-command:
- **Context**: `--profile`, `--org`, `--gvc`
- **Output**: `--output`/`-o` (`text|json|yaml|json-slim|yaml-slim|tf|crd|names`), `--color`, `--ts` (`iso|local|age`), `--max` (default 50; `0` = all)
- **Request**: `--token`, `--endpoint`, `--insecure`/`-k` · **Debug**: `--verbose`/`-v`, `--debug`/`-d`
- **Always use `yaml-slim`/`json-slim` for round-tripping.** Plain `yaml`/`json` include server-side fields (`status`, `id`, `created`, `lastModified`, `links`) that break `cpln apply`.
- **Include `--org` (and `--gvc`) explicitly on every mutation**, even with profile defaults. `--gvc` exists on all subcommands of GVC-scoped resources (workload, identity, volumeset) plus helm, stack, apply, convert, cp, delete, port-forward — but **not** on `cpln logs` (GVC goes inside the LogQL query).
- **Cap lists with `--max`.** Omit only when targeting a specific named resource.
## Standard CRUD
| Action | Syntax | Notes |
|---|---|---|
| **List** | `cpln <resource> get` | No args = list all. **There is NO `list` subcommand.** |
| **Get** | `cpln <resource> get REF...` | |
| **Create** | `cpln <resource> create --name NAME` | Also `--description`, `--tag K=V` |
| **Delete** | `cpln <resource> delete REF...` | Multiple refs |
| **Edit** | `cpln <resource> edit REF` | Opens YAML in `$EDITOR`. `--replace` replaces instead of merging |
| **Patch** | `cpln <resource> patch REF --file FILE` | |
| **Tag** | `cpln <resource> tag REF... --tag K=V` | Remove: `--remove-tag KEY` |
| **Update** | `cpln <resource> update REF --set PROP=VAL` | Also `--unset PROP`; array props take `+=` / `=` / `-=` |
| **Clone** | `cpln <resource> clone REF --name NEW` | Spec only. Not on every kind (map below) |
| **Audit** | `cpln <resource> audit [REF]` | `--since` (default 7d), `--from`/`--to`, `--subject`, `--context` |
| **Query** | `cpln <resource> query` | See below |
Also on most kinds: `access-report REF`, `eventlog REF`, `permissions` (no args). **`eventlog` has the alias `log`** — `cpln workload log` shows platform events, NOT container logs (those come from `cpln logs`).
### Query
```bash
cpln workload query --match all --tag environment=production --tag region=europe
cpln workload query --match any --rel gvc=gvc-a --rel gvc=gvc-b
cpln workload query --property name=my-workload
```
`--match` (`all` default / `any` / `none`); `--tag KEY=VALUE`, `--property`/`--prop NAME=VALUE` (e.g. `status.phase=running`), `--rel KIND=VALUE` — all repeatable. The `gvc`, `policy`, and `group` create commands accept `--query-match`/`--query-tag`/`--query-property`/`--query-rel` (group also `--query-kind user`) for dynamic targeting. Full language: `query-spec` skill.
## Resource command map
Core anti-hallucination reference. **Scope**: org = needs `--org`; gvc = needs `--org` + `--gvc`; local = no API call. "Full" = create, get, delete, edit, patch, tag, update (audit, eventlog, query, access-report, permissions exist nearly everywhere).
| Resource | Scope | CRUD | Non-standard subcommands |
|---|---|---|---|
| **workload** (`w`) | gvc | Full + clone | `connect`, `exec`, `run`, `cron` (get/run/start/stop), `replica` (get/stop), `force-redeployment`, `get-deployments`, `open`, `start`, `stop` |
| **gvc** | org | Full + clone | `add-location`, `remove-location` (both `--location`, repeatable), `delete-all-workloads` |
| **secret** | org | get only — secret data and lifecycle are managed by the user | — |
| **policy** | org | Full + clone | `add-binding`, `remove-binding` |
| **identity** (`id`) | gvc | Full, **no clone** | — |
| **volumeset** | gvc | Full, no clone | `expand`, `shrink`, `snapshot` (create/delete/get/restore), `volume` (delete/get) |
| **domain** | org | create, delete, edit, patch, tag — **no update**, no clone | — |
| **cloudaccount** | org | **No generic create, no update** | `create-aws`, `create-azure`, `create-gcp`, `create-ngs` |
| **image** | org | get, delete, edit, patch, tag only | `build`, `copy`, `docker-login` |
| **agent** | org | Full, no clone | `info`, `manifest`, `up` |
| **group** | org | Full + clone | `add-member`, `remove-member` (`--email`, `--serviceaccount`) |
| **ipset** | org | Full + clone | `add-location`, `remove-location`, `update-location` |
| **serviceaccount** (`sa`) | org | **No update**; clone | `add-key` (`--description` required), `remove-key` |
| **mk8s** | org | **No create**; clone | `dashboard`, `health`, `join`, `kubeconfig` |
| **user** | org | No create | `invite` (`--email`, optional `--group`) |
| **org** | — | create (needs `--accountId`, `--invitee`); **no delete** | — |
| **profile** | local | get, delete, update (creates if missing; alias `create`) | `login`, `set-default`, `token` |
| **helm** | gvc | — | `install` (alias `apply`), `upgrade`, `uninstall`, `get`, `list`, `history`, `rollback`, `template` |
| **stack** (`compose`) | gvc | — | `deploy` (alias `up`), `manifest`, `rm` (alias `down`) |
| **location** (`loc`) | org | create, delete (BYOK locations only), edit, patch — no update | `install`, `uninstall` |
| **auditctx** | org | Full + clone, **no delete** | — |
| **quota** | org | get, edit, patch | — |
| **task** | org | get, delete | `complete`, `get-mine` |
| **account** | — | get only | — |
| **rest** | — | — | `get`, `post`, `put`, `patch`, `delete`, `create`, `edit` against raw API paths |
| **operator** | local | — | `install`, `uninstall` |
## Non-standard commands
### cpln apply / cpln delete
```bash
cpln apply --file ./manifests/ --gvc GVC --ready # DIRECTORY — recursive over .yaml/.yml/.json
cpln apply --file all.yaml --ready # MULTI-DOC file (resources split by ---)
cpln apply --file - < manifest.yaml # stdin
cpln delete --file manifest.yaml # delete the resources listed in a file
```
**Apply multi-resource deploys in one call** (directory or multi-doc file) — the CLI sorts resources into dependency order before applying: `agent, secret, cloudaccount, gvc, identity, volumeset, policy, workload` (other kinds after); `cpln delete --file` runs the same order reversed. Splitting into multiple calls reintroduces the ordering problem. Apply is a PUT upsert — it prints `Created`/`Updated` per resource. **It does not stop at the first failure**: it applies every resource, then aborts with all failures at once, so a later `references non-existent X` error is normally a cascade of an earlier resource being rejected, not an ordering bug. Fix the first failure and re-apply the whole bundle. `--ready` polls workloads (5s interval, up to 5 min) until ready. `--k8s` converts Kubernetes manifests inline (Deployment/Secret/ConfigMap/PVC; pull secrets get linked onto the GVC).
GVC targeting for GVC-scoped resources:
- **Single-GVC bundle** (common): pass `--gvc GVC` — it fills in the GVC for every resource that doesn't declare one.
- **Multi-GVC bundle**: declare `gvc:` inline as a top-level field (same level as `kind`/`name`) and omit the flag.
- Inline `gvc:` plus a **different** `--gvc` value = hard error; they must agree.
- Org-scoped resources ignore the GVC field/flag entirely.
```yaml
kind: workload
name: my-app
gvc: prod # target GVC declared inline
spec: { ... }
```
### cpln logs
```bash
cpln logs '{gvc="GVC", workload="WORKLOAD"}' --org ORG --tail
```
- The query is a **positional argument** (first arg, single quotes, LogQL). `--gvc` is **not** a flag here.
- Labels: `container`, `gvc`, `location`, `provider`, `replica`, `stream`, `workload`. Special: `container="_accesslog"` for HTTP access logs.
- Filters: `|= "error"` (contains), `!= "debug"` (excludes), `|~ "timeout|crash"` (regex).
- Streaming: `--tail` (also `-t`/`-f`). **`--follow` does NOT exist.**
- `--limit N` (default 30; `0` = unlimited, auto-paginates), `--since` (default `1h`), `--from`/`--to`, `--direction forward|backward`, and its own `-o default|raw|jsonl` (`raw` strips labels and timestamps). Full LogQL: `logql-observability` skill.
### cpln workload create
```bash
cpln workload create --name APP --image IMAGE --gvc GVC [flags]
```
`--type` (`serverless|standard`, default `standard`) — **`stateful` and `cron` CANNOT be created via CLI flags; use `cpln apply --file`.** Other flags: `--port` (default 8080 — must match the container's listening port), `--public`, `--identity`, `--env KEY=VALUE`, `--cpu` (default 50m), `--memory`/`--mem` (default 128Mi), `--volume`, `--container-name`, `--inherit-env`. Internal images: `//image/NAME:TAG`.
### Debugging — exec / connect / run / cron / replica
- **exec** — one-shot command in an existing replica: `cpln workload exec APP --gvc GVC -- ls -la`. **The `-- CMD ARG1 ARG2...` part must be last on the line** — every cpln flag (`--container`, `--location`, `--replica`, `--stdin`/`-i`, `--tty`/`-t`, `--quiet`/`-q`) goes before the `--`; everything after it runs in the replica (same rule for `run` and `cron run`)
- **connect** — interactive shell: `cpln workload connect APP --gvc GVC` (`--shell`, default `bash`; same targeting flags)
- **run** — temporary workload + command: `cpln workload run --image IMAGE --gvc GVC -- CMD` (`--clone WORKLOAD`, `--rm`, `-i`, `--cpu`, `--memory`, `--command`/`-c`, `--arg`/`-a`, `--location`)
- **cron run** — one-off execution of a cron workload: `cpln workload cron run --gvc GVC -- CMD` (`--background`/`-b`, `--timeout` default 600s, `--identity`, `--image`, `--env`)
- **cron start** — trigger the job now, optionally overriding `--env`, `--command`, `--arg`, `--active-deadline-seconds`; **cron stop** REF needs `--replica-name` + `--location` (both required); **cron get** REF lists job executions
- **replica get / stop** — list replica names per location; `stop` requires `--replica-name` + `--location`
When `--location` / `--replica` / `--container` are omitted, the CLI defaults to the GVC's first location, the first replica, and the only container (multi-container: the first one with `ports`, else the first) — it prints a "defaulting to" notice. Pass all three explicitly on multi-location or multi-container workloads.
### cpln policy add-binding
```bash
cpln policy add-binding POLICY --permission reveal --identity //gvc/GVC/identity/ID
```
`--permission` required; at least one principal flag required; **all repeatable** (`--email`, `--serviceaccount`, `--group`, `--identity` — name or full link).
### cpln port-forward / cp
```bash
cpln port-forward WORKLOAD [LOCAL:]REMOTE... --gvc GVC # --address (default localhost), --location, --replica
cpln cp LOCAL WORKLOAD:PATH --gvc GVC # reverse the args (WORKLOAD:PATH LOCAL) to copy out; --container, --location, --replica
```
### Migration tools
- `cpln convert --file K8S.yaml` — Kubernetes manifest to Control Plane spec (`--protocol http|http2|grpc|tcp` for container ports)
- `cpln helm install RELEASE CHART --gvc GVC` — Helm charts and template catalog installs (`--wait`, `--timeout` default 300s, `--set`, `--values`)
- `cpln stack deploy --gvc GVC` — Docker Compose from the current directory (`--dir`, `--compose-file` for alternative naming, `--build` default true)
### Volumeset command verbs
Dedicated verb per operation; the flags are **singular** — `--location`, `--volume-index` (plural forms don't exist):
| Operation | Command | Risk |
|---|---|---|
| Expand volume | `cpln volumeset expand REF --new-size GIB [--location LOC] [--volume-index N]` | Safe |
| Create snapshot | `cpln volumeset snapshot create REF --snapshot-name NAME [--location LOC] [--volume-index N]` | Safe |
| Restore snapshot | `cpln volumeset snapshot restore REF --snapshot-name NAME --location LOC --volume-index N` (all required) | Overwrites volume state |
| Delete snapshot | `cpln volumeset snapshot delete REF --snapshot-name NAME` | Destructive |
| Delete volume | `cpln volumeset volume delete REF [--location LOC] [--volume-index N]` | Destructive (data loss) |
| Shrink volume | `cpln volumeset shrink REF --new-size GIB [--location LOC]` | **DESTRUCTIVE — permanent data loss** |
`shrink` provisions a new, smaller volume and removes the old one — data is **not** migrated. Safe only with built-in redundancy (Kafka replication; Cassandra/CockroachDB), on `ext4`/`xfs` (not `shared`). Apply the destructive-op confirmation from `rules/cpln-guardrails.md` first. Detail: `stateful-storage` skill.
## Commands that don't exist
| Wrong | Correct |
|---|---|
| `cpln <resource> list` | `cpln <resource> get` (no args = list all) |
| `cpln logs --follow` | `cpln logs --tail` (or `-t` / `-f`) |
| `cpln workload log` for container logs | that's the `eventlog` alias (platform events); container logs = `cpln logs '{gvc="GVC", workload="W"}'` |
| `cpln cloudaccount create` | `cpln cloudaccount create-aws` / `create-azure` / `create-gcp` / `create-ngs` |
| `cpln mk8s create` | `cpln apply --file mk8s-manifest.yaml` |
| `cpln workload update REF --identity X` | `cpln workload update REF --set spec.identityLink=//identity/X` |
| `cpln gvc update REF --location LOC` | `cpln gvc add-location REF --location LOC` |
| `cpln identity clone` | identity has no clone — `get -o yaml-slim`, edit the name, `cpln apply` |
| `cpln volumeset ... --locations / --volume-indexes` | singular: `--location`, `--volume-index` |
| `cpln whoami` | `cpln profile get` (context) / `cpln account get` |
## Building & referencing images
`cpln image build` puts an image in the org's **private registry** — the registry referenced in workload specs as `//image/NAME:TAG`. Two ways to run it:
```bash
cpln image build --name my-app:v1.0 --remote # builds on Control Plane, pushes for you — no Docker
cpln image build --name my-app:v1.0 --push # builds through the local Docker daemon
```
- **`--remote`**: uploads `--dir` (default `.`, filtered by `.dockerignore` or `.gitignore`, capped at 500 MB / 20,000 files), or builds a GitHub/GitLab HTTPS repo given with `--repo` (+ `--branch`). The service picks Dockerfile vs generated build and always produces `linux/amd64`. `--detach` returns a build id; `Ctrl+C` stops watching but not the build.
- **Local**: Dockerfile auto-detected in `--dir` or passed with `--dockerfile PATH`, built with Docker (buildx when available); no Dockerfile means a buildpack build via `pack` (auto-downloaded), default builder `heroku/builder:24_linux-amd64`, everything after `--` goes to `pack`. `--platform` defaults to `linux/amd64`; multi-arch lists need buildx and `--push`. `--env` is **build-time only**, never runtime.
- **`--dockerfile`, `--builder`, `--buildpack`, `--env`, `--env-file`, `--trust-builder`, `--trust-extra-buildpacks`, `--platform`, and `--push` are rejected with `--remote`**; `--repo`, `--branch`, and `--detach` error without it.
- **A Docker daemon is required for a local build only.** On thin CI runners use `--remote`, or `docker build` + `docker push` against the org registry after `cpln image docker-login`.
- Cross-org copy: `cpln image copy NAME:TAG --to-org ORG2 [--to-name NEW] [--to-profile P]` — logs into both registries, then pulls, tags, pushes. **`copy` has no `--remote` mode; it still needs a local daemon.**
Image reference rules in workload specs:
| Source | Reference in spec | Pull secret? |
|---|---|---|
| **Your org's registry (internal)** | `//image/NAME:TAG` — never the `ORG.registry.cpln.io` hostname | No |
| **Public Docker Hub** | bare name (`nginx:latest`) — never add `docker.io/` | No |
| **Other public registry** | exact host path (`gcr.io/...`, `ghcr.io/...`) | No |
| **External private registry** (ECR, GCR, ACR, private Docker Hub, another CPLN org) | exact host path | **Yes** — `docker`/`ecr`/`gcp` secret on GVC `spec.pullSecretLinks` |
Full image workflow (remote vs local build detail, buildx fallback, cross-org copy, pull-secret setup): `image` skill.
## Workflow: Deploy a workload
The CLI runbook (also the CI/CD path):
```bash
cpln gvc create --name my-gvc --location aws-us-west-2 --org my-org
cpln image build --name my-app:v1.0 --push # or --remote, with no Docker daemon
cpln workload create --name my-app --gvc my-gvc --image //image/my-app:v1.0 --port 8080 --public
cpln workload get-deployments my-app --gvc my-gvc # verify readiness
```
## Workflow: Grant secret access (3 steps)
The 3-step rule (identity + policy + reference) is owned by `rules/cpln-guardrails.md`. The secret must already exist (created by the user — offer to draft the manifest for them to fill and apply; `setup-secret` skill). CLI fallback:
```bash
cpln identity create --name my-app-identity --gvc my-gvc --org my-org
cpln workload update my-app --gvc my-gvc --set spec.identityLink=//identity/my-app-identity
cpln policy create --name secret-access --target-kind secret --resource db-password --org my-org
cpln policy add-binding secret-access --permission reveal \
--identity //gvc/my-gvc/identity/my-app-identity --org my-org
cpln workload update my-app --gvc my-gvc \
--set spec.containers.main.env.DB_PASSWORD.value=cpln://secret/db-password.payload
```
## Workflow: GitOps with cpln apply
```bash
cpln gvc get my-gvc -o yaml-slim > manifests/gvc.yaml # export (slim strips server fields)
cpln workload get my-app --gvc my-gvc -o yaml-slim > manifests/workload.yaml
cpln apply --file ./manifests/ --gvc my-gvc --ready # idempotent; run on every push
```
## Workflow: Rename or clone (names are immutable)
No `rename` exists. **Preferred — `clone`** (on workload, gvc, policy, group, ipset, serviceaccount, mk8s, auditctx; duplicates spec only; secrets are off-limits — the user clones them):
```bash
cpln workload clone old-name --name new-name --gvc my-gvc
cpln workload get-deployments new-name --gvc my-gvc # verify healthy
cpln workload delete old-name --gvc my-gvc # only after verification
```
Kinds without clone (identity, volumeset, domain, agent): `get -o yaml-slim`, edit the name, `cpln apply`. Renaming a workload changes its internal hostname (`WORKLOAD.GVC.cpln.local`) and public URL — update domain routes (`spec.ports[].routes[].workloadLink`), policy `targetLinks`/`targetQuery`, internal-DNS callers, and external clients. Never delete the old workload before the new one is verified healthy.
## Workflow: Debug a failing workload
```bash
cpln logs '{gvc="my-gvc", workload="my-app"}' --org my-org --tail # stream logs
cpln logs '{gvc="my-gvc", workload="my-app"} |= "error"' --org my-org # filter (LogQL, not a shell pipe)
cpln workload exec my-app --gvc my-gvc -- ls /app # inspect the container filesystem
cpln workload connect my-app --gvc my-gvc # interactive shell
cpln port-forward my-app 8080:8080 --gvc my-gvc # probe locally
```
**Cron workloads — query logs per execution, not per workload.** A plain `{gvc=, workload=}` query mixes every past run. Enumerate executions with `cpln workload cron get NAME --gvc GVC`, then scope the LogQL with the `replica` label plus a time window. Full pattern: `logql-observability` skill.
## Platform rules & integration
Scale-to-zero/autoscaling, production defaults/probes, Template Catalog first, destructive ops, secrets, and firewall rules live in `rules/cpln-guardrails.md` and their dedicated skills — not duplicated here. Before authoring any apply YAML / CI manifest / API body, call `get_resource_schema`. IaC: Terraform (`controlplane-com/cpln` provider), Pulumi (`@pulumiverse/cpln`), K8s Operator (`cpln operator install`).
## Related skills
| Need | Skill |
|---|---|
| Remote vs local build detail, buildx fallback, pull secrets | `image` |
| LogQL beyond the basics, per-execution cron queries | `logql-observability` |
| Query language (`--match` / `--tag` / `--rel`) | `query-spec` |
| Volumeset semantics and shrink safety | `stateful-storage` |
| K8s / Compose / Helm migration | `migration-patterns` |
| Pipelines and GitOps patterns | `gitops-cicd` |
| Terraform / Pulumi / K8s operator | `iac-terraform-pulumi`, `k8s-operator` |
## Documentation
- Platform guardrails & resource model: `rules/cpln-guardrails.md`
- [Control Plane Docs](https://docs.controlplane.com) · [AI page index](https://docs.controlplane.com/llms.txt) · [CLI Reference](https://docs.controlplane.com/cli-reference/overview.md)
No comments yet. Be the first to comment!