# Design Principles & Invariants > These principles are **inviolable** and MUST be reflected in all code, UI, documentation, and audit artifacts. ## Core Principles ### Principle 1: Release Identity via Digest ``` INVARIANT: A release is a set of OCI image digests (component → digest mapping), never tags. ``` - Tags are convenience inputs for resolution - Tags are resolved to digests at release creation time - All downstream operations (promotion, deployment, rollback) use digests - Digest mismatch at pull time = deployment failure (tamper detection) **Implementation Requirements:** - Release creation API accepts tags but immediately resolves to digests - All internal references use `sha256:` prefixed digests - Agent deployment verifies digest at pull time - Rollback targets specific digest, not "previous tag" ### Principle 2: Determinism and Evidence ``` INVARIANT: Every deployment/promotion produces an immutable evidence record. ``` Evidence record contains: - **Who**: User identity (from Authority) - **What**: Release bundle (digests), target environment, target hosts - **Why**: Policy evaluation result, approval records, decision reasons - **How**: Generated artifacts (compose files, scripts), execution logs - **When**: Timestamps for request, decision, execution, completion Evidence enables: - Audit-grade compliance reporting - Deterministic replay (same inputs + policy → same decision) - "Why blocked?" explainability **Implementation Requirements:** - Evidence is generated synchronously with decision - Evidence is signed before storage - Evidence table is append-only (no UPDATE/DELETE) - Evidence includes hash of all inputs for replay verification ### Principle 3: Pluggable Everything, Stable Core ``` INVARIANT: Integrations are plugins; the core orchestration engine is stable. ``` **Plugins contribute:** - Configuration screens (UI) - Connector logic (runtime) - Step node types (workflow) - Doctor checks (diagnostics) - Agent types (deployment) **Core engine provides:** - Workflow execution (DAG processing) - State machine management - Evidence generation - Policy evaluation - Credential brokering **Implementation Requirements:** - Core has no hard-coded integrations - Plugin interface is versioned and stable - Plugin failures cannot crash core - Core provides fallback behavior when plugins unavailable ### Principle 4: No Feature Gating ``` INVARIANT: All plans include all features. Limits are only: - Number of environments - Number of new digests analyzed per day - Fair use on deployments ``` This prevents: - "Pay for security" anti-pattern - Per-project/per-seat billing landmines - Feature fragmentation across tiers **Implementation Requirements:** - No feature flags tied to billing tier - Quota enforcement is transparent (clear error messages) - Usage metrics exposed for customer visibility - Overage handling is graceful (soft limits with warnings) ### Principle 5: Offline-First Operation ``` INVARIANT: All core operations MUST work in air-gapped environments. ``` Implications: - No runtime calls to external APIs for core decisions - Vulnerability data synced via mirror bundles - Plugins may require connectivity; core does not - Evidence packets exportable for external audit **Implementation Requirements:** - Core decision logic has no external HTTP calls - All external data is pre-synced and cached - Plugin connectivity requirements are declared in manifest - Offline mode is explicit configuration, not degraded fallback ### Principle 6: Immutable Generated Artifacts ``` INVARIANT: Every deployment generates and stores immutable artifacts. ``` Generated artifacts: - `compose.stella.lock.yml`: Pinned digests, resolved env refs - `deploy.stella.script.dll`: Compiled C# script (or hash reference) - `release.evidence.json`: Decision record - `stella.version.json`: Version sticker placed on target Version sticker enables: - Drift detection (expected vs actual) - Audit trail on target host - Rollback reference **Implementation Requirements:** - Artifacts are content-addressed (hash in filename or metadata) - Artifacts are stored before deployment execution - Artifact storage is immutable (no overwrites) - Version sticker is atomic write on target --- ## Architectural Invariants (Enforced by Design) These invariants are enforced through database constraints, code architecture, and operational controls. | Invariant | Enforcement Mechanism | |-----------|----------------------| | Digests are immutable | Database constraint: digest column is unique, no updates | | Evidence packets are append-only | Evidence table has no UPDATE/DELETE permissions | | Secrets never in database | Vault integration; only references stored | | Plugins cannot bypass policy | Policy evaluation in core, not plugin | | Multi-tenant isolation | `tenant_id` FK on all tables; row-level security | | Workflow state is auditable | State transitions logged; no direct state manipulation | | Approvals are tamper-evident | Approval records are signed and append-only | ### Database Enforcement ```sql -- Example: Evidence table with no UPDATE/DELETE CREATE TABLE release.evidence_packets ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), tenant_id UUID NOT NULL REFERENCES tenants(id), promotion_id UUID NOT NULL REFERENCES release.promotions(id), content_hash TEXT NOT NULL, content JSONB NOT NULL, signature TEXT NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT now() -- No updated_at column; immutable by design ); -- Revoke UPDATE/DELETE from application role REVOKE UPDATE, DELETE ON release.evidence_packets FROM app_role; ``` ### Code Architecture Enforcement ```csharp // Policy evaluation is ALWAYS in core, never delegated to plugins public sealed class PromotionDecisionEngine { // Plugins provide gate implementations, but core orchestrates evaluation public async Task EvaluateAsync( Promotion promotion, IReadOnlyList gates, CancellationToken ct) { // Core controls evaluation order and aggregation var results = new List(); foreach (var gate in gates) { // Plugin provides evaluation logic var result = await gate.EvaluateAsync(promotion, ct); results.Add(result); // Core decides how to aggregate (plugins cannot override) if (result.IsBlocking && _policy.FailFast) break; } // Core makes final decision return _decisionAggregator.Aggregate(results); } } ``` --- ## Document Conventions Throughout the Release Orchestrator documentation: - **MUST**: Mandatory requirement; non-compliance is a bug - **SHOULD**: Recommended but not mandatory; deviation requires justification - **MAY**: Optional; implementation decision - **Entity names**: `PascalCase` (e.g., `ReleaseBundle`) - **Table names**: `snake_case` (e.g., `release_bundles`) - **API paths**: `/api/v1/resource-name` - **Module names**: `kebab-case` (e.g., `release-manager`) --- ## References - [Key Architectural Decisions](decisions.md) - [Module Architecture](../modules/overview.md) - [Security Architecture](../security/overview.md)