## ADDED Requirements

### Requirement: Node output references
Prompts and commands SHALL support `$nodeId.output` to reference the output text of an upstream node, and `$nodeId.output.field` to reference a specific field from a structured output.

#### Scenario: Output reference substitution
- **WHEN** a prompt contains `$analysis.output`
- **THEN** it SHALL be replaced with the full output text of the node with id `analysis`

#### Scenario: Field reference with structured output
- **WHEN** a prompt contains `$analysis.output.summary` and the upstream node declared `output_format: { type: "object", properties: { summary: ... } }`
- **THEN** it SHALL be replaced with the value of the `summary` field from the parsed JSON output

#### Scenario: Missing node reference
- **WHEN** a prompt references `$nonexistent.output`
- **THEN** the reference SHALL resolve to an empty string with a warning

#### Scenario: Missing field on schemaless node
- **WHEN** a prompt references `$node.output.field` and the upstream node has no `output_format` and its output is not valid JSON
- **THEN** the consuming node SHALL fail with an error

#### Scenario: Strict field access for declared schemas
- **WHEN** a prompt references `$node.output.field` and the upstream node's `output_format` declares properties but `field` is not among them
- **THEN** the consuming node SHALL fail with a field-not-found error

### Requirement: Built-in variables
The engine SHALL support `$ARGUMENTS`, `$ARTIFACTS_DIR`, `$WORKFLOW_ID`, `$BASE_BRANCH`, `$DOCS_DIR`.

#### Scenario: $ARGUMENTS substitution
- **WHEN** a prompt contains `$ARGUMENTS`
- **THEN** it SHALL be replaced with the full user message/arguments string

#### Scenario: $ARTIFACTS_DIR substitution
- **WHEN** a prompt contains `$ARTIFACTS_DIR`
- **THEN** it SHALL be replaced with the path to the run's artifact directory

#### Scenario: $WORKFLOW_ID substitution
- **WHEN** a prompt contains `$WORKFLOW_ID`
- **THEN** it SHALL be replaced with the workflow run ID

### Requirement: Loop-specific variables
Loop nodes SHALL support `$LOOP_USER_INPUT` (from approve at interactive gates) and `$LOOP_PREV_OUTPUT` (output of the previous iteration).

#### Scenario: $LOOP_PREV_OUTPUT on first iteration
- **WHEN** a loop node is on its first iteration
- **THEN** `$LOOP_PREV_OUTPUT` SHALL resolve to an empty string

#### Scenario: $LOOP_PREV_OUTPUT on subsequent iterations
- **WHEN** a loop node is on iteration 2+
- **THEN** `$LOOP_PREV_OUTPUT` SHALL contain the cleaned output of the previous iteration

### Requirement: Approval-specific variables
Approval nodes SHALL support `$REJECTION_REASON`.

#### Scenario: $REJECTION_REASON in on_reject prompt
- **WHEN** an approval node is rejected with a reason
- **THEN** `$REJECTION_REASON` SHALL contain the reviewer's feedback text
