8.3 KiB
Markitect Workflow Definition Standard
Purpose
Markitect workflows describe repeatable Markdown-centered dataflow:
Markdown inputs -> extracted data products -> deterministic/assisted steps
-> artifacts and Markdown outputs
The workflow standard is business-facing orchestration. It uses the internal extension framework for execution semantics, diagnostics, provenance, capabilities, and future policy gates, but it is not itself the extension framework.
File Format
A workflow can be either:
- a YAML file
- a Markdown file with a fenced YAML block tagged
workflow,markitect-workflow, ormkt-workflow
Example:
# Release Notes Workflow
```yaml workflow
metadata:
id: release-notes
title: Release Notes
intent:
summary: Build release notes from accepted ADR decisions.
inputs:
adrs:
glob: docs/adr/*.md
extract:
decisions:
selector: sections[heading=Decision]
outputs:
release_notes:
path: out/release-notes.md
content: ${steps.render.markdown}
steps:
render:
kind: template
template: templates/release-notes.md
data:
decisions: ${sources.adrs.extracts.decisions}
```
Top-Level Sections
| Section | Required | Purpose |
|---|---|---|
metadata |
recommended | Stable id, title, owner, version, tags, timestamps. |
intent |
recommended | Why the workflow exists and what success means. |
inputs |
yes | Markdown files, directories, globs, literal values, or future index references. |
steps |
yes for processing | Deterministic or assisted operations over bound data. |
outputs |
optional | Files/artifacts produced from step or source data. |
dependencies |
optional | Workflow-level dependencies on files, workplans, contracts, or other workflows. |
conditions |
optional | Preconditions or skip rules. First version records these for inspection. |
artifacts |
optional | Named non-output products such as manifests, traces, or reports. |
permissions |
optional | Declared filesystem/network/provider/capability requirements. |
resources |
optional | CPU, memory, token, model, or storage expectations. |
timeouts |
optional | Workflow and step timeout budgets. First version records these. |
retry_policies |
optional | Retry rules by step kind or id. First version records these. |
escalation_rules |
optional | When human approval or operator attention is needed. |
observability |
optional | Events, trace detail, metrics, and audit expectations. |
responsibilities |
optional | Human/agent/system boundaries for review, approval, and execution. |
Unknown top-level sections are preserved as extensions in the loaded model so
the standard can evolve without immediately breaking older runners.
Metadata
metadata:
id: release-notes
title: Release Notes
version: "1"
owner: documentation
tags: [adr, release]
metadata.id should be stable. It is used in diagnostics and provenance when
available.
Intent
intent:
summary: Build release notes from accepted decisions.
success_criteria:
- One output file is generated.
- Every accepted ADR contributes its decision section.
Intent is descriptive in the first implementation. Later policy and assessment layers may use it for review or LLM-assisted checks.
Inputs
Inputs are named source collections or literal values.
inputs:
adrs:
glob: docs/adr/*.md
recursive: false
where:
frontmatter.status: accepted
extract:
decisions:
selector: sections[heading=Decision]
status:
selector: frontmatter.status
static_context:
value:
product: Markitect
Supported source fields:
file: one Markdown filepath: alias forfilefiles: list of Markdown filesglob: glob pattern relative to the workflow directorydirectory: directory of Markdown filesrecursive: recurse when usingdirectoryselector: selector to collect matchesextract: named selector mapmetrics: include document metricsfrontmatter: include frontmattervalue: literal structured value, no file parsing
Each Markdown input produces a collection:
items:
- path: docs/adr/001.md
frontmatter: {...}
metrics: {...}
extracts:
decisions:
- "## Decision\n\n..."
extracts:
decisions:
- "## Decision\n\n..."
Steps
Steps are named operations. steps may be either a mapping or a list with id.
steps:
render:
kind: template
template: templates/release-notes.md
data:
decisions: ${sources.adrs.extracts.decisions}
Common fields:
kind: step kinddepends_on: other step idswhen: condition expression, reserved for future execution gatingoptional: do not fail the whole workflow when this step is skipped or blockedpermissions: step-level permissionstimeout: step-level timeout declarationretry: step-level retry policy reference or inline ruleresponsibility:human,agent,system, ormixed
First implementation step kinds:
| Kind | Purpose |
|---|---|
shape |
Resolve data bindings into a structured object. |
extract |
Extract text from a source collection or document. |
query |
Return query match envelopes from a source collection or document. |
template |
Render a deterministic Markdown template. |
compose |
Join Markdown strings or files into one Markdown document. |
transform |
Apply deterministic Markdown transforms. |
include |
Resolve include markers in Markdown. |
contract_stub |
Generate a Markdown stub from a contract. |
contract_check |
Check a Markdown document against a contract, optionally with runtime context. |
form_state |
Evaluate UI-neutral field prefill, validation, and dynamic rules. |
assisted |
Provider-neutral assisted step boundary, optional by default. |
Data Bindings
Workflow expressions use ${...} references:
data:
decisions: ${sources.adrs.extracts.decisions}
summary: ${steps.render.markdown}
If a string is exactly one expression, the resolved value keeps its native type. If an expression appears inside a longer string, it is rendered as text.
Supported roots:
metadataintentsourcesstepsartifactsworkflow
Path behavior:
- dictionary keys use dot notation
- numeric list indexes are supported
- applying a field to a list maps that field over every dictionary item
Outputs
outputs:
release_notes:
path: out/release-notes.md
content: ${steps.render.markdown}
Supported output fields:
path: output path relative to--output-diror workflow directorycontent: Markdown/string/structured value to writetemplate: optional template pathdata: data for template renderingartifact: optional artifact name
Output paths must stay within the output root.
Assisted Steps
Assisted steps define the boundary; they do not require a provider dependency:
review:
kind: assisted
optional: true
prompt: prompts/review.md
input: ${steps.render.markdown}
data:
rubric: concise release note review
When no assisted adapter is supplied:
- optional assisted steps are skipped with a warning diagnostic
- required assisted steps fail with an error diagnostic
This keeps workflows runnable in deterministic environments.
Permissions And Responsibilities
Permissions and responsibilities are declarative in the first runner and become policy inputs for later access-control work.
permissions:
filesystem:
read: [docs, templates]
write: [out]
network: false
assisted_generation: false
responsibilities:
human:
approves_outputs: true
agent:
may_run_deterministic_steps: true
system:
enforces_path_safety: true
Observability
observability:
events:
- workflow.started
- step.completed
- output.written
trace: summary
Workflow runs return trace events and diagnostics in JSON/YAML output. Future backends can persist these events.
Design Rules
- Keep deterministic execution useful without providers.
- Keep all outputs explainable through provenance and diagnostics.
- Preserve unknown metadata rather than rejecting reasonable future extensions.
- Make assisted, external, networked, or sensitive steps explicit.
- Keep internal extension registration separate from business workflow orchestration.