← Control PlaneCONTENT HISTORY
WHAT CHANGED
Update to Control Plane
Snapshot Oct 30, 2026 · 00:05 UTC · version 1.2.0
Collection source: downloaded plugin package.
First saved snapshot
No earlier snapshot is available to establish a change.
Save Control Plane and check future changes in Following.
Up to 10 plugins free · no card required.
Compare saved observations
Download comparison JSONFull technical diff · 0 changed fields
Full snapshot data
{
"description": "Control Plane operating guide: platform facts tools do not enforce or report, high-impact approvals, secrets beyond the core rules, targets, CLI fallback, failures. Use when a task goes beyond what the job tools cover.",
"included_files": [],
"name": "operating-guide",
"skill_md_contents": "---\nname: operating-guide\ndescription: \"Control Plane operating guide: platform facts tools do not enforce or report, high-impact approvals, secrets beyond the core rules, targets, CLI fallback, failures. Use when a task goes beyond what the job tools cover.\"\n---\n\n# Control Plane Operating Guide\n\nThe core rules arrive with every MCP connection. This guide holds only what they and the tool descriptions leave out.\n\n## Approval for high-impact actions\n\nA destructive call needs the user's explicit approval after you say what it removes or breaks. Three kinds need a fresh yes that answers the stated blast radius, even when the opening message already asked:\n\n- **Cascades:** deleting a GVC removes every workload and identity in it; the platform refuses while a volume set remains.\n- **Data loss:** deleting or restoring volumes and snapshots; copying a volume, which deletes the volume at the destination index; uninstalling a template release deletes its volume data.\n- **Production targets:** a name that says so, or public traffic, custom domains, several replicas, or real users.\n\nAlso destructive: removing bindings, members, routes, locations, or policies; shrinking a volume, which moves its data to a new volume and restarts its replica; changing a workload's type or name, or a volume set's filesystem or performance class, which means delete and recreate. Hesitation, \"maybe\", or a counter-question is not approval. A resource you created by mistake this session, and only that, you remove and report.\n\n## Reads\n\nRead the current state before an `update_*` or `delete_resource` call, especially where a field replaces a list or object wholesale. Job tools read state themselves: call them directly and treat their result as the verification.\n\nThe tag `cpln/managedByTerraform: \"true\"` marks a resource Terraform or Pulumi owns, and their next apply reverts a live change. Tell the user before changing one, prefer a change to their code, and after a hotfix they approve, offer the matching code change. Without the tag, ask whether GitOps owns a production resource before changing it.\n\n## Secrets\n\n- Keep generated values and user-entered values in separate secrets, so none is half filled.\n- Access needs three things, and a missing one fails silently: an identity on the workload, a policy granting `reveal` (not `view`), and a `cpln://secret/NAME.KEY` reference. `deploy_app` wires all three for its env; `grant_workload_secret_access` sets the identity and policy once the workload exists.\n- CLI and GitOps users may want a manifest: UPPERCASE placeholders they fill locally, then `cpln apply`. Never apply a file holding a placeholder. On the CLI a value goes in a file, never an inline flag.\n- Service-account keys and agent bootstrap configs are shown once, in the Console: `add_key_to_service_account` and `create_agent` (need `?toolsets=full`) return the link.\n- Redact passwords, tokens, keys, connection strings, and bearer headers from anything you repeat.\n\n## Targets\n\n- A GVC's locations come from the user. When they leave the choice to you, pick the enabled location that fits their users (one, unless they want more), say which, and pass it. `deploy_app` and `add_database` take a location name or a city, country, or cloud region that matches one (`frankfurt`, `eu-central-1`), and refuse `auto`, `any`, and broad areas such as `europe` or `us`. The org's location list is the authority: it includes BYOK locations with operator-chosen names, so never substitute a cloud region for one.\n- A production change needs a plan and a rollback stated before it runs.\n- Create only what the task needs. When something it depends on is missing (the workload a domain routes to, the secret a reference names), ask which existing one to use; never create a placeholder.\n\n## Platform facts the tools do not check\n\n- **App vs workload:** an app is the code or image; a workload is the resource that runs it.\n- **Internal calls** use plain HTTP to `http://WORKLOAD.GVC.cpln.local:PORT`; the sidecar adds mTLS, so `https://` fails.\n- **`CPLN_TOKEN`** inside a workload works only from that workload, against `CPLN_ENDPOINT`.\n- **Images:** run a real image, never an app inlined into a base image. A private external registry needs a GVC pull secret of type `docker`, `ecr`, or `gcp`; any other type fails the pull silently.\n- **Shutdown:** the default `preStop` runs `sleep`; an image without it, or a failing custom `preStop`, kills every container at once. A container running as UID 1337 bypasses the mesh, losing mTLS and firewall enforcement.\n- **Hand-written specs:** ports go in `containers[].ports`, never the deprecated `port`; custom domains use the Domain resource, never the GVC's deprecated `spec.domain`.\n- **Domains** stay pending until their DNS records resolve. Pending is a wait, not an error to retry.\n- **Public** means external inbound allows `0.0.0.0/0` or `::/0`; outbound is a separate list, which the `public: true` shortcut of `create_workload` and `update_workload` also opens.\n- **Reachability:** after ready, a real HTTP GET of the canonical URL settles it. 2xx, 3xx, 401, and 403 mean serving; a timeout points at firewall inbound; a TLS or DNS error means propagation, so wait. Never claim reachability without a response.\n- **App code:** before changing an app's code, `get_app_files` with the NAME from `//image/NAME:TAG` says where the code lives. Never rewrite an app from scratch under an existing name.\n- **Other databases, caches, queues, and search** come from the Template Catalog, never built by hand.\n\n## CLI and profiles\n\nWith the MCP connected, its tools do everything they cover, reads included: never `cpln workload get` or `cpln gvc get` to look around. The `cpln` CLI is only for what the tools cannot do: building a folder on disk (`cpln image build --remote --dir PATH --name NAME:TAG --org ORG`, with the org the MCP uses), `cpln workload connect`, `cpln workload exec`, port-forward, `cpln cp`, `cpln image copy`, `cpln convert`, and CI/CD with a service-account `CPLN_TOKEN`. When the MCP is connected but signed out, ask the user to sign in again rather than switch to the CLI: the CLI acts as its own profile and can reach orgs the user never granted. Without the MCP, use the CLI. Run `cpln` only in a shell on the user's machine; a chat app's sandbox is not one, so there never look for, install, or run it, and give the user the command instead. Every command comes from the `cpln` skill (and `--help` where you can run it), never from memory. When a tool covers the action, call it rather than running or handing the user a command; when none covers a field, use the CLI or say what is missing.\n\n`?toolsets=` on the MCP URL picks the tools: `core` (default), `mk8s`, `full`, or `readonly`. When a task needs a tool this connection lacks, tell the user which profile to reconnect with. The ChatGPT listing always runs `core`: there, do that step in the Console or give the user the CLI command instead.\n\n## Failures\n\n- **Not found:** stop and ask; never try a corrected name. **Permission denied:** report it; never work around it.\n- **Validation error:** fix what it names, then retry; never resend an unchanged call.\n- **Client approval or safety denial:** stop and report the blocked action and reason. Never retry to bypass it or switch tools to perform the same blocked action. A transport failure is different: read the current state before retrying a mutation whose outcome is uncertain.\n- **Partial mutation:** report what changed, what did not, and the current state.\n- **An immutable field** changes only by delete and recreate, which needs approval.\n"
}SHA-256 of public snapshot: dd44fa1b0a4d365acb8a9550844ae917b04470df317909356fe3fb471c4cbf91