Reuse
Procedures
A procedure is a flow other flows run as one of their steps. Draw a piece of work once, such as “tell the team what changed” or “triage a ticket”, and every flow that needs it runs the same procedure. Change the procedure and they all change with it.
Why procedures
Several flows often end, or begin, the same way: post the change to Slack, open a pull request, classify a ticket. Copying those steps into each flow means fixing them in each flow too. A procedure keeps them in one place:
- One definition. Its prompts, models and steps live in the procedure; every caller runs the current version.
- A clear contract. What it takes and what it leaves are named objects, so callers know exactly what to hand in and what comes back.
- A small caller. The caller's board shows one step, Tell the team, rather than its insides.
Making a procedure
Create it
On the flow list, type a name under Procedures and press New procedure. Or turn a flow you already have into one: in its Settings, tick Procedure: a group of processes reused inside other flows. That box can't be unticked while other flows use it.
Draw its board
A procedure is an ordinary flow: a Start, processes and objects. The objects on its top board that it should be given are its inputs: callers hand values to them by name.
Mark its outcomes
Link each object it leaves to the End node. Those end objects are its outcomes: what the procedure's run left of them goes back to the caller.
Using a procedure
Drag it in
Procedures are listed under Procedures in the board's sidebar. Drag one onto the board, and you get a procedure process already pointed at it, together with copies of the procedure's outcomes. You can also add any process and set Type to Procedure, then pick Procedure it runs.
Link what it takes
Link the caller's objects to the procedure process as you would to any step. Each is handed to the object of the same name on the procedure's top board, in the state of the same name.
Check the names
The process's settings list what it Takes and Generates. A name with no match is flagged: no object of that name on its top board, or its namesake there holds different fields. Open the flow jumps to the procedure.
How values cross
The caller and the procedure share no objects. Values cross between them by name, in both directions:
- An object the procedure process takes is given to the procedure's top-board object of the same name, in the state of the same name.
- An object it yields is what the procedure's run left of the end object of the same name.
Copies follow their source
On the caller's board the outcomes are copies of the procedure's objects. A copy follows its source: its name, quantity, states, attributes and parts change only in the procedure. In the copy, Rename and Add state are disabled and its settings are locked, with a note linking to the source. Only where it sits on the board and whether it is stored are its own.
Copies are also how a caller produces exactly what a procedure takes. In the example below, Bump yields a copy of the procedure's Change, so its output has exactly the fields the procedure expects.
A run of its own
When a run reaches a procedure process, the procedure runs as a run of its own, linked to the caller's run:
- The step in the caller's run shows Ran its board as run #N. Click it, or zoom into the procedure process while the run is shown, and the procedure's page opens on that run.
- That run's panel says The run of Tell the team in run #P, with a link back. The browser's back button returns too.
- On the flow list, a procedure's card says how many flows use it, and may read Never run on its own.
A flow can't run itself, however many procedures apart: a procedure that, through others, runs its own flow is refused.
Example: announce a change
Several flows end with “tell the team what changed”. The procedure Announce change takes a Change and leaves an Announcement; Bump dependencies runs it after opening its pull request.
procedures:
- name: Announce change
start:
next: Announce
objects:
- name: Change
attributes:
- name: title
- name: description
- name: link
definition: Where to see the change, such as its pull request.
- name: Announcement
end: true
attributes:
- name: url
definition: The link to the message posted.
processes:
- name: Announce
prompt: |
Post the Change to #changes on Slack: its title, two sentences
of what it means for the team, and the link.
mcpServers: [Slack]
takes: [Change]
yields: [Announcement]
flows:
- name: Bump dependencies
start:
next: Bump
objects:
- copyOf: {flow: Announce change, object: Change}
- copyOf: {flow: Announce change, object: Announcement}
processes:
- name: Bump
prompt: |
Bump every dependency with a patch release available, run the
tests, push the branch and open a pull request. Describe it as
the Change.
yields: [Change]
- name: Tell the team
kind: subflow
runs: Announce change
takes: [Change]
yields: [Announcement]Tell the team is a procedure, which runs the flow Announce change.
Tell the team takes Change.
Tell the team yields Announcement.
Bump pushes and opens the pull request itself, because the procedure works in a workspace of its own. To share only the shape of an object, without any steps, use a struct.