@codiac.io/codiac-cli 1.3.244 → 1.3.246

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/skill/SKILL.md ADDED
@@ -0,0 +1,153 @@
1
+ ---
2
+ name: codiac
3
+ description: >-
4
+ Operate the Codiac platform through the `cod` CLI (and, secondarily, the NATS relay API).
5
+ Use this whenever a task touches Codiac at all: deploying or managing assets/workloads,
6
+ editing scoped configuration or secrets, working with enterprises, environments, cabinets,
7
+ clusters, image registries, CSP/cloud profiles, hosts/ingress, or agents — or any time you
8
+ are about to type a `cod ...` command or reason about how Codiac deploys things. Reach for it
9
+ even when the user doesn't say "Codiac" but names a Codiac concept (asset, cabinet, scoped
10
+ setting, enterprise, environment, cluster, CSP profile, EVC). Its whole job is to stop you
11
+ guessing cod commands, subcommands, args, and flags — the CLI is self-documenting, and this
12
+ skill gives you the concept model plus the one habit that prevents almost every mistake:
13
+ read `cod <topic> <verb> --help` before you call a command you are not certain of.
14
+ ---
15
+
16
+ # Codiac
17
+
18
+ You are operating **Codiac** — a platform that deploys and manages workloads on Kubernetes
19
+ clusters. Your tool is the **`cod` CLI**. Data operations also flow over a **NATS relay API**,
20
+ but the CLI is the primary, safe surface and you should prefer it.
21
+
22
+ ## The one thing that matters most
23
+
24
+ **`cod` is self-documenting, and guessing is the failure mode.** Every command carries a
25
+ description, every flag has its own description, and commands ship titled, copy-pasteable
26
+ examples. So the fast path is never to recall a command from memory — it is:
27
+
28
+ > **Before you run any `cod` command you are not 100% certain of, run `cod <topic> <verb> --help` and read it.**
29
+
30
+ This is faster, not slower, than guessing. A guessed flag fails (or worse, silently does the
31
+ wrong thing against a real cluster), costs a round-trip, and erodes trust. Reading `--help`
32
+ costs one cheap call and makes the very next command correct.
33
+
34
+ Why this is non-negotiable and not just good manners: **Codiac's flag characters collide across
35
+ commands.** `-e` means *enterprise* in `cod asset list` and `cod config view`, but *environment*
36
+ in `cod cabinet create`, `cod config add`, and `cod config settings get` (where enterprise is
37
+ `-n`). Asset version is `-u`, not `-v`. On `cod asset deploy`, `-n` is a cloud username and `-t`
38
+ is a cabinet tag. Several primary inputs (tenant code, cluster, provider, cabinet name) are
39
+ **positional args, not flags**. There is no convention you can lean on — only `--help` is truth.
40
+ See `references/cli-reference.md` for the collision map, but treat even that as orientation:
41
+ `--help` on the specific command is the authority.
42
+
43
+ ## When you're working in this skill
44
+
45
+ Most tasks are one of:
46
+ - **Deploy / manage a workload** — `cod asset deploy`, `asset list`, `asset view`, `asset undeploy`, `asset recycle`.
47
+ - **Read or change configuration / secrets** — `cod config view` (preview the resolved doc), `config add` (set a value), `config settings get` (inspect raw settings), scoped-setting work.
48
+ - **Work with the topology** — enterprises, environments, cabinets, clusters, hosts/ingress.
49
+ - **Cloud/registry auth** — `cod csp login` for a provider (Azure/AWS/DockerHub).
50
+ - **Install an agent** — `cod ai agent install`.
51
+
52
+ If you don't know which command a task maps to, skim the command tree in
53
+ `references/cli-reference.md`, then `--help` the candidate.
54
+
55
+ ## Hold the concept model before you touch a command
56
+
57
+ Codiac's mental model is small but easy to conflate. Get it wrong and you'll pass the wrong
58
+ flag values even with perfect flag names. The essentials:
59
+
60
+ - **tenant → enterprise → environment → cabinet → cluster.** A **tenant** is the account. An
61
+ **enterprise** is a workspace inside it (two *types* exist: normal/`sdlc` and `infrx` for
62
+ infrastructure — some commands enforce the type). An **environment** is a stage (dev/prod/…)
63
+ that **maps to a cluster** (the mapping is data-driven in the DB). A **cabinet** is a concrete
64
+ deployment target that lives **in an environment** — so it inherits that environment's cluster.
65
+ - **Therefore `cod cabinet create` takes `--environment`, never `--cluster`.** Cabinets and
66
+ clusters are ephemeral over an underlying namespace; the env→cluster link is the source of truth.
67
+ - **Asset** = a deployable workload (a `helm` chart or a `service`/container). Registered once,
68
+ versioned (AssetVersionConfig), then deployed into a cabinet.
69
+ - **Scoped settings / config** are values attached at a **scope** — `enterprise`, `environment`,
70
+ or `cabinet` — where **cabinet overrides environment overrides enterprise**. Shareable config
71
+ belongs at the *highest* scope that makes sense (set once, inherited), with narrower scopes as
72
+ optional overrides. Cabinet-scoping something that should be shared is an anti-pattern.
73
+ - The **EVC** (EnterpriseVersionConfig) is the versioned snapshot the platform actually reads;
74
+ deploys write it. Config can be a **literal value** or a **sourced** reference into a vault.
75
+
76
+ That's enough to choose the right command and fill it correctly. For depth — targetFile types
77
+ (`[helm]`/`[env]`/`[label]`/…), dotted-key/escaped-period behavior, `@{...}` templates, CSP
78
+ profiles, the NATS API, and the full hierarchy — read `references/concepts.md`.
79
+
80
+ ## Running a `cod` command safely
81
+
82
+ 1. **Establish context.** Enterprise-scoped commands need a tenant (and often an enterprise).
83
+ `cod tenant switch <code>` sets the tenant; many commands take `--enterprise`. A deployed agent
84
+ usually already runs inside its tenant's context.
85
+ 2. **`--help` the exact command** unless you have literally just read it. Read the flag
86
+ descriptions and the examples — copy an example and adapt it rather than composing from scratch.
87
+ 3. **In automation / non-interactive shells, pass `--silent` and every required arg.** `--silent`
88
+ (and piped stdin, which auto-switches to silent) has **no prompt fallback** — a missing or
89
+ invalid required value throws instead of asking. Secrets that would normally be prompted are
90
+ fed via stdin (e.g. `cod csp login` password, `cod config add --value-stdin`).
91
+ 4. **Preview only in a real terminal — never headless.** `--echo`/`--to-script` render the
92
+ equivalent `--silent` command, but they run the *interactive* build first, so in a non-TTY they
93
+ **prompt and hang**. Headless, `--silent` is your safe mode: it validates and **throws** on a
94
+ missing/invalid arg (fast, never hangs) instead of prompting. To preview a command without
95
+ running it headless, build it from `--help` and simply don't execute — don't reach for
96
+ `--to-script`.
97
+ 5. **Reading a list?** List commands take `--output/-o` (`tree` default; `json`/`yaml`/… for
98
+ machines) and usually `--query/-q` (JMESPath). `-q` implies JSON; `tree`/`text` reject `-q`.
99
+
100
+ ## Operating a running workload (logs, status, events, exec, config)
101
+
102
+ Almost everything about a live workload comes from **`cod asset view`** (and `cod cabinet contents`
103
+ / `cod asset list`) — reach for these first; read-only `kubectl` is only a fallback. `cod asset
104
+ view` flags: `-e` enterprise, `-a` asset, `-n` environment, `-c` cabinet, `-r` replica (`any` =
105
+ first, no prompt), `-t` content type.
106
+
107
+ - **What's deployed** (returns + exits, headless-safe): `cod cabinet contents -e <ent> -c <cab>` and `cod asset list -e <ent> -o json`.
108
+ - **Logs** (headless-safe): `cod asset view -t logs -e <ent> -a <asset> -n <env> -c <cab> -r any -l 50 --silent` — pass `-l N` for N lines (or `-l -1` for all); **omit `-f`** (follow streams forever).
109
+ - **Exec / env / config**: `cod asset view -t exec|env|config …` (config also takes `-T <helm|env|label|annotation|…>`).
110
+ - **Live status + events**: `cod asset view -t status` (aka `asset mon`) is an **interactive
111
+ streaming monitor** — great in a real terminal, but it does **not** return in a non-TTY/`--silent`
112
+ shell, so don't use it in automation. For a headless status snapshot, use `cabinet contents` /
113
+ `asset list` above. (For headless one-shot *events*, use `cod asset view -t events` — a
114
+ returns-and-exits events dump; `-l N` for count.)
115
+
116
+ ## Hard rules (each earns its place)
117
+
118
+ - **Never invent a command, subcommand, or flag.** If it's not confirmed by `--help` or
119
+ `references/cli-reference.md`, verify before running. The grammar is strictly **noun-then-verb**
120
+ (`cod asset deploy`, `cod config settings get`) — never verb-first, never reordered.
121
+ - **`cod` first — don't lead with `kubectl`.** Almost everything about a running workload is
122
+ available through `cod asset view` (logs, exec, env, config, live status+events) and
123
+ `cod cabinet contents` / `cod asset list` (what's deployed) — reach for those before the cluster.
124
+ Read-only `kubectl get`/`describe`/`logs` is a fine fallback for diagnosis (and the user may
125
+ explicitly okay it); the point is to rely on Codiac's own calls first, not to ban `kubectl`. The
126
+ one firm line: **never make a *write* through raw `kubectl`/`helm`** against a Codiac-managed
127
+ asset — that corrupts Codiac's tracked view (stale rootmap/UI); make changes through `cod`.
128
+ - **Set `CODIAC_SESSION_ID` for a multi-step sequence** so every `cod` call shares one session
129
+ (otherwise steps can land in different sessions and lose context).
130
+ - **Treat prod as prod.** Deploys, undeploys, and config changes act on real clusters. In doubt,
131
+ **read first** — `cod config view`, `cod cabinet contents`, `cod asset view` — before you write.
132
+
133
+ ## When something's missing
134
+
135
+ If a task seems to have no `cod` command, the first instinct to resist is **hallucinating a flag**.
136
+ Instead:
137
+ 1. Re-check `--help` on the most relevant command (especially `cod asset view --help` — logs,
138
+ exec, env, config, live status, and events all live there under `-t`).
139
+ 2. Check the command tree in `references/cli-reference.md` for a topic you haven't considered.
140
+ 3. If it's genuinely absent, **name the gap** so it can be added to `cod` — that's the durable fix.
141
+ A **read-only** `kubectl get`/`describe` check is an acceptable stopgap in the meantime (and the
142
+ user may okay it outright); just never a raw `kubectl`/`helm` *write* against a Codiac-managed
143
+ asset, and prefer getting the capability into `cod` over a standing `kubectl` habit.
144
+
145
+ ## Reference files
146
+
147
+ - `references/cli-reference.md` — the command tree (every topic → verbs), the flag-character
148
+ collision map, the list/output (`-o`/`-q`) pattern, positional-arg gotchas, and the `--silent`
149
+ rules. Orientation only; `--help` on the specific command is authoritative.
150
+ - `references/concepts.md` — the full Codiac mental model: the hierarchy and enterprise types,
151
+ assets and versioning, scoped configuration (scope/inheritance, targetFile types, sourced vs
152
+ literal, dotted keys and escaped periods, `@{...}` templates), the EVC/deploy model, CSP/cloud
153
+ auth, and the NATS relay API surface. Read it whenever a task goes past a single obvious command.
@@ -0,0 +1,167 @@
1
+ # `cod` CLI Reference (orientation)
2
+
3
+ **This is orientation, not the source of truth.** `cod <topic> <verb> --help` is authoritative —
4
+ it carries the exact current flags, their descriptions, and copy-pasteable examples. Use this file
5
+ to (a) confirm a command *exists* and its noun-then-verb shape, and (b) stay alert to the traps
6
+ below. Then `--help` the specific command and adapt one of its examples.
7
+
8
+ ## Command grammar
9
+
10
+ - **Noun-then-verb, always.** `cod asset deploy`, `cod cluster stack install`,
11
+ `cod config settings get`. Never verb-first (`cod deploy asset` ✗), never reordered.
12
+ - Directory-to-command mapping: `<topic>/<verb>` → `cod <topic> <verb>`; deeper nesting works too
13
+ (`asset probe list`).
14
+ - A few real **camelCase** topics/verbs exist despite the single-word convention:
15
+ `imageRegistry`, `secretStore`, `pullSecret`, and `auth ... allow onEnvironments`/`onCabinets`.
16
+
17
+ ## Command tree (what actually exists — don't invent beyond this)
18
+
19
+ Top-level: `branch`, `build`, `cli`, `commit`, `deploy`, `dep`, `identity`, `init`, `login`,
20
+ `logout`, `merge`, `portal`, `publish`, `pull`, `push`, `relay-version`, `run`, `stage`, `stash`,
21
+ `status`, `stop`, `switch`, `sync`, `unstage`, `whereami`, `whoami`.
22
+
23
+ - **ai**: `ai agent install`
24
+ - **asset**: `create`, `deploy`, `edit`, `list`, `obliterate`, `recycle`, `undeploy`, `view`, `where`; `entrypoint set/delete`; `probe create/delete/list`; `volume create/delete/list`
25
+ - **auth**: `register`; `cabinet allow/allowed`; `enterprise allow/allowed/allow onEnvironments`; `environment allow/allowed/allow onCabinets`; `role create/delete/list/assign/unassign/allowed`; `user invite/list`
26
+ - **cabinet**: `create`, `list`, `define`, `contents`, `destroy`, `detach`, `forget`, `obliterate`, `restore`; `cluster attach`
27
+ - **cluster**: `connect`, `install`, `bootstrap`, `start`, `stop`; `agent configure/install/uninstall`; `scaling update`; `stack capture/install`
28
+ - **config**: `add`, `delete`, `deploy`, `import`, `view`; `settings get`
29
+ - **csp**: `login`, `logout`, `setup`, `creds list`
30
+ - **enterprise**: `create`, `list`
31
+ - **environment**: `create`, `delete`, `list`; `cluster attach/detach`
32
+ - **env**: `add` *(separate topic from `environment`)*
33
+ - **filestore**: `capture`, `forget`, `list`
34
+ - **host**: `map`, `list`, `view`, `delete`
35
+ - **identity**: `list`, `delete`
36
+ - **imageRegistry**: `capture`, `forget`, `list`; `pullSecret set/unset`
37
+ - **images**: `add`, `list`, `patch`, `remove`, `version`, `version bump`
38
+ - **import**: `cluster`
39
+ - **kit**: `create`
40
+ - **noc**: `noc cluster create/list/init/deinit/capture/restore/destroy/define/forget/grant/journal/credentials-set`
41
+ - **pkg**: `add`, `list`, `patch`, `remove`
42
+ - **pvc**: `create`, `get`, `list`, `delete`
43
+ - **secretStore**: `capture`, `forget`, `list`
44
+ - **snapshot**: `deploy`, `list`, `tag`, `tags`, `untag`
45
+ - **tenant**: `create`, `switch`
46
+
47
+ If a task seems to need a command not on this list, you're probably guessing — re-check the tree
48
+ or `--help` the parent topic (`cod asset --help`, `cod config --help`) to see its verbs.
49
+
50
+ ## Interaction-mode flags (on nearly every command)
51
+
52
+ | Flag | Meaning |
53
+ |---|---|
54
+ | `--silent` | Non-interactive. Runs with zero prompts and **throws on any missing/invalid required arg** — there is no prompt fallback. Pass every required value. |
55
+ | `--echo` | Prints the equivalent `--silent` command string, then runs it. **Runs the interactive build first → prompts and HANGS in a non-TTY.** Interactive terminals only. |
56
+ | `--to-script` | Prints the equivalent `--silent` command string without running it. Same trap: it does the interactive build first, so it **prompts and HANGS headless.** Not a headless dry-run — use it only in a real terminal. Headless, use `--silent` (throws on missing args, never hangs) and build the command from `--help`. |
57
+ | `-h` / `--help` | Help + examples. (A couple of commands don't define it — see traps.) |
58
+ | `--take-defaults` | Auto-accept default/context values without confirmation. |
59
+
60
+ - The mode flags have **no char shortcut**; spell them exactly (`--silent`).
61
+ - **Piped stdin auto-switches to silent** ("Piped input detected…"), so a piped command needs all
62
+ args too. Some commands read secrets from stdin in silent mode (`csp login` password,
63
+ `config add --value-stdin`).
64
+
65
+ ## The flag-character collision map (why you must `--help`)
66
+
67
+ The same char means different things per command. **Never assume.**
68
+
69
+ | Char | `asset deploy` | `asset view` | `config add` / `settings get` | `config view` | `csp login` | `cabinet create` | `ai agent install` |
70
+ |---|---|---|---|---|---|---|---|
71
+ | `-e` | enterpriseCode | enterprise | **enviro (environment)** | enterprise | — | **environment** | enterpriseCode |
72
+ | `-n` | **provider username** | **environment** | **enterprise** | — | — | — | **workload name** |
73
+ | `-u` | **version** | — | — | — | user | — | — |
74
+ | `-t` | cabinet **tag** | **type** (content) | config **type** | config type | **tenantId** | — | agent **type** |
75
+ | `-s` | applySnapshotTag | — | **enterprise-scope** (bool) | — | subscriptionId | — | — |
76
+ | `-c` | cabinetName | cabinet | cabinet | cabinet | — | **cluster** | cabinet |
77
+ | `-a` | asset | asset | asset | asset | — | — | — |
78
+ | `-g` | applyAssetTag | — | — | — | — | — | ingress (`--no-ingress`) |
79
+
80
+ Highlights that bite most often:
81
+ - **`-e` is enterprise in some commands, environment in others.** In `config add` /
82
+ `config settings get`, enterprise is **`-n`** and `-e` is **`--enviro`**. `config view` uses
83
+ `-e` = enterprise. Verify per command every time.
84
+ - **Asset version is `-u`, not `-v`.**
85
+ - On `asset deploy`, `-n` = cloud username and `-t` = cabinet tag (not enterprise, not type).
86
+
87
+ ## Positional args (not flags)
88
+
89
+ Several primary inputs are positional — passing them as `--flag` fails:
90
+
91
+ | Command | Positional |
92
+ |---|---|
93
+ | `cod tenant switch <code>` | tenant code |
94
+ | `cod cluster connect <cluster>` | cluster name |
95
+ | `cod csp login <provider>` | provider (`aws`/`azure`/`docker`) |
96
+ | `cod cabinet create <cabinet>` | cabinet name (env/cluster are flags: `--environment`, `--cluster`) |
97
+ | `cod config view [setting]` | optional setting name |
98
+
99
+ `csp login` and `cluster connect` don't even define `-h` — read their source/behavior, not `--help`.
100
+
101
+ ## List / read commands
102
+
103
+ Commands that return a list support:
104
+ - `--output` / `-o` — `tree` (default, human) · `json` · `yaml` · sometimes `text`/`tsv`/`csv`.
105
+ - `--query` / `-q` — JMESPath, applied to the raw array. `-q` implies JSON; **`tree`/`text`
106
+ reject `-q`** (throws).
107
+
108
+ Examples: `cod asset list -e main -q '[].name' -o json` · `cod cabinet list -e main -o yaml`.
109
+ Exception: `cod config settings get` has **no `-q`** — filter with `--setting`/`--value` globs — and
110
+ defaults to `json`. `cod config view` uses a different format enum (`pretty`/`json`/`yaml`/`auto`).
111
+
112
+ ## `cod asset view` — operating a running workload (no kubectl)
113
+
114
+ Flags: `-e` enterprise · `-a` asset · `-n` **environment** · `-c` cabinet · `-r` replica (`any` =
115
+ first, no prompt) · `-t` content type. The `-t` (`AssetContentType`) values are exactly:
116
+
117
+ | `-t` | What it does | Headless-safe? |
118
+ |---|---|---|
119
+ | `logs` | container logs; `-l N` lines (`-l -1` = all); `-f` follows (streams forever — omit headless) | ✅ with `-l N`, no `-f` |
120
+ | `env` | resolved env vars | ✅ |
121
+ | `config` | resolved config (`-T <helm\|env\|label\|annotation\|…>` or `-F <file>`) | ✅ |
122
+ | `exec` | run a command in a replica (positional cmd after `--`) | interactive |
123
+ | `term` | shell into a replica | interactive only |
124
+ | `events` | recent k8s events for the asset (returns + exits; `-l N` count, default 25) | ✅ **use this for headless events** |
125
+ | `status` | **live streaming monitor** (aliases `asset:monitor`/`asset:mon`) — status + events, updating | ❌ **never returns in a non-TTY** (interactive only) |
126
+
127
+ For events in a script use **`cod asset view -t events`** — it fetches once, prints, and exits
128
+ (unlike `-t status`, which streams). It works even when pods aren't up (that's when events matter:
129
+ ImagePullBackOff, FailedScheduling, CrashLoopBackOff), and works for `helm` assets too, not just
130
+ `service`. Example: `cod asset view -t events -e main -a hello-web -n dev -c demo -l 20 --silent`.
131
+ For a plain status snapshot, `cod cabinet contents` / `cod asset list` also return and exit. No
132
+ `kubectl` needed.
133
+
134
+ ## A few verified recipes (adapt via `--help`)
135
+
136
+ ```bash
137
+ # switch tenant (positional code)
138
+ cod tenant switch ben --silent
139
+
140
+ # preview the resolved config a cabinet will deploy with (best "what will happen?" check)
141
+ cod config view -e main -a hermes-agent -c dev -o pretty --silent
142
+
143
+ # set a helm value at enterprise scope (note: -n = enterprise, -e would be enviro here)
144
+ cod config set -n main -a hermes-agent -t helm --setting model --value 'openai/gpt-4o-mini' -s --silent
145
+
146
+ # inspect raw scoped settings (is it set, and where?)
147
+ cod config settings get -n main -a hermes-agent -t helm -o json --silent
148
+
149
+ # create a cabinet in an ENVIRONMENT (the target is --environment; --cluster is OPTIONAL and
150
+ # defaults to the environment's first cluster — only pass it to disambiguate a multi-cluster env)
151
+ cod cabinet create dev --enterprise main --environment dev --silent
152
+
153
+ # what's deployed in a cabinet (headless-safe)
154
+ cod cabinet contents -e main -c dev --silent
155
+
156
+ # deploy an asset version into a cabinet (version is -u!)
157
+ cod asset deploy -e main -a my-service -u 1.0.0 -c dev --silent
158
+
159
+ # cloud/registry auth (provider positional; secret via stdin)
160
+ cat pw.txt | cod csp login -u me@example.com --silent docker
161
+
162
+ # connect kubectl to a Codiac cluster (positional name)
163
+ cod cluster connect my-cluster --silent
164
+ ```
165
+
166
+ Every one of these was read from source, but flags evolve — if a recipe errors, `--help` the
167
+ command and re-derive it. That habit, not this file, is what keeps you correct.
@@ -0,0 +1,244 @@
1
+ # Codiac Concept Model
2
+
3
+ The mental model an agent must hold to operate Codiac correctly. These concepts are compact but
4
+ easy to conflate; getting them straight is what lets you pick the right command and fill its
5
+ arguments with the right *values* (flag names you get from `--help`, but the *meaning* of the
6
+ values comes from here).
7
+
8
+ > Rule of thumb: if you catch yourself unsure what a term means (is a cabinet a cluster? does
9
+ > config live on the asset or the cabinet?), stop and re-read the relevant section. A wrong
10
+ > mental model produces confident, wrong commands.
11
+
12
+ ## Contents
13
+ 1. [The topology: tenant → enterprise → environment → cabinet → cluster](#1-the-topology)
14
+ 2. [Assets: the deployable unit](#2-assets)
15
+ 3. [Scoped configuration and secrets](#3-scoped-configuration-and-secrets)
16
+ 4. [Versioning and the deploy model](#4-versioning-and-the-deploy-model)
17
+ 5. [Cloud/registry auth (CSP)](#5-cloudregistry-auth-csp)
18
+ 6. [Hosts and ingress](#6-hosts-and-ingress)
19
+ 7. [The API surface (NATS, not HTTP)](#7-the-api-surface)
20
+ 8. [Agents on Codiac](#8-agents-on-codiac)
21
+
22
+ ---
23
+
24
+ ## 1. The topology
25
+
26
+ Codiac nests five things. Keep them in this order:
27
+
28
+ ```
29
+ tenant → enterprise → environment → cabinet → cluster
30
+ ```
31
+
32
+ - **Tenant** — the account boundary (e.g. `ben`, `cod`). Everything you do happens inside one
33
+ tenant. A CLI session has a *current tenant*; set it with `cod tenant switch <code>`. A deployed
34
+ agent typically already runs inside its own tenant's context.
35
+ - **Enterprise** — a workspace within a tenant (e.g. `main`). A tenant can have several. There are
36
+ **two enterprise *types***:
37
+ - normal / **`sdlc`** — where your application workloads live.
38
+ - **`infrx`** — infrastructure enterprise, holding cluster-scoped components (operators, agents,
39
+ platform stacks). Some commands are "infrx-only" or "sdlc-only" and will auto-switch or reject
40
+ based on type. If a command complains about enterprise type, you're likely in the wrong one.
41
+ - **Environment** — a stage inside an enterprise (e.g. `dev`, `prod`). **An environment maps to a
42
+ cluster** (or clusters). The mapping is **data-driven in the DB**, not something you pass on the
43
+ command line — which is why you attach clusters to environments (`cod environment cluster attach`),
44
+ not to cabinets.
45
+ - **Cabinet** — the concrete deployment target: a named slot inside an environment where assets get
46
+ deployed. Because a cabinet lives in an environment, it **inherits that environment's cluster**.
47
+ A cabinet corresponds to a Kubernetes namespace (typically `<tenant>-<cabinet>`, e.g. `ben-dev`).
48
+ - **Cluster** — the actual Kubernetes cluster. Cabinets and clusters are *ephemeral over the
49
+ underlying namespace*; the durable link is environment → cluster.
50
+
51
+ **The trap this prevents:** `cod cabinet create` takes **`--environment`**, never `--cluster`.
52
+ You create a cabinet in an environment; the cluster comes along via the env mapping. Trying to
53
+ pass a cluster to `cabinet create` is a classic mistake.
54
+
55
+ Related commands: `cod enterprise list`, `cod environment list/create`,
56
+ `cod environment cluster attach/detach`, `cod cabinet create/list/destroy`,
57
+ `cod cluster connect/list`. (Always `--help` for exact flags — see the CLI reference.)
58
+
59
+ ---
60
+
61
+ ## 2. Assets
62
+
63
+ An **asset** is a deployable workload. Two kinds matter:
64
+
65
+ - **`helm`** — deployed from a Helm chart (chart identity lives on the asset's image ref:
66
+ chart name + registry + version).
67
+ - **`service`** (container) — Codiac builds a Deployment for it from a container image.
68
+
69
+ Lifecycle:
70
+ 1. **Register** the asset once (`cod asset create`) — this records its identity in the enterprise.
71
+ 2. **Version** it — a specific version is captured as an `AssetVersionConfig`.
72
+ 3. **Deploy** a version into a cabinet (`cod asset deploy`). Deploy is idempotent-ish
73
+ (`helm upgrade --install` under the hood for helm assets).
74
+ 4. Inspect/operate: `cod asset list`, `cod asset view` (logs/term/exec/env/config/status),
75
+ `cod asset undeploy`, `cod asset recycle`.
76
+
77
+ **Image registries — policy:** never AWS ECR. Images live in **Docker Hub** or **Azure
78
+ Container Registry (ACR)**. Registries are captured as first-class objects
79
+ (`cod imageRegistry ...`, `cod secretStore ...` for pull secrets).
80
+
81
+ The `type` of an asset (`helm` vs `service`) changes which config `targetFile`s apply (see §3):
82
+ `[helm]` values for charts, `[env]`/`[footprint]`/etc. for services.
83
+
84
+ ---
85
+
86
+ ## 3. Scoped configuration and secrets
87
+
88
+ This is the richest — and most misunderstood — part of Codiac. Configuration is **not** stored
89
+ on the asset as one blob. It is a set of **scoped settings** that get *smash-merged* into a config
90
+ document at deploy time.
91
+
92
+ ### Scope and inheritance
93
+ Every setting has a **scope**, one of:
94
+
95
+ - `enterprise`
96
+ - `environment`
97
+ - `cabinet`
98
+
99
+ **Precedence: cabinet overrides environment overrides enterprise.** A cabinet-scoped value wins
100
+ for that cabinet; otherwise the value is *inherited* from the environment, then the enterprise.
101
+
102
+ **Design principle:** put shareable config at the **highest** scope that makes sense — set it
103
+ *once* at the enterprise, let every cabinet inherit it, and add a narrower (cabinet/environment)
104
+ override only when a specific target genuinely differs. Cabinet-scoping something that should be
105
+ shared is an anti-pattern: it breaks reproducibility (every new cabinet would need it re-set) and
106
+ a stray empty cabinet override silently shadows a good enterprise value.
107
+
108
+ ### targetFile — where a setting lands at runtime
109
+ A setting's `targetFile` says *what artifact it becomes*:
110
+
111
+ | targetFile | Becomes |
112
+ |---|---|
113
+ | `[helm]` | a Helm chart value (`.Values.<path>`) for a helm asset |
114
+ | `[env]` | an OS environment variable on the container |
115
+ | `[footprint]` | container resource footprint (cpu/mem requests/limits) |
116
+ | `[label]` | a Kubernetes label |
117
+ | `[annotation]` | a Kubernetes annotation |
118
+ | `[filestore]` | a mounted file/volume value |
119
+ | a file path (e.g. `app-config.json`) | a key inside that config file |
120
+
121
+ Choosing the wrong `targetFile` is a common error — e.g. putting a helm chart value under `[env]`
122
+ (where Codiac builds Deployments for *service* assets) instead of `[helm]`.
123
+
124
+ ### Literal value vs sourced reference
125
+ A setting's value is either:
126
+ - a **literal** `value` (stored directly), or
127
+ - a **sourced** reference (`KvpReference`) that points into a **vault / KVP store** — the concrete
128
+ value is resolved at deploy time. This keeps secrets out of the config records. Sourcing requires
129
+ a vault store to exist for the tenant.
130
+
131
+ ### Dotted keys and the escaped-period trap
132
+ A setting *key* can be a dotpath — e.g. `dashboard.password` — which **nests** into the config
133
+ document (`{ dashboard: { password: ... } }`) via an object-flattener. Consequences you must
134
+ respect:
135
+ - The dot is a **hierarchy delimiter**. `ingress.host` sets `.Values.ingress.host` in a helm chart.
136
+ - Internally, dotted keys are **stored with escaped periods (`\.`)**. An exact-string match on the
137
+ raw dotted key can silently miss — normalize `\.`→`.` when comparing, and don't assume a naive
138
+ query on a dotted name will match.
139
+ - **Vault key names can't contain dots** (Azure Key Vault allows only `[0-9A-Za-z-]`). When a
140
+ dotted key is sourced into a vault, the vault key must be sanitized (dots→dashes) or it fails to
141
+ round-trip and resolves empty.
142
+
143
+ ### Templates (`@{...}`)
144
+ Setting values can be **view-engine templates** resolved per target. Example ingress host:
145
+ `@{asset.name}.@{cabinet.name}.@{environment.name}.example.com` — one enterprise-scope value that
146
+ resolves to a different concrete host in each cabinet. Prefer a shareable template at enterprise
147
+ scope over a concrete value re-computed per cabinet.
148
+
149
+ ### Commands
150
+ - `cod config view` — **preview the resolved config doc** for a cabinet (all scopes merged,
151
+ sources resolved). Your best "what will actually deploy?" check.
152
+ - `cod config add` (alias `config set`) — set a scoped setting (`--setting`, `--value` /
153
+ `--value-stdin`, scope via `--enterprise-scope`/`--enviro`/`--cabinet`, `--type` = targetFile).
154
+ - `cod config settings get` — inspect the *raw* stored settings (filter by `--setting`/`--value`
155
+ globs). Good for "is this set, and at what scope?".
156
+
157
+ > Flag caution: in `config add` and `config settings get`, **`-n` = enterprise and `-e` =
158
+ > environment (`--enviro`)** — the reverse of the usual `-e = enterprise`. `config view` uses
159
+ > `-e = enterprise`. Always `--help`.
160
+
161
+ ---
162
+
163
+ ## 4. Versioning and the deploy model
164
+
165
+ - **AssetVersionConfig** — a specific captured version of an asset.
166
+ - **EnterpriseVersionConfig (EVC)** — the **versioned snapshot of the enterprise's state** that the
167
+ platform reads (the rootmap the CLI shows is derived from it). A cabinet points at an EVC version.
168
+ - **Deploy** (`cod asset deploy`, or the relay `invokeDeploymentSequence`) records the deployed
169
+ asset+version into the enterprise state. The relay writes EVCs through a `getsertVersion` call and
170
+ creates a **DeployAttempt** record for each deploy.
171
+ - **Snapshots** (`cod snapshot ...`) tag enterprise states so they can be re-deployed/rolled.
172
+
173
+ Why it matters: many downstream systems (status/UI, the asset→label mapping publisher) read the
174
+ **EVC**, not the live cluster. If a freshly-deployed asset isn't reflected where you expect,
175
+ suspect an EVC/snapshot timing issue rather than a cluster problem — re-check with `cod config
176
+ view` / `cod asset list` (both EVC-derived).
177
+
178
+ ---
179
+
180
+ ## 5. Cloud/registry auth (CSP)
181
+
182
+ CSP = Cloud Service Provider integration.
183
+
184
+ - A tenant onboards providers via a **cspTenantProfile** (`cod csp setup`).
185
+ - **`cod csp login <provider>`** authenticates the tenant's own creds for that provider; tokens are
186
+ cached **server-side per tenant**, so a later headless operation (deploy, agent install) can use
187
+ them without re-login.
188
+ - You typically need **two** logins for a full deploy: the **cloud provider** that owns the cluster
189
+ (e.g. `azure`) *and* the **registry** hosting the chart/image (e.g. `docker` for Docker Hub).
190
+ A "no credentials found" / "DockerHub credentials not found" failure during deploy almost always
191
+ means one of these logins is missing.
192
+ - Provider is a **positional arg** on `cod csp login` (`aws`/`azure`/`docker`), and secrets are fed
193
+ via **stdin** in `--silent` mode.
194
+
195
+ Commands like `cod cluster connect <name> --silent` use the cached CSP creds to set up kubectl
196
+ auth — prefer it over raw cloud CLIs for cluster access.
197
+
198
+ ---
199
+
200
+ ## 6. Hosts and ingress
201
+
202
+ - A workload with an ingress needs a **host**. Codiac resolves hosts from a **host-naming strategy**
203
+ attached to a scope (`ScopedHostNameConfig`) — e.g. `svc_dot_cab_dot_domain`
204
+ (`<service>.<cabinet>.<domain>`) or `shared_ingress_ip`.
205
+ - You can set the ingress host directly as a `[helm]` scoped setting (`ingress.host`), ideally as a
206
+ shareable enterprise-scope **template** (`@{asset.name}.@{cabinet.name}.….<domain>`) so it
207
+ resolves per cabinet.
208
+ - Commands: `cod host list/map/view/delete`.
209
+
210
+ ---
211
+
212
+ ## 7. The API surface
213
+
214
+ Codiac's data plane is **NATS, not HTTP**. Key implications:
215
+
216
+ - The platform communicates over **NATS pub/sub** (subjects, request/reply, streaming events), not
217
+ REST. The web frontend follows a **Facade → NATS → Store (Akita) → Query → Component** pattern;
218
+ it does not fetch over HTTP for platform data.
219
+ - There is a **relay** with endpoints (operationIds) invoked over NATS; the CLI's `executeTask`
220
+ makes exactly one such relay call per command. This is why the CLI is the safe surface — it wraps
221
+ the correct subjects, auth, and payloads for you.
222
+ - There is a **tenant → hub account boundary**. A long *synchronous* request/reply does **not**
223
+ survive the import across that boundary — long operations use an **ack-then-stream** pattern
224
+ (return an ack immediately, then publish terminal status as an event on the tenant's
225
+ `events.>` channel). If you ever build against the API directly, don't expect a long blocking
226
+ reply from a customer tenant to the hub; subscribe for the streamed result instead.
227
+
228
+ Practically: **use the CLI.** Only reach for the raw NATS API when the CLI genuinely cannot express
229
+ what you need — and then mirror how the CLI builds the call.
230
+
231
+ ---
232
+
233
+ ## 8. Agents on Codiac
234
+
235
+ Codiac can run AI agents as first-class workloads.
236
+
237
+ - **`cod ai agent install`** provisions an agent into a cabinet. `--type` selects the framework:
238
+ `openclaw`, `hermes`, or `byoa` (bring-your-own-agent). `--name` is the workload name, `-c` the
239
+ cabinet, and ingress is on by default (needs a `--naming` strategy in silent mode).
240
+ - Provisioning follows the same asset/scoped-config/deploy machinery above: it registers an asset,
241
+ writes scoped settings (secrets sourced to the vault, shared config at enterprise scope), maps the
242
+ ingress host, and deploys — so everything in §§2–6 applies to agents too.
243
+ - Secrets an agent needs (API keys, dashboard password) are scoped settings; set them **once** at
244
+ enterprise scope and let cabinets inherit, rather than re-prompting per install.