# O7 DSL Reference for @generate

Source: `spec/spec.md`
Generated from sections: named-workflows; checks; external-execution-boundary; version-header; canonical-operator-set; block-structure; negation; canonical-example; run-workflow-name; conditional-execution; parallel-blocks; no-goto-in-v1; deferred-goto-and-label; match-statement; exec-principles; required-core-fields; harness-definitions-shared-config; prompt-file-discovery

Use this as the compact DSL reference for `@generate`.
If this file conflicts with `spec/spec.md`, the spec wins.

---

### 5.1 Named Workflows

The primary reusable unit is a named workflow.

- Workflows are declared explicitly with `workflow <name>`.
- A workflow may contain multiple commands, nested control flow, and further `run` calls.
- Names may encode namespace-like structure by convention, for example `workflow reviews::security`.
- The `::` separator is part of the name string — it has no structural meaning to the parser.

### 5.2 Checks

Checks are named workflows used in conditional positions (`if`, `while`).

- A check is a workflow whose execution produces a structured boolean result.
- The runner interprets the check workflow's output to determine control flow.
- Check output schema (v1):

```json
{
  "result": true,
  "reason": "All tests passing"
}
```

- `result` (boolean): required. Determines the branch/loop decision.
- `reason` (string): optional. Human-readable explanation, not a control input.

**Check execution model**: When a check is evaluated (for `if`, `if not`, `while`, or `while not`), the engine executes the named check workflow as a normal `run` invocation. The check workflow's final `exec` block must produce JSON output on stdout conforming to the check output schema: `{ "result": <boolean>, "reason": <optional string> }`. The engine captures the stdout of the last `exec` block in the check workflow and parses it as JSON. Additional properties beyond `result` and `reason` are rejected as invalid.

Check workflows used with `match` statements return a variant string in the `variant` field (see `conformance/schemas/match-output.schema.json`) instead of a boolean `result` field. See §7.6 for the `match` statement.

### 5.3 External Execution Boundary

O7 is not the agent runtime. A workflow eventually reaches an `exec` block, which hands structured execution intent to a named harness adapter.

The workflow DSL describes:
- which harness to use
- which prompt input to provide
- which structured execution arguments to pass

The harness layer describes:
- how those fields map to a concrete CLI invocation or API call
- any adapter logic needed by a specific coding CLI

### 6.1 Version Header

Every `.7` file must begin with a version declaration:

```text
version 1
```

- The runner must reject files with an unrecognized or missing version.
- This enables forward-compatible parser evolution.

### 6.2 Canonical Operator Set

```text
workflow <name>
run <workflow-name>
if <check-name>
if not <check-name>
while <check-name>
while not <check-name>
par-and <join-workflow-name>
match <check-name>
exec
```

Not part of the v1 canonical language:
- `goto`
- `label`
- Markdown headings as executable syntax
- Bare-name shorthand (parsers may accept as non-normative sugar, but all docs/examples/tests use `run <name>`)

### 6.3 Block Structure

- Indentation is semantically meaningful.
- Nested blocks are used for `if`, `if not`, `while`, `while not`, `par-and`, and `exec`.
- Markdown or prose may appear in files only if it is semantically irrelevant to execution.

### 6.4 Negation

- `while not <check>` repeats while the check returns false.
- `if not <check>` executes its block only if the check returns false.
- Symbolic `!` is not part of the canonical syntax.

### 6.5 Canonical Example

```text
version 1

workflow main
  run init-rust-from-idea
  run plan-generic
  run review-spec
  while not goal-met
    run run-impl
    run ensure-tested
    run review-impl
    run commit
    run review-all
    par-and combine-reviews
      run review-sec
      run review-code
      run review-tests
    if has-outstanding-issues
      run prepare-remaining-tasks
  run report-all
```

This preserves the intent of the original source example while using structured looping instead of `goto`.

### 7.1 `run <workflow-name>`

- Executes the named workflow.
- The named workflow may contain nested control flow and additional `run` calls.
- The runner records status for the invocation and its nested steps.

### 7.2 Conditional Execution

- `if <check-name>` executes its block only if the named check returns true.
- `if not <check-name>` executes its block only if the named check returns false.
- `while <check-name>` repeats its block while the check returns true.
- `while not <check-name>` repeats its block while the check returns false.
- Conditions do not support arbitrary inline expressions in v1.

### 7.3 Parallel Blocks

`par-and <join-workflow-name>` introduces an indented parallel block.

**Branch rule**: direct children of a `par-and` block must be `run <workflow-name>` entries.

**Execution rules**:
- Each direct child `run` starts as an independent branch.
- The join workflow receives the collected outputs of all completed child branches.
- If all branches succeed, the named join workflow runs with the collected outputs.

**Failure policy**: configurable per block, defaulting to a global setting.

Two supported policies:
- **fail-fast** (default): first branch failure cancels remaining branches immediately; the join workflow does not run.
- **wait-then-fail**: all branches run to completion regardless of individual failures; the join workflow does not run if any branch failed; all failure information is available for inspection.

Syntax direction for per-block override (exact syntax deferred):
```text
par-and combine-reviews fail-policy:wait-then-fail
  run review-sec
  run review-code
  run review-tests
```

The global default can be set in runner config.

**V1 branch output access**: The join workflow receives collected branch outputs as engine-internal state. However, v1 does not define a mechanism for the join workflow's `exec` blocks to access these outputs (e.g., via environment variables, stdin, or injected parameters). The outputs are available for the engine's internal tracking and future expansion. A concrete access mechanism is deferred to a future spec version (see §20).

**Nesting restriction**: `par-and` blocks cannot be nested inside parallel branch workflows. Each branch executes as a sequential workflow; if a branch workflow contains a `par-and` statement, it is a runtime error. This restriction simplifies the execution model and avoids complex nested parallelism.

### 7.4 No `goto` in v1

The v1 spec removes `goto` and `label` from the executable core language. Structured loops and checks provide a smaller, more analyzable control-flow surface consistent with the KISS and one-idiom goals.

### 7.5 Deferred: `goto` and `label`

`goto` and `label` appeared in the original loose-spec and are retained as documented future expansion material. However, there is active uncertainty about whether they should ever be added:

- **For**: some workflows have genuinely non-structured retry patterns that are awkward without goto.
- **Against**: goto introduces potential for spaghetti workflows, complicates static analysis, and conflicts with the one-idiomatic-way principle.
- **Status**: deferred to v2+ evaluation. If added, they should be constrained (e.g., backward-only jumps, or labeled-loop break/continue) rather than arbitrary.

Implementations should not include `goto`/`label` support unless a future spec version explicitly adopts them.

### 7.6 Match Statement

The `match` statement branches on the variant returned by a check workflow. A check workflow used with `match` returns JSON conforming to `match-output.schema.json`: `{ "variant": "<name>", "reason": "<optional>" }`. The `match` statement allows the workflow author to handle each variant distinctly.

**Syntax**:

```text
match <check-name>
  <variant-name> -> run <workflow-name>
  <variant-name> ->
    run <workflow-name>
    run <another-workflow>
  else ->
    run <fallback-workflow>
```

**Rules**:

- `match <check-name>` evaluates the named check workflow and inspects the `variant` field of its JSON output.
- Each arm specifies a variant name followed by `->` and either a single `run` statement on the same line, or an indented block of statements.
- The `else` arm is an optional catch-all that matches when no other arm matches. If present, it must be the last arm.
- If no arm matches and no `else` arm is present, the engine raises a runtime error with the unmatched variant name.

**Example**:

```text
workflow handle-review
  match classify-review
    needs-refactor -> run refactor-code
    needs-tests ->
      run add-tests
      run run-tests
    approved -> run finalize
    else -> run escalate
```

### 8.1 `exec` Principles

`exec` is the dedicated external execution boundary.

- `exec` is structured, not shell-shaped.
- `exec` uses named keyword fields, not positional-only syntax.
- `exec` is canonically written as an indented multi-line block.
- `exec` references a named harness rather than embedding raw commands.

### 8.2 Required Core Fields

| Field | Required | Description |
| --- | --- | --- |
| `harness` | yes | Named harness to invoke |
| `prompt_file` | one of prompt/prompt_file | Path to prompt content file |
| `prompt` | one of prompt/prompt_file | Inline prompt content string |
| `args` | no | Structured key-value mapping of extra execution arguments |

`prompt` and `prompt_file` are mutually exclusive.

**Canonical form**:

```text
workflow run-impl
  exec
    harness: claude-code
    prompt_file: prompts/run-impl.md
    args:
      mode: implement
      model: sonnet
```

**Inline prompt variant**:

```text
workflow quick-check
  exec
    harness: codex
    prompt: "Review the changed files and summarize the main risk."
```

### 8.3 Harness Definitions (Shared Config)

Named harnesses are defined in a shared configuration file outside the workflow DSL.

**Location**: `.7/harnesses.toml` (canonical) or equivalent runner config.

**Format**: the harness config must be a shared cross-implementation format so both TS and Rust runners resolve the same harness definitions identically.

A harness entry defines:
- the harness name
- the command or invocation template
- how `exec` fields (`prompt`, `prompt_file`, `args`) map to the concrete command via named slots
- any adapter-specific defaults

Conceptual model:
- `exec` produces a structured invocation object.
- The named harness adapter consumes that object and constructs the concrete tool invocation.
- Workflow files never see the raw command template.

**Example harness config direction** (exact format deferred but directional):

```toml
[harness.claude-code]
command = "claude"
prompt_slot = "--prompt-file"
args_mapping = "flags"

[harness.codex]
command = "codex"
prompt_slot = "--prompt"
args_mapping = "flags"
```

## 9. Prompt File Discovery

Prompt files referenced in `exec` blocks via `prompt_file` are resolved using a defined search order:

1. Relative path from the project root (if `prompt_file` contains a `/`).
2. `prompts/<name>` — primary conventional directory.
3. `.7/prompts/<name>` — secondary project-local directory.

Discovery rules:
- If `prompt_file` is an explicit relative path (contains `/`), use it directly.
- If `prompt_file` is a bare name, search `prompts/` then `.7/prompts/` in order.
- Missing prompt file is an error.

**Inline prompts**: When an `exec` block uses `prompt` (inline string) instead of `prompt_file`, prompt file discovery does not apply. The inline prompt content is delivered directly to the harness adapter. The adapter is responsible for providing the content to the external tool (e.g., via a temporary file, stdin, or command-line argument as appropriate for the harness).
