openova/products
e3mrah d66d514e42
feat(catalyst-chart): land Environment CRD catalyst.openova.io/v1 (slice B2, #1095) (#1107)
Realizes the Environment CRD spec from docs/EPICS-1-6-unified-design.md §3.2.2
and NAMING-CONVENTION.md §11. Environment is the user-facing scope where
Applications are installed. The full Environment name is composed as
{organizationRef}-{envType} (e.g. acme-prod) per NAMING §11.1.

DR is explicitly NOT an envType — there is no `*-dr` Environment. Multi-
region disaster-recovery topology is expressed via Application.spec.placement
(active-active | active-hotstandby), per the design doc and NAMING §11.1.
The schema enforces this by limiting envType to prod|stg|uat|dev|poc.

Cluster-scoped (Environments span vClusters across regions; not namespace-
bound).

Spec carries:
- organizationRef — pattern-validated lowercase slug (matches Organization.spec.slug)
- envType — enum prod|stg|uat|dev|poc (NAMING §2.4)
- placement — enum single-region | multi-region (different from Application's
  active-active|active-hotstandby; this is structural, not failover)
- regions[] — minItems=1 maxItems=5; each entry has provider/region/
  buildingBlock with proper enums; optional hostCluster override
- policyRef — optional EnvironmentPolicy CR for promotion gating + compliance weights

Status carries phase, regionCount (printer column), per-region vcluster
realization summary with phase, giteaRepoRef.{org,branch} (per NAMING §11.2
develop/staging/main ↔ dev/stg/prod), jetstreamSubjectPrefix (per
ARCHITECTURE.md §5: ws.{org}-{envType}.>), conditions[], observedGeneration.

additionalPrinterColumns surface organizationRef, envType, placement,
regionCount, phase, age via `kubectl get env`.

Validated against a real k3s control plane:
- 2 valid samples accepted: single-region acme-dev + multi-region acme-prod
- 2 invalid samples REJECTED with all 6 seeded error vectors:
  * organizationRef=ACME → uppercase pattern fail
  * envType=dr → enum (DR is on Application, not Env)
  * placement=active-active → enum (active-* is for Application)
  * regions[0].provider=linode → enum
  * regions[0].buildingBlock=core → enum
  * regions=[] → minItems=1

Refs: #1094, #1095, docs/EPICS-1-6-unified-design.md §3.2.2, NAMING-CONVENTION.md §11/§11.1/§11.2

Co-authored-by: hatiyildiz <hatiyildiz@noreply.openova.io>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 22:02:32 +04:00
..
axon feat(axon): make qwen3-coder thinking mode toggleable via request parameter 2026-04-26 09:20:33 +02:00
catalyst feat(catalyst-chart): land Environment CRD catalyst.openova.io/v1 (slice B2, #1095) (#1107) 2026-05-08 22:02:32 +04:00
cortex docs(pass-52): bundled date-sweep + cross-component namespace clean; knative clean 2026-04-28 00:37:21 +02:00
fabric docs(seaweedfs+guacamole): replace MinIO with SeaweedFS as unified S3 encapsulation; add Guacamole to bp-relay 2026-04-28 10:23:46 +02:00
fingate docs(pass-52): bundled date-sweep + cross-component namespace clean; knative clean 2026-04-28 00:37:21 +02:00
relay docs(seaweedfs+guacamole): replace MinIO with SeaweedFS as unified S3 encapsulation; add Guacamole to bp-relay 2026-04-28 10:23:46 +02:00