diff --git a/docs/FORMAT.md b/docs/FORMAT.md index 1fdce54df..d94ac7c38 100644 --- a/docs/FORMAT.md +++ b/docs/FORMAT.md @@ -44,18 +44,26 @@ desc_field ::= "description:" ws text version_field ::= "version:" ws text author_field ::= "author:" ws text tags_field ::= "tags:" newline tag_list -inputs_fm_field ::= "inputs:" newline inputs_map +inputs_fm_field ::= "inputs:" newline input_list + | "inputs:" ws inline_sequence required_field ::= "required:" newline required_list + | "required:" ws inline_sequence +outputs_fm_field ::= "outputs:" newline output_fm_list + | "outputs:" ws inline_output_sequence name_string ::= [a-zA-Z0-9_-] ( [a-zA-Z0-9_ -]* [a-zA-Z0-9_-] )? tag_list ::= ( ws "- " tag newline )+ tag ::= text -inputs_map ::= ( ws variable_name ":" ws value newline )+ -value ::= text +input_list ::= ( ws "- " variable_name newline )+ required_list ::= ( ws "- " variable_name newline )+ +inline_sequence ::= "[" variable_name ( "," variable_name )* "]" +output_fm_list ::= ( ws "- " quoted_output_entry newline + | ws "- " output_entry newline )+ +inline_output_sequence ::= "[" ( output_sequence_entry ( "," output_sequence_entry )* )? "]" +output_sequence_entry ::= output_entry | quoted_output_entry ``` -Additional fields beyond those listed are preserved (open schema). All fields are optional. +Public frontmatter keys are case-insensitive (`inputs:`, `INPUTS:`, and `Inputs:` are equivalent); unknown keys are preserved with their original casing. All fields are optional. ## Steps @@ -90,12 +98,13 @@ Substeps cannot contain nested substeps. See [SPEC.md §1.1](./SPEC.md) for the outputs_directive ::= "- OUTPUTS" newline output_list output_list ::= ( ws "- " output_entry newline )+ output_entry ::= variable_name ( ws output_value )? +quoted_output_entry ::= quoted_string output_value ::= helper_call | template_variable | quoted_string | variable_name helper_call ::= "{{" ws? variable_name ( ws argument )+ ws? "}}" argument ::= quoted_string | variable_path ``` -A step or substep may declare at most one OUTPUTS directive. Duplicate directives on the same target are rejected. The `- INPUTS` directive has been removed — use the frontmatter `inputs:` field to declare default variable values. +A step or substep may declare at most one OUTPUTS directive. Duplicate directives on the same target are rejected. OUTPUTS declares values to inject into the runbook's live variable space after step completion. An entry may be a **naked declaration** (name only) diff --git a/packages/claude-code-plugin/skills/writing-runbooks/SKILL.md b/packages/claude-code-plugin/skills/writing-runbooks/SKILL.md index 7228d29c0..8ac74ac33 100644 --- a/packages/claude-code-plugin/skills/writing-runbooks/SKILL.md +++ b/packages/claude-code-plugin/skills/writing-runbooks/SKILL.md @@ -142,12 +142,12 @@ REQUIRED: --- ``` -- `INPUTS:` is a YAML sequence of variable names the runbook accepts. Declarations only — entries do not carry values. Names must match `/^[a-zA-Z_][a-zA-Z0-9_]*$/` and must not collide with reserved/built-in names. -- `REQUIRED:` is a subset of `INPUTS:`. Every name in `REQUIRED:` must also appear in `INPUTS:` — mismatch is a parse-time error. Missing values trigger a hard `MISSING_REQUIRED_VARS` error at resolution. +- `INPUTS:` is a YAML sequence of variable names the runbook accepts. Declarations only — entries do not carry values. Names must match `/^[a-zA-Z_][a-zA-Z0-9_]*$/` and must not collide with reserved/built-in names. Values may come from `.rundown/config.yaml`, `--input`, `--input-json`, `--input-file`, `RD_INPUT_*` env, or parent-forwarded vars from a parent runbook/step. +- `REQUIRED:` is a subset of `INPUTS:`. Every name in `REQUIRED:` must also appear in `INPUTS:` — mismatch is a parse-time error. Missing values trigger a hard `MISSING_REQUIRED_VARS` error at resolution if not supplied by `.rundown/config.yaml`, `--input`, `--input-json`, `--input-file`, `RD_INPUT_*` env, or parent-forwarded vars from a parent runbook/step. -Defaults are not carried in frontmatter. Provide values via `--input`, `--input-json`, `--input-file`, `RD_INPUT_*` env, parent-forwarded variables (from a parent runbook's `OUTPUTS:`), or project `.rundown/config.yaml`. +Defaults are not carried in frontmatter. Provide values via `.rundown/config.yaml`, `--input`, `--input-json`, `--input-file`, `RD_INPUT_*` env, or parent-forwarded vars from a parent runbook/step. -Variable resolution precedence (highest → lowest): CLI `--input` / `--input-json` / `--input-file`, `RD_INPUT_*` env, parent-forwarded variables, project `.rundown/config.yaml`, built-in defaults. +Variable resolution precedence (highest → lowest): CLI flags (`--input-json` > `--input` > `--input-file`), `RD_INPUT_*` environment variables, parent-forwarded variables, project `.rundown/config.yaml`, built-in defaults. ## Transitions @@ -237,8 +237,8 @@ Use `{{ variableName }}` syntax. See [CLAUDE.md — Template Variables](../../.. Key authoring notes: - Undefined variables preserved as literal `{{ variable }}` text -- Frontmatter `INPUTS:` declares names only — defaults come from `.rundown/config.yaml`, `--input`, `--input-json`, `--input-file`, or `RD_INPUT_*` env -- Data sources for FOR loops: use `--input-json` for inline arrays, or `.rundown/config.yaml` / `--input-file` for arrays and `file:` values +- Frontmatter `INPUTS:` declares names only — values may come from `.rundown/config.yaml`, `--input`, `--input-json`, `--input-file`, `RD_INPUT_*` env, or parent-forwarded vars from a parent runbook/step +- Data sources for FOR loops: use `--input-json` for inline arrays, or `.rundown/config.yaml`, `--input-file`, or parent-forwarded vars from a parent runbook/step for arrays and `file:` values ## Common Mistakes @@ -248,7 +248,7 @@ Key authoring notes: | Command block + substeps in same step | Choose one — cannot mix | | OUTPUTS after transitions | Content order: OUTPUTS → FOR → transitions → body | | Reserved word as step ID | `PASS`, `FAIL`, `CONTINUE`, etc. are reserved | -| `INPUTS:` written as a key→default map (`VarName: default`) | `INPUTS:` is a YAML sequence of bare names (`- VarName`). Defaults live in config / `--input-file` / `--input-json` / env, not in frontmatter. | +| `INPUTS:` written as a key→default map (`VarName: default`) | `INPUTS:` is a YAML sequence of bare names (`- VarName`). Values may come from `.rundown/config.yaml`, `--input`, `--input-json`, `--input-file`, `RD_INPUT_*` env, or parent-forwarded vars from a parent runbook/step, not frontmatter defaults. | | Name in `REQUIRED:` not declared in `INPUTS:` | `REQUIRED:` must be a subset of `INPUTS:`. Add the name to `INPUTS:` too. | | Skipping `rd check` | Always validate: `rd check ` |