The platform

The platform half of folio-assistant: the skills, schemas, processes and MCP server an agent uses to author a folio. It holds no subject matter. A paper, a WHO SMART Guideline, an Implementation Guide — those live in their own repositories and instances, and this one is the machinery they run on.


One sentence, and every word in it is a declared object

An actor performs a task in a process as a role, using that role’s skills.

That sentence is the whole model, and the five nouns are five different things that are easy to collapse into each other:

what it iswhy it is not the one next to it
Actora concrete participant — a person, an agent session, a scheduled jobpersists across processes; a role does not
Rolethe BPMN swimlane — a persona an actor takes on for the duration of a lanenobody is a reviewer; somebody acts as one, here, now
Taskone activity in one diagramthe unit of work, not the ability to do it
Processthe diagram itself: lanes bind roles, activities name skills, gateways may compute a branchthe shape of the work, not an instance of it
Skillthe instructions the actor needs to perform the taskknowledge, not permission — what an actor may do is a permission, and it lives on the actor

The full argument, including why moving permissions onto Role produced thirty-six conflicts, is in the role-model skill.

Processes — every one is BPMN, and the diagrams are executable

A process here is not a picture of a workflow drawn after the fact. The .bpmn file is the source of truth: workflow_start, workflow_next, workflow_gate and workflow_complete run it, workflow_complete refuses a step that holds no token, and the running instance is committed so a sibling session sees the same position. A diagram that disagreed with what the tools do would be a defect in the diagram.

Entry point or step inside another — the distinction is derived, not labelled. A process that no other diagram calls is somewhere work begins: you enter it deliberately. A process named by a callActivity somewhere else is a step inside that larger one, and entering it directly means starting in the middle of something. Nothing marks this in the file; it falls out of who calls whom, which is why it stays true as diagrams are added.

Worked, because the abstract version misleads. Content acquisition is an entry point: nothing calls it, so reaching for it is how acquisition starts. Adjudication reads like one and is not — it is called from the Translation Workflow, from the Ingestion subprocess — the L1 completeness gate, and from Refresh materialized remote content. So “run Adjudication” is not a thing anybody does on its own; it is what one of those three reaches when it needs a decision, and starting there means starting in the middle of whichever one you were actually in. Criterion adjudication is a level further in again, called by Wireframe design review and Voice overlay review.

The lesson generalises past those names: a process whose title sounds like a verb you would type is not evidence that you may enter it. Ask the index who calls it — that is the one question the diagram answers and a name does not.

Three things worth knowing before you open one:

  • A lane is an accountability boundary. When a token crosses into another lane, who is answerable for the next step changes — that is the point of drawing it, and why “say which process you are in” is a rule rather than a courtesy.
  • An activity names the skill that performs it. So a process is also a map of which skills matter for which work, and a step whose skill is missing is a finding rather than a blank.
  • A gateway may be computed. Where a branch is backed by a DMN table, the agent supplies the facts and the table returns the branch. A hand-supplied outcome is refused, so nobody talks their way past a gate.

Every process, with its lanes, its activities and the skills they name → That index is generated from the diagrams on every build, so it is what the repository actually contains rather than what this page remembers.

Roles, tasks and skills

Skills are knowledge-graph content, not a directory to memorise. An agent asks for one — skill_list for what exists, skill_fetch for a named skill’s instructions — and an instance inherits its dependencies’ skills through the same declaration, so what is reachable depends on where you are standing.

Every skill, by sub-graph →

Roles are declared in scenarios/roles.json and bound to lanes by the diagrams; permissions are declared on the actor, because what somebody may do cross-cuts the lanes they act in. bun run cat kg:audit checks one criterion per join between them and writes its findings as committed sidecars rather than as console output — a printed verdict is gone, which makes “unbound since it was drawn” and “broken in the commit under review” indistinguishable.

Every role, with the skills its lane carries →

Every task, by the process that draws it →

What the two indexes do not tell you is how differently sized their entries are, so: a role here is as likely to be mechanical as human. Adjudicator and Business analyst are personas a person or an agent takes on; Build pipeline, Attestation service and Activity log are lanes held by something that is not a person at all, and they appear in the same list because a swimlane does not care. That is why nothing is a reviewer — somebody acts as one for the length of a lane.

Tasks are finer than either. They are the individual steps inside a diagram — Read the sidecar findings, Classify what changed, Accept, or send back, Authorise the extraction — and there are an order of magnitude more of them than there are processes, which is the honest reason the task index is a reference rather than a reading list. Open it when you want to know which diagram a step you have been asked to perform belongs to; the lane it sits in is what says who is answerable for it.

What the handler publishes, and why it is not here

/cat-harness/ is a handler namespace, not a section of this page. Every route under it is <base>/<handler>/<kind>/ — the platform rendering one declared graph — and the handler segment is read from the instance’s declared name, never composed.

This page used to sit at /cat-harness/ as the one authored file among them. Two path rules meet there: <base>/<handler>/<kind>/ is the machinery rendering something, and <base>/<instance>/ is an instance presenting itself. The platform is both, so the rules collided at exactly that path, and the owner settled it on 2026-09-21 — the handler wins. Bean 8h42.

what it showsgenerated by
auto-docsderived indexes over a sub-graph — processes and skillsgen-auto-docs.ts
librarythe L1 corpus: what is ingested, how far, what references it, and what is still queuedgen-library-viz.ts
schemasthe schema graph — declarations and the edges between themgen-schema-viz.ts
voicesevery voice an instance declares, and the passage each rule was read fromgen-voices-viz.ts

The table is the four that exist, read from the sibling directories rather than remembered — it named three for a day after the fourth landed.

Each is regenerated from the tree it describes, so a stale one is a build problem rather than an editing problem. This page is the opposite: nothing regenerates it, and it goes stale silently if the thing it describes moves. If you change how processes, roles or skills relate to each other, change it here too — that is the cost of the half an index cannot write.

Where to go next


folio-assistant — code under the Apache License 2.0, documentation under CC BY 3.0. Generated schema and API references are rebuilt from source on every push to main.

deployed dev