# Values and Types

## Why This Exists

Values cross every compiler phase: env defaults, invocation args, top-level declarations, captures, thrown errors, and generated CLI flags. The IR needs one representation that preserves type intent without leaking shell syntax into resolver or emitter internals.

## Producers

- **Parser lowering:** converts literals, variable references, templates, type annotations, named enums, and declarations into typed IR values.
- **Resolver:** validates values against operation signatures, env surfaces, and custom type references.

## Consumers

- **Resolver:** checks compatibility, unresolved variables, env conflicts, and secret rules.
- **Emitter:** chooses POSIX-safe quoting, flattening, JSON access, and CLI parsing behavior.
- **Machine output:** reports structured validation errors and source spans.

## Value Shape

All composite values use array payloads. Leaf values (literal strings, numbers, booleans) are scalar payloads.

```json
[
  {
    "role": "declaration",
    "name": "notice",
    "payload": [
      { "role": "type", "payload": "string" },
      { "role": "value", "payload": "release started" },
      { "role": "source", "payload": "#/sourcemap/declarations.notice" }
    ]
  },
  {
    "role": "env",
    "payload": [
      {
        "role": "entry",
        "name": "TARGETS",
        "payload": [
          {
            "role": "type",
            "payload": [
              { "role": "name", "payload": "string" },
              { "role": "list", "payload": true },
              { "role": "separator", "payload": "space" }
            ]
          },
          { "role": "default", "payload": ["linux", "darwin"] }
        ]
      },
      {
        "role": "entry",
        "name": "DEPLOY_TOKEN",
        "payload": [
          { "role": "type", "payload": "secret" },
          { "role": "required", "payload": true }
        ]
      }
    ]
  },
  {
    "role": "pipeline",
    "name": "release",
    "payload": [
      {
        "role": "call",
        "payload": [
          { "role": "target", "payload": "deploy" },
          { "role": "args", "payload": [
            { "role": "named", "name": "target", "payload": [{ "role": "var", "payload": "DEPLOY_TARGET" }] },
            { "role": "named", "name": "message", "payload": [
              { "role": "literal", "payload": "deploying " },
              { "role": "var", "payload": "DEPLOY_TARGET" }
            ]}
          ]}
        ]
      }
    ]
  }
]
```

In OPX:

```
Dc01_ 0.declaration
nDc01 1.name:string."notice"
tDc01 1.type:string."string"
vDc01 1.value:string."release started"
sDc01 1.source:string."#/sourcemap/declarations.notice"
Ev01_ 0.env
eE01_ 1.entry
nE01_ 2.name:string."TARGETS"
tE01_ 2.type
nT01_ 3.name:string."string"
lT01_ 3.list:bool.true
sT01_ 3.separator:string."space"
dE01_ 2.default
d1E01 3.item:string."linux"
d2E01 3.item:string."darwin"
eE02_ 1.entry
nE02_ 2.name:string."DEPLOY_TOKEN"
tE02_ 2.type:string."secret"
rE02_ 2.required:bool.true
Pl01_ 0.pipeline
nPl01 1.name:string."release"
cP01_ 1.call
tC01_ 2.target:string."deploy"
aC01_ 2.args
nA01_ 3.named
nnA01 4.name:string."target"
vnA01 4.var:string."DEPLOY_TARGET"
nA02_ 3.named
nnA02 4.name:string."message"
lnA02 4.literal:string."deploying "
vnA02 4.var:string."DEPLOY_TARGET"
```

Variable references use `{ "role": "var", "payload": "NAME" }`. Template strings are composite payloads with ordered `literal` and `var` items.

## Type Shape

Simple types use a scalar payload. Parameterized or modified types use a composite payload:

```json
// Simple type — leaf payload
{ "role": "type", "payload": "string" }

// Enum with variants — composite payload
{ "role": "type", "payload": [
  { "role": "name", "payload": "enum" },
  { "role": "variants", "payload": ["alpha", "beta", "production"] }
]}

// List type with separator — composite payload
{ "role": "type", "payload": [
  { "role": "name", "payload": "enum" },
  { "role": "variants", "payload": ["alpha", "beta", "production"] },
  { "role": "list", "payload": true },
  { "role": "separator", "payload": "comma" }
]}
```

In OPX:

```
// Simple type — leaf payload
Tp01_ 0.type:string."string"

// Enum with variants — composite payload
Tp02_ 0.type
nT02_ 1.name:string."enum"
vT02_ 1.variants
v1T02 2.item:string."alpha"
v2T02 2.item:string."beta"
v3T02 2.item:string."production"

// List type with separator — composite payload
Tp03_ 0.type
nT03_ 1.name:string."enum"
vT03_ 1.variants
v1T03 2.item:string."alpha"
v2T03 2.item:string."beta"
v3T03 2.item:string."production"
lT03_ 1.list:bool.true
sT03_ 1.separator:string."comma"
```

The two-case dispatch applies: if the type payload is a scalar string, it is a simple type name. If it is an array, iterate for modifiers. Scalar type `name` values follow [type-system](../features/type-system.md): `string`, `int`, `number`, `bool`, `email`, `url`, path/file variants, `command`, `glob`, `json`, `file-json`, `duration`, `semver`, `secret`, time variants, regex, and custom validators.

## Secret Invariant

`@secret` values are never valid lowered literals. These source forms are compile errors:

```ops
@secret TOKEN: "raw-value"
@secret API_KEY: `literal-ish {42}`
```

Allowed sources are runtime env, CLI/CI secret injection, secret-store references, or provider references modeled as metadata:

```json
{
  "role": "entry",
  "name": "DEPLOY_TOKEN",
  "payload": [
    { "role": "type", "payload": "secret" },
    { "role": "required", "payload": true },
    { "role": "provider", "payload": [
      { "role": "env-provider", "payload": "DEPLOY_TOKEN" }
    ]}
  ]
}
```

In OPX:

```
Se01_ 0.entry
nSe01 1.name:string."DEPLOY_TOKEN"
tSe01 1.type:string."secret"
rSe01 1.required:bool.true
pSe01 1.provider
epSe1 2.env-provider:string."DEPLOY_TOKEN"
```

The IR can carry the provider reference and source span. It must not carry the secret value.

## Invariants

- Named enums lower to explicit variant lists.
- Untyped env entries lower as `string`.
- List defaults lower to arrays and keep their CLI separator policy.
- Template values lower to ordered `literal` and `var` items in a composite payload.
- Variable references are `{ "role": "var", "payload": "NAME" }`, not strings that happen to start with `$`.
- Raw literal defaults for `secret` are rejected during lowering.

## Design References

- [env-block](../features/env-block.md) defines env grammar, defaults, and CLI surface.
- [type-system](../features/type-system.md) defines `DslType`.
- [strings-and-templates](../features/strings-and-templates.md) defines literal and template lowering.
- [error-handling](../features/error-handling.md) defines the built-in `@error` value shape.
