Skip to content

Flows

A flow is a configured path into the knowledge base: what gets read, who it's written for, and what produces it. The list of flows answers the question "what writes in here, and when?"

Kind What produces it Needs
analyse an AI, from a prompt, reading a source instructions, target personas, a source
ingest an adapter, copying a source into the ground layer a source
act an AI that does something outside the knowledge base: builds, runs tests, merges instructions only; its outcome is what counts

Flows are configured under Settings → Knowledge Base → Flows, or written over MCP. See Configuration for the full shape.

- id: step-development
  name: Step development
  kind: analyse
  source: {kind: repo, ref: my-app}      # repo | kb_source | context | web
  targets:
    personas: [backend, frontend]
    node_types: []                       # empty = every type of those personas
  work_item: {kind: feature, required: true}
  prompt:
    instructions: "Implement the step described in the context, then document ..."
    stages:
      - {id: read, label: Read the context}
      - {id: build, label: Build the backend}
  triggers: [manual, mcp]

The prompt is mostly generated

Only instructions is written by a person. Everything else in the prompt is generated: the personas, a full description of every node type in scope (its fields or its template), where the result goes, and how to write it back. An output contract that someone can edit by hand is one that breaks without anyone noticing. Preview on the Flows tab shows the whole prompt.

An empty targets.node_types means every type of the target personas plus the shared ones, so a type added for a persona is usable by its flows right away.

Three ways to start one

What happens Needs
Brief the prompt is handed to an AI you already have, which carries it out over MCP nothing
Run here Roadmap reads the source, asks its own AI provider, and writes the answer as a background job the knowledgebase.flows plugin and a provider
Source trigger a scheduled scan starts the flow when its source has moved (a new commit) the above, plus the scheduler

The brief is the cheap path and the reason it exists. The costly half of an analysis is the thinking, and an AI already connected over MCP is already paid for.

Over MCP, an AI takes a flow on like this:

kb_flow("describe", id="step-development")          # what it reads and writes
kb_flow("brief", id="step-development",
        work_item="manual/feature/password-reset")  # the prompt and a run id
kb_flow("progress", id="<run>", stage="read")       # as each stage starts
kb_write(action="add_node", ..., run="<run>")       # write, stamped with the run
kb_flow("finish", id="<run>", outcome="ok")         # how it went

Runs and provenance

A run exists from the moment a flow is handed out. That puts work done by an outside AI in the same history as everything else, and it gives the nodes a run id to carry.

Every node written under a run carries a provenance stamp in its details:

"provenance": {
  "flow": "delphi-tip-analysis", "flow_version": 1, "prompt_version": 1,
  "run": "run_c2ccdabacad1",
  "trigger": {"mode": "mcp", "tool": "kb_flow"},
  "source_position": "9af336c8a5c2...",
  "model": "claude-opus-5", "at": "2026-10-11T09:15:02+00:00"
}

The stamp is applied on the server and overwrites whatever the writer sent: provenance that a writer could forge would be worthless. It lets you ask "which topics came from the old prompt?" after improving it.

A run can be undone, which makes writing straight into the graph safe without a staging area. Undo works per node: a node the run created is deleted, a node it changed is put back as it was (the first change keeps the old version), and the links it made are removed.

Stages and progress

A run can take an hour. To show what it's doing without tracing every call, a flow can declare stages: the few large blocks it goes through (Read the context, Build the backend, Run the whole suite). The worker reports each one as it starts it, and the reports show on the run and on the unit of work's Progress tab.

Outcomes

Only the worker knows whether the work reached its goal, so a run ends with an outcome:

Status Means The work item
ok the work reached its goal moves to the flow's on_finish state
failed the work was done and didn't reach it: a test fails, a build breaks moves to on_fail, with the message in its log
error the run itself broke (the provider failed) stays where it is
undone the run was taken back stays where it is

A failed run needs a message, because it's what the next run starts from. Moving work on from an outcome is usually the job of an orchestration.