Skip to content

feat: environments — per-instance state + dev→prod promotion workflow #22

Description

@2000game

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions