Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/extensions/docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,17 @@ Extensions
`ubCode <https://ubcode.useblocks.com>`__ VS Code extension.
Getting IDE support for Sphinx-Needs in a Bazel context made easy.

.. grid-item-card::

Module Verification Report
^^^
One Need per module gives that module a report page whose sections behave
like ordinary RST.
:ref:`Module Verification Report<module-verification-report>`,
or jump straight to the
:ref:`live example<module-verification-report-example>`.


.. grid-item-card::

Mounts
Expand All @@ -80,4 +91,6 @@ Extensions
Source Code Linker <source_code_linker>
Extension Guide <extension_guide>
Sync TOML <sync_toml>
Module Verification Report <module_verification_report>
Module Verification Report Example <module_verification_report_example>
mounts_internals
111 changes: 111 additions & 0 deletions src/extensions/docs/module_verification_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<!-- ----------------------------------------------------------------------------
Copyright (c) 2026 Contributors to the Eclipse Foundation

See the NOTICE file(s) distributed with this work for additional
information regarding copyright ownership.

This program and the accompanying materials are made available under the
terms of the Apache License Version 2.0 which is available at
https://www.apache.org/licenses/LICENSE-2.0

SPDX-License-Identifier: Apache-2.0
----------------------------------------------------------------------------- -->

(module-verification-report)=
# Module Verification Report

Give a module a verification report page by writing **one Need**. The report's
sections are ordinary RST sections: they appear in the sidebar and the local
ToC, they are `:ref:`-able from other pages, they land in the search index, and
they survive into non-HTML builders.

---

## Authoring

```rst
.. mod_ver_report:: Baselibs Verification Report
:id: mod_vrep__baselibs
:belongs_to: mod__baselibs
:covers: comp__baselibs_json, comp__baselibs_bit_manipulation
:safety: ASIL_B
:security: NO
:status: valid
:verification_method: test
:titles:
comp__baselibs_json = JSON Utilities

Free-form introduction. It becomes the Need's description.
```

Scaling to N modules means adding N Needs — nothing else.

### Options

| Option | Meaning |
| ------ | ------- |
| *argument* | Report title. |
| `:id:` | Report Need id. Mandatory; also namespaces every generated anchor. |
| `:belongs_to:` | The module this report is about. |
| `:covers:` | The components in scope. A **real link field**, comma and/or whitespace separated. |
| `:titles:` | Optional presentation-only heading overrides, one `id = Heading` per line. |
| *anything else* | Forwarded verbatim to the Need. The metamodel decides what is valid. |

Everything except `:titles:` ends up on the Need, so `covers_back` and the usual
link validation come for free.

### Generated sections

1. **Report Metadata** — the report's own fields.
2. **Verification Scope** — the covered components.
3. **One section per covered component** — a `:need:` reference plus a table of
everything related to it.
4. **Verification Evidence** — whatever links to the report via `contains` or
`evidence`.

Anchors are namespaced with the report id, e.g.

```rst
See :ref:`mod_vrep__baselibs__comp__baselibs_json`.
```

so they are stable across rebuilds and two reports on one page never collide.

---

## Why the component list has to be written out

Sphinx turns headings into sections exactly once, during the read phase, before
the Need graph exists. A report cannot therefore discover its own components
from the graph and still get real sections — the two happen at different times.

So the list is authored, and drift is **detected rather than silently
corrected**: the metamodel check
`check_mod_ver_report_scope` compares the report's `:covers:` against the
module's `includes` in **both** directions and fails the build if they differ.
The fix is always a one-line edit.

---

## Design rule for contributors

> The extension emits RST. It never reads the Need model to compute an answer.

The directive emits `needtable` filters and `:need:` references; sphinx-needs
resolves them after collection. That is why the extension has no `NeedsView`, no
registry, no `build-finished` pass and no build lifecycle hooks at all.

If new report content needs Python that walks needs and computes something, the
line has been crossed. If it needs a new `needtable` filter, it has not.

Two invariants are enforced by tests and must not be "cleaned up":

- **The report body is a sibling of the Need, not its child.** sphinx-needs
parses Need content with `match_titles=False`; moving the body inside the Need
node silently removes every section, and the HTML still looks fine.
- **`setup()` registers directives and nothing else.** The single
`config-inited` handler exists only because directive registration is
last-one-wins.

See `src/extensions/score_module_verification_report/README.md` for the
configuration values and the full rationale.
166 changes: 166 additions & 0 deletions src/extensions/docs/module_verification_report_example.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
..
# *******************************************************************************
# Copyright (c) 2026 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
#
# This program and the accompanying materials are made available under the
# terms of the Apache License Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0
# *******************************************************************************

.. _module-verification-report-example:

==========================================
Module Verification Report: Live Example
==========================================

This page renders a real report. Everything below the "Rendered report" heading
is produced by a single ``mod_ver_report`` directive — look at the sidebar and
the local contents to see that its sections are ordinary RST sections.

See :ref:`module-verification-report` for the reference documentation.

.. note::

The architecture needs on this page exist only to give the example something
to point at. They are not part of the Docs-as-Code architecture.

The module being reported on
============================

A module with two components:

.. feat:: Example Baselibs Feature
:id: feat__example_baselibs
:version: 1
:security: NO
:safety: QM
:status: valid

Container feature for the example components.

.. comp:: Example JSON Component
:id: comp__example_baselibs_json
:version: 1
:security: NO
:safety: QM
:status: valid
:belongs_to: feat__example_baselibs

Parses and serialises JSON.

.. comp:: Example Bit Manipulation Component
:id: comp__example_baselibs_bits
:version: 1
:security: NO
:safety: QM
:status: valid
:belongs_to: feat__example_baselibs

Bit-level helpers.

.. comp_arc_sta:: Example JSON Package Diagram
:id: comp_arc_sta__example_feature__json
:version: 1
:security: NO
:safety: QM
:status: valid
:belongs_to: comp__example_baselibs_json

An architecture view of the JSON component. It shows up in the JSON
component's table below because it links to that component.

.. comp_arc_sta:: Example Bit Manipulation Package Diagram
:id: comp_arc_sta__example_feature__bits
:version: 1
:security: NO
:safety: QM
:status: valid
:belongs_to: comp__example_baselibs_bits

An architecture view of the bit manipulation component.

.. workproduct:: Example Baselibs Test Report
:id: wp__example_baselibs_test_report
:version: 1
:status: valid

Stands in for the artefact backing the verification report. The report links
to it with ``evidence``, so it appears in the report's Verification Evidence
section.

.. mod:: Example Baselibs Module
:id: mod__example_baselibs
:version: 1
:security: NO
:safety: QM
:status: valid
:includes: comp__example_baselibs_json, comp__example_baselibs_bits

The module the report below is about.

What the author writes
======================

One Need. That is the whole input for the page you see below it:

.. code-block:: rst

.. mod_ver_report:: Example Baselibs Verification Report
:id: mod_vrep__example_feature__baselibs
:version: 1
:belongs_to: mod__example_baselibs
:covers: comp__example_baselibs_json, comp__example_baselibs_bits
:safety: QM
:security: NO
:status: valid
:verification_method: test_and_inspection
:evidence: wp__example_baselibs_test_report
:titles:
comp__example_baselibs_json = JSON Utilities
comp__example_baselibs_bits = Bit Manipulation

Verification report for the example Baselibs module.

``:covers:`` is a real link field, so ``mod__example_baselibs`` gets a
``covered by`` backlink and the metamodel checks that the list matches the
module's ``includes`` in both directions. ``:titles:`` is optional; without it
the headings are derived from the component ids.

Rendered report
===============

.. mod_ver_report:: Example Baselibs Verification Report
:id: mod_vrep__example_feature__baselibs
:version: 1
:belongs_to: mod__example_baselibs
:covers: comp__example_baselibs_json, comp__example_baselibs_bits
:safety: QM
:security: NO
:status: valid
:verification_method: test_and_inspection
:evidence: wp__example_baselibs_test_report
:titles:
comp__example_baselibs_json = JSON Utilities
comp__example_baselibs_bits = Bit Manipulation

Verification report for the example Baselibs module.

The sections are real
=====================

Each generated section carries an anchor namespaced with the report id, so it
can be referenced from anywhere like any other section:

.. code-block:: rst

See :ref:`mod_vrep__example_feature__baselibs__comp__example_baselibs_json`.

Which renders as: :ref:`mod_vrep__example_feature__baselibs__comp__example_baselibs_json`
— the link text comes from the section title, because the target *is* a
section. The same anchors appear in the sidebar, in the local contents, in the
search index and in the LaTeX/PDF bookmarks.
Loading
Loading