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: 1. Write a **Flow Story** (the *why*). 2. Derive one or more **Specifications** (the *what*, testable). 3. Author **Instructions** and/or **Skills** that implement the spec (the *how*). 4. Only then write or update the ``.agent.md`` file. 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: .. code-block:: text 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) .. mermaid:: 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 -------------- .. list-table:: :header-rows: 1 :widths: 20 20 20 40 * - Link name - From - To - Meaning * - ``has_agents`` - ``FAM_`` - ``AGT_`` - Family aggregates its member agents * - ``covered_by`` - ``FLST_`` - ``AGT_`` - User story is realized by this agent * - ``satisfies`` - ``FLSP_`` - ``FLST_`` - Spec makes a flow story testable and concrete * - ``implements`` - ``FLIN_`` - ``FLSP_`` - Instruction is the behavioral realization of a spec * - ``supports`` - ``FLSK_`` - ``FLSP_`` - Skill provides the procedural knowledge for a spec * - ``applies`` - ``AGT_`` - ``FLIN_`` - Agent is bound by this instruction * - ``employs`` - ``AGT_`` - ``FLSK_`` - Agent consults this skill during execution * - ``uses`` - ``AGT_`` - ``FLTL_`` - Agent invokes this external tool or MCP server ID Conventions -------------- IDs follow the pattern ``__``, e.g. ``FLST_UBFLOW_001``. .. list-table:: :header-rows: 1 :widths: 15 15 30 40 * - Type - Prefix - Example - Remarks * - Agent Family - ``FAM_`` - ``FAM_ASPICE_001`` - Exactly one per project; defined in root ``index.rst`` * - Agent - ``AGT_`` or ``AGENT_`` - ``AGT_ASPICE_001`` / ``AGENT_INSTALLER`` - ``AGT__NNN`` for fully-qualified family agents; ``AGENT_`` for short standalone agent IDs * - Flow Story - ``FLST_`` - ``FLST_UBFLOW_035`` - Sequential, never reuse a retired ID * - Specification - ``FLSP_`` - ``FLSP_UBFLOW_001`` - Sequential per project namespace * - Instruction - ``FLIN_`` - ``FLIN_UBFLOW_001`` - Sequential per project namespace * - Skill - ``FLSK_`` - ``FLSK_UBFLOW_001`` - Sequential per project namespace * - Tool - ``FLTL_`` - ``FLTL_UBFLOW_001`` - 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 , I want , so that .* 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_by`` to the responsible agent once it exists. .. code-block:: rst .. 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 .* 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 ``satisfies`` to the parent flow story. .. code-block:: rst .. 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 ``implements`` to the parent spec. - An instruction MAY stand alone without a companion skill. .. code-block:: rst .. 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 ``supports`` to the parent spec. - If a non-trivial procedure is implied by an instruction but no skill exists yet, create a ``draft`` skill with a ``TODO`` body immediately. .. code-block:: rst .. 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:``. .. code-block:: rst .. 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 ``applies`` to every instruction the agent is bound by. - Link ``employs`` to every skill the agent consults. - Link ``uses`` to every tool the agent invokes. .. code-block:: rst .. 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: .. code-block:: text / ├── ubproject.toml ← sphinx-needs config for this family project ├── conf.py ├── index.rst ← FAM_ need └── / ├── 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//`` and is the unit that ``ubflow-installer`` copies into a target repository. The aspice family (``families/aspice/``) is the reference example. Directory layout ~~~~~~~~~~~~~~~~ .. code-block:: text families// ├── 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/ └── / ├── 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.yml`` points exclusively to this subdirectory via ``_subdirectory: "family"``. Step-by-step: adding a new family ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1. **Create the directory** ``families//``. 2. **Add the Sphinx project files** at the root: - ``conf.py`` — standard Sphinx config; add ``sphinx_needs`` to ``extensions``; exclude ``copier.yml`` from ``exclude_patterns``. - ``ubproject.toml`` — copy from ``families/aspice/ubproject.toml`` and 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 the ``agentfamily`` need (``FAM__001``), optionally list agents via ``:has_agents:``, and add a ``toctree`` that points into ``family/index``. 3. **Create ``copier.yml``** at the root with at minimum: .. code-block:: yaml _subdirectory: "family" _answers_file: ".ubflow-answers.yml" package_name: type: str default: "" package_version: type: str default: "0.1.0" 4. **Add ``ubflow_package.json``** at the root. This file is read by the installer CLI before invoking Copier: .. code-block:: json { "schema_version": 1, "package_name": "", "package_version": "0.1.0", "display_name": "My Agent Family", "description": "One-sentence description.", "directories": [], "epics": [] } 5. **Populate ``family/``** with the RST content to be installed: - ``family/index.rst`` — top-level entry; must include a ``toctree`` that references each agent subdirectory. - ``family/agents//`` — one directory per agent, containing ``index.rst``, ``user_stories.rst``, ``specs.rst``, ``instructions.rst``, ``skills.rst``, and ``traceability/``. 6. **Build the family documentation** to verify zero warnings: .. code-block:: bash sphinx-build -b html -W families/ families//_build/html 7. **Test the installation** locally without committing: .. code-block:: bash make test-install # scaffolds tests/temp/host_project/ ubflow-installer install 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_version`` in both ``ubflow_package.json`` and ``copier.yml`` after every change to ``family/`` 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: deprecated`` instead. - Run ``make test-install`` after any content change to confirm the installation flow still works end-to-end. Build and Validation -------------------- .. code-block:: bash 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** .. code-block:: bash make test-install This runs ``tests/run_install_test.sh``, which: 1. Deletes any existing ``tests/temp/host_project/`` directory. 2. Copies ``tests/templates/host_project/`` (a minimal Sphinx project with ``conf.py``, ``index.rst``, and ``ubproject.toml``) into ``tests/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: .. code-block:: bash ubflow-installer install aspice tests/temp/host_project --repo-root . Or via the Installer Agent in Copilot Chat: .. code-block:: text @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** .. code-block:: bash 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** .. code-block:: bash make test-clean This removes ``tests/temp/`` entirely. Run ``make test-install`` again whenever you need a fresh scaffold. **Summary of available make targets** .. list-table:: :header-rows: 1 :widths: 30 70 * - Target - Description * - ``make test-install`` - Scaffold ``tests/temp/host_project/`` from the test template * - ``make test-clean`` - Remove ``tests/temp/`` entirely * - ``make test-installer`` - Run the installer unit-test suite (``tools/installer/tests/``) * - ``make test`` - Alias for ``make test-installer`` 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: 1. Save your Mermaid code in ``/docs/_mermaid/MY_FILE.mmd``. 2. Reference the file in Sphinx docs with ``.. mermaid:: /_mermaid/MY_FILE.mmd``. 3. Export to SVG using ``npx @mermaid-js/mermaid-cli -i input.mmd -o output.svg -c config.json``. Adjust file paths as needed. 4. Include the exported SVG in Marp presentations with ``![](../docs/_mermaid/MY_FILE.svg)``. 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.