Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ Every compiled pipeline runs as three sequential jobs:
│ ├── compile/ # Pipeline compilation module
│ │ ├── mod.rs # Module entry point and Compiler trait
│ │ ├── common.rs # Shared helpers across targets
│ │ ├── agentic_pipeline.rs # Canonical Setup → Agent → Detection → SafeOutputs → Teardown shape (shared by every target); BuiltPipelineContext, build_pipeline_context, build_canonical_jobs, per-job builders, fold_agent_conditions, agent_job_variables_hoist
│ │ ├── standalone.rs # Standalone pipeline compiler
│ │ ├── onees.rs # 1ES Pipeline Template compiler
│ │ ├── job.rs # Job-level ADO template compiler (target: job)
Expand Down
2 changes: 1 addition & 1 deletion docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,6 @@ These commands are not shown in `--help` but are available for contributors work

## Pipeline IR Reference

The compiler builds typed Azure DevOps pipeline IR and lowers it through one YAML emitter. Target-specific builders (`standalone_ir.rs`, `onees_ir.rs`, `job_ir.rs`, and `stage_ir.rs`) own job/stage names, template parameters, triggers, resources, and 1ES wrapping.
The compiler builds typed Azure DevOps pipeline IR and lowers it through one YAML emitter. The canonical Setup → Agent → Detection → SafeOutputs → Teardown shape lives in `agentic_pipeline.rs` (shared by every target); target-specific builders (`standalone_ir.rs`, `onees_ir.rs`, `job_ir.rs`, and `stage_ir.rs`) own only the per-target envelope (pipeline shape, template parameters, 1ES wrapping).

See [`docs/ir.md`](ir.md) for the complete IR reference.
4 changes: 2 additions & 2 deletions docs/extending.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ ado-aw compiles agent markdown into Azure DevOps YAML through the typed pipeline
When extending the compiler:

1. **New CLI commands**: add variants to the `Commands` enum in `src/main.rs`, implement dispatch, and add parsing/behavior tests.
2. **New compile targets**: build a typed `Pipeline` IR in a target module under `src/compile/`; use existing `standalone_ir.rs`, `onees_ir.rs`, `job_ir.rs`, and `stage_ir.rs` as references.
2. **New compile targets**: build a typed `Pipeline` IR in a target wrapper module under `src/compile/` (use existing `standalone_ir.rs`, `onees_ir.rs`, `job_ir.rs`, and `stage_ir.rs` as references). The canonical 5-job shape itself lives in `src/compile/agentic_pipeline.rs` and is reused by every target — wrappers only set the per-target `PipelineShape` and lift the shared `BuiltPipelineContext` into the right envelope.
3. **New front matter fields**: add fields to `FrontMatter` or nested config types in `src/compile/types.rs`. Breaking changes require a codemod under `src/compile/codemods/`; see [`docs/codemods.md`](codemods.md).
4. **New compiler extensions**: implement the `CompilerExtension` `name` / `phase` / `declarations` trio and return typed `Declarations`.
5. **New safe-output tools**: add to `src/safeoutputs/`, implement the safe-output data model and executor, and register it in MCP and Stage 3 execution wiring.
Expand Down Expand Up @@ -196,7 +196,7 @@ Available forms include `Succeeded`, `Always`, `Failed`, `SucceededOrFailed`, `A

## Adding a compile target

A compile target should build a complete typed `Pipeline` and then use the shared IR emit path. Follow the existing target builders:
A compile target should build a complete typed `Pipeline` and then use the shared IR emit path. Follow the existing target wrapper modules — they delegate the heavy lifting to `src/compile/agentic_pipeline.rs::build_pipeline_context` and only handle the per-target envelope:

- `src/compile/standalone_ir.rs`
- `src/compile/onees_ir.rs`
Expand Down
11 changes: 7 additions & 4 deletions docs/filter-ir.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,10 +196,13 @@ Maps each field of `PrFilters` to a `FilterCheck`:
### The `expression` Escape Hatch

The `expression` field on both `PrFilters` and `PipelineFilters` is **not**
part of the filter IR. It is a raw ADO condition string appended to the Agent
job's typed `Condition` by the target IR builder (for standalone, see
`build_agent_condition()` in `src/compile/standalone_ir.rs`), not to the bash
gate step.
part of the filter IR. It is a raw ADO condition string contributed to the
Agent job's typed `Condition` by `AdoScriptExtension` via
`Declarations::agent_conditions` (see
`src/compile/extensions/ado_script.rs::build_agent_conditions`); the
agentic-pipeline builder folds it into the Agent job's `condition:` along
with the typed gate-passed clauses. The `expression` is **not** wired into
the bash gate step.

## Pass 2: Validation

Expand Down
16 changes: 9 additions & 7 deletions docs/ir.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ _Part of the [ado-aw documentation](../AGENTS.md)._

ado-aw no longer compiles pipelines by substituting strings into YAML template files. Every production target builds a typed Azure DevOps pipeline IR, resolves graph-level facts, lowers that IR to `serde_yaml::Value`, and serializes once with `serde_yaml::to_string`.

The implementation lives under `src/compile/ir/` and the target-specific builders live beside the legacy target modules:
The implementation lives under `src/compile/ir/`. The canonical 5-job agentic-pipeline shape (Setup → Agent → Detection → SafeOutputs → Teardown) lives in `src/compile/agentic_pipeline.rs` and is shared by every target. Per-target wrappers handle only the envelope:

- `src/compile/standalone_ir.rs`
- `src/compile/onees_ir.rs`
- `src/compile/job_ir.rs`
- `src/compile/stage_ir.rs`

Those builders are the only place target shape should be assembled. Shared target logic should be typed IR construction helpers, not string fragments.
Those wrappers are the only place per-target shape (top-level `PipelineShape`, template parameters, 1ES `extends:`) should be assembled. Shared canonical-shape logic belongs in `agentic_pipeline.rs`. Shared target logic should be typed IR construction helpers, not string fragments.

## Module layout

Expand Down Expand Up @@ -253,11 +253,13 @@ This gives all targets one serialization path and one canonical YAML style. Targ

## Per-target compilers

The production target builders are:
The production target wrappers are:

- `standalone_ir.rs` — builds the standalone five-job pipeline and top-level triggers/resources.
- `onees_ir.rs` — builds the same logical job graph with `PipelineShape::OneEs`, causing the lowerer to emit the 1ES `extends:` wrapper and `templateContext` outputs.
- `job_ir.rs` — builds the target-job template with external `dependsOn` / `condition` template parameters.
- `stage_ir.rs` — builds the target-stage template with the stage-level external-parameter wrapper.
- `standalone_ir.rs` — wraps the canonical shape in a top-level standalone pipeline.
- `onees_ir.rs` — wraps the same canonical shape with `PipelineShape::OneEs`, causing the lowerer to emit the 1ES `extends:` wrapper and `templateContext` outputs.
- `job_ir.rs` — wraps the canonical shape as a target-job template with external `dependsOn` / `condition` template parameters.
- `stage_ir.rs` — wraps the canonical shape as a target-stage template with the stage-level external-parameter wrapper.

The canonical 5-job Setup → Agent → Detection → SafeOutputs → Teardown shape itself lives in `agentic_pipeline.rs` and is reused unchanged by every wrapper above; extensions plug into it via `Declarations` (steps, env, hosts, MCPG entries, and Agent-job condition clauses — see `Declarations::agent_conditions`).

When adding a target, follow the same pattern: parse and validate front matter, collect extension `Declarations`, build typed jobs/stages/steps, set the correct `PipelineShape`, and call the shared emit path.
4 changes: 2 additions & 2 deletions site/src/content/docs/guides/extending.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ ado-aw compiles agent markdown into Azure DevOps YAML through the typed pipeline
When extending the compiler:

1. **New CLI commands**: add variants to the `Commands` enum in `src/main.rs`, implement dispatch, and add parsing/behavior tests.
2. **New compile targets**: build a typed `Pipeline` IR in a target module under `src/compile/`; use existing `standalone_ir.rs`, `onees_ir.rs`, `job_ir.rs`, and `stage_ir.rs` as references.
2. **New compile targets**: build a typed `Pipeline` IR in a target wrapper module under `src/compile/` (use existing `standalone_ir.rs`, `onees_ir.rs`, `job_ir.rs`, and `stage_ir.rs` as references). The canonical 5-job shape itself lives in `src/compile/agentic_pipeline.rs` and is reused by every target — wrappers only set the per-target `PipelineShape` and lift the shared `BuiltPipelineContext` into the right envelope.
3. **New front matter fields**: add fields to `FrontMatter` or nested config types in `src/compile/types.rs`. Breaking changes require a codemod under `src/compile/codemods/`; see [Codemods](/ado-aw/reference/codemods/).
4. **New compiler extensions**: implement the `CompilerExtension` `name` / `phase` / `declarations` trio and return typed `Declarations`.
5. **New safe-output tools**: add to `src/safeoutputs/`, implement the safe-output data model and executor, and register it in MCP and Stage 3 execution wiring.
Expand Down Expand Up @@ -199,7 +199,7 @@ Available forms include `Succeeded`, `Always`, `Failed`, `SucceededOrFailed`, `A

## Adding a compile target

A compile target should build a complete typed `Pipeline` and then use the shared IR emit path. Follow the existing target builders:
A compile target should build a complete typed `Pipeline` and then use the shared IR emit path. Follow the existing target wrapper modules — they delegate the heavy lifting to `src/compile/agentic_pipeline.rs::build_pipeline_context` and only handle the per-target envelope:

- `src/compile/standalone_ir.rs`
- `src/compile/onees_ir.rs`
Expand Down
11 changes: 7 additions & 4 deletions site/src/content/docs/reference/filter-ir.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -197,10 +197,13 @@ Maps each field of `PrFilters` to a `FilterCheck`:
### The `expression` Escape Hatch

The `expression` field on both `PrFilters` and `PipelineFilters` is **not**
part of the filter IR. It is a raw ADO condition string appended to the Agent
job's typed `Condition` by the target IR builder (for standalone, see
`build_agent_condition()` in `src/compile/standalone_ir.rs`), not to the bash
gate step.
part of the filter IR. It is a raw ADO condition string contributed to the
Agent job's typed `Condition` by `AdoScriptExtension` via
`Declarations::agent_conditions` (see
`src/compile/extensions/ado_script.rs::build_agent_conditions`); the
agentic-pipeline builder folds it into the Agent job's `condition:` along
with the typed gate-passed clauses. The `expression` is **not** wired into
the bash gate step.

## Pass 2: Validation

Expand Down
16 changes: 9 additions & 7 deletions site/src/content/docs/reference/ir.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ description: Typed Azure DevOps pipeline IR, graph pass, output refs, conditions

ado-aw no longer compiles pipelines by substituting strings into YAML template files. Every production target builds a typed Azure DevOps pipeline IR, resolves graph-level facts, lowers that IR to `serde_yaml::Value`, and serializes once with `serde_yaml::to_string`.

The implementation lives under `src/compile/ir/` and the target-specific builders live beside the legacy target modules:
The implementation lives under `src/compile/ir/`. The canonical 5-job agentic-pipeline shape (Setup → Agent → Detection → SafeOutputs → Teardown) lives in `src/compile/agentic_pipeline.rs` and is shared by every target. Per-target wrappers handle only the envelope:

- `src/compile/standalone_ir.rs`
- `src/compile/onees_ir.rs`
- `src/compile/job_ir.rs`
- `src/compile/stage_ir.rs`

Those builders are the only place target shape should be assembled. Shared target logic should be typed IR construction helpers, not string fragments.
Those wrappers are the only place per-target shape (top-level `PipelineShape`, template parameters, 1ES `extends:`) should be assembled. Shared canonical-shape logic belongs in `agentic_pipeline.rs`. Shared target logic should be typed IR construction helpers, not string fragments.

## Module layout

Expand Down Expand Up @@ -256,11 +256,13 @@ This gives all targets one serialization path and one canonical YAML style. Targ

## Per-target compilers

The production target builders are:
The production target wrappers are:

- `standalone_ir.rs` — builds the standalone five-job pipeline and top-level triggers/resources.
- `onees_ir.rs` — builds the same logical job graph with `PipelineShape::OneEs`, causing the lowerer to emit the 1ES `extends:` wrapper and `templateContext` outputs.
- `job_ir.rs` — builds the target-job template with external `dependsOn` / `condition` template parameters.
- `stage_ir.rs` — builds the target-stage template with the stage-level external-parameter wrapper.
- `standalone_ir.rs` — wraps the canonical shape in a top-level standalone pipeline.
- `onees_ir.rs` — wraps the same canonical shape with `PipelineShape::OneEs`, causing the lowerer to emit the 1ES `extends:` wrapper and `templateContext` outputs.
- `job_ir.rs` — wraps the canonical shape as a target-job template with external `dependsOn` / `condition` template parameters.
- `stage_ir.rs` — wraps the canonical shape as a target-stage template with the stage-level external-parameter wrapper.

The canonical 5-job Setup → Agent → Detection → SafeOutputs → Teardown shape itself lives in `agentic_pipeline.rs` and is reused unchanged by every wrapper above; extensions plug into it via `Declarations` (steps, env, hosts, MCPG entries, and Agent-job condition clauses — see `Declarations::agent_conditions`).

When adding a target, follow the same pattern: parse and validate front matter, collect extension `Declarations`, build typed jobs/stages/steps, set the correct `PipelineShape`, and call the shared emit path.
Loading