# Invocation arguments

## Usage

```ops
@ci {
  condition.all(git.bump bash.shellcheck bash.bats)
  bash.coverage(threshold: 80 overrides: { "foo.sh": 50 "bar.sh": 60 })
  self.bake(...$STAGED_FILES)
}
```

## Grammar

```
Invocation      = '(' ArgList? ')'
ArgList         = (NamedArg | SpreadArg | PositionalArg)*
NamedArg        = IDENT ':' ArgValue
SpreadArg       = '...' '$' IDENT
PositionalArg   = Atom
ArgValue        = '{' (ObjKey ':' Atom)* '}' | Atom
ObjKey          = IDENT | STRING_LIT
Atom            = Literal | VarRef | IDENT
```

## IR representation

Canonical argument shape lives in [pipelines-and-steps](../ir/pipelines-and-steps.md) and [values-and-types](../ir/values-and-types.md).

```json
{
  "args": {
    "positional": ["arg1", "arg2"],
    "named": { "threshold": 80, "overrides": {"foo.sh": 50} }
  }
}
```

## Runtime

- `@in.type name` — named typed input on `@operation`
- `--spread` — accepts forwarded args via `...`
- `--variadic` — unbounded positional args

## Implementation

**Build tier:** Tier 4 — Invocation arguments

| Layer | Responsibility |
|-------|----------------|
| `ast.rs` | `Invocation { positional, named }`, `ArgValue` (Scalar \| Object), `ArgExpr` (Literal \| Spread) |
| `parser.rs` | Inside `(...)`: `key:` → named (peek `{` → object), `...` → spread, else positional |
| `lower.rs` | Emit `args: { positional, named }` when args present |

**Validates:** bats tests for each arg form and combinations.

## Design decisions

- **Commas in step args:** Not delimiters in bash; stick to words. Rust standardizes: commas are optional whitespace-equivalent separators in all list contexts.
- **Numeric coercion:** bash uses `jq tonumber? // $v` in object literals; the Rust engine should replicate the same coercion logic natively (awk/shell arithmetic in emitted code, not jq).
- **Unquoted atoms:** `[a-zA-Z0-9._/@:+-]+`

## Caveats

Behavior matches the bash reference for argument parsing and lowering; object literal coercion rules must stay aligned when porting.

## Open questions

- **`--lazy` evaluation:** deferred args for iteration/conditionals — syntax and semantics undefined.
