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

# Code Hierarchy

> Share config and provider versions across multiple child projects with ubx.root.yaml and ubx.root.iac.

**Code hierarchy** lets you place organisation-wide defaults — backend, tags, stacks, and provider versions — in a root config that every child project automatically inherits. Child projects can override any field; on conflict, the child always wins.

This mirrors the Terragrunt pattern: a monorepo root sets the baseline, individual service directories customise what they need.

## File structure

```
./                               ← root config lives here
  ubx.root.yaml                  ← org-wide defaults (backend, tags, stacks)
  ubx.root.iac                   ← org-wide provider versions (optional)

  services/
    api/
      ubx.yaml                   ← child project — overrides what it needs
      main.iac
      inputs.iac
    worker/
      ubx.yaml
      main.iac
```

Scaffold this structure with one command:

```bash theme={"theme":"css-variables"}
ubx init --hierarchy
```

## Root config: `ubx.root.yaml`

```yaml theme={"theme":"css-variables"}
# ubx.root.yaml — place at the monorepo root

backend: s3://my-org-bucket/state

default_stack: dev
stacks:
  - dev
  - staging
  - prod

default_tags:
  managed: ubx
  team: platform
```

### Supported fields

| Field           | Type            | Description                                                               |
| --------------- | --------------- | ------------------------------------------------------------------------- |
| `backend`       | string          | Pulumi state backend URL (e.g. `s3://bucket/state`, `file://.ubx/state`)  |
| `default_stack` | string          | Default stack name when `--stack` is not set                              |
| `stacks`        | list of strings | Valid stack names for the organisation                                    |
| `default_tags`  | map             | Resource tags applied to all taggable units (deep-merged with child tags) |

## Root providers: `ubx.root.iac`

Declare provider version constraints that apply to all child projects:

```hcl theme={"theme":"css-variables"}
# ubx.root.iac — shared provider versions

provider "aws" {
  version = "~> 6.0"
}

provider "gcp" {
  version = "~> 7.0"
}
```

`ubx.root.iac` supports `provider` blocks only. The provider constraints are merged into the child's `package.json` at compile time — you don't need a `provider` block in every child project.

## Child project: `ubx.yaml`

A child project only needs to declare what differs from the root:

```yaml theme={"theme":"css-variables"}
# services/api/ubx.yaml — child project

project: api

# backend, stacks, and default_tags are inherited from ubx.root.yaml.
# Uncomment to override:
# backend: s3://my-team-bucket/state
# stacks: [dev, staging]
# default_stack: staging
```

### Tag merge example

Root `ubx.root.yaml`:

```yaml theme={"theme":"css-variables"}
default_tags:
  managed: ubx
  team: platform
```

Child `ubx.yaml`:

```yaml theme={"theme":"css-variables"}
default_tags:
  env: prod
  team: api-team       # overrides root's "team" value
```

Effective tags applied to all resources in the child project:

```
managed: ubx           ← from root
team: api-team         ← child overrides root
env: prod              ← from child only
```

Child values always win on conflict. Tags that only appear in the root are always inherited.

## Child providers: extend and override

A child project can declare its own `provider` block to use a different version than the root:

```hcl theme={"theme":"css-variables"}
# services/api/providers.iac

provider "aws" {
  version = "~> 6.1"   # overrides the root's "~> 6.0" for this project only
}
```

Same-name provider → child version is used. Providers declared only in the root are
inherited automatically with no declaration needed in the child.

## Merge rules

| Field                 | Rule                                                                |
| --------------------- | ------------------------------------------------------------------- |
| `backend`             | Child wins if declared; otherwise inherit root                      |
| `default_stack`       | Child wins if declared; otherwise inherit root                      |
| `stacks`              | Child wins if declared (even partial list); otherwise inherit root  |
| `default_tags`        | Deep merge — root provides base; child overwrites on key conflict   |
| Provider blocks       | Union — root provides baseline; same-name child block wins entirely |
| `ubx.root.iac` absent | Treated as no root providers — not an error                         |

## Root discovery

When you run any ubx command from a child directory, ubx automatically walks **up** the directory tree looking for `ubx.root.yaml`:

```
services/api/    ← start here
services/        ← checked, no ubx.root.yaml
./               ← found! ubx.root.yaml here
```

Walking stops at the **first** `ubx.root.yaml` found, or at a `.git` directory (single-project mode — no root applied, no error).

```
monorepo/
  .git/          ← boundary: stops search here
  services/
    api/         ← starts here, stops at .git above — no root applied
```

This prevents accidentally inheriting config from outside your git repository.

## `--root` flag

Override discovery with an explicit root directory:

```bash theme={"theme":"css-variables"}
ubx validate --root /path/to/root
ubx plan     --root ../shared-root
ubx apply    --root ../shared-root
```

The `--root` flag is available on `validate`, `plan`, `apply`, and `destroy`.

## Root line in output

When a root config is active, ubx shows it before the compile phase:

```
  ◆ Root       ../.. (ubx.root.yaml)
  ◆ Compile    stack.iac

  ✓  valid
```

If no root is found, the Root line is absent — single-project mode runs as before.

## Scaffold with `ubx init --hierarchy`

The `--hierarchy` flag creates the full root + child structure in one step:

```bash theme={"theme":"css-variables"}
ubx init --hierarchy           # scaffold in current directory
ubx init myproject --hierarchy # scaffold into myproject/
```

Generated structure:

```
./
  ubx.root.yaml                  ← org defaults (backend, stacks, tags, managed=ubx)
  ubx.root.iac                   ← shared aws provider ~> 6.0
  services/
    api/
      ubx.yaml                   ← minimal child (inherits everything from root)
      main.iac                   ← sample S3 bucket + output
      inputs.iac                 ← region input
```

## Running Commands Across All Projects

The `--all` flag runs `validate`, `plan`, or `apply` across every child project discovered under the root, in a single command.

### Basic usage

```bash theme={"theme":"css-variables"}
# From the root or any child directory — discovers root automatically
ubx validate --all
ubx plan     --all
ubx apply    --all --yes
```

You can run from the root directory **or** from any child directory. ubx walks up to find `ubx.root.yaml` and then discovers all child projects beneath it.

### Output format

```
  ◆ Workspace  3 project(s) found

  ◆ Validate   services/api
  ✓  services/api

  ◆ Validate   services/worker
  ✓  services/worker

  ◆ Validate   infra/networking
     ◆ Root       ../.. (ubx.root.yaml)
     ◆ Compile    stack.iac
     ✗  stack.iac:6  unknown attribute "fake_attr"
     ✗  1 error(s)
  ✗  infra/networking

  ────────────────────────────────────────
  2 passed · 1 failed
```

### `--filter` — run a subset of projects

```bash theme={"theme":"css-variables"}
# Exact path match
ubx validate --all --filter services/api

# Glob pattern (quote to prevent shell expansion)
ubx validate --all --filter 'services/*'
ubx validate --all --filter 'infra/*'
```

Paths are relative to the root directory. Exact match is tried first; then `filepath.Match` glob semantics are applied.

### `--parallel` — concurrent execution

```bash theme={"theme":"css-variables"}
ubx validate --all --parallel 4    # validate 4 projects concurrently
ubx plan     --all --parallel 2
```

Default is `1` (sequential). Output is printed in project order regardless of completion order.

### `--continue-on-error` — collect all results

```bash theme={"theme":"css-variables"}
ubx validate --all --continue-on-error
```

Without `--continue-on-error`, `--all` **stops on the first failure** and marks remaining projects as `skipped`:

```
  ◆ Validate   infra/networking
  ✗  infra/networking

  ◆ Validate   services/api
  ·  skipped

  ◆ Validate   services/worker
  ·  skipped

  ────────────────────────────────────────
  0 passed · 1 failed · 2 skipped
```

With `--continue-on-error`, every project runs regardless of failures. The summary shows final counts:

```
  2 passed · 1 failed
```

### Error: no root found

If `ubx.root.yaml` is not found in any parent directory, `--all` exits immediately:

```
Error: --all requires a ubx.root.yaml in a parent directory
```

Use the `--root` flag to point to an explicit root when outside the discovery path:

```bash theme={"theme":"css-variables"}
ubx validate --all --root /path/to/root
```

### `--all` flag reference

| Flag                  | Default | Description                                                |
| --------------------- | ------- | ---------------------------------------------------------- |
| `--all`               | `false` | Run across all child projects under the root               |
| `--filter string`     | *(all)* | Exact path or glob pattern to restrict which projects run  |
| `--parallel int`      | `1`     | Number of projects to run concurrently                     |
| `--continue-on-error` | `false` | Keep running even after a failure (default stops on first) |

## Complete example

**`ubx.root.yaml`** (monorepo root):

```yaml theme={"theme":"css-variables"}
backend: s3://my-org-state/state
default_stack: dev
stacks: [dev, staging, prod]
default_tags:
  managed: ubx
  team: platform
```

**`ubx.root.iac`** (monorepo root):

```hcl theme={"theme":"css-variables"}
provider "aws" {
  version = "~> 6.0"
}
```

**`services/api/ubx.yaml`** (child project):

```yaml theme={"theme":"css-variables"}
project: api
default_tags:
  service: api
  env: "${input.env}"
```

**`services/api/main.iac`** (child project):

```hcl theme={"theme":"css-variables"}
input "env" {
  type    = "string"
  default = "dev"
}

unit "aws_s3_bucket_v2" "uploads" {
  bucket = "api-uploads-${input.env}"
}

output "uploads_bucket" {
  value = unit.aws_s3_bucket_v2.uploads.bucket
}
```

Running from `services/api/`:

```bash theme={"theme":"css-variables"}
ubx validate
# ◆ Root       ../.. (ubx.root.yaml)
# ◆ Compile    stack.iac
# ✓  valid

ubx plan
# ◆ Root       ../.. (ubx.root.yaml)
# ◆ Compile    stack.iac → .ubx/index.ts
# ...
```

Effective config for `services/api/`:

* Backend: `s3://my-org-state/state` (from root)
* Stacks: `[dev, staging, prod]` (from root)
* Tags: `{managed: ubx, team: platform, service: api, env: "${input.env}"}` (merged)
* AWS provider: `~> 6.0` (from root — no override in child)
