Authoring deliverables in workflows
A workflow job becomes "deliverable-producing" the moment it sets with.deliverableSpecRef. There's no second declaration — that one field is the contract.
Literal form
1jobs:
2 requirements:
3 uses: xema/agent
4 with:
5 agentRef: requirements
6 deliverableSpecRef: requirements-standard
7 agentContext:
8 prompt: ${{ inputs.request }}The compiler resolves the spec ref against the registry at compile time. A typo or a missing spec fails with DSL_UNKNOWN_DELIVERABLE_SPEC — fast, clear, no runtime surprise.
Expression form
When the spec depends on runtime data — typically a clarification step's output — author the ref as a ${{ … }} expression.
1jobs:
2 build:
3 needs: [clarify]
4 strategy:
5 dynamic:
6 from: ${{ needs.clarify.outputs.targets }}
7 as: target
8 keyBy: name
9 maxEntries: 32
10 uses: xema/agent
11 with:
12 agentRef: builder
13 deliverableSpecRef: ${{ target.specRef }}
14 agentContext:
15 prompt: ${{ target.prompt }}The ref resolves at dispatch time, when the matrix iteration's binding is materialized. The runtime fetches the spec, validates the harvest, and surfaces the canonical envelope.
Authors who supply expression-shaped refs accept that the compiler can't pre-validate the ref — the runtime fail-fasts on unknown specs with a typed RENDER_FAILED error naming the offending value.
Variable count, mixed kinds
The matrix mechanism is the single answer to "produce a different number of deliverables based on user intent." The upstream clarification step decides how many targets the user asked for, of which kinds, and emits a typed array. Each matrix iteration:
- Resolves its own
deliverableSpecReffrom the matrix entry. - Drives its own agent session with the entry's prompt.
- Harvests + validates against that spec.
- Surfaces its result under
byKey[<name>].deliverable.content.<...>for downstream jobs.
1clarify:
2 uses: xema/agent
3 with:
4 agentRef: clarification-coordinator
5 deliverableSpecRef: handoff-package
6 agentContext:
7 prompt: Clarify the request and emit a typed handoff package.
8 outputs:
9 targets: ${{ job.outputs.deliverable.content.value.targets }}
10
11build:
12 needs: [clarify]
13 strategy:
14 dynamic:
15 from: ${{ needs.clarify.outputs.targets }}
16 as: target
17 keyBy: name
18 uses: xema/agent
19 with:
20 agentRef: builder
21 deliverableSpecRef: ${{ target.specRef }}
22 agentContext:
23 prompt: ${{ target.prompt }}A user asking for "five microservices and one frontend" produces a clarification output with six targets (five specRef: microservice-template, one specRef: frontend-template). The matrix expands to six concurrent agent runs. Zero deliverables = empty array = zero iterations.
What you don't need to declare
- No output-key mapping. Workflow expressions read
deliverable.content.<...>directly. - No validation flag on the producing job. Validation is a job of its own — add
xema/validate-deliverablesdownstream when you want a verdict to gate on. See 04 Validation.
Action version
1uses: xema/[email protected]Previous: ← Concepts Next: Output Envelope →