> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ubiquex.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Design Decisions

> Why ubx makes the choices it does.

## Why Pulumi (not Terraform)?

ubx uses Pulumi as its runtime because:

1. **`Output&lt;T&gt;` type system** — Pulumi's `Output&lt;T&gt;` is the right primitive for `Pending&lt;T&gt;`. Terraform has no equivalent.
2. **Multi-language support** — Pulumi providers work with TypeScript, Go, Python, Java.
3. **Automation API** — Programmatic control over plan/apply without subprocess calls.
4. **Component Resources** — First-class support for reusable component abstractions.

Terraform/OpenTofu is supported only as a migration source (`ubx convert --from terraform`).

## Why HCL-inspired syntax (not YAML)?

* YAML is whitespace-sensitive and error-prone for complex nested structures
* HCL is familiar to the largest IaC user base (Terraform)
* Block-based syntax maps naturally to cloud resource declarations
* Comments, string interpolation, and expressions are first-class

## Why a `~` sigil for `Pending&lt;T&gt;`?

The `~` prefix makes `Pending&lt;T&gt;` references visually distinct at a glance:

```hcl theme={null}
engine   = "postgres"                        # Resolved — obvious
password = input.db_password                  # Resolved — obvious
host     = ~unit.aws_rds_instance.db.endpoint # Pending — obvious
```

Alternative syntaxes considered: `${}` (clashes with interpolation), `@{}` (less readable), no prefix (ambiguous).

## Why single label for `component`?

```hcl theme={null}
# Two labels (old, confusing)
component "eks_platform" "main" { source = "..." }

# Single label (current, clear)
component "main" { source = "..." }
```

The first label was redundant — `source` already expresses the type. Single label is consistent with `input`, `output`, `local`.

## Why `output` not `export`?

`export` has TypeScript connotations. `output` is familiar to Terraform/OpenTofu users and matches the `ubx output` CLI command.

## Why no OPA for policies?

The `policy` block evaluates conditions at compile time using a simple boolean expression evaluator. This eliminates:

* External OPA server dependency
* Rego learning curve
* Network calls during `ubx validate`

For complex compliance, consider OPA as a pre-commit hook.

## Why BYOK for AI features?

Bring Your Own Key (BYOK) means:

* No ubx telemetry or data collection
* Users control their Anthropic API spend
* AI features work with any Anthropic-compatible endpoint
* No dependency on Ubiquex infrastructure for AI functionality
