Building & testing the docs =========================== The documentation is built with Sphinx. The build needs none of the compiled stack (NEML2, MOOSE/PUMA, NEPER, CUBIT); ``docs/conf.py`` mocks those imports, so it runs from a plain checkout. .. _pandoc-prerequisite: System prerequisite: pandoc --------------------------- The tutorials are Jupyter notebooks, and ``nbsphinx`` converts them by shelling out to the **pandoc** binary. pandoc is a system program, not a Python package, so ``pip install -e ".[docs]"`` does **not** install it. Without it the build stops at the first notebook with:: nbsphinx.PandocMissing: Pandoc wasn't found. Install it with your system package manager, or into the build environment: .. code-block:: bash sudo apt-get install pandoc # Debian/Ubuntu (what CI uses) brew install pandoc # macOS conda install -c conda-forge pandoc # conda environments Other platforms and the official installers are at https://pandoc.org/installing.html. Install the docs toolchain -------------------------- .. code-block:: bash pip install -e ".[docs]" Build the HTML -------------- .. code-block:: bash cd docs make html # open docs/_build/html/index.html For a strict build that treats warnings (broken cross-references, import failures) as errors, the same check CI runs: .. code-block:: bash sphinx-build -W --keep-going -b html docs docs/_build/html Doc tests --------- Runnable snippets marked with the ``doctest`` directive are executed by the doctest builder, and external links are checked by the linkcheck builder: .. code-block:: bash make -C docs doctest make -C docs linkcheck A minimal doctest, verifying the package imports and exposes a version string: .. doctest:: >>> import graintrace >>> isinstance(graintrace.__version__, str) True Continuous integration ---------------------- ``.github/workflows/build_docs.yml`` runs the strict HTML build plus ``doctest`` and ``linkcheck`` on every push and pull request to ``main`` and ``documentation``. ``linkcheck`` is informational and does not fail the job; the strict build and ``doctest`` do. Every run — any branch, any pull request — uploads the built HTML as a downloadable ``docs-html`` artifact, so a change can be reviewed without deploying. Only a push to ``main`` deploys, via GitHub's own ``actions/deploy-pages`` (OIDC, ``pages: write`` + ``id-token: write``). There is no ``gh-pages`` branch and pull requests get no live preview URL; download the artifact instead. Writing new pages ----------------- - API pages under ``docs/api/`` are thin ``automodule`` stubs; add one per new public module and list it in ``docs/api/api.rst``. - Tutorial pages under ``docs/tutorials/`` are Jupyter notebooks, listed in ``docs/tutorials/tutorials.rst``. They carry their code inline rather than including the matching ``examples/`` script; keep the two in step by hand. - New prose pages must be **reStructuredText**. ``myst_parser`` is not installed and ``source_suffix`` is not set, so a ``.md`` file dropped into ``docs/`` is silently ignored rather than reported as an error. - Keep the prose plain and factual; let the code examples carry the detail. - Define every symbol you introduce, or point at :doc:`notation`. Equations that a later paragraph refers to get a ``:label:`` and are cited with ``:eq:``. .. _definition-of-done: Definition of done (adding or changing code) -------------------------------------------- A new feature or code change is not complete until all five of these are done in the same change: 1. **Tests pass.** Add or extend tests under ``tests/`` and keep the suite green: ``pytest``, ``black --check graintrace tests``, and ``pylint --rcfile=.pylintrc graintrace``. Tests that need the external stack self-skip via ``pytest.importorskip``/``skipif``. 2. **Docstrings updated.** Every new or changed public class, method, and function has a docstring (Google or NumPy style). Document new constructor keyword arguments; they surface directly in the API reference. 3. **Docs updated.** Update the relevant tutorial under ``docs/tutorials/``, :doc:`configuration` for new options, and add an ``automodule`` page under ``docs/api/`` for a new public module. The strict build and ``doctest`` must pass (see above). 4. **CLAUDE.md updated.** Update ``.claude/CLAUDE.md`` (the working reference for the codebase) so it stays the source of truth. 5. **MCP updated.** If the change is a workflow segment or adds/changes user-facing parameters, update the MCP tool in ``graintrace/mcp/tools/``, its recipe in ``graintrace/mcp/recipes/``, and the tool table in ``graintrace/mcp/README.md``. New external-tool dependencies must be reported by ``dependency_status``.