Files
markitect-tool/docs/workflow-definition-standard.md

315 lines
8.7 KiB
Markdown

# Markitect Workflow Definition Standard
## Purpose
Markitect workflows describe repeatable Markdown-centered dataflow:
```text
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`, or `mkt-workflow`
Example:
````markdown
# 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
```yaml
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
```yaml
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.
```yaml
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 file
- `path`: alias for `file`
- `files`: list of Markdown files
- `glob`: glob pattern relative to the workflow directory
- `directory`: directory of Markdown files
- `recursive`: recurse when using `directory`
- `selector`: selector to collect matches
- `extract`: named selector map
- `metrics`: include document metrics
- `frontmatter`: include frontmatter
- `value`: literal structured value, no file parsing
Each Markdown input produces a collection:
```yaml
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`.
```yaml
steps:
render:
kind: template
template: templates/release-notes.md
data:
decisions: ${sources.adrs.extracts.decisions}
```
Common fields:
- `kind`: step kind
- `depends_on`: other step ids
- `when`: condition expression, reserved for future execution gating
- `optional`: do not fail the whole workflow when this step is skipped or blocked
- `permissions`: step-level permissions
- `timeout`: step-level timeout declaration
- `retry`: step-level retry policy reference or inline rule
- `responsibility`: `human`, `agent`, `system`, or `mixed`
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:
```yaml
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:
- `metadata`
- `intent`
- `sources`
- `steps`
- `artifacts`
- `workflow`
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
```yaml
outputs:
release_notes:
path: out/release-notes.md
content: ${steps.render.markdown}
```
Supported output fields:
- `path`: output path relative to `--output-dir` or workflow directory
- `content`: Markdown/string/structured value to write
- `template`: optional template path
- `data`: data for template rendering
- `artifact`: 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:
```yaml
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.
```yaml
permissions:
filesystem:
read: [docs, templates]
write: [out]
network: false
assisted_generation: false
policy:
subject_from_token: examples/policy/netkingdom-claims.yaml
policy_map: examples/policy/enterprise-policy-map.yaml
required_assurance:
mfa: true
emergency_justification: INC-123
decision_log: .markitect/policy-decisions.jsonl
flex_auth:
resource_manifest: examples/policy/flex-auth-resource-manifest.yaml
responsibilities:
human:
approves_outputs: true
agent:
may_run_deterministic_steps: true
system:
enforces_path_safety: true
```
## Observability
```yaml
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.