Skip to content

Workflow Engine — Conceptual Deep Dive ​

Purpose & Mental Model ​

Agentweaver workflows answer one question: which execution process should move an agent run from intent to a reviewed outcome?

The workflow engine is the policy layer between orchestration and runtime execution. The coordinator decides what the team should accomplish. The workflow engine decides which gates, loops, and terminal paths govern the run that carries out that work.

Conceptually, a workflow engine has five jobs:

  1. Define reusable process graphs as declarative workflow templates.
  2. Discover built-in, catalog, and project-authored workflow definitions.
  3. Track invocation context and automation metadata so runs carry the right operational context without changing workflow validity.
  4. Select the best process fit when several workflows are available.
  5. Bind the selected definition to real runtime executors, failing closed if any node or edge cannot run safely.

A useful rebuilding rule is: workflows are declarative policy graphs; binding is the safety boundary that turns policy into execution.

The executor chain shown is the built-in default, not every workflow. Checkpoints use ICheckpointStoreFactory: PostgreSQL-backed shared storage for the PostgreSQL provider, file storage for local/default configuration (apps/Agentweaver.Api/Program.cs:1063–1065; apps/Agentweaver.Api/Runs/RunWorkflowFactory.cs:181–188). Pending human decisions are durable records, not browser-local state.

Workflows are one half of run orchestration. The coordinator and run lifecycle are covered in orchestration.md; the focus here is how workflow definitions are authored, generated, selected, and bound.

Core Design Invariants ​

These invariants are the backbone of the workflow engine:

  • Definitions are data, not code. YAML describes nodes, edges, and metadata. It does not execute directly.
  • Discovery is server-side. Clients list, render, and edit workflows, but loading, validation, selection, and binding happen in the API.
  • Trigger evaluation and workflow execution are separate concerns. A workflow definition may declare a trigger, but trigger verification/filtering happens before the workflow is selected and bound.
  • Overrides cannot bypass safety. A requested workflow id is honored only if it resolves, validates, and binds.
  • Selection is bounded model authority. The selector may choose among already-safe candidates; it may not invent ids or bypass availability and validation checks.
  • Binding fails closed. A node type, gate, or edge with no known executor mapping aborts the build instead of becoming a no-op.
  • Gates belong to workflow definitions. Effective workflow resolution does not inject a configurable project review policy; the binder checks the declared graph.
  • A built-in default is always available. The default workflow is embedded in code and serves projects that ship no workflow files of their own, so every project has a valid workflow to run.

Workflow Template as Policy Graph ​

What a Workflow Template Is ​

A workflow template is a declarative graph with:

  • a stable id,
  • a human-readable name and optional description / version,
  • a start node,
  • typed nodes,
  • directed edges,
  • optional board stages,
  • and node metadata used for rendering and execution context.

The key abstraction is that a workflow describes what process should happen, not the hidden plumbing required to execute it. A single logical edge such as rai -> review when review may expand into adapters, state storage, predicates, review ports, and graph outputs when bound to the runtime.

The loader validates the static shape first: required fields, valid node type, unique node ids, known edge endpoints, check branches with matching outgoing edges, and valid references from structured node fields.

The binder then validates runtime bindability. This second phase matters because the schema can represent graph concepts before the live executor graph has executor support for them.

Node Types ​

Agentweaver's workflow schema models these conceptual node types:

  • prompt — an agent turn that produces work or analysis.
  • publish — an agent-backed action classified as NodeKind.Agent, not the deterministic GitHub PR executor (apps/Agentweaver.Api/Workflows/NodeClassifier.cs:78).
  • peer_review — an AI review turn that can emit approval, change request, decline, pass, or fail verdicts.
  • build_test — the platform-owned Build & Test gate. It runs the canonical build/test/preview instruction, emits approved, request-changes, or declined, and should sit after any RAI safety gate and before human review for software workflows. In Sandbox:AgentExecutionMode=pod-per-run, assembly Build & Test first launches a dedicated AgentHost pod for the coordinator run and configures it with the detached integration worktree as its working directory, so the gate and any start_preview server run from the same assembled tree.
  • check — a routing gate with declared branches. Known gate kinds include rai, human-review, and rubberduck.
  • merge — an action that applies produced changes.
  • open_pull_request — a platform-owned deterministic action, not an LLM turn. It invokes the PR client with configured title, body, base, head, and draft fields; templates support {run_id}, {worktree_branch}, {originating_branch}, and {outcome_summary}. It can follow an agent turn or a supported approval/merge transition. Successful publication emits the PR number/url; ordinary validation, credential, and client errors emit a failed step while passing the produced AgentTurnOutput onward unchanged. Cancellation is rethrown rather than swallowed (packages/Agentweaver.AgentRuntime/Workflow/OpenPullRequestTurnExecutor.cs:88–166). Do not equate one client invocation with a guaranteed single network request.
  • scribe — a recording step that captures the outcome.
  • terminal — an explicit sink such as done, declined, or safety failed.
  • fan_out, fan_in, coordinator_composed — schema-level extension points for richer topologies.
  • serial is not a workflow node type; ordinary directed edges express sequential execution.

Runtime binding supports prompt/publish agent turns, peer-review, build_test, open_pull_request, check gates with known gate kinds, merge, scribe, terminal sinks, and a set of sequential / review / direct-completion topologies. Extension node types remain explicit schema concepts; until executors bind them, the runtime fails closed.

An open_pull_request node binds from a producing prompt node directly, or from a peer_review/build_test gate's approved/pass verdict (mirroring the existing gate → merge transition), and forwards into scribe exactly like an agent turn does:

yaml
nodes:
  - id: implement
    type: prompt
    agent: worker
    prompt: "Implement the requested change."
  - id: build-test
    type: build_test
  - id: open-pr
    type: open_pull_request
    title: "Agentweaver: {outcome_summary}"
    body: "Automated changes from run `{run_id}` on `{worktree_branch}`."
    base: main
  - id: record
    type: scribe
edges:
  - from: implement
    to: build-test
  - from: build-test
    to: open-pr
    when: approved
  - from: open-pr
    to: record

Software assembly gate order ​

Authored assembly gates are ordered using a breadth-first traversal from start over unconditional edges and verdict edges whose when is approved, pass, or review. The resolver selects known check/Build & Test nodes, sorts them by that traversal index (unvisited gates sort last, in declaration order), projects canonical assembly stages (rai, build-test, rubberduck, human-review), and deduplicates by stage. For non-code-producing work, the platform Build & Test gate is omitted (apps/Agentweaver.Api/Coordinator/CoordinatorAssemblyService.cs:1586–1676). This is aggregate gate projection, not execution of every workflow node by the assembly service.

For the built-in software workflows this means RAI runs before Build & Test, even if a YAML author groups node declarations differently. bug-fix follows triage -> fix -> verify -> rai-check -> build-test -> human-review; software-delivery follows plan -> implement -> test-gate -> rai-check -> rubberduck -> code-review -> build-test -> review-gate (packages/Agentweaver.Squad/Catalog/Resources/workflows/bug_fix.yaml, software_delivery.yaml). Copilot workflow and blueprint generation prompts carry the same rule so generated software workflows place build_test after any RAI gate and immediately before human review (apps/Agentweaver.Api/Workflows/WorkflowGatePromptGuidance.cs:7, apps/Agentweaver.Api/Workflows/CopilotWorkflowGenerator.cs:243, apps/Agentweaver.Api/Blueprints/CopilotBlueprintGenerator.cs:152).

Build & Test infrastructure failures are not authored request-changes verdicts. Pod capacity, launch/readiness, endpoint-resolution, and A2A transport failures are raised as typed infrastructure exceptions, then parked as retryable assembly_blocked reasons or failed terminally for non-retryable configuration errors (apps/Agentweaver.Api/Coordinator/CoordinatorAssemblyService.cs:1039–1043, :3559–3632). The emitted event payload includes detail, exceptionMessage, innerExceptionMessage, innerExceptionType, and infrastructureReason, so operators can distinguish a quota park from an AgentHost launch or A2A transport root cause.

The Default Workflow ​

The default workflow encodes the standard standalone run pipeline. Its canonical source is the code-embedded DefaultWorkflowTemplate (id default), loaded once through the real loader as BuiltInWorkflows.Default. DefaultWorkflowTemplate.TryMaterialize can write an inspectable project copy at .agentweaver/workflows/default.yaml; customization requires a new workflow id because the registry skips a materialized default. The current success path is agent -> rai -> review -> merge -> push-pr -> scribe -> done, with separate safety-failed and declined sinks (apps/Agentweaver.Api/Workflows/DefaultWorkflowTemplate.cs:42–161).

This default produces work, applies Responsible AI safety review, pauses for human review when required, merges if approved, attempts PR publication, and records the outcome. Its RAI routing distinguishes no-change, revision, human-review and safety-failed paths; it must not be confused with collective assembly, where RAI RED opens durable human review. The loops are part of the workflow, not exceptional control flow.

Role Slots, Catalog Roles, and Bespoke Charters ​

Workflow nodes carry two different kinds of "role" information:

  1. Workflow role slots describe the node's place in the graph or UI lane: agent, review, merge, scribe, plumbing, and similar labels.
  2. Catalog or bespoke execution roles identify who should perform a node when a real agent identity is needed.

Do not collapse these into one concept. A node with role: review is in a review lane; it is not automatically a catalog role named review. A peer-review node names a concrete reviewer with agent: qa-engineer when it needs that agent. A generated or project-authored node carries an inline charter when no catalog role fits.

The runtime uses explicit node fields and run context to build the agent prompt. Catalog roles are preferred because their charters are already known to the casting system. Bespoke charters are a controlled escape hatch for generated workflows whose process needs a role outside the catalog.

Execution context is node-specific, not one universal precedence chain. Generic prompt/publish nodes pass charter and prompt into AgentTurnExecutor while retaining the run's assigned identity; this binding does not pass node.Agent. Peer-review nodes pass both agent and charter to RubberduckTurnExecutor; Build & Test passes agent to its platform executor (apps/Agentweaver.Api/Runs/RunWorkflowFactory.cs:935–1006). role and kind remain graph/render metadata and do not select the executing agent.

Discovery, Validation, and Registry ​

Source Precedence ​

For a project, WorkflowRegistry.Build assembles a ProjectWorkflowSet from:

  1. the built-in default workflow (BuiltInWorkflows.Default, from DefaultWorkflowTemplate),
  2. conformance-checked catalog library workflows from CatalogConformanceSnapshot,
  3. project-authored .yaml / .yml files under .agentweaver/workflows/ (WorkflowRegistry.WorkflowsRelativePath).

The result is cached per project in WorkflowRegistry.GetOrLoad. Each cache entry is keyed by a signature of the project's top-level workflow YAML files plus the project's allowed workflow id set, so a replica refreshes its local cache when shared project files or blueprint restrictions change. WorkflowRegistry.Sync still provides the explicit user-facing refresh path and rebuilds from disk; validation errors are cached as registry results for replica coherence. Invalid workflows remain visible in ProjectWorkflowSet.Results with their errors, but ProjectWorkflowSet.Available excludes them.

The built-in default is always available. Catalog workflows are available without project-local files. A blueprint may restrict the allowed workflow ids for a project via Project.AllowedWorkflowIds; WorkflowRegistry.FilterByAllowedSet keeps only allowed ids plus the built-in default, which is always retained so a project never has zero workflows. An empty/absent allowed set means all workflows are returned (backward compatible).

Reserved ids are protected. A loaded project definition with id default is silently skipped as a materialized copy; other reserved catalog ids produce conflicts rather than overrides (WorkflowRegistry.cs:183–203). Duplicate ids are resolved deterministically in WorkflowRegistry.AddResult: among built-in/catalog collisions the higher semantic Version wins (ties keep the first-loaded source); among project files the first valid file wins and later duplicates are invalid load results. Source categories are therefore not an override-precedence hierarchy.

Validation Layers ​

Validation happens in layers:

  1. YAML parse — WorkflowDefinitionLoader.Load turns malformed YAML into a file-scoped invalid result.
  2. Schema mapping — node type, start node, edge endpoints, branches, and references are checked.
  3. Bindability dry-run — WorkflowRegistry.ValidateBindable runs RunWorkflowGraphBinder.GetBindabilityErrors to check whether every node and transition can map to real executor wiring.
  4. Runtime resolution and binding — the effective workflow is resolved again and its declared graph is bound before execution.

This layered design lets the UI show useful authoring errors while preserving runtime safety.

Invocation Context ​

RunOrigin describes how a run began. Backlog pickup records RunOrigin.BacklogPickup; manually started and child runs have their own origin/responsibility context. The selector does not convert this into a separate invocation-kind eligibility filter (apps/Agentweaver.Api/Coordinator/CoordinatorOrchestratorExecutor.cs:297–300). There is no current WorkflowInvocationKind / ResolveInvocationKindAsync API.

Event and schedule automation are implemented upstream producers, not future selector modes. A matching trigger must obtain or recover an authorized automation invocation before the Ready task is published with a workflow pin (apps/Agentweaver.Api/Workflows/WorkflowEventTriggerService.cs:59–116; WorkflowScheduleTriggerService.cs:145–199). Manual starts and heartbeat pickup use the same normally available workflow set.

All valid workflows in the project's available set are candidates. A backlog task can carry a WorkflowOverrideId. The override is honored only if the workflow exists, is valid, and can bind safely. Otherwise the system logs the mismatch and continues with normal selection or safe fallback behavior.

Rebuild guidance: keep origin, trigger authorization, and workflow selection separate. See selection for override precedence and post-decomposition compatibility; do not treat an invalid requested id as executable.

Event Trigger Evaluation Pipeline ​

Event-triggered workflows add a narrow routing layer in front of the normal backlog → coordinator pickup path. The trigger mechanism is intentionally small:

  1. POST /api/github/webhooks/repo-app bounds the raw body and verification time;
  2. the endpoint verifies the configured Repo App HMAC keys (including rotation) before JSON deserialization, lifecycle routing, or predicate evaluation;
  3. installation/repository lifecycle processing resolves connected active projects and derives event names: github.<event> and, when GitHub sent an action, github.<event>.<action>;
  4. WorkflowEventTriggerService scans valid workflows' event declarations, evaluates if: predicates, and claims or recovers an authorized automation invocation before publishing matching Ready tasks;
  5. the coordinator heartbeat claims those Ready tasks through the same accountable path as schedule triggers and manual backlog work.

That ordering is the trust boundary: unsigned or badly signed deliveries never reach predicate evaluation, backlog creation, or prompt assembly.

Source: apps/Agentweaver.Api/Endpoints/GitHubWebhookEndpoints.cs:14–135 and apps/Agentweaver.Api/Workflows/WorkflowEventTriggerService.cs:59–116.

Curated predicate DSL ​

The event trigger DSL is deliberately not a general expression language. It supports:

  • hasLabel
  • isNotLabeledWith
  • baseBranch
  • reviewState
  • ref
  • category
  • commentMatches
  • or
  • not

Sibling entries in trigger.if are ANDed by default. or and not provide the only compound logic. Predicate support is event-specific (reviewState only for pull_request_review, ref only for push, and so on), and invalid event/predicate combinations are rejected when the workflow is loaded rather than silently ignored at runtime.

commentMatches privacy and ReDoS boundary ​

commentMatches is the only predicate that inspects raw user-authored text, so it has an explicit security boundary:

  • the only raw text admitted is the verified comment.body string from the GitHub payload;
  • the pattern is fixed in saved workflow configuration — not generated dynamically from the incoming comment;
  • the pattern is validated against a restricted safe subset before the workflow is accepted;
  • runtime matching uses .NET's non-backtracking regex engine plus a hard 200 ms match timeout;
  • match failures, compile errors, and timeouts fail closed to “no match”;
  • only the boolean match result crosses into workflow firing — Agentweaver does not log, persist, or forward the raw comment body into backlog task text or downstream prompts.

This keeps comment-command workflows possible without widening the rest of the engine into a free-form text processing surface.

Use snake_case in YAML and camelCase in the structured trigger API/UI. For example:

yaml
trigger:
  type: event
  event_name: github.issue_comment.created
  if:
    - comment_matches: { pattern: "^/agentweaver:triage$" }
    - not:
        or:
          - has_label: { label: "ignore-bot" }
          - comment_matches: { pattern: "^/agentweaver:skip$" }

Workflow Library and Generation ​

Catalog Library ​

The catalog library provides reusable functional processes, with only conformance-checked definitions entering normal selection. A blueprint can restrict workflow ids and set a default.

The library is process-oriented. Workflow selection compares process steps and expected outputs rather than matching names. Inspect the current registry rather than assuming a fixed catalog count or that a retired id remains selectable.

Workflow Generation ​

Workflow generation turns a natural-language process request into an unsaved YAML draft.

Generation has these rules:

  • The prompt is built server-side.
  • The user's description is fenced as untrusted data.
  • The prompt includes the schema, supported runtime node vocabulary, validation rules, available project roles, and few-shot examples.
  • Output is cleaned for accidental Markdown fences.
  • If the model omits an id, a kebab-case id is derived from the description.
  • The generator validates with the same loader and binder dry-run used by runtime authoring paths.
  • Exactly one correction pass is allowed.
  • The result is a draft; it is not written to .agentweaver/workflows/ until a save/apply path persists it.

Trigger-aware generation extends that same flow rather than introducing a separate side channel. Both create-mode and edit-mode prompts teach the model:

  • the schedule trigger schema (daily / weekly / monthly, UTC time_of_day, weekly day_of_week, monthly day_of_month);
  • the curated GitHub event shortlist (issues, issue_comment, pull_request, pull_request_review, push, release, discussion);
  • the structured predicate vocabulary and boolean wrappers (or, not);
  • a few-shot set of natural-language trigger examples such as label-driven issue triage, weekly schedules, and exact comment commands.

The output still goes through the same loader and binder gate as any other generated workflow. A bad event name, malformed predicate, or unsafe commentMatches pattern triggers the single correction pass; if the corrected draft is still invalid, generation fails closed instead of saving a broken trigger.

Blueprint generation can also invoke workflow generation when no library workflow is a good process fit. Applying that blueprint writes the generated workflow file, syncs the registry, and makes the workflow selectable.

Selection Logic ​

Workflow selection chooses a process for a task. It runs inside CoordinatorOrchestratorExecutor.SelectWorkflowAsync and is intentionally conservative: deterministic rules narrow the space first (registry ordering, availability, overrides), and WorkflowSelector.SelectAsync only chooses among 2+ available definitions.

The selector prompt asks for process fit:

  • Match on the steps the workflow runs and the output it produces.
  • Do not choose by name similarity or domain-word overlap.
  • Prefer project/custom workflows when they perform the requested process.
  • If nothing fits, select the first listed workflow, which is the project default.

The requested model response is JSON with a selected workflow id and short rationale. Candidate matching also accepts normalized ids/display names and supported string/prose forms; unusable responses get one retry before deterministic fallback. The selector prefers available default/standard fallback definitions, while the coordinator's outer exception fallback uses its resolved project default. See workflow selection for these distinct rules and post-decomposition Build & Test compatibility.

Overrides ​

There are three override channels, checked before automatic singleton handling:

  • Request/dialog override — CoordinatorDraftInput.WorkflowOverrideId, checked before the backlog-task pin. An unavailable dialog value continues normal selection without falling back to that pin.

  • Backlog task override — BacklogTask.WorkflowOverrideId, persisted on the task before it is claimed. CoordinatorPickupService prepends use {id} to the goal at pickup, and SelectWorkflowAsync also resolves the override id directly against the registry and available set.

  • Conversational override — revision feedback use {workflow-id} is parsed before the candidate-count shortcut and used when available. Available request, backlog, and conversational choices emit selection events even with one candidate.

An explicit override wins only inside the candidate safety boundary. It does not let a user or backlog item execute a workflow that the registry cannot resolve or that cannot bind safely.

Selection vs Runtime Resolution ​

The coordinator persists the selected workflow id on its WorkPlan for decomposition and collective assembly. Standalone run graph construction independently resolves a backlog-task override or the project default and binds that definition; it does not compose a review policy or read the coordinator's selected WorkPlan as its override source (apps/Agentweaver.Api/Runs/RunWorkflowFactory.cs:1495–1558). Child graphs take the separate trimmed path. These are different resolution responsibilities, not a promise that every run replays the selector's exact result.

Binding Declarative Nodes to Runtime Execution ​

Binding is where a workflow stops being YAML and becomes an executable graph.

The binder:

  1. classifies each node by type and, for gates, gate_kind;
  2. resolves the node to a known executor kind;
  3. expands every logical edge into concrete executor wiring and predicates;
  4. wires terminal outputs from incoming edge semantics;
  5. preserves hidden plumbing such as adapters and stored merge data;
  6. fails closed when a node or transition has no mapping.

The binder resolves by node type, not by hardcoded ids. A workflow can rename agent, rai, review, merge, and scribe and still bind if the node types and gate kinds describe the same process. This is what lets library and generated workflows use meaningful node ids while preserving the same runtime semantics.

Canonical Transition Families ​

The default family includes:

  • agent work into RAI,
  • RAI revision back to agent,
  • RAI safety failure to terminal,
  • RAI no-change to scribe,
  • RAI review path to human review,
  • human approval to merge,
  • human change request back to agent,
  • human decline to terminal,
  • merge completion to PR publication and then scribe in the current default (direct merge-to-scribe remains a supported family),
  • merge blocked back to review,
  • scribe to done.

Catalog-style workflows add supported generic families:

  • sequential agent turns,
  • agent output into peer review,
  • peer-review pass or approval into merge / RAI / a subsequent agent turn,
  • peer-review fail or request-changes back to an agent,
  • direct agent or review completion through scribe,
  • merge blocked back into peer review or an agent.

Anything outside supported transition families is not "best effort." It is a binding error.

Workflow-declared gates, not a project policy overlay ​

Author required gates in the workflow nodes and edges. Effective resolution returns the validated workflow without a separate policy-composition pass (apps/Agentweaver.Api/Runs/RunWorkflowFactory.cs:1495–1517). Blueprint validation accepts only review_policy: default (apps/Agentweaver.Api/Blueprints/BlueprintService.cs:113–115). There is no configurable project review-policy registry here.

Policy-prefixed adapters retained in RunWorkflowFactory are executor plumbing for declared gate transitions; their names do not establish a live composer. An unsupported declared gate or edge fails binding instead of becoming optional.

Relationship to Runs and Coordinator Work ​

A workflow is selected at the point where a run needs an execution process. Different run origins use the same concepts but have different responsibility boundaries:

  • Manual run — an explicit start.
  • Backlog pickup coordinator run — a heartbeat-started run with durable RunOrigin.BacklogPickup.
  • Scheduled or event-driven automation — implemented trigger producers publish authorized, workflow-pinned Ready backlog tasks; normal pickup starts the coordinator.
  • Coordinator parent run — owns planning, assembly, review, merge, and scribe for coordinated work.
  • Coordinator child run — uses a trimmed child pipeline in an isolated working tree: agent work terminating at assemble-ready or a typed failure terminal. It does not perform per-child RAI, human review, merge, or scribe independently. Dependency outputs are merged forward through the coordinator integration branch before dependent children launch.

The important boundary is that workflows govern run gates, while the coordinator owns intent, decomposition, dependency frontiers, and assembly. A child run can produce a safe piece of work; the parent workflow decides how the assembled result is reviewed and merged.

See orchestration.md for the broader run lifecycle and coordinator model.

Extension Points and Gotchas ​

  • Do not execute by id alone. Workflow ids identify definitions; node types and edge semantics determine bindability.
  • Unattended pickup is governed outside the workflow YAML. Use project settings and automation rules to decide when a workflow should start automatically.
  • Keep generated examples bindable. A generator that teaches unsupported node types will produce attractive but unrunnable YAML.
  • Role metadata can be misleading. Distinguish render lanes from concrete catalog agent ids and inline charters.
  • Peer review must be verdict-routed. A peer_review node needs verdict-labeled outgoing edges; otherwise bindability validation rejects it instead of guessing how to route it.
  • Terminal nodes are resolved by incoming semantics. Renaming done is fine; losing the scribe-sourced or verdict-sourced incoming edge is not.
  • Registry sync matters. Saving a file should be followed by an explicit sync for immediate feedback; other replicas refresh when they observe the changed shared-file signature.
  • Workflow gates are explicit. Do not infer a configurable review-policy overlay from legacy adapter names.
  • Selection and binding have separate responsibilities. Coordinator topology is persisted on the WorkPlan; standalone graph resolution and trimmed child graphs follow their own paths.

Rebuilding Blueprint ​

If you were rebuilding the workflow engine from scratch, implement it in this order:

  1. Define the workflow schema: start, typed nodes, edges, branches, and metadata.
  2. Write a loader that returns valid and invalid load results without crashing the whole set.
  3. Embed a built-in default workflow and parse it through the same loader as user files.
  4. Build a registry that discovers built-in, catalog, and project workflows, caches per project with a shared-file signature, and syncs explicitly.
  5. Add invocation-context tracking and keep it separate from candidate availability.
  6. Add bindability validation that rejects unsupported node types and transitions before runtime.
  7. Implement node classification by type and gate kind, never by fixed ids.
  8. Implement edge expansion from (from kind, to kind, when) to concrete executor wiring.
  9. Keep authored review gates explicit and validate every gate transition before binding.
  10. Add default and override resolution that revalidates availability and bindability.
  11. Add process-fit selection among available candidates with deterministic fallback.
  12. Add generation as a draft-only server-side prompt + validation + one correction pass.
  13. Surface graph descriptors and workflow-selected events for clients, but keep clients out of selection and binding.
  14. Add recovery tests that prove renamed nodes, invalid edges, invalid overrides, and unsupported types fail safely.

The central design principle is simple: load workflows as data, select among valid available process graphs, bind every edge to real executors, and fail closed whenever policy cannot be proven executable.

Where this lives ​

  • apps/Agentweaver.Api/Workflows/
  • apps/Agentweaver.Api/Coordinator/WorkflowSelector.cs
  • apps/Agentweaver.Api/Coordinator/CoordinatorOrchestratorExecutor.cs
  • apps/Agentweaver.Api/Runs/RunWorkflowFactory.cs
  • packages/Agentweaver.Squad/Catalog/Resources/workflows/
  • docs/workflow-binder.md
  • docs/workflow-generation.md
  • docs/workflow-library.md
  • docs/workflow-selection.md
Diagram details and constraints
ElementContract
titleGeneric default workflow
subtitleBuilt-in template • merge → PR publication → Scribe
returns-headingSOURCE / RETURN
outcomes-headingOUTCOMES
footerPR action can skip / fail and still reach Scribe. No-changes also reaches Scribe.
Agent workAgent
Agent workAgent task
Agent workagent
RAI gateRai
RAI gateVerdict routing
RAI gaterai
Human reviewReview
Human reviewhuman-review
MergeMerge
MergeMerge outcome routing
Mergemerge
Publish / reuse PRPublish / reuse PR
Publish / reuse PRCreate / reuse; not git push
Publish / reuse PRaction
ScribeScribe
ScribeRecord the run outcome
Scribescribe
Safety failedSafety failed
Safety failedWorkflow endpoint
DeclinedDeclined
DoneDone
edge-02-labelrevise
edge-03-labelsafety- failed
edge-04-labelno- changes
edge-05-labelreview
edge-06-labelapproved
edge-07-labelrequest-changes
edge-08-labeldeclined
edge-09-labelmerged
edge-10-labelblocked
Diagram details and constraints
ElementContract
titleHow work enters the coordinator
takeawayOrigin produces work; it does not filter the set of selectable workflows.
group-title-0ORIGIN CHANNELS
group-title-1AUTOMATION ADMISSION AND DURABLE WORK
group-title-2PICKUP, CONFIRMATION AND SELECTION
Manual requestManual request
Manual requestStart coordinator directly
Manual requestsubmitting user
Verified Repo App eventVerified Repo App event
Verified Repo App eventHMAC before JSON parsing
Verified Repo App eventconfigured signing keys
Due scheduleDue schedule
Due scheduleClaim scheduled occurrence
Due schedulerecover outstanding work
Trigger + authorizationTrigger + authorization
Trigger + authorizationMatch and claim invocation
Trigger + authorizationrejected: no work
Pinned Ready taskPinned Ready task
Pinned Ready taskDurable workflow choice
Pinned Ready taskautomation work item
Atomic pickupAtomic pickup
Atomic pickupClaim and reserve a run
Atomic pickupstart reserved coordinator
Coordinator runCoordinator run
Coordinator runManual or backlog origin
Coordinator runRunOrigin recorded
Approval policyApproval policy
Approval policyAutopilot controls unattended
Approval policynot origin alone
Available workflowsAvailable workflows
Available workflowsNo invocation-kind filter
Available workflowsvalid supplied candidates
e0start
e1match
e2claim
e3publish
e4pickup
e6policy
e7select
groupsORIGIN CHANNELS; AUTOMATION ADMISSION AND DURABLE WORK; PICKUP, CONFIRMATION AND SELECTION
Diagram details and constraints
ElementContract
titleWorkflow selection
subtitleTrigger-agnostic • explicit choices precede singleton
returns-headingSOURCE / RETURN
outcomes-headingOUTCOMES
footerPost-decomposition Build & Test compatibility is a separate check (executor:407–494).
Load candidatesLoad candidates
Load candidatesProject default ordered first
Load candidatesregistry.Available
Explicit override?Explicit override?
Explicit override?Dialog value, else backlog pin
Explicit override?must be available
Conversational choice?Conversational choice?
Conversational choice?Revision feedback: use {id}
Candidate countCandidate count
Candidate countOnly automatic selection
Candidate count0 / 1 / multiple
Ask selection modelAsk selection model
Ask selection modelGoal + roles + process fit
Ask selection modelmaximum 2 attempts
Usable candidate?Usable candidate?
Usable candidate?Parse / normalize / prose match
Usable candidate?reject unknown choices
Selected workflowSelected workflow
Selected workflowEmit selection + rationale
Selected workflowworkflow_selected
Explicit choiceExplicit choice
Explicit choiceEmit selection
Explicit choicenot auto-selected
Silent choiceSilent choice
Silent choiceOne: candidate
Silent choiceZero: project default
Model fallbackModel fallback
Model fallbackdefault / standard then non-code-review
Model fallbackelse first candidate
Outer fallbackOuter fallback
Outer fallbackProject default
Outer fallbackwhen catch permits
edge-02-labelavailable
edge-03-labelabsent / invalid
edge-06-label0 or 1
edge-07-label2+
edge-08-labelresponse
edge-09-labelexception
edge-10-labelaccepted
edge-11-labelretry once
edge-12-label2 unusable
edge-13-labelemit choice
edge-14-labelouter catch
fallbackdefault / standard
Diagram details and constraints
ElementContract
titleFrom workflow definition to execution
takeawayBinding, checkpointed execution and observation are distinct responsibilities.
group-title-0DECLARATIVE INPUT AND BINDING
group-title-1EXECUTION AND CHECKPOINTS
group-title-2DURABLE OBSERVATION
Selected definitionSelected definition
Selected definitionConcrete authored workflow
Selected definitionno policy overlay
Node classificationNode classification
Node classificationTypes and gate contracts
Node classificationnot fragile node IDs
Factory + binderFactory + binder
Factory + binderExecutors and typed edges
Factory + binderfail closed if unsupported
Executable MAF graphExecutable MAF graph
Executable MAF graphRun the bound workflow
Executable MAF graphnot always default chain
Checkpoint storeCheckpoint store
Checkpoint storeProvider-aware persistence
Checkpoint storenot universally files
Default exampleDefault example
Default exampleMerge -> push-pr -> Scribe
Default exampleauthored default only
Watch loopWatch loop
Watch loopConsume execution updates
Watch loopsupervised observer
Pending + run statePending + run state
Pending + run stateDurable request/status state
Pending + run statetyped terminal projection
Workflow-step eventsWorkflow-step events
Workflow-step eventsProgress for observers
Workflow-step eventsnot runtime control
e0classify
e1bind
e2execute
e3checkpoint
e4example
e5stream
e6persist
e7publish
groupsDECLARATIVE INPUT AND BINDING; EXECUTION AND CHECKPOINTS; DURABLE OBSERVATION
Diagram details and constraints
ElementContract
titleGenerate a draft, not a saved workflow
takeawayOne correction attempt reuses loader and binder validation; saving is a separate action.
group-title-0DRAFT REQUEST AND GENERATION
group-title-1NORMALIZATION AND VALIDATION
group-title-2BOUNDED CORRECTION OR RESULT
User descriptionUser description
User descriptionRequest workflow generation
User descriptionnot a save command
Server prompt + modelServer prompt + model
Server prompt + modelConstrained generation request
Server prompt + modelauthored draft response
Clean draft + IDClean draft + ID
Clean draft + IDNormalize returned content
Clean draft + IDbuilt-in edit: new ID
Loader validationLoader validation
Loader validationParse workflow definition
Loader validationsame validation pipeline
Binder validationBinder validation
Binder validationCheck runtime bindability
Binder validationnot syntax alone
Valid draft responseValid draft response
Valid draft responseReturn YAML to caller
Valid draft responsenot persisted/applied
Error + one retryError + one retry
Error + one retryAsk model to correct error
Error + one retryexactly one correction
Validate correctionValidate correction
Validate correctionSame cleanup/loader/binder
Validate correctionsecond pass only
Generation exceptionGeneration exception
Generation exceptionCorrection still invalid
Generation exceptionexplicit failure
e0request
e1clean
e2load
e3bind
e4valid
e5invalid
e7retry
groupsDRAFT REQUEST AND GENERATION; NORMALIZATION AND VALIDATION; BOUNDED CORRECTION OR RESULT
Diagram details and constraints
ElementContract
titleDeclarative data is not an executor
takeawayA parsed workflow still needs structural and runtime-bindability validation.
group-title-0DECLARATIVE SHAPE
group-title-1STRUCTURE AND SEMANTIC CLASSIFICATION
group-title-2BINDABILITY AND RESULT
Workflow YAMLWorkflow YAML
Workflow YAMLAuthored graph document
Workflow YAMLstart + nodes + edges
Start + typed nodesStart + typed nodes
Start + typed nodesStable node identity
Start + typed nodestype / gate contracts
Edges + metadataEdges + metadata
Edges + metadataTransitions and render fields
Edges + metadatarole / kind: visual
Structural checksStructural checks
Structural checksReferences and graph shape
Structural checksloader-valid definition
Runtime classifierRuntime classifier
Runtime classifierKnown node execution kinds
Runtime classifierpublish -> agent kind
Executor bindingsExecutor bindings
Executor bindingsConcrete execution contracts
Executor bindingsnot metadata inference
Start/edge compatibilityStart/edge compatibility
Start/edge compatibilityTyped transitions must fit
Start/edge compatibilitydry-run bindability
Executable graphExecutable graph
Executable graphValid concrete MAF graph
Executable graphready to execute
Binding errorBinding error
Binding errorUnsupported node/start/edge
Binding errorWorkflowBindException
e0parse
e2validate
e4classify
e5bind
e6check
e7valid
e8invalid
groupsDECLARATIVE SHAPE; STRUCTURE AND SEMANTIC CLASSIFICATION; BINDABILITY AND RESULT
Diagram details and constraints
ElementContract
titleVisual role versus runtime context
takeawayNode fields feed different executors; role/kind never becomes an executing catalog identity.
group-title-0AUTHORED FIELD FAMILIES
group-title-1PRESENTATION AND WORKER CONTEXT
group-title-2SPECIALIZED EXECUTOR CONTEXT
Authored nodeAuthored node
Authored nodeFields are not interchangeable
Authored nodenode declaration
role / kindrole / kind
role / kindRendering metadata
role / kindnot executing identity
prompt / charterprompt / charter
prompt / charterGeneric worker context
prompt / charterprompt or publish node
Diagram presentationDiagram presentation
Diagram presentationVisual role and grouping
Diagram presentationno agent assignment
AgentTurnExecutorAgentTurnExecutor
AgentTurnExecutorReceives prompt + charter
AgentTurnExecutornot node.Agent
Peer-review fieldsPeer-review fields
Peer-review fieldsagent + charter
Peer-review fieldsreviewer-specific contract
Rubberduck executorRubberduck executor
Rubberduck executorReceives agent + charter
Rubberduck executorpeer-review context
Build & Test fieldBuild & Test field
Build & Test fieldagent
Build & Test fieldplatform executor context
Build & Test executorBuild & Test executor
Build & Test executorReceives agent context
Build & Test executornot role/kind mapping
e0visual
e1worker
e2render
e3bind
e4peer
e6build
groupsAUTHORED FIELD FAMILIES; PRESENTATION AND WORKER CONTEXT; SPECIALIZED EXECUTOR CONTEXT
Diagram details and constraints
ElementContract
titleDiscover and cache valid workflows
takeawayRegistry sources are categories, not a project-policy precedence chain.
group-title-0DEFINITION SOURCES
group-title-1VALIDATION AND FILTERING
group-title-2DIAGNOSTICS, CACHE AND AVAILABILITY
Embedded defaultEmbedded default
Embedded defaultPlatform-provided definition
Embedded defaultdefault retained
Conforming catalogConforming catalog
Conforming catalogKnown catalog workflows
Conforming catalogreserved IDs protected
Project YAMLProject YAML
Project YAMLProject-defined documents
Project YAMLnot review-policy files
Loader + bindabilityLoader + bindability
Loader + bindabilityValidate usable definitions
Loader + bindabilityinvalid entries diagnosed
Identity collisionsIdentity collisions
Identity collisionsReserved catalog conflicts
Identity collisionsmaterialized default skipped
Allowed-set filterAllowed-set filter
Allowed-set filterFilter available choices
Invalid diagnosticsInvalid diagnostics
Invalid diagnosticsKeep errors in results
Invalid diagnosticsnot selectable candidates
Signature cacheSignature cache
Signature cachePer-project refresh key
Signature cachesync invalidates/refreshes
Available candidatesAvailable candidates
Available candidatesValid and allowed workflows
Available candidatesselection input
e0load
e3check IDs
e4invalid
e5valid
e6cache
e7available
groupsDEFINITION SOURCES; VALIDATION AND FILTERING; DIAGNOSTICS, CACHE AND AVAILABILITY
Diagram details and constraints
ElementContract
titleBind contracts, not just node names
takeawayTyped executor, start and transition contracts can reject otherwise parseable YAML.
group-title-0DEFINITION AND CLASSIFICATION
group-title-1EXECUTOR AND MESSAGE CONTRACTS
group-title-2START, EDGE AND TERMINAL VALIDATION
Parsed definitionParsed definition
Parsed definitionLoader-valid graph data
Parsed definitionnot execution proof
Type/gate classifierType/gate classifier
Type/gate classifierKnown node kinds
Type/gate classifierrenamed IDs still work
Unsupported kindUnsupported kind
Unsupported kindNo concrete runtime contract
Unsupported kindfail closed
Executor bindingsExecutor bindings
Executor bindingsConcrete executor instances
Executor bindingsfactory integrations
Transition adaptersTransition adapters
Transition adaptersTyped predicates and messages
Transition adaptersnot arbitrary arrows
Terminal outputsTerminal outputs
Terminal outputsKnown result contracts
Terminal outputstyped completion
Start + edge checksStart + edge checks
Start + edge checksDry-run bindability
Start + edge checksverdict start may fail
MAF graphMAF graph
MAF graphValidated executable graph
MAF graphstart executor resolved
WorkflowBindExceptionWorkflowBindException
WorkflowBindExceptionUnsupported contract reported
WorkflowBindExceptionno silent fallback graph
e0classify
e1unknown
e2known
e3wire
e4outputs
e5check
e7valid
e8invalid
e9raise
groupsDEFINITION AND CLASSIFICATION; EXECUTOR AND MESSAGE CONTRACTS; START, EDGE AND TERMINAL VALIDATION

Visual model ​

Workflow invocation ​

Flow showing interactive starts, library workflow runs, and authorized event or schedule automation converging on durable task staging, atomic coordinator pickup, planning, dependency-aware dispatch, and child execution.

Structured source · Editable draw.io