Publication workflow

On this page
  1. Every workflow in the repo
    1. They also run
    2. Some decisions are computed, not judged
    3. The base processes are strict
    4. How to read them
  2. Editing and the HCI validation gate
    1. The one rule this diagram exists to state
    2. Mechanical vs non-mechanical validation
    3. Activities and the skills that implement them
  3. From corpus to published folio
  4. Content lifecycle overview
  5. The work plan — tasks as beans
  6. Who is who
    1. People
    2. Agents and system actors
  7. Changing these diagrams
    1. Which diagrams are BPMN, and which are not
  8. See also

This page is generated from docs/source/process-publication-workflow/ — each section below links to its own source.

✎ Edit

How a change gets from an editor had an idea to the folio is officially published — expressed as BPMN 2.0 swimlane diagrams, with the roles, the validation gate, the skills, and the shared work plan all named.


Every workflow in the repo

✎ Edit

Every process here is a real BPMN 2.0 document with diagram interchange — open it in bpmn.io, Camunda Modeler, or any BPMN tool. The SVGs are generated from those files by bun run cat render:bpmn; never hand-edit an SVG.

The table below is not written on this page. It is read from the published knowledge graph — the named-subgraph JSON-LD that bun run cat subgraph:jsonld frames from kg-export — by walking each instance’s processes subgraph. Each row’s text is the first sentence of that diagram’s own bpmn:documentation, carried on its Process node as summary. To change what a row says, change the diagram. The derived process index lists this instance’s corpus of diagrams with their lanes and skills.

Bootstrap’s diagrams are in the table, read from bootstrap’s own graph. bootstrap and bootstrap-tools sit below this instance, and their processes are kept out of its graph on purpose (pve3): they publish their own named subgraphs at their own sites, and the repository index here links each with seeAlso. The table follows those links, so a row for a bootstrap diagram is read from bootstrap’s site — and if that site cannot be read, the page says so beside the table rather than drawing a shorter one.

What the table cannot tell you is which of two neighbouring processes you are in, so that is the only thing said here:

  • Before anything else. initialize-harness is the one bootstrap process an actor starts; every other bootstrap diagram is a sub-process reached from it. Once a harness exists, getting-started is where a request to “create a folio” begins.
  • Content-agnostic, nested. content-lifecycle is one cycle of a folio; it calls draft-to-publication, which calls editing-hci-validation for one proposed change to one block. The content-type processes — authoring-a-document, authoring-a-paper, l2-dak-authoring, l3-fhir-pipeline — describe how that change is drafted for a given kind of folio.
  • Content or platform. content-change-review takes a change to a folio’s content; code-change-review takes a change to the platform, and calls merge-base to bring the base branch in.
  • Review. review-task is the generic entry. It descends into review-narrative, review-code or narrative-code-review as separate processes rather than as extra skills on one reviewer, because a called process’s lane is scoped to that call path.
  • A disagreement. criterion-adjudication is for two reviewer entries on one QA criterion; every other judgement that no mechanism can settle goes to adjudication.
  • Remote content. materialize-remote decides whether a local copy may be held; refresh-materialized keeps one current; copy-out-materialized is how somebody edits content held as a read-only copy; sample-import and subscribe-kg call the first two rather than restating them.
  • Upstream releases. upstream-pin-watch notices a pinned dependency has fallen behind; upstream-version-adoption is the reusable sub-process that decides whether to take the release.
  • Translation. translation-workflow is the machine half; human-translation-workflow is the same cycle with a human translator and a subject-matter reviewer in it.
  • CI workflows. A .github/workflows/*.yml names the diagram it implements with a # bpmn: line, and each job names its node with # bpmn-node:; bun run cat check:workflow-coverage compares the two.

They also run

✎ Edit

Since bean fq0b these files are not only pictures. The MCP server interprets them: workflow_start opens an instance for a subject, workflow_next reports what is enabled now — with the lane that performs it and the skill that implements it — and workflow_complete refuses a step the process has not reached. Commit into the corpus cannot be reported done before the editor’s decision is recorded, because there is no token on it until then.

That is ordering, not enforcement: nothing yet stops an agent calling a capability tool directly. The case for making it binding — and the argument that the commit boundary is the right place — is in Proposal: workflow orchestration.

Some decisions are computed, not judged

✎ Edit

Ten exclusive gateways sit across the six diagrams, and they are not all the same kind of question. Accept, revise or discard? is the editor’s call. Build green, no sorries? is arithmetic over lean_build and proof_status.

A gateway carrying <cat-harness.processes:decision ref="decisions/x.dmn#Decision_Id"/> has its outcome computed from a DMN decision table under processes/decisions/. The agent supplies facts — { failCritical: 0, failMajor: 2 } — and the table returns the branch; workflow_complete refuses a hand-supplied outcome there, and records which rule fired.

GatewayTableReads
Build green, no sorries?lean-build-gate.dmnbuildOk, deferredSorries
Draft QA green?draft-qa-gate.dmnfailCritical, failMajor

QC clean? and FHIR valid? are equally mechanical and equally deserve tables — they wait on a WHO/FHIR adapter, because a table keyed to facts no tool emits looks authoritative and is not.

The base processes are strict

✎ Edit

The three content-agnostic diagrams — editing, draft-to-publication, lifecycle — carry <cat-harness.processes:policy enforcement="strict"/>. workflow_gate refuses a step they have not reached. The three per-content-type diagrams are advisory, because what counts as adequate review of a Lean proof and of a FHIR profile are different questions, and the package that knows the domain should answer them.

A content package may relax a base step by declaring it in skills/<package>/workflow-policy.json with a reason — an unexplained relaxation does not load, so the file is the record of what was waived and why. Five steps refuse to be relaxed at all: Task_ReviewFindings, Gateway_EditorDecision and Task_Commit (the editor seeing the findings, the decision, the write), plus Task_AuthorizeRelease and Task_PublishRelease (the publish-authorized SHALL). If those were negotiable the base would not be strict, it would be a suggestion.

bun run cat check:workflow-policy lists the policy and validates every relaxation; it runs in CI, so one that has stopped applying is a build failure rather than a discovery on the day it is needed.

The commit boundary is where this is enforced rather than merely answerable. scripts/check-corpus-gate.ts, run in the folio repo from a pre-commit hook or CI, refuses a changed content block that no instance records the editor having authorised. workflow_gate answers an agent that asks; the hook does not depend on anyone asking.

bun run <platform>/scripts/check-corpus-gate.ts --staged --platform <platform>
bun run <platform>/scripts/check-corpus-gate.ts --staged --warn   # adopt gradually

How to read them

✎ Edit

  • A lane is a role. Every lane maps to an actor in cat-harness/scenarios/actors/ — see Who is who.
  • [skill-name] under an activity is the folio-assistant skill that implements it. The same reference is carried machine-readably as a <bootstrap.processes:skill ref="…"/> extension element on the BPMN activity.
  • The “Work plan — beans” lane is the shared to-do store. Steps in that lane read and write beans/, and are marked <cat-harness.processes:bean store="beans/"/> in the source.
  • A thick-bordered box is a call activity — it expands into another diagram on this page.

Editing and the HCI validation gate

✎ Edit

This is the diagram that matters most day to day: one proposed change to one content block.

BPMN swimlane diagram: an editor describes a change, an authoring agent drafts it, the proposed change fans out through mechanical and non-mechanical validation, the findings are shown to the editor, and only an accepted change is committed to the corpus.

Open the BPMN source

The one rule this diagram exists to state

✎ Edit

Nothing reaches the corpus before the editor has seen the findings. The authoring agent produces a proposed change, not a commit. That proposal fans out through the HCI validation pipeline, the results are collated into one report, and the editor decides — accept, revise, or discard. The Commit into the corpus activity sits after that decision, in its own lane, and is the only step that writes content.

Mechanical vs non-mechanical validation

✎ Edit

The parallel gateway splits the pipeline in two, and the split is the point:

  • Mechanical validation — anything a machine can settle on its own, with a reproducible verdict: block schema and constraint rules, label prefixes, syntax, spelling, cross-references and citation resolution, Lean build and proof status, LaTeX compilation, FHIR/SUSHI validation, QA axes. No judgement, no negotiation; it passes or it does not.
  • Non-mechanical validation — everything that needs judgement: is the claim accurate, does the prose keep the folio’s voice, does the change actually say what the editor meant. A review agent handles the routine cases; anything turning on clinical or scientific judgement escalates to a human reviewer or SME. Both branches are the same stage of the pipeline — the reviewer being a person or an agent changes who answers, not where the answer goes.

Both branches must report before the join. A green mechanical run does not excuse a missing review, and a clean review does not excuse a red build.

Activities and the skills that implement them

✎ Edit

ActivityLaneSkill
Describe the intended changeEditor / author— (human)
Claim or open the beanWork plantodo-manager
Draft the block editAuthoring agentcontent-author
Schema and constraint checksMechanical validationcontent-validate
Syntax, spelling and linksMechanical validationcontent-validate
Build and QA gatesMechanical validationcontent-test
Agent review of the changeNon-mechanical validationcontent-review
Human / SME reviewNon-mechanical validationcontent-review
Collate findings into a reportHCI validation pipeline— (pipeline)
Log findings on the beanWork plantodo-manager
Review the findingsEditor / author— (human — this is the gate)
Revise the proposed changeAuthoring agentcontent-author
Commit into the corpusCorpus— (subject to the commit-hygiene requirement)
Resolve or re-open the beanWork plantodo-manager

The domain-specific checks hang off content-validate / content-test by content type: lean-formalization and proof-verification for papers, fhir-validation and quality-control for IGs, latex-authoring for rendering.


From corpus to published folio

✎ Edit

The corpus is not the publication. A draft is built from it, reviewed as a whole by the review team, and only then released.

BPMN swimlane diagram: the corpus is built into a draft publication, QA gates run, the publication manager circulates it, the review team and SMEs review in parallel, change requests become beans that re-enter editing, and an approved draft is authorised by the programme manager and published.

Open the BPMN source

Three things to note:

  1. A red draft is fixed in the editing process, not in the artifact. The no branch off Draft QA green? goes back through the editing call activity — which means back through the HCI validation gate. Nobody patches a built PDF or a generated IG.
  2. Review is parallel, and both halves must land. The review team (content reviewer, QC reviewer, technical officer) reviews the draft as a publication; the clinical or scientific SMEs sign off on the domain content. The join waits for both.
  3. Change requests become beans. A changes requested outcome does not evaporate into a review thread — each request is opened as a bean, so whoever picks the work up next (human or agent) sees exactly what review asked for.
ActivityLaneSkill
Open or claim the release beanWork plantodo-manager
Build the draft publicationCorpus + build pipelinecontent-publish
Run publication QA gatesCorpus + build pipelinecontent-test · quality-control
Editing and HCI validationEditors + authoring agentscall activity → diagram 3
Circulate the draftPublication managercontent-review
Review the draft publicationReview teamcontent-review
Clinical / scientific sign-offSMEscontent-review
Open beans for the change requestsWork plantodo-manager · content-feedback
Authorise the releaseProgramme managercontent-publish
Version, tag and publishPublication managercontent-publish · ig-publication
Close the release beansWork plantodo-manager

This diagram implements the req:content-lifecycle phase gates — validate-before-review, review-before-test, test-before-publish, publish-authorized — see skills/requirements/content-lifecycle.json.


Content lifecycle overview

✎ Edit

One cycle of a folio, plan to retire. Both diagrams above appear here as call activities.

BPMN swimlane diagram: the programme manager plans, the plan is seeded as beans, editing and HCI validation runs, integration test and QA sweep, draft-review-publish, feedback is triaged and filed as beans, then either another cycle or retirement.

Open the BPMN source

This is the same lifecycle as the linear plan → author → validate → review → test → publish → feedback → retire strip, with the actors and the loops made explicit. Note that Editing and HCI validation runs once per proposed change, not once per cycle — the linear strip flattens that.


The work plan — tasks as beans

✎ Edit

Every diagram has a Work plan lane, and it is not decoration. Editing work is tracked as beans (hmans/beans) in a committed beans/ directory, which makes it the one place where a human and an agent see the same answer to what is done, and what is next.

Where in the workflowWhat happens to the work plan
Plan is agreedThe plan is seeded as beans
An edit startsThe bean is claimed (--status in-progress) before any drafting
Validation reportsFindings are appended to the bean
The change is committedThe bean is resolved — or left open with what is still outstanding
Review requests changesEach request is opened as its own bean
A release shipsShipped work is closed; what slipped stays open into the next cycle

Why it is modelled as a lane rather than a note:

  • It is shared state, not session state. beans/ is committed, so the plan survives a resumed session and is visible to sibling agents working other branches. An agent’s ephemeral in-memory to-do list is not.
  • Claiming is how two workers avoid the same item. Claim before you work, and never resolve someone else’s bean.
  • beans create is not idempotent. Check for an existing bean by exact title before creating one — the guard, and the incident that motivates it, are in todo-manager.
  • Beans are not sidecars. Machine-generated queues (QA *.qa.json, witness files, watcher queues) stay bulk JSON; they never become beans.

Who is who

✎ Edit

The roles in the lanes, and the actor definition each one maps to. Roles inherit (viewer → reviewer → author → admin). What an actor may do is not a property of its role: it is an ODRL rule in policies/, and before every task the BPMN executor checks that the actor is authenticated, eligible for the lane’s role, permitted by policy and allowed to touch the content (task-authorization, issue #1207).

People

✎ Edit

In the diagramsActorAuthority
Editor / authorauthorCreates and modifies content. Decides accept / revise / discard at the HCI gate. Inherits reviewer.
ReviewerreviewerViews content and leaves review comments. Cannot make direct changes.
Human / SME reviewer (editing)clinical-smeDomain ground truth. Answers the judgement calls a review agent escalates.
Review team (draft)content-reviewerFormal approval and phase-gate sign-off — the approval authority on a draft.
qc-reviewerPublication-readiness QA across layers; runs the QA reports.
technical-officerProgramme-area coordination and first-pass review.
Publication managerpublication-managerBuilds, versions, tags, deploys. Does not authorise the release.
Programme managerprogramme-managerScope, team, timeline, governance — and release authorisation.
AdminadminFull administrative access: roles, settings, all content.

Domain-authoring roles that appear inside content-author rather than as their own lane: business-analyst (L2 DAK), fhir-modeller (L3 FHIR), terminologist (code systems and value sets), translator (localisation).

Agents and system actors

✎ Edit

In the diagramsActorWhat it does — and what it cannot do
Authoring agentauthoring-agentDrafts and revises a proposed change. Has content-authoring; does not commit — its output goes to the editor through the validation gate.
Review agentreview-agentNon-mechanical validation: accuracy, voice, exposition. Has review-comments only — it reports findings, it does not approve.
Mechanical validationlean-mcpLean 4 proof checking and diagnostics over MCP.
ig-publisher-serviceFHIR IG Publisher build and QA reporting.

The distinction the diagrams enforce: an agent can propose and can report, but approval and commit are a person’s. A review agent’s finding and an SME’s finding arrive at the same place in the pipeline — but neither of them decides; the editor does, and the release is authorised by the programme manager.

For the full role list, their capabilities, and how a user is mapped to a role, see Skills & roles.


Changing these diagrams

✎ Edit

The .bpmn files are the source of truth.

# 1. edit processes/<diagram>.bpmn — in a modeler, or by hand
# 2. regenerate the SVGs
bun run cat render:bpmn
# 3. or, in CI, just check they are not stale
bun run cat render:bpmn:check

render:bpmn renders each .bpmn with bpmn-js in headless Chromium and writes docs/assets/img/workflows/<diagram>.svg. If the sandbox ships a Chromium that does not match the pinned Playwright build, point at it with CHROMIUM_PATH=/path/to/chrome.

When you add an activity, add its <bootstrap.processes:skill ref="…"/> extension (and <cat-harness.processes:bean store="beans/"/> if it touches the work plan) and the matching row in the tables above — the diagram and the skill list drifting apart is the failure this page exists to prevent.

Which diagrams are BPMN, and which are not

✎ Edit

Every process in the docs is BPMN. The diagrams that remain Mermaid are not processes, and BPMN would be the wrong notation for them — a pool with lanes implies actors performing activities over time, which none of these have:

DiagramNotationWhy
README.md, home — “What it does”MermaidComponent / data-flow map of the platform, not a sequence of activities
Architecture — server and adaptersMermaidDeployment and module structure
Skills & roles — how the five concepts composeMermaidConceptual composition, no time axis
Skills & roles — viewer → reviewer → author → adminMermaidAn inheritance lattice, not a flow
Home — documentation mapMermaidNavigation graph
Adding a content type — “What you provide”MermaidWhat you hand over, not what you do
Writing a paper — the Lean sessionMermaid sequenceDiagramAn interaction transcript between you, the assistant and the MCP server. BPMN’s equivalent — a collaboration with message flows — would add ceremony without adding meaning

If you add a diagram that does have actors, activities and a control flow, it belongs in processes/ as BPMN, not in a Mermaid fence.


See also

✎ Edit


Notes on this page (2)

The notes attached to this page, in document order. Every note in this folio is on the todos board.

  1. Decide which roles content-pipeline-navigator and platform-boundary-guard take on

    Status
    blocked
    Priority
    medium
    Raised by
    agent
    Created
    2026-09-19
    About
    folio-assistant-core/process/publication-workflow › agents-and-system-actors

    ci-health-watcher is settled: it is a mechanical participant in the CI process, so it takes build-pipeline and validation-pipeline, both actorKind: "system". Declared, and memoryForRoles now discriminates because of it.

    **The other two are not settled by that argument, and the reason is precise.** Both system roles are described as running a fixed program and exercising *no judgement*. That is exactly what makes them the right home for a watcher — and exactly why they are the wrong home for these two:

    - **platform-boundary-guard** decides whether a literal naming one folio belongs in platform code, and whether a new content type needs an adapter or only a profile. Those are judgements; a wrong one is not a failed check. - **content-pipeline-navigator** is closer to mechanical — it knows which stage owns which file — but it also answers "should this be a block kind", which is not.

    ## What differs depending on the answer

    Nothing breaks either way today: memory is scoped by agent and the duplication is already fixed, because one node can reach several agents. What changes is whether a fact written for one of these two reaches an agent standing in that lane, or only the agent named in the file.

    ## Options

    1. **Leave both agent-scoped, and say so in the role model.** Costs nothing, and is honest — neither is a lane anyone else acts in. The cost is that the role axis stays half-used, with one actor on it. 2. **Give them a judgement-bearing existing role** — editor and code-reviewer are the nearest. Cheap, and wrong if the fit is loose: a forced edge is one every later audit trusts as true. 3. **Add roles for them.** Honest edges. But AGENTS.md warns under skill-in-role-or-process against "inventing roles and activities to absorb tools that do not want them", and a role with one actor describes the tool rather than the work.

    No recommendation. The ci-health-watcher case was settled by a property of the work (it exercises no judgement); neither option here has an equivalent, which is why it is a person's call and not an agent's.

    ## If nothing is decided

    Option 1 is the status quo and nothing regresses.

  2. Decide what 'kick off' means mechanically for the two CI-watcher dispatch points

    Status
    in_progress
    Priority
    medium
    Raised by
    agent
    Created
    2026-09-19
    About
    folio-assistant-core/process/publication-workflow › agents-and-system-actors

    Stated 2026-09-19: a CI watcher *"should kick off during feature development once changes are made to feature branch. and when approved for final publication/merge to main."*

    The two dispatch points are clear. **What performs the dispatch is not**, and the three candidates differ enough that guessing would be wasted work.

    ## ANSWERED, 2026-09-19

    Owner: *"kick off if like task or workflow initation or bean roast"*.

    **Option 2.** A dispatch point is a **task / workflow initiation**, and it opens a **bean** — not a GitHub Actions job. That is the answer the repo's own machinery is already shaped for: an activity carrying <folio:bean op="claim"/> performs the bean operation when the step completes, so "start the watcher" and "record that it is running" are one declared step rather than two mechanisms that can disagree.

    It also settles the cost I flagged against option 2 — that a BPMN activity only fires while somebody is working. With a bean opened at initiation, the work is *durable*: a later session sees the bean whether or not the session that opened it is still alive.

    Remaining, and now narrow: which diagrams host the two steps, and whether the feature-branch one needs a process that does not yet exist.

    ## Options, with what each costs

    1. **A GitHub Actions job.** Fires without anybody present, which is the whole premise of xom7 — the failure being guarded against is a quiet stretch with nobody looking. Cost: it cannot read the session's memory, so the "dispatch an agent with a specific memory context" half does not happen. 2. **An activity in a BPMN process**, performed by a session. Gets the memory context, and puts the dispatch where workflow_next can report it. Cost: it only fires while somebody is working — precisely the stretch that is already covered. 3. **An MCP tool a workflow step calls.** Both, at the price of building the tool and deciding who calls it.

    ## Where the two dispatch points already live

    Both are steps in diagrams that exist, which is why this todo is tagged with them rather than describing them:

    - **"approved for final publication / merge to main"** is Process_Publication (draft-to-publication.bpmn), whose lane carries *Authorise the release* and *Version, tag and publish*. The dispatch point the owner named is that authorisation step. - **"once changes are made to feature branch"** is Process_CodeReview, reached from Process_Review.

    ## What is already true, so this is not started from nothing

    The two dispatch points are process events, so wherever they are performed they should be DRAWN in BPMN under processes/. The likely homes are draft-to-publication for the merge-to-main gate and a feature-branch process that may not exist yet — that needs checking rather than assuming.

    ## If nothing is decided

    Nothing fires. bun run cat check:ci-health still runs in the session-start sweep and ci-health.yml still runs weekly, so the watcher is not silent — it is just not tied to the two moments named above.

    • process: Process_CodeReview
    • process: Process_Publication
    • who: github:litlfred
    • bean: folio-assistant-29ij

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 b08c961 · 2026-10-23T23:11:09Z