Contributing¶
This page explains how the ubFlow documentation is structured, what the data model looks like, and how to write high-quality Sphinx-Needs objects.
Documentation Philosophy¶
Every agent rule in ubFlow must be fully traceable to a documented need. The documentation is the single source of truth — no instruction or skill may exist without a chain of evidence that leads back to a flow story.
The workflow always follows this order:
Write a Flow Story (the why).
Derive one or more Specifications (the what, testable).
Author Instructions and/or Skills that implement the spec (the how).
Only then write or update the
.agent.mdfile.
The Meta-Model¶
The meta-model uses the prefix flow for all its artifact types to avoid naming collisions
with object types used in end-user projects and their documentation — for example, “user story”
in a SCRUM-based software development project.
To keep names concise, types are abbreviated: an instruction is written as flowinst,
a skill as flowskill, and so on.
Objects and their relationships form a strict hierarchy:
agentfamily (FAM_)
└── agent (AGT_)
├── flowstory (FLST_) ← agent is realized by flow stories
│ └── flowspec (FLSP_) satisfies FLST_
│ ├── flowinst (FLIN_) implements FLSP_
│ └── flowskill (FLSK_) supports FLSP_
├── flowinst (FLIN_) applies (direct link)
├── flowskill (FLSK_) employs (direct link)
└── flowtool (FLTL_) uses (direct link)
flowchart TD
FAM["agentfamily (FAM_)"]
AGT["agent (AGT_)"]
UST["flowstory (FLST_)"]
SPEC["flowspec (FLSP_)"]
INST["flowinst (FLIN_)"]
SKILL["flowskill (FLSK_)"]
TOOL["flowtool (FLTL_)"]
FAM -->|has_agents| AGT
UST -->|covered_by| AGT
SPEC -->|satisfies| UST
INST -->|implements| SPEC
SKILL -->|supports| SPEC
AGT -->|applies| INST
AGT -->|employs| SKILL
AGT -->|uses| TOOL
Link Reference¶
Link name |
From |
To |
Meaning |
|---|---|---|---|
|
|
|
Family aggregates its member agents |
|
|
|
User story is realized by this agent |
|
|
|
Spec makes a flow story testable and concrete |
|
|
|
Instruction is the behavioral realization of a spec |
|
|
|
Skill provides the procedural knowledge for a spec |
|
|
|
Agent is bound by this instruction |
|
|
|
Agent consults this skill during execution |
|
|
|
Agent invokes this external tool or MCP server |
ID Conventions¶
IDs follow the pattern <PREFIX>_<NAMESPACE>_<NUMBER>, e.g. FLST_UBFLOW_001.
Type |
Prefix |
Example |
Remarks |
|---|---|---|---|
Agent Family |
|
|
Exactly one per project; defined in root |
Agent |
|
|
|
Flow Story |
|
|
Sequential, never reuse a retired ID |
Specification |
|
|
Sequential per project namespace |
Instruction |
|
|
Sequential per project namespace |
Skill |
|
|
Sequential per project namespace |
Tool |
|
|
Sequential per project namespace |
Allowed status values: draft | approved | deprecated.
New objects start as draft; set to approved after peer review.
Writing Good Sphinx-Needs Objects¶
Flow Story (FLST_)¶
A flow story answers: As a <role>, I want <goal>, so that <benefit>.
Rules:
Use one sentence per clause — role, goal, benefit.
The title is a short noun phrase (3–6 words), not a full sentence.
Do not describe implementation details — keep it goal-oriented.
Link
covered_byto the responsible agent once it exists.
.. flowstory:: Template and version selection
:id: FLST_UBFLOW_INST_06
:status: approved
:tags: ubflow, installer
:covered_by: AGENT_INSTALLER
As an installing developer, I want to select the agent family template
and its version before installation, so that I can reproduce the same
installation at any later point.
Specification (FLSP_)¶
A spec answers: The system / agent SHALL <observable behaviour>.
Rules:
Start the body with “The agent shall” or “The installer shall”.
Keep it testable — avoid vague terms like “fast” or “easy”.
One spec = one verifiable requirement. Split compound specs.
Link
satisfiesto the parent flow story.
.. flowspec:: Present available template versions
:id: FLSP_UBFLOW_INST_001
:status: approved
:satisfies: FLST_UBFLOW_INST_06
The installer shall present all available template versions retrieved
from the configured source and require the developer to confirm the
selected version before proceeding.
Instruction (FLIN_)¶
An instruction states what the agent shall do — a binding behavioral obligation. It must not describe procedure steps (that belongs in a skill).
Rules:
Use imperative mood: “Always confirm …”, “Never proceed without …”.
One instruction = one behavioral rule.
Link
implementsto the parent spec.An instruction MAY stand alone without a companion skill.
.. flowinst:: Confirm template version before writing files
:id: FLIN_UBFLOW_INST_001
:status: approved
:implements: FLSP_UBFLOW_INST_001
Always present the resolved template version to the developer and require
explicit confirmation before writing any files to the target repository.
Skill (FLSK_)¶
A skill describes how the agent performs a task — a step-by-step procedure or reference knowledge. Use a skill when the how is non-trivial or reusable across multiple instructions.
Rules:
Write numbered steps or clearly structured prose.
Link
supportsto the parent spec.If a non-trivial procedure is implied by an instruction but no skill exists yet, create a
draftskill with aTODObody immediately.
.. flowskill:: Resolve template version from source
:id: FLSK_UBFLOW_INST_001
:status: draft
:supports: FLSP_UBFLOW_INST_001
TODO: Describe how to query available template versions from the
configured source (local path, git tag, registry).
1. Read the ``source`` field from the installer answers file.
2. List available versions (git tags or directory names).
3. Sort versions semantically (newest first).
4. Return the list to the calling instruction for display.
Tool (FLTL_)¶
A tool represents an external capability the agent can invoke — an MCP server, CLI command, or API.
Rules:
Title = the canonical tool name.
Body describes purpose, invocation method, and any known constraints.
Link agents to tools via
:uses:.
.. flowtool:: ubCode MCP Server
:id: FLTL_UBFLOW_001
:status: approved
:tags: mcp, ubcode
The ubCode MCP server provides read access to the indexed Sphinx-Needs
project. Agents invoke it to retrieve instructions, skills, and need
relationships at runtime without reading RST files directly.
Agent (AGT_)¶
An agent node declares the identity and purpose of a Copilot agent.
Rules:
The body is a concise capability statement (2–4 sentences).
Link
appliesto every instruction the agent is bound by.Link
employsto every skill the agent consults.Link
usesto every tool the agent invokes.
.. agent:: Installer Agent
:id: AGENT_INSTALLER
:status: draft
:tags: ubflow, installer
:applies: FLIN_UBFLOW_INST_001
:employs: FLSK_UBFLOW_INST_001
:uses: FLTL_UBFLOW_001
The Installer Agent guides developers through the interactive setup of
an ubFlow agent family inside their repository. It validates prerequisites,
resolves conflicts, and writes a deterministic, reproducible installation.
File and Folder Layout¶
Each agent family lives in its own top-level directory (e.g. aspice/).
Inside it, every agent gets its own subdirectory:
<family>/
├── ubproject.toml ← sphinx-needs config for this family project
├── conf.py
├── index.rst ← FAM_ need
└── <agent>/
├── index.rst ← AGT_ need
├── user_stories.rst
├── specs.rst
├── instructions.rst
├── skills.rst
└── traceability/
├── index.rst
└── overview.rst
The docs/ directory describes ubFlow itself and follows the same layout.
Creating and Maintaining a Family Package¶
A family package lives under families/<name>/ and is the unit that
ubflow-installer copies into a target repository. The aspice family
(families/aspice/) is the reference example.
Directory layout¶
families/<name>/
├── conf.py ← Sphinx project root (documentation only)
├── index.rst ← FAM_ need; documents the family for developers;
│ links into family/ via toctree
├── ubproject.toml ← Sphinx-Needs schema + ubCode server config
├── copier.yml ← Copier manifest (_subdirectory: "family")
└── family/ ← installable content — everything in here is
├── index.rst copied into the target repository by copier
└── agents/
└── <agent>/
├── index.rst
├── user_stories.rst
├── specs.rst
├── instructions.rst
├── skills.rst
└── traceability/
The split between root and family/ is deliberate:
Root items (
conf.py,ubproject.toml,index.rst) are the developer-facing Sphinx project for the family author. They are never copied to the user’s repository.``family/`` contains only the RST files the end user receives.
copier.ymlpoints exclusively to this subdirectory via_subdirectory: "family".
Step-by-step: adding a new family¶
Create the directory
families/<name>/.Add the Sphinx project files at the root:
conf.py— standard Sphinx config; addsphinx_needstoextensions; excludecopier.ymlfromexclude_patterns.ubproject.toml— copy fromfamilies/aspice/ubproject.tomland update[project]section (name,description). The need schema (link types, need types, statuses) is intentionally shared and should remain compatible with the ubFlow meta-model.index.rst— define theagentfamilyneed (FAM_<NS>_001), optionally list agents via:has_agents:, and add atoctreethat points intofamily/index.
Create ``copier.yml`` at the root with at minimum:
_subdirectory: "family" _answers_file: ".ubflow-answers.yml" package_name: type: str default: "<name>" package_version: type: str default: "0.1.0"
Add ``ubflow_package.json`` at the root. This file is read by the installer CLI before invoking Copier:
{ "schema_version": 1, "package_name": "<name>", "package_version": "0.1.0", "display_name": "My Agent Family", "description": "One-sentence description.", "directories": [], "epics": [] }
Populate ``family/`` with the RST content to be installed:
family/index.rst— top-level entry; must include atoctreethat references each agent subdirectory.family/agents/<agent>/— one directory per agent, containingindex.rst,user_stories.rst,specs.rst,instructions.rst,skills.rst, andtraceability/.
Build the family documentation to verify zero warnings:
sphinx-build -b html -W families/<name> families/<name>/_build/html
Test the installation locally without committing:
make test-install # scaffolds tests/temp/host_project/ ubflow-installer install <name> tests/temp/host_project --repo-root . ubflow-installer verify tests/temp/host_project make clean_tests # removes tests/temp/
Maintaining an existing family¶
Increment
package_versionin bothubflow_package.jsonandcopier.ymlafter every change tofamily/content, so installed projects can detect that an update is available.Never rename or remove a Sphinx-Needs ID that has already been released — retire it by setting
:status: deprecatedinstead.Run
make test-installafter any content change to confirm the installation flow still works end-to-end.
Build and Validation¶
make venv # create / update shared .venv
make html # build docs/
make aspice # build aspice/
make all-html # build both projects
After every change to any .rst file, the build must succeed with
zero errors and zero warnings before the change is considered complete.
Testing a Family Installation Locally¶
Before committing changes to a family package, verify the full installation
flow in an isolated scratch project under tests/temp/.
Step 1 — Scaffold the test host project
make test-install
This runs tests/run_install_test.sh, which:
Deletes any existing
tests/temp/host_project/directory.Copies
tests/templates/host_project/(a minimal Sphinx project withconf.py,index.rst, andubproject.toml) intotests/temp/host_project/.
The resulting directory is git-ignored and can be wiped at any time.
Step 2 — Install the family
Using the CLI directly:
ubflow-installer install aspice tests/temp/host_project --repo-root .
Or via the Installer Agent in Copilot Chat:
@installer install aspice family in tests/temp/host_project
Both options run the same sequence: locate the family source under
families/aspice/, check prerequisites, scan for conflicts,
invoke Copier, write the manifest, and run post-install validation.
Step 3 — Verify the installation
ubflow-installer verify tests/temp/host_project
The verify command re-computes SHA-256 digests for every file listed
in .ubflow-manifest.json and reports any mismatch. Exit code 0
means the installation is intact.
Step 4 — Clean up
make test-clean
This removes tests/temp/ entirely. Run make test-install again
whenever you need a fresh scaffold.
Summary of available make targets
Target |
Description |
|---|---|
|
Scaffold |
|
Remove |
|
Run the installer unit-test suite ( |
|
Alias for |
Mermaid Integration¶
Mermaid diagrams can be embedded directly in Sphinx documentation using the .. mermaid:: directive.
Marp does not natively support Mermaid diagrams, so you must export them as SVG or PNG files for inclusion.
To do this:
Save your Mermaid code in
/docs/_mermaid/MY_FILE.mmd.Reference the file in Sphinx docs with
.. mermaid:: /_mermaid/MY_FILE.mmd.Export to SVG using
npx @mermaid-js/mermaid-cli -i input.mmd -o output.svg -c config.json. Adjust file paths as needed.Include the exported SVG in Marp presentations with
.
The config.json file defines color rules for the black Useblocks theme used in Marp presentations. If omitted, the default background is white and colors are optimized for light themes.
Hint
There is a known issue with background styling: the background remains white regardless of theme settings. Colors are currently optimized for readability on a white background.