generated from coulomb/repo-seed
315 lines
8.7 KiB
Markdown
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.
|