The Agentic Layer
Workflow Configuration
One file orchestrates the entire workflow. Phase ordering, loop limits, gate bindings, tool permissions, template routing. This is the control plane.
workflow.yaml: The Control Plane
The workflow.yaml file is the central config for your agentic layer. It defines which phases run, in what order, how many retries each loop gets, what happens on failure, and which gates and templates apply. Every other artifact in the agentic layer is referenced from here.
Two approaches to workflow definition
Declarative (YAML + engine)
A workflow.yaml file defines phases, gates, loops, and escalation rules. A separate workflow engine reads the YAML and orchestrates execution. This is the approach shown throughout this page.
When to use it: When you want one engine to serve multiple projects, or when non-engineers need to configure workflow behavior. The workflow definition is data, not code.
Trade-off: You need to build or adopt a workflow engine that interprets the YAML. The engine is a significant piece of software: phase orchestration, state management, retry logic, escalation routing.
Imperative (scripts)
Orchestrator scripts chain phase executors together directly. Each script defines a workflow variant: which phases run, in what order, with what error handling. Different autonomy levels are different scripts (or the same script with different configuration parameters).
When to use it: When you're building for a single project, or when the workflow needs to do things YAML can't easily express (subprocess management, environment setup, notification formatting). The workflow definition is code, not data.
Trade-off: Workflow behavior is spread across script files rather than centralized in one config. Adding a new workflow variant means writing a new script (or parameterizing an existing one).
Which one is right?
The framework is agnostic. The important thing is that workflow configuration is separate from phase implementation. Your plan template shouldn't know whether it was invoked by a YAML engine or a Python script. The rest of this page uses YAML because it's easier to read in documentation, but every YAML example has an imperative equivalent.
Maturity note: Teams often start with imperative scripts (faster to build, easier to debug) and migrate to declarative config when they need to reuse the same engine across multiple projects.
Minimum viable vs full enterprise
# workflow.yaml -- minimum viable config
# Enough to run the workflow with defaults
version: 1
phases:
# - intent # optional: requirement refinement
- plan
- build
- test
- review
- deploy
# Everything else uses framework defaults:
# - Loop limits: 3
# - Escalation: human
# - Gates: built-in
# - Templates: prompts/{phase}.md
Imperative equivalent
The same workflow defined as a script:
# workflow_sdlc.py -- equivalent to the YAML above
phases = ["plan", "build", "test", "review", "deploy"]
for phase in phases:
result = run_phase(phase, issue, state)
if not result.success:
if phase_config[phase].get("retry"):
result = run_healing_loop(phase, result, max_retries=3)
if not result.success:
if phase_config[phase]["required"]:
escalate(phase, result)
break
else:
log_warning(phase, result)
The behavioral logic is identical. The difference is where the configuration lives (YAML file vs code).
# workflow.yaml -- full enterprise config
version: 1
# -- Phase Ordering ------
phases:
- plan
- build
- test
- review
- document
- deploy
- monitor
# -- Template Routing ----
templates:
plan:
feature: prompts/plan-feature.md
bug: prompts/plan-bug.md
task: prompts/plan-task.md
patch: prompts/plan-patch.md
default: prompts/plan.md
build: prompts/build.md
test: prompts/test.md
review: prompts/review.md
document: prompts/document.md
deploy: prompts/deploy.md
monitor: prompts/monitor.md
# -- Feedback Loops ------
loops:
test_retry:
max: 3
trigger: test.fail
action: rebuild
cooldown_ms: 5000
review_patch:
max: 3
trigger: review.blockers
action: rebuild_and_retest
cooldown_ms: 5000
full_rebuild:
max: 1
trigger: review.architectural
action: replan_and_rebuild
# -- Escalation ----------
escalation:
handler: human
timeout_hours: 24
notification:
channel: engineering
context:
- plan
- build_report
- test_results
- review_issues
- failure_history
# -- Quality Gates -------
gates:
after_build: gates/build-lint.yaml
after_test: gates/test-coverage.yaml
after_review: gates/review-severity.yaml
after_document: gates/doc-completeness.yaml
after_deploy: gates/deploy-readiness.yaml
# -- Tool Permissions ----
tools:
configs:
file_system: tools/file-system.yaml
code_execution: tools/code-execution.yaml
external_apis: tools/external-apis.yaml
context_providers: tools/context-providers.yaml
phase_overrides:
plan:
code_execution: disabled
file_system.write: disabled
review:
code_execution: disabled
file_system.write: disabled
# -- Parallel Execution --
parallel:
- [document, deploy_prepare]
# -- Monitoring ----------
monitoring:
track:
- workflow_success_rate
- average_iterations_per_loop
- phase_duration_ms
- cost_per_run
- escalation_rate
alert_on:
escalation_rate_above: 0.3
avg_iterations_above: 2.5
Configuration reference
Define which phases run and in what order. You can skip phases or reorder them. Default: plan, build, test, review, document, deploy, monitor.
# Skip document for quick patches
phases:
- plan
- build
- test
- review
- deploy # skip document for speedMaximum retries per feedback loop. Too few (1) = every transient failure escalates. Too many (10) = workflow burns time on unfixable issues. Default: 3.
loops:
test_retry:
max: 3
review_patch:
max: 3
full_rebuild:
max: 1 # full rebuilds are expensive -- keep lowWhat happens when loops exhaust. Who gets notified, what context they receive, how long before auto-close.
escalation:
handler: human # human | auto_close | fallback_workflow
timeout_hours: 24
notification:
channel: engineering
mention: "@oncall"
context:
- plan
- build_report
- test_results
- review_issues
- failure_historyMap gate files to phase triggers. Reference external YAML or inline criteria.
gates:
after_test: gates/test-coverage.yaml
after_review: gates/review-severity.yaml
after_document:
inline: # inline gate definition
criteria:
has_changelog_entry: true
on_fail: retry
max_retries: 1Override the default tool permission matrix for specific projects.
tools:
phase_overrides:
review:
external_apis.browser: enabled # enable visual review
build:
external_apis.git: disabled # builds should not touch gitUse custom templates instead of defaults. Supports issue-type routing.
templates:
plan:
feature: prompts/plan-feature.md
bug: prompts/plan-bug.md
default: prompts/plan.md
build: prompts/custom-build.md # project-specificPhases that can run concurrently. Only phases without data dependencies can run in parallel.
parallel:
- [document, deploy_prepare] # run at the same timeThe complete directory structure
agentic-layer/
├── prompts/ # Prompt templates
│ ├── plan.md # Default plan template
│ ├── plan-feature.md # Issue-type routing variants
│ ├── plan-bug.md
│ ├── plan-task.md
│ ├── plan-patch.md
│ ├── build.md
│ ├── test.md
│ ├── review.md
│ ├── document.md
│ ├── deploy.md
│ └── monitor.md
├── gates/ # Quality gate definitions
│ ├── test-coverage.yaml
│ ├── review-severity.yaml
│ ├── doc-completeness.yaml
│ ├── build-lint.yaml
│ └── deploy-readiness.yaml
├── tools/ # Tool integration configs
│ ├── file-system.yaml
│ ├── code-execution.yaml
│ ├── external-apis.yaml
│ └── context-providers.yaml
├── commands/ # Human-invoked commands
│ ├── commit.md
│ ├── security-audit.md
│ └── explain.md
├── skills/ # Agent-invoked skills
│ ├── run-tests.md
│ ├── lint-check.md
│ └── dependency-check.md
└── workflow.yaml # Central orchestration config
| Directory | Contents | Typical Count |
|---|---|---|
| prompts/ | One markdown file per phase, plus routing variants | 7-15 files |
| gates/ | One YAML file per quality gate | 3-5 files |
| tools/ | One YAML file per tool category | 4 files |
| commands/ | One markdown file per custom command | 3-10 files |
| skills/ | One markdown file per reusable skill | 3-10 files |
| Root | workflow.yaml | 1 file |
Configuration by team size
PHASES
Skip document
LOOP LIMITS
2 (save cost)
GATES
test-coverage only
TEMPLATES
Defaults, no routing
TOOLS
Minimal config
TOTAL FILES
~10
# Solo: fast and lean
phases: [plan, build, test, review, deploy]
loops:
test_retry: { max: 2 }
review_patch: { max: 2 }
gates:
after_test: gates/test-coverage.yaml