Skip to content

What's inside a workflow library

If you just want to use a pre-built library — the SWE guardrails, say — it’s one line in your gateway config:

repos:
- path: ~/repos/cognitive-architectures

That pulls in a whole tree of ready-made workflows for your coding agent. You don’t have to know how it’s built to use it. This page is for when you want to know what’s inside that bundle — or you’re ready to build and ship your own.

You wire up a good workflow: three skills your agent reads, two scripts it runs, an MCP connection to GitHub, and a merge step that waits for a human (a human-in-the-loop approval gate). It works. Then a teammate wants the same thing — and there’s nothing to hand them. The skills live in your gateway config, the scripts live in your internal git repo, the connection lives in your head, and the approval gate is a one-off declaration nobody else has seen. You’ve built a workflow nobody else can adopt, and that you can’t cleanly version or update.

A workflow that needs all five pieces is a workflow that needs all five to ship together. That’s what a library is: one Git repo that packages every primitive a set of workflows needs, so consuming it is the one-liner above and updating it is a git pull.

This page is the tour — what a library can ship, how the pieces compose, and why bundling them beats scattering them.

Five artifact kinds, five purposes, all loadable from a single repo:

PrimitiveWhat it isWhere it lives in a repoLoaded into config block
SkillGuidance fragment the agent reads on demand. Verb + subject + body.skills/*.yamlskills:
ScriptDeterministic shell/binary action. Verb + subject + body or uri+hash.scripts-library/*.yamlscripts:
Capability (v0.2)Typed sub-workflow with a snippet contract — the reusable composition leaf.capabilities/*.yamlworkflows: (as cap.* ids)
Orchestrator (v0.2)Lifecycle workflow that strings capabilities together via use: bindings.orchestrators/*.yamlworkflows: (as flow.* ids)
ConnectionMCP server / CLI / REST endpoint declaration.connections/*.yamlconnections:

There’s also a sixth piece worth knowing about: shared context — a small glossary so every workflow uses a term like evidence-pack to mean the same thing, instead of each one redefining it inline. Today you declare it in your gateway config (the lexicon: block — see Lexicon); shipping it inside a repo alongside the workflows that use it is on the roadmap. “Shared context across a library” below covers why it matters.

A repo’s flowgate.repo.yaml manifest declares which of these layouts it uses. A repo can ship any subset — a connections-only repo, a skills-only repo, or a full SWE library. The manifest’s layout: block points each tier at a directory:

repos/swe-core/flowgate.repo.yaml
schema: flowgate.repo/v1
name: swe-core
namespace: swe
version: 0.6.0
layout:
capabilities: capabilities
orchestrators: orchestrators
skills: skills
scripts: scripts-library
connections: connections

Missing tiers (no directory at that path) are silently skipped. See Multi-repo loading for the loading semantics.

These primitives compose top-down. An orchestrator at the top; capabilities under it; skills, scripts, connections under those.

flow.add-feature ← orchestrator (lifecycle)
├──> cap.plan.draft ← capability (composition leaf)
│ └──> skills: [plan.specify.change-request] ← skill (LLM guidance)
├──> cap.plan.vet
│ └──> skills: [compose.plan.vet]
├──> cap.implement.tdd-loop
│ └──> skills: [implement.tdd.discipline]
├──> cap.verify.workspace-green
│ └──> kind: script + subject: verify.workspace.green ← script
├──> cap.review.adversarial
│ └──> skills: [review.code.adversarial]
└──> cap.coordinate.pr-open
└──> kind: mcp + connection: github_mcp ← connection

The orchestrator never references a skill or a script directly. It invokes capabilities. The capabilities reference skills (for cognitive caps) or scripts (for deterministic caps) or connections (for coordination caps). That’s the layered model.

Three concrete cases.

A team improves cap.review.adversarial — better rubric, additional check for security issues. The improvement lives in one file in one repo. Every orchestrator that composes that cap (in cognitive-architectures, flow.add-feature, flow.bugfix-from-error-log, and flow.safe-refactor all do) picks up the improvement on git pull. No copy-paste drift between three workflows that each carry their own version of “review the diff.”

If the cap’s snippet contract changes — a new required input, a renamed enum value — every dependent orchestrator surfaces a load-time error with the exact mismatch. You can’t ship the cap update without also updating its callers. The dependency graph is enforced by the type system, not by author discipline.

A repo ships cap.coordinate.pr-open, which needs a github_mcp connection. The same repo ships a reference connections/github-mcp.yaml that declares the connection’s contract. When you load the repo you get both — the cap that needs the connection and a worked example of the connection it expects. You wire up your own GitHub MCP server (your token, your host) and point the connection name at it. The repo doesn’t ship a network configuration; it ships the shape of what you need to provide.

That’s the difference between “here’s a cap, figure out what it expects” and “here’s a cap, here’s exactly the connection contract it needs, plug in your specifics.” The bundling is what makes the cap actually adoptable.

A repo ships skills that all reference the term evidence-pack, and every workflow in the repo uses it in the same sense. You define the term once — in your gateway’s lexicon: block today — and every cap, orchestrator, and skill in the repo speaks the same vocabulary.

Without that shared context, every workflow that needs a term redefines it inline (“for the purposes of this workflow, an evidence pack means…”) and the definitions drift apart. Defining it once and letting the whole library share it (see Lexicon) keeps the vocabulary consistent. Shipping that shared context inside the repo itself — so the term travels with the workflows that use it — is on the roadmap.

A repo’s loaded definitions get prefixed <namespace>/<id>. Internal references within the repo use bare names and resolve to the repo’s own namespace; cross-namespace references must be fully qualified.

The fall-through resolution rule applies uniformly across primitives:

Reference kindResolution order
kind: workflow + definitionId: cap.XTry <my-namespace>/cap.X first; then bare cap.X. Unresolved → V22 error.
kind: script + subject: X.yTry <my-namespace>/X.y first; then bare X.y.
skills: [X.y] (in workflow body)Try <my-namespace>/X.y first; then bare X.y.
connection: foo (in executor)Bare name only; connections aren’t namespaced in v0.2.

The bare-name-first pattern means a repo’s internal composition stays clean — cap.plan.draft invoking cap.plan.vet writes them as bare names; both resolve to the repo’s own namespace at load. To compose across repos, fully qualify: definitionId: other/cap.special-vet.

The manifest is short — six required fields plus the layout block:

flowgate.repo.yaml
schema: flowgate.repo/v1 # pinned; new repo schemas use new constants
name: swe-core # repo identifier (lowercase kebab)
namespace: swe # prefix every loaded id gets
version: 0.6.0 # repo version; surfaces in `flowgate.query({subject})`
description: | # surfaces in `flowgate.query({subject})` and operator-facing diagnostics
Core SWE capabilities + lifecycle orchestrators for plan-driven
feature delivery, bugfix-from-error-log, and safe-refactor.
layout: # all fields optional; defaults match the directory names
capabilities: capabilities
orchestrators: orchestrators
skills: skills
scripts: scripts-library
connections: connections

Validation rules V19 (manifest schema), V20 (namespace uniqueness across repos), V21 (no duplicate ids within a repo) fire at load. See Validation rules for the full V1–V23 catalog.

Two repos ship as v0.2’s first content. Which one you start with depends on what you’re doing:

  • Want guardrails for your day-to-day coding agent? Start with cognitive-architectures — lifecycle workflows for the work you already do: flow.add-feature (plan → TDD loop → review → open PR), flow.bugfix-from-error-log, flow.safe-refactor, and flow.triage-issue, plus the reusable capabilities, skills, and scripts they’re composed from. The dependency tree above is from this library; it’s the one most senior engineers running Claude Code or Cursor want first.

  • Want to author or tune your own workflows? Reach for flowgate-meta — a self-bootstrapping authoring loop: flow.author-capability, flow.author-flow, flow.optimize-capability, flow.optimize-flow, and flow.configure-models (the guided agents.yaml setup flow), plus the capabilities and skills behind them.

Load both alongside each other — the same repos: entry you’d use for one, twice (this is the config your gateway runs; see How to run it for where that gateway lives):

gateway.yaml
version: "1.0.0"
repos:
- path: ~/repos/cognitive-architectures
- path: ~/repos/flowgate-meta
overrides:
- cognitive/cap.review.adversarial # use cognitive's richer version
- cognitive/cap.coordinate.pr-open # rather than flowgate-meta's stub shadows

The overrides: block makes the shadow selection explicit. See Multi-repo loading for V23’s anonymous-shadowing protection.

You don’t always need a repo. The tradeoff:

PathWhen
Inline in gateway configTools or workflows that are highly specific to your codebase. Two or three skills, one or two workflows. The whole config fits in a 200-line file.
include: filesThe config is getting long. You want logical grouping (one file per workflow, one for skills, one for connections) but everything’s still local to your gateway.
A library repo (repos: block)The library is going to be reused — across multiple gateways, multiple teams, or multiple people. You want namespace isolation, hash-pinned versioning, and the V19–V23 collision protection.

The migration is one-directional — you only ever add, never rewrite: inline config → include: files → repo. You can always add a repos: entry without disturbing existing skills: / scripts: / workflows: blocks. The two paths compose into the same registry.