Example: Document Template

A multi-page architecture document. The spec declares manifest.json + per-page markdown files.

Not runnable today. This example depends on the workspace harvest, which is not running: nothing turns the files the agent writes into artifacts, so the page list below is never produced and the publish step has nothing to read. The spec itself is still valid and still installs. See the note on the section index.


Spec

The spec lives in deliverable-specs-api with kind document-template:

json
1{
2  "ref": "architecture-standard",
3  "kind": "document-template",
4  "outputContract": {
5    "title": "Architecture Standard",
6    "mode": "workspace-files",
7    "targetSlot": { "kind": "deliverables" },
8    "multiPage": {
9      "manifestPath": "manifest.json",
10      "pagePathTemplate": "pages/<slug>.md",
11      "pages": [
12        { "slug": "overview",     "title": "Overview" },
13        { "slug": "components",   "title": "Components" },
14        { "slug": "data-model",   "title": "Data Model" },
15        { "slug": "deployment",   "title": "Deployment" }
16      ]
17    }
18  }
19}

Workflow

yaml
1apiVersion: xema.dev/workflow/v1alpha1
2kind: Workflow
3metadata:
4  name: document-template-example
5  version: 1.0.0
6on:
7  workflow_dispatch:
8    inputs:
9      request:
10        type: string
11        required: true
12permissions:
13  artifacts: write
14  kb: write
15jobs:
16  architecture:
17    title: Build architecture document
18    uses: xema/agent
19    with:
20      agentRef: architecture
21      stageKey: architecture
22      deliverableSpecRef: architecture-standard
23      agentSession: false
24      agentContext:
25        prompt: ${{ inputs.request }}
26    outputs:
27      handoff: ${{ job.outputs.structuredOutput }}

A publish job reading the harvested pages back out used to follow here. It is removed rather than rewritten: xema/publish-kb resolves an artifactId by reading payload.body, and no artifact with that shape is produced today.

Reading the result

This is the envelope the harvest was designed to expose. It is not produced today — shown so the spec's intent is legible, not as something to consume:

ts
1agentResult: {
2  deliverable: {
3    specRef: 'architecture-standard',
4    kind: 'document-template',
5    targetSlot: { kind: 'deliverables' },
6    content: {
7      kind: 'document',
8      manifestPath: 'deliverables/manifest.json',
9      pages: [
10        { slug: 'overview', title: 'Overview', artifactId: 'art-1', versionId: 'ver-1', version: 1 },
11        { slug: 'components', title: 'Components', artifactId: 'art-2', versionId: 'ver-2', version: 1 },
12        { slug: 'data-model', title: 'Data Model', artifactId: 'art-3', versionId: 'ver-3', version: 1 },
13        { slug: 'deployment', title: 'Deployment', artifactId: 'art-4', versionId: 'ver-4', version: 1 },
14      ],
15    },
16  },
17}

Neither outputs.deliverable nor outputs.deliverables resolves to this — both were removed from the action on 2026-08-29. What the job does expose is structuredOutput, the agent's structured handoff.

Validating the result

Validation is a job of its own. Add xema/validate-deliverables between the producing job and the publish, and gate the publish on its verdict:

yaml
1  validate:
2    needs: [architecture]
3    uses: xema/validate-[email protected]
4    with:
5      deliverableSpecRef: architecture-standard
6      strictness: standard
7      artifactIds:
8        - ${{ needs.architecture.outputs.structuredOutput.artifactId }}
9    outputs:
10      verdict: ${{ job.outputs.verdict }}
11      issues: ${{ job.outputs.issues }}

publish then declares needs: [architecture, validate] and if: ${{ needs.validate.outputs.verdict == 'pass' }}.

Passing the handoff artifact to a document-template spec will not produce a passing verdict — a JSON handoff is not the multi-page document the spec describes. The validator's built-in rules are artifact-count rules — it does not verify page-slug coverage today. A document spec that needs a floor states it as rules.minArtifactCount; producing fewer than that surfaces an INSUFFICIENT_ARTIFACTS issue and a fail verdict. See 04 Validation.


Previous: ← Examples Overview Next: JSON schema →