Files
git.stella-ops.org/docs/modules/release-orchestrator/design/principles.md

7.1 KiB

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

-- 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

// 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<DecisionResult> EvaluateAsync(
        Promotion promotion,
        IReadOnlyList<IGateProvider> gates,
        CancellationToken ct)
    {
        // Core controls evaluation order and aggregation
        var results = new List<GateResult>();
        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