You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
feat: environments — per-instance state + dev→prod promotion workflow #22
Introduce an explicit environment concept so the same config repo drives eqrm-dev (rehearsal) and prod (real), Terraform-workspace-style. Part of the Phase 6 epic. Foundation already in place: the state file is host-bound and loading against a different host throws (src/state/state.ts) — this issue builds the ergonomics and the promotion workflow on top.
Depends on portable configs (logical references) — without them the same config cannot target two instances at all.
Scope
Environment profiles: named (host, token reference, state file path) triple, e.g. in a small ct.envs.json / config-repo file; ct plan --env prod, ct apply --env dev. No env flag → current single-host behavior unchanged.
Token store supports multiple hosts — verified: it does not today.src/auth/tokenStore.ts stores a single credentials blob (one host+token pair). Extend to per-host keychain accounts (account name keyed by host); until then multi-env runs must pass CT_HOST/CT_LOGINTOKEN per invocation, which CI does anyway.
State file convention per env (ct-state.dev.json / ct-state.prod.json), both committed to the config repo.
Guardrail: applying to an env whose name matches a configurable "protected" list (prod) requires the typed confirmation even with --auto-approve, or a distinct --yes-prod — decide and document.
Promotion workflow documented: plan dev → apply dev → verify (round-trip/refresh) → plan prod → apply prod.
Version gate per env (src/api/version.ts) — envs may run different CT versions; surface both in ct plan output.
Acceptance criteria
One config repo, two state files, two hosts: ct plan --env dev and --env prod both work in the same checkout with no file edits.
Cross-contamination impossible: env's state file bound to env's host (existing throw covers it; add a test for the env path).
Promotion workflow documented in the README/guide.
Activity
feat(env): environment profiles + multi-host token store (#22)
feat(env): --env selection + protected-env guardrail across commands (#…
test(env): unit + command coverage for environments (#22)
docs(env): promotion guide + protected-env guardrail + example (#22)